一、是什么?
HyDE(Hypothetical Document Embeddings,假设性文档嵌入)是一种 RAG 增强检索策略。
传统检索直接用用户的问题去匹配文档,而 HyDE 先让 LLM 根据问题生成一段假设性回答,再用这段回答去向量库中检索真实文档。
核心思想:用「像答案的文本」去找答案,语义更贴近,检索效果更好。
流程对比:
| 传统检索 | HyDE 检索 | |
|---|---|---|
| 检索输入 | 原始用户问题 | LLM 生成的假设性回答 |
| 语义匹配 | 问题与文档可能有差距 | 回答与文档语义更接近 |
| 额外消耗 | 无 | 一次 LLM 调用 |
二、有什么用?
- 用户问题模糊或较短,难以直接匹配文档
- 知识库内容专业性强,与日常问法差异大
- RAG 系统召回率不佳,需要提升检索质量
- 适用于企业知识库问答、技术文档检索、智能客服等场景
三、核心组件
1. WeaviateVectorStore(向量数据库)
Weaviate 是开源向量数据库,LangChain 通过 WeaviateVectorStore 封装了存储和检索接口。
index_name:Weaviate 中的集合名称text_key:存储原始文本的字段名embedding:向量化模型(此处用千帆 Embeddings)search_type="mmr":MMR 算法,兼顾相关性与结果多样性
2. HyDERetriever(自定义检索器)
继承 BaseRetriever,重写 _get_relevant_documents 方法实现 HyDE 逻辑。
3. LCEL 检索链
用 LangChain Expression Language(管道符 |)串联各组件,数据流如下:
用户 query
↓
RunnablePassthrough() # 透传原始问题
↓
ChatPromptTemplate # 构造生成假设回答的 prompt
↓
LLM(moonshot-v1-8k) # 生成假设性回答文本
↓
StrOutputParser() # 解析 LLM 输出为字符串
↓
Retriever(Weaviate MMR) # 用假设回答检索真实文档
↓
返回 List[Document]
四、示例代码
python
from typing import List
import dotenv
import weaviate
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.language_models import BaseLanguageModel
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.retrievers import BaseRetriever
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
from langchain_weaviate import WeaviateVectorStore
from weaviate.auth import AuthApiKey
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
dotenv.load_dotenv()
class HyDERetriever(BaseRetriever):
"""HyDE 混合策略检索器"""
retriever: BaseRetriever
llm: BaseLanguageModel
def _get_relevant_documents(
self, query: str, *, run_manager: CallbackManagerForRetrieverRun
) -> List[Document]:
# 1. 构建生成假设性文档的 prompt
prompt = ChatPromptTemplate.from_template(
"请用一段简洁的话(100字以内)来回答这个问题。\n"
"问题: {question}\n"
"回答: "
)
# 2. 构建 HyDE 检索链
chain = (
{"question": RunnablePassthrough()}
| prompt
| self.llm
| StrOutputParser()
| self.retriever
)
return chain.invoke(query)
# 1. 构建向量数据库与检索器
db = WeaviateVectorStore(
client=weaviate.connect_to_wcs(
cluster_url="<YOUR_CLUSTER_URL>",
auth_credentials=AuthApiKey("<YOUR_API_KEY>"),
),
index_name="DatasetDemo",
text_key="text",
embedding=QianfanEmbeddingsEndpoint(),
)
retriever = db.as_retriever(search_type="mmr")
# 2. 创建 HyDE 检索器
hyde_retriever = HyDERetriever(
retriever=retriever,
llm=ChatOpenAI(model="moonshot-v1-8k", temperature=0),
)
# 3. 执行检索
documents = hyde_retriever.invoke("关于 LLMOps 应用配置的文档有哪些?")
print(documents)
print(len(documents))
五、关键知识点
| 知识点 | 说明 | ||
|---|---|---|---|
BaseRetriever | LangChain 自定义检索器基类,重写 _get_relevant_documents 即可接入任意链路 | ||
| `LCEL 管道符 | ` | LangChain Expression Language,用 ` | ` 连接组件,数据从左向右流动 |
RunnablePassthrough | 透传输入值,常用于在字典结构中保留原始 query | ||
StrOutputParser | 将 LLM 返回的 AIMessage 对象转为纯字符串 | ||
MMR 算法 | Maximum Marginal Relevance,检索时兼顾相关性和多样性,避免返回重复文档 | ||
temperature=0 | 使 LLM 输出稳定确定,适合生成假设性文档等任务 |