我精心“测试”过的 Agent,上线第一天就翻车了
我一度以为 Agent 测试跟接口测试差不多:写几条断言,看通过还是失败。直到我把一个自认为“测试充分”的报销 Agent 交给业务同事,它在前 20 种真实输入里表现完美,然后在第 21 种上把发票金额当成了订单号,还一脸自信地继续执行。我翻回测试记录,发现我的“充分测试”其实只覆盖了 3 条我亲手编的路径。模型在其余 197 种说法里,全靠运气。

这个场景你应该不陌生——单元测试、集成测试、端到端测试这些词在传统的 Web 服务里各有各的用法,可放到 Agent 身上全都变味了。原因只有一个:Agent 是一个概率系统,你没法用“断言相等”来锁住它的行为。
测试金字塔是给确定性系统设计的
Mike Cohn 在《Succeeding with Agile》里提出了经典测试金字塔:底层大量单元测试,中间少量集成测试,顶层极少端到端测试。这个模型的前提是:被测系统的输入输出是确定的,同一个输入理应得到同一个输出。所以你可以像筛沙子一样,用几百个低成本测试把底层逻辑筛干净,再用几个高成本测试守护整体流程。
Agent 不满足这个前提。同样的 prompt,同一个模型,这次返回 A,下次返回 B。很多团队因此干脆放弃测试,把 Agent 当玄学调。但我的经验是:不是测了没用,是你没把它拆开测。
单元测试:先把手脚的确定性锁死
Agent 代码里真正“不撒谎”的部分远比你以为的多:工具函数、状态机、参数拼接、JSON 解析、重试逻辑、prompt 模板。这些和模型输出无关,是纯逻辑。比如我写了一个 parse_tool_action,要处理模型吐出带 Markdown 标记的 JSON,这种容错逻辑完全可以用几十个固定样例压测,把格式兼容性锁住。
这一层的正确姿势是:把 LLM 调用 mock 掉,只测你的代码对某种输出的反应。单元测试是合格证,确认你的“手脚”没长歪。注意,凡是需要真实模型才能判断对错的,都不该放进这一层。
集成测试:让模型真的跑一小段
Agent 的“脑子”是 LLM,决策都发生在它那几毫秒的采样里。你不可能永远不碰它。集成测试的目的,是让模型在受控环境里真正推理一次,然后校验它走出来的那几步是否符合预期。
具体做法:给定一个 任务+当前状态,让 Agent 跑几步,然后断言它调用了哪个工具、传了什么参数、是否在异常时重新生成。比如“用户要删除一个正在审批的报销单”,正确的决策是先检查审批状态,而不是直接调删除接口。这种断言的对象是结构化行为,不是自然语言文本。
集成测试要尽量快,所以外部依赖可以用 mock 或轻量替代:数据库用 Testcontainers,云服务用 Moto。但 LLM 本身必须是真实的,至少是一个低成本小模型。你在这一层花的钱,换来的是对“模型是否还听指令”的监控。
端到端测试:像用户一样把 Agent 逼到墙角
金字塔顶端是端到端。这里不再关心单步决策,而是关心用户从头到尾经历的一切:输入、等待、输出、落库、通知。这种测试用例应该少而金贵,只挑那些一出错就天塌的场景,比如“预算不足时必须拒绝提交并说明原因”“工具超时三次后必须挂起并通知人类”。
在实现层面,如果 Agent 有 UI,用 Playwright 或 Cypress 驱动;如果没有 UI,直接调接口再轮询异步结果。关键是要有隔离环境,给 Agent 一个测试专用身份,别让它真的去发邮件、动账单。
我也曾一口气写了 20 条端到端测试,结果每轮都要跑 20 分钟,而且任一步失败都不知道从哪查起。后来砍到 5 条,从“覆盖所有路径”变成“覆盖最要命的路径”,反而每一次都能给你真正反馈。
真正的新层:评估,而不是断言
Agent 测试金字塔和传统金字塔最大的不同,是它多了一个横向的切片:评估层。评估不关心某个输入是否通过,而关心模型在一批多样本上的平均表现。单元测试、集成测试、端到端测试回答的是“这条路通不通”,评估层回答的是“这条路还稳不稳”。
我的做法是准备一个 100 条左右的正负样本集,每次改 prompt 或换模型后跑一遍,统计工具调用成功率、目标完成率和回复相似度。如果这周从 93% 跌到 80%,别分析了,大概率是你哪儿改坏了。市场上现成的工具如 LangSmith、DeepEval 能帮你搭,但一个 embedding 加上阈值也够用。
| 层级 | 测什么 | 断言方式 |
|---|---|---|
| 单元 | 工具函数、解析器、模板 | 相等、抛错 |
| 集成 | 决策轨迹和工具调用 | 结构化 API |
| 端到端 | 用户完整旅程 | 终态 |
| 评估(切片) | 分布表现 | 分数、成功率 |
三个坑,教你如何把测试写得没用
- 用文本字符串断言模型输出。模型哪怕意思对,字也可能不一样,你的测试会随机红,随机绿。正确做法是断言行为结构:有没有调对函数,有没有进入正确状态。
- 把模型也 mock 掉。模型一旦被替换成固定返回,你的 prompt 写错、系统指令被忽略、对提示注入的防护失效,这些全测不出来。集成以上层,模型必须是活的。
- 让端到端测试统治一切。端到端数量一多,流水线慢得像便秘,而且一个环节挂了要排查半天。用金字塔的直觉去配置数量:单元 > 集成 > 端到端。
我的金字塔落地姿势
先把 Agent 的状态图画出来,列出所有工具和它们的输入输出。为每个纯逻辑函数配 5-10 个单元测试,把模型 mock 成不同性格;为每个关键决策路径配一条集成测试,用真实小模型和隔离的外部服务;再挑 3-5 个最可怕场景做端到端测试,剩下的交给评估集。每次改 prompt、换模型、动工具,全量跑一遍,绿灯才能上线。
这套金字塔不能消灭幻觉,因为模型还是可能一本正经地胡说。但它能保住两件事:你的 Agent 不会因为解析 bug 原地爆炸,也不会因为一次反向改进让成功率从 90% 掉到 50%。在 Agent 领域,能做到这两点,你已经跑赢大多数团队了。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/1745.html