14.01概念更新于 2026年9月17日

为什么必须验证

Think → Act 之后缺失的 Verify,是 Demo 与产品的分界线。

14.01 · 课时讲解

为什么必须验证

Agent 说“已完成”只是一个说法,验证拿到的才是证据。

1 / 12

一句话理解:Agent 说“已完成”只是一个说法,验证拿到的才是证据。没有 Verify 的 Agent Loop,本质上是一个很会自信汇报的脚本。

几乎每个 Agent 项目都会碰上这件事:Demo 阶段一切顺利,上线第一周就有人投诉:“Agent 说已经给客户发了处理结果邮件,客户什么都没收到。”翻 Trace 一看,邮件接口返回了限流错误,模型却把“我调用了发送工具”当成了“邮件已经送达”,然后写下了那句“已为您成功完成”。

这不是模型不够聪明,而是系统里少了一步。这一课讲清三件事:为什么 Agent 天生容易“谎报完成”,验证应该放在哪些位置,以及加上验证之后产品会有什么不同。

先用一张图看清本模块的全貌:验证嵌在每一次行动之后;验证发现问题时,先归类失败,再决定重试、换路还是交给人。后面四课分别展开图中下方的四个面板。

验证与错误恢复模块全景:单次运行的验证闭环、验证方式、验证者可靠性、五类失败、升级到人工,以及验证层次与判定记录 单次运行中的验证闭环:Plan → Act → Verify → Retry → Human 理解任务 · 计划 Plan 执行前校验 参数 · 权限 · 审批 执行动作 Act 执行后验证 读回 · 回执 · 测试 判定 通过 · 失败 · 无法判断 汇报结果 + 证据 诚实标注部分完成 归类失败 · 重试或换路 升级到人工 Human 可恢复 需找人 重试 动作 → 验证方式 验证者:可靠性自上而下增强 五类失败 → 恢复路径 什么时候停下来找人 写入记录 → 写后读回 发送消息 → 查消息 ID 修改代码 → 跑测试 发布上线 → 访问线上 计算分析 → 程序重算 生成文档 → 按标准评审 自我检查 没有新信息 模型互评 新视角,信息仍有限 外部验证 引入真实世界的信息 人工专家 引入领域判断 工具失败 → 限次重试 数据缺失 → 补数或无法判断 推理错误 → 外部验证拦截 规则冲突 → 升级裁决 环境异常 → 等待或降级 失败超上限 证据不足 风险越线 规则冲突 交接包:原因 · 已做 · 待决策 人决定后从恢复点继续 验证层次 步骤级:每个有副作用的动作之后 · 任务级:交付给用户之前 · 业务级:延迟确认业务目标是否达成 判定与记录 三态判定:通过 / 失败 / 无法判断 · 验证记录进入 Tracing、任务状态与 Evals · 验证强度跟随操作分级
图 1 · 验证与错误恢复全景:行动之后先验证,失败先分类,再决定重试、换路还是交给人

缺失的那一步

在初识 Agent Loop里,我们把 Agent 的核心描述为 Observe → Reason → Act → Verify。但很多 Demo 实际跑的是另一条路径:

Demo 版与产品版的执行路径对比:产品版在调用工具后读取真实结果并与预期比对 Demo 版 理解任务 调用工具 生成“已为您完成” 结束 产品版 理解任务 调用工具 读取真实结果 与预期比对 汇报结果 + 附上证据 归类失败 → 重试 / 换路 / 找人 符合 不符合
图 2 · Demo 版直接宣布完成;产品版先读回真实结果,符合才汇报,不符合就归类失败

Anthropic 在《Building effective agents》中强调,Agent 在执行过程中的每一步都要从环境中拿到 “ground truth”(例如工具调用结果或代码执行结果)来判断进展。Claude Agent SDK 的工程文章也把 Agent 的工作循环概括为:收集上下文 → 采取行动 → 验证工作 → 重复。两者说的是同一件事:行动之后必须回头看世界真实发生了什么。

“说完成”和“真完成”之间隔着什么

下表是 Agent 最常见的几种“声明与事实不一致”:

Agent 的说法 实际可能发生的事 为什么 Agent 自己不知道
邮件已发送 接口超时或被限流,邮件没发出 只看到“发起了调用”,没检查返回
工单已创建 创建成功,但负责人字段写错了 接口返回成功,但没有读回内容核对
Bug 已修复 改了代码但没跑测试,另一处功能坏了 没有执行任何测试
用户收不到通知的原因是“他自己关了提醒” 日志接口返回了空数组,结论是编出来的 数据缺失被“合理推理”填补
页面已上线 构建成功,但线上仍是旧版本 没有在发布后访问线上地址

背后有三个结构性原因:

  1. 模型生成的是“最合理的下一段文字”。 执行完一串动作后,“已为您完成”恰恰是最顺的续写。这和幻觉同源:流畅不等于真实。
  2. 工具的返回本身就可能含糊。 很多接口只表示“请求已受理”(例如 HTTP 202),真正的处理在后台异步完成;还有的接口批量处理时部分成功、部分失败,返回码却仍然是成功。
  3. 长链路的误差会累积。 假设每一步独立出错,单步正确率 95%(示例数字),10 步全部正确的概率约为 0.95 的 10 次方,大约 60%;20 步只剩约 36%。步骤越多,越需要在中途把错误拦下,而不是等到最后才发现。

