c56bef871b
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
152 lines
6.1 KiB
Plaintext
152 lines
6.1 KiB
Plaintext
---
|
|
title: "MultiQueryEmbeddingRetriever"
|
|
id: multiqueryembeddingretriever
|
|
slug: "/multiqueryembeddingretriever"
|
|
description: "Retrieves documents using multiple queries in parallel with an embedding-based Retriever."
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs';
|
|
import TabItem from '@theme/TabItem';
|
|
|
|
# MultiQueryEmbeddingRetriever
|
|
|
|
Retrieves documents using multiple queries in parallel with an embedding-based Retriever.
|
|
|
|
<div className="key-value-table">
|
|
|
|
| | |
|
|
| --- | --- |
|
|
| **Most common position in a pipeline** | After a [`QueryExpander`](../query/queryexpander.mdx) component, before a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) in RAG pipelines |
|
|
| **Mandatory init variables** | `retriever`: An embedding-based Retriever (such as `InMemoryEmbeddingRetriever`)<br />`query_embedder`: A Text Embedder component |
|
|
| **Mandatory run variables** | `queries`: A list of query strings |
|
|
| **Output variables** | `documents`: A list of retrieved documents sorted by relevance score |
|
|
| **API reference** | [Retrievers](/reference/retrievers-api) |
|
|
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/components/retrievers/multi_query_embedding_retriever.py |
|
|
|
|
</div>
|
|
|
|
## Overview
|
|
|
|
`MultiQueryEmbeddingRetriever` improves retrieval recall by searching for documents using multiple queries in parallel. Each query is converted to an embedding using a Text Embedder, and an embedding-based Retriever fetches relevant documents.
|
|
|
|
The component:
|
|
- Processes queries in parallel using a thread pool for better performance
|
|
- Automatically deduplicates results based on document content
|
|
- Sorts the final results by relevance score
|
|
|
|
This Retriever is particularly effective when combined with [`QueryExpander`](../query/queryexpander.mdx), which generates multiple query variations from a single user query. By searching with these variations, you can find documents that might not match the original query phrasing but are still relevant.
|
|
|
|
Use `MultiQueryEmbeddingRetriever` when your documents use different words than your users' queries, or when you want to find more diverse results in RAG pipelines. Running multiple queries takes more time, but you can speed it up by increasing `max_workers` to run queries in parallel.
|
|
|
|
:::tip[When to use a `MultiQueryTextRetriever` instead]
|
|
|
|
If you need exact keyword matching and don't want to use embeddings, use [`MultiQueryTextRetriever`](multiquerytextretriever.mdx) instead. It works with text-based Retrievers like `InMemoryBM25Retriever` and is better when synonyms can be generated through query expansion.
|
|
:::
|
|
|
|
### Passing Additional Retriever Parameters
|
|
|
|
You can pass additional parameters to the underlying Retriever using `retriever_kwargs`:
|
|
|
|
```python
|
|
result = multi_query_retriever.run(
|
|
queries=["renewable energy", "sustainable power"],
|
|
retriever_kwargs={"top_k": 5},
|
|
)
|
|
```
|
|
|
|
## Usage
|
|
|
|
This pipeline takes a single query "sustainable power generation" and expands it into multiple variations using an LLM (for example: "renewable energy sources", "green electricity", "clean power"). The Retriever then converts each variation to an embedding and searches for similar documents. This way, documents about "solar energy" or "wind energy" can be found even though they don't contain the words "sustainable power generation".
|
|
|
|
Before running the pipeline, documents must be embedded using a Document Embedder and stored in the Document Store.
|
|
|
|
<Tabs>
|
|
<TabItem value="python" label="Python" default>
|
|
|
|
```python
|
|
from haystack import Document, Pipeline
|
|
from haystack.document_stores.in_memory import InMemoryDocumentStore
|
|
from haystack.components.embedders import (
|
|
SentenceTransformersTextEmbedder,
|
|
SentenceTransformersDocumentEmbedder,
|
|
)
|
|
from haystack.components.retrievers import (
|
|
InMemoryEmbeddingRetriever,
|
|
MultiQueryEmbeddingRetriever,
|
|
)
|
|
from haystack.components.query import QueryExpander
|
|
|
|
documents = [
|
|
Document(
|
|
content="Renewable energy is energy that is collected from renewable resources.",
|
|
),
|
|
Document(
|
|
content="Solar energy is a type of green energy that is harnessed from the sun.",
|
|
),
|
|
Document(
|
|
content="Wind energy is another type of green energy that is generated by wind turbines.",
|
|
),
|
|
Document(
|
|
content="Geothermal energy is heat that comes from the sub-surface of the earth.",
|
|
),
|
|
]
|
|
|
|
doc_store = InMemoryDocumentStore()
|
|
doc_embedder = SentenceTransformersDocumentEmbedder(
|
|
model="sentence-transformers/all-MiniLM-L6-v2",
|
|
)
|
|
doc_embedder.warm_up()
|
|
documents_with_embeddings = doc_embedder.run(documents)["documents"]
|
|
doc_store.write_documents(documents_with_embeddings)
|
|
|
|
pipeline = Pipeline()
|
|
pipeline.add_component("query_expander", QueryExpander(n_expansions=3))
|
|
pipeline.add_component(
|
|
"retriever",
|
|
MultiQueryEmbeddingRetriever(
|
|
retriever=InMemoryEmbeddingRetriever(document_store=doc_store, top_k=2),
|
|
query_embedder=SentenceTransformersTextEmbedder(
|
|
model="sentence-transformers/all-MiniLM-L6-v2",
|
|
),
|
|
),
|
|
)
|
|
pipeline.connect("query_expander.queries", "retriever.queries")
|
|
|
|
result = pipeline.run({"query_expander": {"query": "sustainable power generation"}})
|
|
|
|
for doc in result["retriever"]["documents"]:
|
|
print(f"Score: {doc.score:.3f} | {doc.content}")
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="yaml" label="YAML">
|
|
|
|
```yaml
|
|
components:
|
|
query_expander:
|
|
type: haystack.components.query.query_expander.QueryExpander
|
|
init_parameters:
|
|
n_expansions: 3
|
|
retriever:
|
|
type: haystack.components.retrievers.multi_query_embedding_retriever.MultiQueryEmbeddingRetriever
|
|
init_parameters:
|
|
retriever:
|
|
type: haystack.components.retrievers.in_memory.embedding_retriever.InMemoryEmbeddingRetriever
|
|
init_parameters:
|
|
document_store:
|
|
type: haystack.document_stores.in_memory.document_store.InMemoryDocumentStore
|
|
init_parameters: {}
|
|
top_k: 2
|
|
query_embedder:
|
|
type: haystack.components.embedders.sentence_transformers_text_embedder.SentenceTransformersTextEmbedder
|
|
init_parameters:
|
|
model: sentence-transformers/all-MiniLM-L6-v2
|
|
|
|
connections:
|
|
- sender: query_expander.queries
|
|
receiver: retriever.queries
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|