OpenSearchHybridRetriever

OpenSearchHybridRetriever

OpenSearch를 백엔드 Document Store로 사용해 하이브리드 Retriever를 단일 컴포넌트로 구현한 SuperComponent예요.

출처: 문서

본문

하이브리드 Retriever는 문서 검색에 전통적인 키워드 기반 검색(BM25 등)과 임베딩 기반 검색을 모두 사용해서 두 방식의 장점을 결합해요. 그러고 나서 두 방식의 결과를 병합하고 재순위화하죠.

OpenSearchHybridRetriever는 두 가지 검색 방식을 결합해요.

  1. BM25 검색: BM25 알고리즘으로 용어 빈도와 역문서 빈도를 기반으로 문서를 찾는 키워드 기반 검색이에요. OpenSearchBM25Retriever 컴포넌트를 기반으로 하며 전통적인 키워드 검색에 적합해요.
  2. 임베딩 기반 검색: 검색어와 의미적으로 유사한 문서를 찾기 위해 벡터 유사도를 사용하는 시맨틱 검색이에요. OpenSearchEmbeddingRetriever 컴포넌트를 기반으로 하며 시맨틱 검색에 적합해요.

이 컴포넌트가 자동으로 처리하는 것:

  • 제공된 임베더로 검색어를 임베딩으로 변환
  • 두 검색 방식을 병렬로 실행
  • 지정된 조인 모드로 결과를 병합하고 재순위화

설정과 설치

pip install opensearch-haystack

선택 파라미터

이 Retriever는 다양한 선택 파라미터를 받아요. 최신 파라미터 목록은 API 참조에서 확인할 수 있어요.

bm25_retriever와 embedding_retriever 딕셔너리로 내부 컴포넌트에 추가 파라미터를 넘길 수 있어요. DocumentJoiner 파라미터는 OpenSearchHybridRetriever 클래스에 모두 노출되어 있어서 직접 설정할 수 있어요.

예를 들어:

retriever = OpenSearchHybridRetriever(
    document_store=document_store,
    embedder=embedder,
    bm25_retriever={"raise_on_failure": True},
    embedding_retriever={"raise_on_failure": False},
)

더 알아보기 (Learn more)

단독으로 쓰기

이 Retriever는 문서로 채워진 OpensearchDocumentStore가 필요해요. 단독으로는 쓸 수 없어요.

파이프라인에서 쓰기

OpenSearchHybridRetriever를 쓰는 기본 예제를 볼게요.

Docker로 OpenSearch를 로컬에서 실행할 수 있는 명령은 다음과 같아요. Docker가 설치·실행되고 있어야 해요. 이 예제는 단순함을 위해 보안 플러그인을 끈 점을 참고하세요. 운영 환경에서는 보안 기능을 켜야 해요.

docker run -d \
  --name opensearch-nosec \
  -p 9200:9200 \
  -p 9600:9600 \
  -e "discovery.type=single-node" \
  -e "DISABLE_SECURITY_PLUGIN=true" \
  opensearchproject/opensearch:3.5.0

이 페이지의 예제는 sentence-transformers-haystack 패키지의 Sentence Transformers 임베더를 사용해요. 예제를 실행하려면 설치하세요.

pip install sentence-transformers-haystack
from haystack import Document
from haystack_integrations.components.embedders.sentence_transformers import (
    SentenceTransformersTextEmbedder,
    SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.components.retrievers.opensearch import (
    OpenSearchHybridRetriever,
)
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore

# Initialize the document store
doc_store = OpenSearchDocumentStore(
    hosts=["http://localhost:9200"],
    index="document_store",
    embedding_dim=384,
)

# Create some sample documents
docs = [
    Document(content="Machine learning is a subset of artificial intelligence."),
    Document(content="Deep learning is a subset of machine learning."),
    Document(content="Natural language processing is a field of AI."),
    Document(content="Reinforcement learning is a type of machine learning."),
    Document(content="Supervised learning is a type of machine learning."),
]

# Embed the documents and add them to the document store
doc_embedder = SentenceTransformersDocumentEmbedder(
    model="sentence-transformers/all-MiniLM-L6-v2"
)
docs = doc_embedder.run(docs)
doc_store.write_documents(docs["documents"])

# Initialize some haystack text embedder, in this case the SentenceTransformersTextEmbedder
embedder = SentenceTransformersTextEmbedder(
    model="sentence-transformers/all-MiniLM-L6-v2"
)

# Initialize the hybrid retriever
retriever = OpenSearchHybridRetriever(
    document_store=doc_store,
    embedder=embedder,
    top_k_bm25=3,
    top_k_embedding=3,
    join_mode="reciprocal_rank_fusion",
)

# Run the retriever
results = retriever.run(
    query="What is reinforcement learning?", filters_bm25=None, filters_embedding=None
)

print(results)
# >> {'documents': [Document(id=..., content: 'Reinforcement learning is a type of machine learning.', score: 1.0),
# >>   Document(id=..., content: 'Supervised learning is a type of machine learning.', score: 0.9760624679979518),
# >>   Document(id=..., content: 'Deep learning is a subset of machine learning.', score: 0.4919354838709677),
# >>   Document(id=..., content: 'Machine learning is a subset of artificial intelligence.', score: 0.4841269841269841)]}