跳到主要内容

你从未构建过的智能体反馈闭环

· 阅读需 11 分钟
Tian Pan
Software Engineer

每天,你的智能体(Agent)都会把失败案例打包成“礼物”发还给你。一名用户点击了“踩”。另一名用户读完答案后一言不发,直接关掉了标签页。第三名用户将同一个问题改写了三次,直到智能体终于答对。每一个都是带标签的失败案例 —— 真实的输入、真实的上下文、系统失误的真实时刻 —— 由那些最希望系统运行正常的人免费提供给你。

大多数团队都会把这些信息全部丢掉。并非故意为之。点击“踩”只是增加了仪表盘上的一个计数;放弃使用表现为留存图表中的一次下滑;改写问题看起来就像普通的日常使用。没有任何东西能将信号及其产生的上下文一并捕捉,因此也就无法进行回放、分选(Triage)或转化为测试用例。你所拥有的最丰富的评估数据源正擦肩而过,而团队却还在继续手动编写合成的评估(Eval)案例。

这就是你从未构建的智能体反馈循环。它不是你忘记购买的某种工具,而是一条流水线 —— 从用户信号,到分选后的失败案例,再到新的评估案例 —— 它之所以未能建立,与技术本身关系不大。

没有 Trace 的“踩”只是数字,而非教训

从最常见的错误开始:只收集反馈,不收集上下文。

添加一个“踩”按钮很容易。它会在某处写入一行数据:timestamp, user_id, rating: -1。一周下来,你会得到一个数字 —— “满意度降至 71%”。这个数字告诉你出了问题,但它没告诉你哪里出了问题,也没提供任何可操作的建议。

相比之下,如果一个“踩”附带了完整的决策上下文:精确的用户输入、对话历史、系统提示词版本、模型版本、检索到的文档、调用的工具及其返回结果,以及用户拒绝的最终输出。那就不再是一个数字。那是一个可复现的失败案例。你可以打开它,查看发生了什么,提出假设,修复它,并且 —— 至关重要的一点 —— 将其保留为测试用例,确保同样的失败不再发生。

这两种产物之间的区别,就是反馈循环存在与否的区别。没有 Trace 的评分只是情绪。绑定到 Trace 的评分才是数据。大多数生产系统收集的是前者,却以为自己拥有后者。

修复方法是结构性的,且必须在反馈到来之前就位。每一次智能体运行都应该生成一个 Trace —— 一个记录了智能体看到的所有输入和采取的所有步骤的结构化记录。反馈信号无论何时产生,都通过 ID 关联到该 Trace。当用户点击“踩”时,你记录的不是一个观点,而是标记了一个特定的、可回放的执行过程供审查。先构建 Trace,按钮是最简单的部分。

大多数反馈是无声的

显式反馈 —— 赞、踩、星级评分 —— 是每个人都会埋点的部分,但它只是最小的一部分。反馈组件的使用率极低是众所周知的;点击的用户往往是带有偏见、发声欲望强烈的少数群体。如果你只从点击中学习,那你只从极小部分的流量中学习,错过了其余大部分信息。

更大的信号是隐式的,它们现在就躺在你的日志里。关于人类与 LLM 对话的研究总结了这些信号的特征:

  • 改写 (Rephrasing)。用户用不同的词再次询问同一件事。这是前一个答案未达预期的最强烈隐式信号 —— 没有人会对满意的答案进行改写。
  • 放弃 (Abandonment)。对话在任务中途停止。用户得到了答案后直接离开而没有后续行动,或者直接放弃了。
  • 复制粘贴与后续模式。用户复制了输出的一部分,并立即提出修正。他们转向同一个目标的另一种表述方式。他们用平实的语言表达挫败感。
  • 升级 (Escalation)。用户要求人工介入,或者愤怒地退出并转向支持渠道。

这些都没有对应的按钮。它们是从行为中推断出来的 —— 而这种推断正是团队感到紧张的地方,因为隐式信号具有噪声。用户改写问题可能是因为想到了更好的问法,而不是因为之前的答案不好。最近的研究直言不讳:隐式反馈对于理解用户很有启发,但作为直接的训练信号则充满噪声。

这种噪声是分选隐式信号的理由,而不是忽略它们的借口。将它们视为候选失败案例,而非确定的失败。改写事件会为人工审核标记一个 Trace;由人来查看并判断这是否是真实的失误。你不是在进行自动标注,而是利用隐式信号引导稀缺的人工审核资源去关注那 2% 最可能包含缺陷的流量,而不是让他们进行盲目采样。仅凭这一点就值得构建。

流水线:信号 → 分选后的失败案例 → 评估案例

反馈循环不是一个功能,而是一个具有不同阶段的流水线,每个阶段都可能被跳过 —— 而且通常确实被跳过了。以下是它正常工作时的样子:

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates