Hypothetical Document Embeddings
Hypothetical Document Embeddings (HyDE)
검색 품질이 기대만큼 나오지 않을 때, 특히 성능이 떨어지는 검색 단계를 개선하고 싶을 때 쓸 수 있는 기법이에요. 초기 질의에 대해 "가상의 문서"를 생성해 검색을 강화하는 방법, HyDE를 소개합니다.
출처: 공식문서
언제 유용한가
HyDE 방법은 다음 상황에서 특히 유용합니다.
- 파이프라인의 검색 단계 성능이 충분하지 않을 때(예: 낮은 Recall 메트릭).
- 검색 단계가 질의를 입력으로 받고 더 큰 문서 기반에서 문서를 반환할 때.
- 특히 데이터(문서 또는 질의)가 Retriever가 훈련된 전형적인 데이터셋과 매우 다른 특수 도메인에서 오는 경우 시도해 볼 가치가 있습니다.
어떻게 동작하나
많은 임베딩 기반 retriever는 새롭고 본 적 없는 도메인에 일반화를 잘 못합니다. 이 접근 방식은 그 문제를 해결하려 합니다. 질의가 주어지면 Hypothetical Document Embeddings(HyDE)는 먼저 지시를 따르는 언어 모델을 zero-shot으로 프롬프트하여 초기 질의에서 관련 텍스트 패턴을 포착하는 "가짜" 가상 문서를 생성합니다. 실제로는 이 작업을 다섯 번 수행하죠. 그런 다음 각 가상 문서를 임베딩 벡터로 인코딩하고 평균을 냅니다. 결과로 나온 단일 임베딩은 문서 임베딩 공간에서 이웃을 식별하는 데 쓸 수 있고, 벡터 유사도를 기준으로 비슷한 실제 문서가 검색됩니다. 다른 retriever와 마찬가지로 이렇게 검색된 문서는 파이프라인 하류(예: RAG용 Generator)에서 사용할 수 있습니다. 자세한 내용은 "Precise Zero-Shot Dense Retrieval without Relevance Labels" 논문을 참고하세요.

Haystack에서 어떻게 만드나
먼저 필요한 컴포넌트를 모두 준비합니다.
이 페이지의 예시는 sentence-transformers-haystack 패키지로 이동한 Sentence Transformers embedder를 사용합니다. 예시를 실행하려면 설치하세요.
pip install sentence-transformers-haystack
import os
from numpy import array, mean
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.builders import ChatPromptBuilder
from haystack import component, Document
from haystack.components.converters import OutputAdapter
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack.dataclasses import ChatMessage
# We need to ensure we have the OpenAI API key in our environment variables
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_KEY"
# Initializing standard Haystack components
generator = OpenAIChatGenerator(
model="gpt-4o-mini",
generation_kwargs={"n": 5, "temperature": 0.75, "max_tokens": 400},
)
prompt_builder = ChatPromptBuilder(
template=[
ChatMessage.from_user(
"""Given a question, generate a paragraph of text that answers the question. Question: {{question}} Paragraph:""",
),
],
required_variables="*",
)
# The ChatGenerator returns ChatMessage replies, so we read each reply's text.
# unsafe=True lets the adapter return actual Document objects instead of a string.
adapter = OutputAdapter(
template="{{answers | build_doc}}",
output_type=list[Document],
custom_filters={"build_doc": lambda data: [Document(content=d.text) for d in data]},
unsafe=True,
)
embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
# Adding one custom component that returns one, "average" embedding from multiple (hypothetical) document embeddings
@component
class HypotheticalDocumentEmbedder:
@component.output_types(hypothetical_embedding=list[float])
def run(self, documents: list[Document]):
stacked_embeddings = array([doc.embedding for doc in documents])
avg_embeddings = mean(stacked_embeddings, axis=0)
hyde_vector = avg_embeddings.reshape((1, len(avg_embeddings)))
return {"hypothetical_embedding": hyde_vector[0].tolist()}
그다음 그것들을 모두 파이프라인으로 조립합니다.
from haystack import Pipeline
pipeline = Pipeline()
pipeline.add_component(name="prompt_builder", instance=prompt_builder)
pipeline.add_component(name="generator", instance=generator)
pipeline.add_component(name="adapter", instance=adapter)
pipeline.add_component(name="embedder", instance=embedder)
pipeline.add_component(name="hyde", instance=HypotheticalDocumentEmbedder())
pipeline.connect("prompt_builder.prompt", "generator.messages")
pipeline.connect("generator.replies", "adapter.answers")
pipeline.connect("adapter.output", "embedder.documents")
pipeline.connect("embedder.documents", "hyde.documents")
query = "What should I do if I have a fever?"
result = pipeline.run(data={"prompt_builder": {"question": query}})
# 'hypothetical_embedding': [0.0990725576877594, -0.017647066991776227, 0.05918873250484467, ...]}
결과 파이프라인의 그래프는 이렇습니다.

이 파이프라인 예시는 질의를 하나의 임베딩으로 만듭니다.
이 임베딩을 아무 Embedding Retriever에 넣어 Document Store에서 유사한 문서를 찾는 데 계속 사용할 수 있어요.
더 알아보기
📚 아티클: Optimizing Retrieval with HyDE
🧑🍳 쿡북: Using Hypothetical Document Embedding (HyDE) to Improve Retrieval