跳转至

展示预览被当作回答证据:关键限制条件被截断

2026 年 4 月,goagent 知识库问答出现一个反复被误判的问题:用户问代步工具的管理规则,检索面板显示命中了正确资料,回答却把关键限制条件丢掉了——规则原文里"允许使用"后面的限定只剩半句,模型判断不了电动车到底允不允许。

排查

这个现象最容易被归到两个方向:模型理解力不够,或者检索没召回到正确文档。排查时这两个方向都排除了:召回没有问题,候选池里有完整正文;换模型也解决不了,因为证据在进入模型之前就已经被裁短,换什么模型都只能在残缺证据上猜。

沿"候选 → 引用 → 最终提示词"的路径逐段检查,问题出在候选转换:检索阶段拿到了完整 chunk,转换成候选引用时只保留了 220 字的 preview 字段,最终回答提示又直接把这个 preview 当作证据注入模型。

根因

展示字段和推理字段被混成了同一个字段。preview 本来只给调试面板和候选列表用,让人快速扫一眼命中了什么,不承担回答证据的职责。把展示预览直接送进最终回答提示,系统就等于在回答前主动裁掉了证据:面板上看是命中了,模型实际看到的只有截断的一小段摘要。

同一轮还发现一个会叠加放大这个问题的缺陷:检索规划器有时把查询写成口语提问,甚至夹带"需要改一下"这种编辑性尾巴,同一问题在不同轮次生成不同的召回输入。召回不稳定和证据截断叠加,同一问题在不同轮次的表现不一致,排查也更容易先走错方向。

修复与验证

修复划清两类字段的边界:EvidenceText 保存完整正文,只服务最终回答和引用链路;Preview 和 Summary 保留,只服务界面、调试和候选展示。最终回答提示不再读取 preview,只读完整证据。

规划器侧不加新的代码兜底,直接把约束写进提示词:normalized_query、lexical_query 和 queries.text 都必须是检索短语,不得保留对话语气、动作描述和尾部补充。这个约束属于规划器的职责,不该靠后处理补锅。

验证围绕链路行为,不只看结构体定义。一条单测卡住候选转换的组装函数 plannedCandidatesToReferences:从候选到引用必须同时保留完整 EvidenceText 和截断 Preview,缺任何一个都失败。另一条单测卡住最终提示:注入的必须是 evidence= 而不是 preview=。再补一条提示词约束测试,防止有人把检索查询放回口语句式。这轮没有留下真实问答的前后对照产物,结论停在"链路行为被回归钉住"。

以后再遇到"面板命中了正确文档,回答却只像读了半句",排查的第一步是检查候选引用里传给最终提示的到底是 EvidenceText 还是某个展示字段。