MultiQueryEmbeddingRetriever
MultiQueryEmbeddingRetriever
임베딩 기반 Retriever로 여러 개의 검색어를 병렬로 사용해 문서를 검색해 주는 컴포넌트예요.
출처: 문서
본문
MultiQueryEmbeddingRetriever는 여러 검색어를 병렬로 검색해서 리트리벌 재현율(recall)을 높여요. 각 검색어는 Text Embedder로 임베딩으로 바뀌고, 임베딩 기반 Retriever가 관련 문서를 가져오죠.
이 컴포넌트는:
- 스레드 풀(thread pool)로 검색어를 병렬 처리해 성능을 개선해요.
- 문서 내용을 기준으로 결과의 중복을 자동으로 제거해요.
- 최종 결과를 관련성 점수순으로 정렬해요.
이 Retriever는 단일 사용자 검색어에서 여러 검색어 변형을 만들어 내는 QueryExpander와 함께 쓸 때 특히 효과적이에요. 이 변형들로 검색하면 원래 검색어 문구와 정확히 맞지 않아도 관련 있는 문서를 찾을 수 있어요.
문서가 사용자 검색어와 다른 단어를 쓰거나, RAG 파이프라인에서 더 다양한 결과를 얻고 싶을 때 MultiQueryEmbeddingRetriever를 쓰세요. 여러 검색어를 돌리는 건 시간이 더 걸리지만 max_workers를 늘려 병렬로 실행하면 빨라져요.
언제 MultiQueryTextRetriever를 쓸까?
정확한 키워드 일치가 필요하고 임베딩을 안 쓰고 싶다면 MultiQueryTextRetriever를 쓰세요. InMemoryBM25Retriever 같은 텍스트 기반 Retriever와 동작하며, 검색어 확장으로 동의어를 만들 수 있을 때 더 좋아요.
추가 Retriever 파라미터 넘기기
retriever_kwargs를 사용해 내부 Retriever에 추가 파라미터를 넘길 수 있어요.
result = multi_query_retriever.run(
queries=["renewable energy", "sustainable power"],
retriever_kwargs={"top_k": 5},
)
더 알아보기 (Learn more)
검색 파이프라인을 돌리기 전에 문서를 Document Embedder로 임베딩해서 Document Store에 저장해 두어야 해요.
이 페이지의 예제는 sentence-transformers-haystack 패키지의 Sentence Transformers 임베더를 사용해요. 예제를 실행하려면 설치하세요.
pip install sentence-transformers-haystack
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack_integrations.components.embedders.sentence_transformers 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",
)
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}")
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_integrations.components.embedders.sentence_transformers.sentence_transformers_text_embedder.SentenceTransformersTextEmbedder
init_parameters:
model: sentence-transformers/all-MiniLM-L6-v2
connections:
- sender: query_expander.queries
receiver: retriever.queries