每日一技第三天——RAG的查询重写机制

📅 2026/6/24 10:42:37
每日一技第三天——RAG的查询重写机制
导入先看这样一个场景前两天我用豆包查高考作文题。我说“豆包简单回答一下今年新高考二卷的语文作文要求写什么。”它给了我材料主旨和核心立意。我接着又问了一句“英语呢”就两个字但豆包准确地回答了新高考二卷的英语作文要求。它知道我在问什么——它记住了“新高考二卷”记住了“作文”。这个体验很自然自然到我们几乎不会去思考它为什么能做到。但如果我们把视角切到后台看看这短短两个字的背后发生了什么你会发现事情远没有那么简单。当我说“英语呢”豆包的系统实际上做了两件事第一它回头看了一眼我们的对话历史确认了“新高考二卷”这个实体和“作文”这个主题然后默默地把我的问题补全成了——“新高考二卷的英语作文要求是什么”第二它把这个补全后的问题拿去检索或生成答案而不是直接用“英语呢”这三个字去理解。这两件事共同构成了一个看似简单的能力让AI能听懂“人话”能理解那些“你懂的”“那个”“还是刚才那个问题”这类人类对话中再正常不过的省略和指代。但在我自己搭建RAG系统的过程中发现这恰恰是最容易翻车的地方。当用户第三轮问“那第二个方案呢”我的机器人一脸茫然——它完全不知道“第二个方案”指的是什么。我们的RAG系统是需要先去向量数据库中检索相关的chunk然而检索系统拿到的query是用户的原始问题那向量化后和我们想要的chunk的向量距离可能差距有点大检索回的结果大概不是我们想要的。这个问题的根本就是在经历之前的会话记忆加载后大模型有了记忆但是呢检索系统没有但是我们可以通过Query改写来补全原始的问题。如何让RAG系统具备有效的Query改写能力让对话像豆包那样连贯自然正是这篇文章要探讨的核心问题。Query改写要解决的问题问题一指代消解Reference Resolution用户说的“它”、“那个”、“这个”指的是什么用户原话需要补全成“那第二个方案呢”“那第二个方案的价格是多少”“它支持这个功能吗”“刚才提到的那个产品支持刚才提到的那个功能吗”“那红色的呢”“那红色的款式有货吗”用户的表达天然依赖上下文但检索系统和LLM没有“眼睛”回头看如果你不把指代物显式写进查询它根本无法知道“它”是什么。问题二省略补全Ellipsis Resolution用户省掉的主语、谓语、宾语是什么用户原话完整语境需要补全成“英语呢”上下文在聊“新高考二卷的语文作文”“新高考二卷的英语作文要求是什么”“那北京呢”上文在问“上海的天气怎么样”“北京的天气怎么样”“那后来呢”上文在讲一个故事的经过“那个故事的后续发生了什么”人类对话中省略是常态但检索系统需要完整的句子才能做语义匹配。拿“英语呢”去向量库里搜匹配到的大概率是不相关的内容。问题三意图澄清与补全Intent Completion用户真正想问的是什么 有时用户的问题太短、太模糊甚至包含错别字需要结合历史推断完整意图。用户原话上下文推断后的完整意图“那便宜的那个呢”之前讨论过两款产品“那款价格更低的产品有哪些参数”“有风险吗”之前提到某个投资方案“刚才提到的投资方案存在哪些风险”“确定吗”前文模型给出一个结论“前文结论的置信度/依据是什么”问题四多轮对话中的信息衰减与聚焦Information Focus有时候用户问的不是“缺了什么”而是“问的是什么”。在多轮对话中用户的关注点可能发生了转移但他不会明说。Query改写不仅要“补全”有时还要重新聚焦。例如第1轮“帮我看看A产品的价格”第2轮“那B产品呢”改写为“B产品的价格是多少”——主语变了但谓宾沿用第3轮“能便宜点吗”改写为“A产品和B产品分别能便宜多少”——此时主语变成了“A和B”谓语变成了“便宜多少”需要综合前两轮推断Query改写的本质是把用户丢给你的“碎片”基于对话历史拼回一张完整的“拼图”。问题五多意图混合问题以上四个问题指代、省略、意图、聚焦还只是“单个问题”的补全。但现实中的对话更复杂——用户的一句话里往往同时包含多个意图。比如“新高考二卷的语文和英语作文要求分别是什么”这里有两个平行的意图。如果我只把它改写成“新高考二卷的语文和英语作文要求”拿去检索大概率只能翻到其中一篇相关的资料另一篇被模糊掉了。更复杂的是“那便宜的方案能用吗”这句话至少依赖两个前置意图一是“哪个是便宜的方案”二是“这个方案是否可用”。如果第二步的改写没有先解决“哪个是便宜的方案”第三步的回答一定跑偏。所以有效的Query改写不仅要“补全”还要“拆解”甚至要“排顺序”。这就是多意图混合问题——Query改写中最具挑战性的一环。Query改写的核心策略策略一基于规则的改写Rule-Based Rewriting核心思想预定义一系列规则匹配特定模式后进行字符串替换或补全。常见规则类型规则类型触发条件改写动作示例指代词替换检测到“它/那个/这个”替换为上一轮提到的实体“它支持吗”→“A产品支持吗”省略补全检测到“X呢”模式复用上一轮的谓语/宾语“英语呢”→“新高考二卷的英语作文要求是什么”短句补全长度≤3个字拼接上一轮的主题“价格呢”→“A产品的价格是多少”关键词映射匹配预定义关键词替换为标准查询模板“天气”→“今天的天气情况如何”优点缺点实现简单零延迟零成本覆盖率低只能处理预定义的模板可解释性强容易调试无法处理复杂、模糊的省略适用场景对话模式固定、高频套路明确的场景。策略二基于模板的改写Template-Based Rewriting核心思想维护一套查询模板库根据意图分类匹配对应模板把槽位填满。示例用户输入意图分类模板补全后的Query“英语呢”主题切换{current_topic}的{new_subject}要求“新高考二卷的英语作文要求”“那第二个呢”序列引用{entity_list}[2]的信息“第二个方案的信息”“便宜的那个”属性筛选{entity_list}中价格最低的“A产品中价格最低的”优点缺点比纯规则更灵活适合结构化场景模板维护成本高意图类别爆炸可批量生成改写样本无法处理模板外的自由表达策略三基于LLM的生成式改写LLM-Based Rewriting核心思想直接把对话历史当前用户输入丢给LLM让模型生成改写后的完整查询。这是目前最主流、效果最好的方式。Prompt设计关键你是一个查询改写助手。请根据对话历史将用户当前的问题改写为完整、独立、可检索的查询语句。 规则 1. 把“它”、“这个”、“那个”替换为具体实体 2. 补全省略的主语、谓语、宾语 3. 如果用户切换了话题以新话题为主 4. 只输出改写后的查询不要输出其他内容 对话历史 用户新高考二卷的语文作文要求是什么 助手材料主旨是关于守住根本的古语写作要求结合材料自拟标题... 用户英语呢 改写后的查询 新高考二卷的英语作文要求是什么多意图拆解增强版Prompt如果用户的问题包含多个意图请拆解为多个独立查询用[SEP]分隔。 示例 用户A和B哪个便宜哪个口碑好 输出A的价格是多少[SEP]B的价格是多少[SEP]A的口碑如何[SEP]B的口碑如何优点缺点理解准确率高能处理复杂语境每次改写多一次LLM调用有延迟和成本天然支持多意图拆解和指代消解Prompt设计敏感需要反复调优零规则维护适应性强输出不稳定可能产生幻觉策略四基于检索增强的改写Retrieval-Augmented Rewriting核心思想改写时不只是依赖对话历史还会检索历史中的相关片段而非完整对话用这些片段辅助生成更精准的改写。这和普通的RAG的区别普通RAG是用原始用户问题去检索这里是用检索结果反过来辅助查询改写。用户当前问题“那个方案的风险呢” Step 1: 用原始问题模糊检索历史 → 命中“方案A”、“方案B”、“风险评估”等片段 Step 2: 把检索到的片段作为上下文注入改写Prompt Step 3: LLM生成改写 → “方案A和方案B分别存在哪些风险”适用场景超长对话几十轮历史摘要不足以补全信息时。五种策略对比总览策略实现复杂度准确率延迟成本适用场景规则匹配⭐ 极低★★☆ 中低极低零高频固定模式模板填充⭐⭐ 低★★★ 中极低零结构化意图场景LLM生成⭐⭐⭐⭐ 高★★★★★ 高中每次改写1次大多数生产场景推荐检索增强改写⭐⭐⭐⭐⭐ 最高★★★★★ 高高检索LLM超长对话、复杂上下文混合策略⭐⭐⭐ 中★★★★ 高低部分触发先规则后LLM的兜底方案学习途径马丁老师