系列:100 天系统学习 AI Agent 开发
当前阶段:RAG、知识库与工具边界
今日目标:查询改写可以把口语化问题转成更适合检索的关键词、子问题或多路查询。
“这个怎么部署”不是一个完整查询
“这个”指哪个项目?部署到本地、容器还是云平台?用户想要安装命令,还是正在排查报错?如果直接把这六个字拿去搜,检索系统只能猜,召回一堆看似相关的部署页面。
Query Rewrite 的意义不是把句子润色得更正式,而是把隐含条件显式化,让检索器得到可执行查询。最危险的副作用也在这里:改写器可能替用户补了一个并不存在的条件,悄悄改变原意。
四种不同的改写动作
| 动作 | 适用情况 | 示例 | 风险 |
|---|---|---|---|
| 规范化 | 同义词、缩写、错别字 | “py 环境”→“Python 运行环境” | 专有名词被误改 |
| 补上下文 | 代词依赖当前会话 | “这个”→“当前讨论的 LangGraph 项目” | 引用对象解析错 |
| 拆子问题 | 一个问题含多个信息需求 | 环境、命令、常见错误 | 子问题失去共同约束 |
| 多路查询 | 用户表达与文档措辞可能不同 | “恢复任务”“checkpoint resume” | 查询过多引入噪声和成本 |
改写前应先判断信息是否足够。缺少关键实体时,最好的 rewrite 是不改写,先追问。
把一句话拆成三条可检索查询
假设会话已明确对象为“某个 Python Agent 项目”,目标是“本地部署”。在这个前提下,可以得到:
- 环境:该项目本地部署需要的 Python 版本、系统依赖和环境变量;
- 命令:从安装依赖到启动服务的官方命令顺序;
- 错误:本地启动时端口占用、缺少密钥、依赖冲突的排查方法。
如果对象和环境没有被确认,上述内容只能作为模板,不能直接当真实查询。结构化输出可以把“已知”和“未知”分开:
{
"original_query": "这个怎么部署",
"resolved_context": {
"target": null,
"environment": null,
"version": null
},
"missing_fields": ["target", "environment"],
"decision": "ask_user",
"rewritten_queries": []
}
信息齐全后才生成查询:
{
"original_query": "这个怎么部署",
"resolved_context": {
"target": "example-agent",
"environment": "local",
"version": "2.4"
},
"decision": "search",
"rewritten_queries": [
"example-agent 2.4 本地部署 环境依赖",
"example-agent 2.4 本地安装 启动命令",
"example-agent 2.4 本地启动 常见错误"
]
}
一条防止意图漂移的流程
原始问题必须进入 trace。只保存改写结果,失败时无法判断是用户表达含糊、上下文解析错,还是检索本身有问题。
怎么评测改写好不好
不要给改写句子打“更自然”的分,而要看它是否改善检索:
| 样本 | 原查询命中 | 改写后命中 | 意图是否保持 | 结论 |
|---|---|---|---|---|
| 有明确对象的部署问题 | 待运行 | 待运行 | 待审查 | 比较 Top K |
| 缺少对象 | 不应搜索 | 不应搜索 | 应追问 | 测路由 |
| 指定旧版本 | 待运行 | 待运行 | 必须保留版本 | 测约束 |
| 专有名词拼写相近 | 待运行 | 待运行 | 不得擅自替换 | 测实体保护 |
有些短查询已经足够精确,例如错误码、函数名、订单号,不必为了使用技术而改写。多路查询也要限制数量并去重,否则延迟和噪声会同时上升。
我的阶段性判断
好的 Query Rewrite 更像一个谨慎的翻译员:把口语转成检索语言,但不替用户做主。它要敢于保留未知、敢于追问,也要把每次补充条件的来源说清。下一篇进入 RAG 评测后,我会把“意图保持”与“检索提升”拆成两项,而不是只看最终答案。
面试官会追问:Query Rewrite 会不会把用户意思改错?
会,所以改写不能只追求“更专业”。我会让改写器同时输出 original_intent、rewritten_queries、assumptions 和 must_keep_entities;订单号、产品型号、时间范围等实体必须原样保留。信息不足时生成澄清问题,而不是偷偷补一个假设。
评测时准备三类样本:口语省略、上下文指代、带精确实体的混合查询。除了检索 Recall,还要检查“意图保持率”。例如“它支持私有部署吗”若上一轮讨论的是 Qdrant,改写必须包含 Qdrant;若上下文里有两个产品,就应该追问。
面试回答可以总结为:Query Rewrite 是受约束的检索适配器,不是自由发挥的文案润色器。
今日检查清单
- 永远保留 original_query 和上下文来源
- 缺关键实体时先追问,不靠模型脑补
- 版本、权限、租户等硬约束不能被改写掉
- 用同一问题集比较改写前后检索命中
- 多路查询有数量、去重和成本限制

208

被折叠的 条评论
为什么被折叠?



