查询改写与 HyDE:提升检索命中率
用户提问和文档措辞往往不匹配。学习查询改写、多查询扩展与 HyDE 提升召回。
检索失败的头号原因:词汇不匹配
用户问"钱怎么退回来",文档写"退款流程" —— 向量再近也有距离。先改写查询,再检索,是性价比最高的优化。
多查询扩展(Multi Query)
让模型把一个问题改写成多个不同角度的查询,分别检索后合并去重:
from langchain.retrievers.multi_query import MultiQueryRetriever
retriever = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(), llm=llm)
docs = retriever.invoke("钱怎么退回来?")
# 内部自动生成:"退款流程是什么" "如何申请退款" 等多个查询
HyDE:假设文档检索
思路反直觉但有效:先让模型编一个假想的答案,拿这个"答案"去检索 —— 因为答案和真实文档的措辞天然接近:
hyde_prompt = ChatPromptTemplate.from_template(
"写一段可能的答案(可以不准确):{question}")
hyde_chain = hyde_prompt | llm | StrOutputParser()
fake_answer = hyde_chain.invoke({"question": q})
docs = vectorstore.similarity_search(fake_answer, k=3)
压缩与上下文优化
检索到的片段可能很长,ContextualCompressionRetriever 用模型把片段压缩到只保留与问题相关的句子,减少噪声、节省 token。
调参顺序建议:先查询改写 → 再调 chunk 大小 → 最后才考虑换 embedding 模型。
📝 课后练习
quiz-1 HyDE 检索策略的做法是?