Query Rewriting
Query Rewriting 是在检索前用 LLM 改写用户查询,使其更适合检索。用户的问题可能模糊、口语化或包含指代,改写后检索更准确。
#type / concept
#status / evergreen
#tech / ai
[!info] related notes
- 所属 MOC: RAG Engineering MOC
- 相关: Retriever, Multi-query Retrieval
Query Rewriting
一句话定义
Query Rewriting 是在检索前用 LLM 改写用户查询。用户说”那个东西怎么退货”,改写成”退货流程和政策”后检索效果更好。
核心原理
改写类型
| 类型 | 原始查询 | 改写后 |
|---|---|---|
| 口语化转书面 | ”那个东西咋退" | "退货流程” |
| 指代消解 | ”它多少钱" | "iPhone 15 价格” |
| 扩展 | ”退款" | "退款流程 退货政策 退款时效” |
| 压缩 | ”我想问一下关于公司的年假政策是怎样的" | "公司年假政策” |
Python 实现
class QueryRewriter:
def __init__(self, llm):
self.llm = llm
async def rewrite(self, query: str, conversation_history: list = None) -> str:
prompt = f"""
请将以下用户查询改写为更适合搜索的形式。
规则:
- 去除口语化表达
- 消解指代词(他、它、那个)
- 保留核心意图
- 不要改变原意
"""
if conversation_history:
prompt += f"对话历史:\n{format_history(conversation_history)}\n\n"
prompt += f"用户查询: {query}\n\n改写后的查询:"
return await self.llm.chat(prompt)
常见设计模式
1. LLM 改写
用 LLM 理解意图后改写。
2. 同义词扩展
用同义词词典扩展查询。
3. HyDE (Hypothetical Document Embeddings)
让 LLM 生成一个假设的答案,用答案的 Embedding 去检索。
常见坑
- 改写丢失原意: LLM 过度改写导致偏离用户意图
- 不做改写: 口语化查询检索效果差
- 改写增加延迟: 每次检索前都调用 LLM