Appearance
检索查询改写专题
版本:
v1.2最后更新:
2026-07-09
很多 RAG 系统失败,并不是因为知识库里没有答案,而是因为:
- 用户的问题表达太口语
- 查询词和文档里的标准术语不一致
- 多轮对话里充满代词、省略和上下文依赖
- 原始问题同时混着多个意图、多个限制条件
这也是为什么检索查询改写经常是 RAG 优化里性价比很高的一步。它不直接增加知识,也不直接提高模型推理能力,但它会显著改变:
- 召回到什么证据
- 是否能命中权威文档
- 上下文里噪音有多少
- 最终答案是不是更接近用户真实意图
1. 什么是查询改写
更实用的理解通常是:
- 在真正检索前
- 把用户原始问题改写成更适合召回知识的查询表达
它不是简单“换个说法”,而是为了让检索系统更容易命中正确证据。
这个动作通常位于:
text
User Question
-> Query Understanding
-> Query Rewrite / Expansion
-> Retrieval
-> Rerank
-> Context Assembly
-> Answer Generation查询改写不是回答问题本身,而是在为后续检索做“查询工程”。
2. 为什么原始用户问题经常不适合直接检索
真实用户的问题往往不是为搜索引擎写的,而是为人写的。常见情况包括:
- 表达省略
- 指代不明
- 多轮上下文依赖强
- 术语口语化
- 混杂多个意图
- 把真正问题埋在长段背景里
例如这些问题都很常见:
这个开票后还能退吗刚才那个审批链要走几级500 这个错怎么处理帮我看下企业版那个退款规则
如果把原问题原样送进检索,系统很容易:
- 命中表面相似但业务无关的内容
- 错过标准术语文档
- 召回过宽,导致上下文被噪音填满
- 把多意图问题误当单意图处理
3. 查询改写到底在解决什么
查询改写通常在解决四类问题。
3.1 语义补全
用户没有把必要上下文说完整,系统需要补足:
- 产品名
- 模块名
- 当前实体
- 上下文里的主语
例如:
这个开票后还能退吗
在多轮上下文里可能需要改成:
企业版订单开票后是否支持退款
3.2 术语标准化
用户说的是口语,文档里写的是标准术语。
例如:
打钱回去撤单关单
文档里实际可能对应:
退款取消订单关闭工单
3.3 多意图拆分
一个问题里同时有多个子问题,直接检索会让候选结果混杂。
例如:
帮我看下企业版价格,顺便看开票后还能不能退
这类问题更适合拆成两个检索子任务:
- 企业版价格
- 开票后退款政策
3.4 检索展开
不是只生成一个 query,而是生成多个并行检索表达,覆盖不同说法。
这通常适合:
- 术语别名多
- 中英混用
- 业务黑话多
- 用户表达波动大的系统
4. 查询改写不是越激进越好
查询改写常见误区是:
- 只要能多召回,就认为改写有效
但真正要看的不是:
- 改写后召回更多了没有
而是:
- 改写后是否更接近用户真实意图
因为改写过度会带来新的问题:
- 改写偏离原意
- 加入错误约束条件
- 错把单问题拆成多个不相关问题
- 用标准术语覆盖掉用户真正问的边界条件
- 对精确编号、错误码、产品码做了不该做的“语义化”
尤其是下面这些内容,经常不适合被“聪明改写”:
- 错误码
- 产品型号
- 合同条款号
- 法条编号
- 工单号
- 订单号
这类 query 往往更适合保留原词精确检索。
5. 更实用的查询改写分类法
把查询改写分成几类来治理,比一套 prompt 包打天下更稳。
5.1 归一化改写
目标:
- 去掉明显无意义噪音
- 保留原始核心意图
- 标准化格式
适合:
- 语气词多
- 口语化严重
- 中英混杂但结构简单
5.2 上下文补全改写
目标:
- 从多轮会话里恢复出完整主语、对象和约束条件
适合:
这个那个刚才那个规则上次说的审批
这类问题一定要谨慎,最好保留原 query 和补全后的 query 供回放。
5.3 术语映射改写
目标:
- 把用户说法映射到知识库标准表达
例如:
打款->退款报销单->费用报销申请白名单->允许名单
适合:
- 企业内部黑话重
- 术语标准化严格
- 同义表达很多
5.4 多查询展开
目标:
- 生成多个等价或互补查询,扩大召回覆盖
适合:
- 语义别名很多
- 文档说法不统一
- 产品线历史文档口径不一致
但要注意控制展开数量,不然会导致:
- 候选集爆炸
- rerank 成本飙升
- 上下文噪音增加
5.5 结构化条件抽取
目标:
- 从自然语言里提取可过滤字段
例如:
- 产品线
- 部门
- 时间范围
- 租户
- 文档类型
这比只做自由文本改写更适合企业知识库。因为很多企业检索失败,不是语义没对上,而是缺少过滤条件。
6. 查询改写应当保留原始问题,而不是覆盖原问题
这是非常重要的一条工程原则。
不要把查询改写做成:
- 改完就把原 query 丢掉
更稳妥的做法通常是保留三份内容:
- 原始 query
- 改写后 query
- 改写理由或改写类型
例如:
json
{
"original_query": "这个开票后还能退吗",
"rewritten_query": "企业版订单开票后是否支持退款",
"rewrite_type": "context_completion",
"rewrite_reason": "从上一轮会话补全产品对象为企业版订单"
}这样做的收益很直接:
- 方便排查误改写
- 方便把失败样例回流到评测集
- 方便比较“原查”和“改写查”的效果差异
7. 查询改写如何进入多轮对话系统
多轮系统里,很多检索失败并不是用户不会问,而是系统没把上下文接对。
查询改写在多轮场景里通常要额外处理:
- 当前轮的显式问题
- 上一轮提到的实体
- 当前会话里的目标对象
- 已确认的业务约束
但不要把整段聊天历史全拼进检索 query。
更推荐的做法是先做“会话状态抽取”,再改写:
json
{
"entity": "企业版订单",
"topic": "退款政策",
"constraint": "已开票",
"user_query": "这个还能退吗"
}然后输出更适合检索的 query:
企业版订单 已开票 退款政策
这通常比把 20 轮聊天都塞进检索更稳。
8. 查询改写和 metadata 过滤应一起设计
很多团队把 query 改写理解成“把文字改得更像搜索词”,但企业检索里常常还需要同步生成过滤条件。
例如问题:
今年生效的华东区企业客户退款规则是什么
除了 query 文本本身,系统还可能需要提取:
- 时间范围:
2026 - 区域:
华东 - 客户类型:
企业客户 - 文档类型:
政策
所以更成熟的输出通常不是一个字符串,而是一份结构化查询对象:
json
{
"query_text": "企业客户退款规则",
"filters": {
"region": "east_china",
"customer_type": "enterprise",
"effective_year": 2026
}
}这会让后续检索、缓存和回放都更稳定。
9. 改写最好有明确 contract,而不是随手写个 prompt
很多团队会先写一句:
- “请把用户问题改成更适合检索的问题”
然后就开始上线。
这通常不够,因为系统并没有明确:
- 哪些信息必须保留
- 哪些信息可以补
- 哪些信息禁止猜
- 输出到底是一条 query 还是一个结构化对象
一个更稳的 rewrite contract,至少应回答:
must_preserve:编号、产品名、时间、组织、角色是否必须保留may_normalize:口语表达、术语别名是否允许归一化may_expand:是否允许生成多 query 展开must_not_infer:没有明示的条件能不能猜output_shape:字符串、query 列表,还是 query + filters
9.1 对高风险 query,contract 应更保守
例如制度、审批、价格、权限类问题,通常更适合:
- 保留原词
- 限制扩写
- 限制多 query 展开
- 强制带出结构化 filters
9.2 同义词映射有时比 generative rewrite 更稳
Azure AI Search 当前 synonym map 文档说明:
- 同义词映射可以在不改用户原 query 的情况下扩展术语覆盖范围
这给工程实践一个很实用的启发:
- 术语归一化不一定非要靠模型自由改写
- 对稳定词表、产品别名、行业术语,静态 synonym map 往往更可控
10. 不同查询类型应该走不同改写策略
并不是所有 query 都该强行改写。
一个实用的分流方式通常是:
| 查询类型 | 是否建议改写 | 重点 |
|---|---|---|
| 精确编号/错误码 | 谨慎,通常弱改写 | 保留原词精确匹配 |
| FAQ/口语问答 | 建议改写 | 术语映射、口语标准化 |
| 多轮指代问题 | 建议改写 | 上下文补全 |
| 多条件复杂问题 | 建议改写 | 条件抽取、拆分 |
| 高风险制度问答 | 建议谨慎改写 | 避免过度扩写导致误导 |
如果所有问题都走同一套改写 prompt,后面几乎一定会出现:
- 某些 query 改得很好
- 某些 query 被改坏且难以解释
10.1 query 路由表比统一 prompt 更重要
一个更像生产系统的规划方式通常是:
text
exact-id query
-> no rewrite or weak normalize
multi-turn reference query
-> context completion rewrite
policy query
-> rewrite + filters extraction
-> strict preserve of time / role / org重点不是改写做得多花,而是:
- 不同 query 桶有没有正确的改写边界
11. 查询改写要怎么评测
查询改写如果只看“召回多了没有”,很容易把系统带偏。
更建议从四层看:
11.1 改写质量本身
- 改写是否保留原始意图
- 是否错误添加条件
- 是否错误删掉关键实体
11.2 检索层效果
- Recall@k 是否改善
- MRR 是否改善
- 是否更容易命中权威文档
11.3 证据层效果
- 改写后进入上下文的证据质量是否更高
- 是否减少无关候选
- 是否降低冲突证据比例
11.4 最终答案效果
- 答案相关性是否更高
- 引用是否更正确
- 拒答率是否更合理
- 高风险场景是否更稳
一个最小评测样例可以长这样:
json
{
"original_query": "这个开票后还能退吗",
"rewritten_query": "企业版订单开票后是否支持退款",
"must_hit_docs": ["refund-policy-enterprise-v3"],
"must_not_hit_docs": ["invoice-header-change-policy"],
"expected_answer_behavior": "应回答不能自动退款,需人工审批"
}11.5 评测最好保留 original / rewritten 并排对比
更稳的评测并不是只跑 rewrite 之后的结果,而是同时保留:
- original query 结果
- rewritten query 结果
- 合并或路由后的最终结果
否则你很难判断:
- 是 rewrite 真有帮助
- 还是本来原 query 就够用了
12. 改写链路最好能被 trace 和 replay 完整还原
如果改写只发生在某个黑盒 prompt 里,出了问题几乎很难复盘。
至少建议保留:
original_queryrewrite_queryrewrite_typerewrite_versionrewrite_filtersrewrite_confidencequery_bucketretrieval_strategy_version
如果系统允许多 query 展开,建议再保留:
expanded_queriesexpanded_query_count- 每条 expanded query 的命中贡献
这样后面你才能真正回答:
- 是哪种 rewrite 在变坏
- 是哪类 query 桶在退化
- 是哪条 expanded query 把脏结果放大了
13. 查询改写失败时,常见是哪里出了问题
13.1 过度语义化
把用户精确问的对象“智能泛化”掉了。
13.2 胡乱补全上下文
系统自己猜了一个错误主语。
13.3 多查询展开太多
召回是多了,但噪音也一起放大。
13.4 改写链路不可见
出了问题,没人知道检索用的是哪一版 query。
13.5 把生成质量问题误判成 query 问题
有时命中了正确证据,但模型没正确消费,这不是改写层的问题。
13.6 把同义词、过滤、rerank 问题全推给 rewrite
很多问题看起来像“query 不够好”,其实根因可能是:
- 术语词表没补
- filter 没带上时间/角色/组织
- rerank 没看到正确候选
14. 查询改写发布时,最值得盯的是哪类退化
查询改写一旦上线,最危险的不是平均值小幅波动,而是某些关键 query 桶突然变坏。
尤其要单独盯:
- 编号 / 错误码 query
- 时间敏感 query
- 权限敏感 query
- 高风险制度 / 审批 query
- 高频客服 query
更稳的做法通常是:
- 先按 query 桶灰度
- 对高风险桶保留 original query fallback
- 让典型 rewrite 失败样例进入 release blocker
15. 一个更稳的落地顺序
如果你准备把查询改写接进生产 RAG,建议按这个顺序推进:
- 先收集真实检索失败样例。
- 判断失败是否真的由 query 表达导致。
- 先做保守型改写,不要一上来搞复杂多 query 展开。
- 保留原 query、改写 query 和改写类型日志。
- 用固定评测集验证改写是否提升命中和答案质量。
- 再逐步加入上下文补全、术语映射和结构化过滤提取。
- 最后再做 query 桶灰度和 release blocker 门禁。
这样查询改写才会是可治理能力,而不是一堆不可解释的 prompt 花活。
16. 常见反模式
- 所有问题都强行改写
- 改写结果无法回放和解释
- 只看 top-k,不看最终答案质量
- 原 query 和改写 query 断链
- 把 query rewrite 当成弥补知识缺失的手段
- 改写失败样例不进入回归集
- 没有 original query fallback 就直接全量放开
- 本该用 synonym map 的稳定术语,也全交给模型自由改写
17. 推荐搭配阅读
18. 重点官方资源
以下资源已按 2026-07-09 的官方入口重新整理:
- OpenAI Retrieval guide:https://developers.openai.com/api/docs/guides/retrieval
- OpenAI File search guide:https://developers.openai.com/api/docs/guides/tools-file-search
- Azure AI Search query rewrite:https://learn.microsoft.com/en-us/azure/search/semantic-how-to-query-rewrite
- Azure AI Search semantic ranking:https://learn.microsoft.com/en-us/azure/search/semantic-how-to-query-request
- Azure AI Search hybrid search overview:https://learn.microsoft.com/en-us/azure/search/hybrid-search-overview
- Azure AI Search synonyms:https://learn.microsoft.com/en-us/azure/search/search-synonyms
- Azure AI Search relevance overview:https://learn.microsoft.com/en-us/azure/search/search-relevance-overview
- Anthropic Contextual Retrieval:https://www.anthropic.com/engineering/contextual-retrieval
说明:
- Azure 的 query rewrite 文档在
2026-07-09仍标注为preview,官方同时说明该预览功能不建议直接用于生产关键负载,所以更适合作为能力参考和实验入口,而不是无条件照搬生产默认方案。
19. 落地检查清单
- 是否为不同 query 桶定义了不同改写边界
- 是否保留了 original query、rewrite query 和 rewrite filters
- 是否能从 trace 还原每次改写链路与 query 路由
- 是否同时看改写质量、检索效果、证据质量和最终答案效果
- 是否把高风险 rewrite 失败样例接进回归与发布门禁