智能体排障遗漏了上游检索决策
作者指出,智能体日志往往从模型请求开始,遗漏了检索查询和上下文候选集合。缺少这些上游记录,会让故障复盘难以定位信息选择环节的问题。
AI 深度解读
Agent 答错了,很多团队会先改提示词、换模型。作者提醒我们:错误可能更早就发生了,检索系统已经把不该出现的人或材料送进了上下文,而日志只记录了模型如何回答。
这篇文章的价值,是把排查起点往前挪:除了看输出,还要看候选材料如何入选。作者用一个内部 Agent 的实际问题说明,这层记录能解释提示词解决不了的错误,但他提出的人名来源约束还没有实现。
模型开口之前,谁决定了它看什么
作者观察到,自己的 Agent trace 往往从模型请求才开始:system prompt、messages、tools、params 都有记录,上游却被压缩成一个名字很可靠的函数,例如 retrieve_context()。检索使用了什么查询、哪些材料被选中,通常没有被当作一次决策留下来。
结果是,开发者只能调试「角色已经选好」之后的半套系统。模型的回答最容易被看见,于是也最容易成为事故复盘的归责对象。
进入上下文的材料,本身就是系统行为的一部分。
作者把 top_k=10 称为一种政策。这里的政策可以理解为:系统规定哪些材料有机会影响回答。语料库、分块方式、embedding model、索引新鲜度和默认参数,共同决定了这个范围。相似度分数只能描述匹配程度,不能判断某个人是否应该进入这次讨论。
这也解释了为什么单改提示词可能无效:模型面对的题目和参考材料,已经由上游替它选好了。不过,作者也承认,模型和糟糕的提示词确实会造成问题,不能把责任全部推给检索。
先记一周候选集,再谈复杂治理
作者给出的第一步很具体:连续一周记录候选集,包括 IDs、scores、query,以及返回顺序。不要把向量全部倒出来,信息量太大,反而难以检查。
候选集就是检索返回、可能被送给模型的那批材料。检查它,能把「模型为什么这样说」拆成更容易定位的问题:它究竟看到了什么,这些内容为什么会排在这里?
作者在一个小型内部 Agent 上做过这件事,发现系统仍在检索一个几个月前就已弃用的来源。索引重建时悄悄保留了旧文档。这个发现解释了三个异常回答,而作者此前已经花了一个下午怀疑模型。
随后,作者加入了一份排除列表:某些实体无论得分多高,都不属于任务范围。他认为,这段并不优雅的代码,对输出质量的帮助超过了自己尝试过的任何提示词重写。这里没有量化指标或对照实验,应当把它看作个人实践反馈。
另一项要求尚未落地:如果系统要写出涉及具名人物的句子,上下文就应有支撑该句的来源,否则不该生成。作者强调,仅在答案末尾放一个引用还不够,还要能指出这个名字通过哪份文档进入上下文。
困难在于,检索并非单个步骤。作者将其描述为六步流程,却没有列出具体六步。故障可能藏在步骤交界处:过期分块、评论里夹带的实体,或 Agent 连续改写两次后已经偏移的查询。因此,他主张像检查慢查询和持续增长的数据表一样,定期检查这条链路。
我的判断
我认同把检索纳入可观测范围。只保留模型请求日志,能还原模型看见的最终输入,却未必能解释材料为什么被选中。候选集记录补上的,正是这段决策过程。
但「生成器最不该负责」是作者的强烈判断,文中没有跨系统数据支持。唯一具体案例证明了陈旧索引会导致错误,无法证明检索问题比模型问题更普遍。
排除列表适合边界明确的内部任务,比反复要求模型「不要提及某些对象」更直接;它也需要持续维护,不能替代索引清理。人物来源约束则还停留在目标阶段:能追到名字的入口,并不等于能证明围绕这个名字生成的每句话都成立。作者没有给出句子与证据如何对应的实现方案。
能拿来做什么
- 如果你在维护带检索的 Node Agent,可以先按作者建议记录一周候选集,保留 IDs、scores、query 和返回顺序,排查异常回答时从材料入选过程查起。
- 对已经弃用的知识来源,检查索引重建后是否仍能检索到旧文档;仅修改来源配置,未必完成了旧数据清理。
- 对任务范围明确的内部助手,可以维护实体排除列表,并检查它是否覆盖当前业务边界,把检索范围限制落到代码里。
- 如果 Agent 会输出具名人物的信息,先确认能否追踪名字进入上下文的具体位置,再评估如何校验句子证据,不要把输出中的引用当作校验已经完成。