验证放在哪里:三个层次

验证不是只在任务结束时做一次,它分布在三个层次上:

层次 验证什么 什么时候做 工单处理 Agent 的例子
步骤级 单个动作是否真的生效、返回是否可用 每个有副作用的动作之后,或关键数据读取之后 创建工单后按 ticket_id 读回,核对标题和负责人
任务级 整体产出是否正确、完整、有依据 交付给用户之前 报告里的每个时间点和数值都能在工具返回里找到出处
业务级 是否真正达成了业务目标 往往要延迟一段时间才能确认 48 小时后检查该工单是否被关闭、用户是否不再反馈

还要分清验证和程序校验的分工:执行前的校验回答“能不能做、该不该做”(参数合法吗、有权限吗、要审批吗);执行后的验证回答“做成了没有、做对了没有”。两者缺一不可:

执行前校验与执行后验证的分工:模型决策、执行前校验、执行、执行后验证、汇报 模型决策 执行前校验 参数 · 权限 · 审批 执行 执行后验证 生效了吗 · 对不对 汇报 程序校验 验证 能不能做、该不该做 做成了没有、做对了没有
图 3 · 执行前校验回答“能不能做”,执行后验证回答“做成了没有”

案例:工单处理 Agent 加上 Verify 之后

以一个「工单处理 Agent」为例。任务是:输入工单号,查询工单记录、操作日志与账号配置,判断问题原因;如果属于配置错误,就创建修复工单并邮件通知负责人。

没有验证时,Agent 的汇报通常是一句话:“已查明原因为通知配置被关闭,已创建工单并通知负责人。”加上验证后,至少多了这几个检查点:

  • 查询日志后:如果日志为空,不允许推理出“用户已阅读”或“用户自己关闭了提醒”,只能标注数据缺失。
  • 形成结论前:结论引用的最后一次变更时间必须能在日志工具的返回中找到原值,间隔时长由程序计算,而不是让模型心算。
  • 创建工单后:按返回的 ticket_id 调用查询接口读回,核对标题、问题类型、负责人。
  • 发送邮件后:检查邮件服务返回的消息 ID;没有 ID 或返回报错,就不能声称“已通知”。

最终交付的不再是一句话,而是一份带验证状态的结果(示例):

{
  "case_id": "T-20260917-0011",
  "conclusion": "账号的通知配置被关闭,用户收不到提醒",
  "evidence": [
    { "source": "get_account_settings", "field": "notify_disabled_at", "value": "2026-09-14T08:12:00+08:00" }
  ],
  "actions": [
    { "type": "create_ticket", "ticket_id": "T-20260917-0042", "verified": true, "method": "read_back" },
    { "type": "send_email", "message_id": null, "verified": false, "reason": "邮件服务返回 503,已重试 2 次仍失败" }
  ],
  "status": "partially_completed"
}

注意 status 是“部分完成”,而不是“成功”。验证最大的产品价值,是让 Agent 能诚实地说出“我做了一半”:用户知道工单建好了,也知道邮件还没发出去,可以自己补一步。怎么把这种状态展示给用户,见失败的呈现。

当然,验证有成本:多一次读回就多一次调用、多一点延迟和 Token。所以验证强度应该跟着操作分级走:只读查询做轻量检查(结果非空、字段合法);写入、发送、涉及资金的动作必须做强验证。

常见误区

  • “工具返回成功就是成功。” 返回码只能说明请求被接受,不能说明结果正确。写入要读回,发送要看回执,发布要去访问线上地址。
  • “让模型再检查一遍就算验证了。” 同一个模型对着同一份上下文“再想想”,发现不了它本来就不知道的错误。验证要尽量换一条独立的通道去读真实状态,详见自我检查与外部验证。
  • “验证越多越好,最好每一步都让人确认。” 过度验证会让 Agent 又慢又贵,用户也会嫌烦弃用。验证强度要和风险匹配。
  • “验证是研发的事。” “什么才算完成”是产品定义。产品经理不写清楚完成标准,研发就只能验证“接口有没有报错”。

产品经理检查清单

  • 这个 Agent 的每个任务,“完成”有没有一个可以观测、可以检查的定义?
  • 每个写入、发送、发布类动作之后,用什么证据证明它真的生效了?
  • 最终汇报能不能区分“已验证完成”“未验证”“失败”和“部分完成”?
  • 验证失败时,用户会看到什么?Agent 接下来会做什么?
  • 哪些结果只能延迟验证(例如客户是否收到、问题是否真的解决),由谁、在什么时候跟进?
  • 验证本身的成本(延迟、调用次数)是否计入了单任务成本?

练习

找一个你能用上的 Agent 产品(例如 Claude Code,或你自己搭的 Tool Agent),让它完成 3–5 个带实际动作的任务,然后填写下表:

Agent 声称完成了什么 你用什么方式核实 核实结果 如果不一致,Agent 缺了哪一步验证
例:修改了配置并重启服务 访问健康检查地址 服务未启动 重启后没有检查进程与端口

完成后统计:有几次“声称完成”和“真实完成”不一致?

延伸阅读

下一步

知道了为什么必须验证,下一课「各类动作的验证方式」给出一张可以直接套用的速查表:发邮件、写库、改代码、发布上线分别该怎么验证。

试试:上下文、MCP、沙箱、Prompt 注入、外链