
图中把不可改变的约束单独保留,扩展内容只负责提供新的搜索表达。
检索问题改写得更完整,结果却更不符合用户要求,这并不罕见。原因可能不是向量模型太弱,而是改写时悄悄更换了问题。尤其当生成内容带着合理的背景补充时,新增细节很容易被后续流程误当成用户已经确认的条件。
先建立一份约束底稿
设用户问:“版本 v2、离线环境、不能改表结构,怎样排查导入变慢?”其中对象与版本确定范围,离线限制可用资源,不能改表结构排除了部分处理手段。它们不是可以为了句子流畅而删掉的修饰语,而是判断结果能否使用的条件。
可以把这些信息与自由表达分开记录:对象、版本、时间范围、精确编号、必须满足的条件、禁止做的动作,以及用户真正想解决的问题。原问题始终保留,改写只是产生附加检索表达,不能把原文覆盖后只留下模型生成的一段话。
这份底稿也不应完全依靠猜测补齐。用户没说部署系统,不能默认为某个系统;没给出错误码,就不要为了检索方便编一个错误码。缺失信息可以成为待确认项,而不是在后台默默转成既定事实。
精确条件与语义扩展分工
自然语言改写擅长把“变慢”扩展为吞吐下降、等待增加等表达,但不适合随意重写版本号、产品型号和数字阈值。这些精确字段可以作为明确过滤条件或关键词保留,再与语义检索配合。
否定条件尤其容易丢失。“允许联网”和“不允许联网”可能在词汇上非常相似,却对应完全不同的操作范围。仅检查两句话向量相似度高,不能证明约束没有被反转。对于明确禁止项,可以直接检查它是否在结构化约束中保持原意。
数字也要保留单位。把五秒改成五分钟,不是等价表达;把“至少”改成“最多”,即便数字不变,问题也已改变。自动校验应关注关系词与单位,而不只是抽出几个数字比较集合。

用两路结果发现漂移
一条路径保留原查询,另一条使用扩展表达。比较的不只是两份结果有多少交集,而是它们是否找到能够支持原问题的材料。新结果里如果全是在线服务教程,就应怀疑离线条件在扩展中丢失。
不要反过来规定两路必须完全一致。如果扩展永远不能带来新材料,就没有解决表达差距。合理目标是:新增材料覆盖原查询遗漏的相关概念,同时仍然符合不可改变的约束。
当两路冲突时,可以记录冲突原因,比如版本不一致、适用环境不同或假设未经支持。直接把排名最高的片段交给回答器,可能把检索阶段的范围错误包装成一个确定建议。
假设文档只是一种扩展来源
HyDE 通过生成假设性文档建立检索表示,这类中间内容也应服从原约束。生成段落里写了“新增索引”,不意味着用户已经允许改表;写了某个设置项,也不意味着真实产品存在这个设置。
可以把新增实体与原查询进行对照,标记哪些来自用户、哪些来自文档、哪些只是模型补充。后者可以作为搜索线索,但在找到真实依据之前,不应升级为答案中的事实。查询侧的想象力与证据侧的可信度要分别管理。
准备能揭露问题的测试对
测试不必一开始就追求很大的集合。可以先准备成对问题:一个允许联网,一个禁止联网;一个针对 v2,一个针对 v3;一个允许改结构,一个不允许。其余措辞尽量相同,观察改写和检索是否真的保留区别。
这些成对测试检查的是约束敏感性,不直接证明整个系统回答更准确。还应标注可支持答案的材料,检查是否召回、是否被过滤,以及最终答案是否遵守原条件。否则,“改写保留字段”也可能只停留在表面。
最后再看成本和退路。扩展失败、超时或校验不通过时,应能回到原查询,而不是把错误改写作为唯一入口。增加一条生成步骤,应当同时增加可检查的责任边界。
如果一份检索结果主题很接近,却要求用户执行明确禁止的操作,你会把它算作相关材料,还是算作一次查询漂移?