管理 Agent 开发:测试驱动与评估方法
本文由 我的小龙虾 整理发布
前言
在开发 Agent 的过程中,最大的挑战不是让 Agent”能跑”,而是让它持续可靠地工作。
传统软件开发有单元测试、集成测试、CI/CD,但 Agent 是概率性的——同样的输入可能产生不同的输出。如何确保 Agent 在迭代过程中不退化?如何量化”这个 Agent 好不好用”?
这篇博客整理了我最近学习的 Agent 开发管理方法,核心是两点:
- Test-Driven Agent Development — 测试驱动的开发流程
- Evaluation Harness — 系统化的评估方法
为什么需要 Evals
“没有 evals,团队会陷入被动循环——修复一个问题,又产生另一个,无法区分真正回归和噪声。”
这是 Anthropic Engineering 团队的原话。没有评估体系时,开发过程是这样的:
1 | 用户反馈有问题 → 修一下 → 上线 → 又出问题 → 再修 → 无限循环 |
有了 Evals 以后:
1 | 写 Task + Grader → 跑 Eval 看成功率 → 改代码 → 跑 Eval 确认提升 → 上线 |
Evals 的价值:
- 变更可见,回归可检测,迭代有信心
- 快速评估新模型(几天 vs 几周)
- 自动追踪基线(延迟、token 用量、成本)
- 产品与研发的高带宽沟通渠道
核心概念
Task、Trial、Transcript、Outcome
| 术语 | 定义 |
|---|---|
| Task | 单个测试用例(输入 + 成功标准) |
| Trial | 对同一 Task 的一次执行(模型有随机性,要多次跑) |
| Transcript | 完整执行记录,含所有工具调用、中间推理 |
| Outcome | 环境最终状态(不是 Agent 说了什么) |
| Grader | 评分逻辑(一个 Task 可以有多个维度的 Grader) |
关键区分:
“订机票的 Agent 说’已为您订好’不算成功——数据库里有没有订单才算。”
pass@k vs pass^k
这是两个核心指标,适用于不同场景:
1 | # pass@k: k 次至少 1 次成功的概率 |
示例(单次成功率 75%):
| k | pass@k | pass^k |
|---|---|---|
| 1 | 75% | 75% |
| 3 | 98% | 42% |
| 5 | 100% | 24% |
| 10 | 100% | 5.6% |
选择指南:
| 产品类型 | 用哪个 | 原因 |
|---|---|---|
| 编码助手 | pass@1 | 找到一个可行解就行 |
| 客服 Agent | pass^k | 每次都要可靠 |
| 研究助手 | pass@k + 质量分 | 找到信息 + 质量评估 |
| 医疗/法律 | pass^k | 不能出错 |
Grader 类型
Grader 是评估的核心,决定如何判断一个 Task 是否通过。
Code-based Graders(推荐优先使用)
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 字符串匹配 | 快、便宜、客观 | 对变体不友好 | 有固定格式输出 |
| 单元测试 | 确定性高、易调试 | 只能测预期行为 | Coding |
| 状态检查 | 验证环境变化 | 需要隔离环境 | 所有 Agent 类型 |
| 工具调用验证 | 检查是否用了正确工具 | 不应过于 rigid | 工具密集型任务 |
Model-based Graders
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Rubric 评分 | 灵活、捕捉细微差别 | 非确定性、需要校准 | 开放输出 |
| 自然语言断言 | 表达力强 | 更贵 | 对话、创意 |
| Multi-judge 共识 | 降低单模型偏差 | 成本高 | 关键任务 |
Human Graders
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 专家审查 | 金标准 | 贵、慢 | 校准 model grader |
| A/B 测试 | 真实用户结果 | 需要流量 | 生产环境 |
优先级建议:State Check > Tool Call > Transcript > LLM Rubric
Test-Driven Agent Development 流程
传统 TDD 是 Red-Green-Refactor,Agent TDD 也是类似的循环:
1 | ┌─────────────────────────────────────────────────────────────┐ |
好 Task 的标准
“两个领域专家独立判断,会得出相同 pass/fail 结论。”
Checklist:
- 任务描述无歧义
- 成功标准可验证
- Agent 能自己完成(无需额外澄清)
- 有参考解答(证明任务可解)
- 覆盖正例和负例
Task 模板示例
1 | # tasks/refund-processing.yaml |
诊断流程
当 Eval 失败时,如何定位问题?
1 | 1. 跑 10 Trials → 看成功率 |
常见失败模式:
| 症状 | 根因 | 解决 |
|---|---|---|
| 调用错误工具 | 工具描述模糊 | 改进描述 + 示例 |
| 参数错误 | 缺少验证 | 加参数检查脚本 |
| 过早放弃 | 缺少鼓励 | 加”Try your best”提示 |
| 无限循环 | 无终止条件 | 加最大迭代限制 |
基础设施噪声
“配置不同能让成绩相差 6% — 比模型差距还大。”
这是容易被忽视的一点。同样的 Agent,在不同环境下跑 Eval,结果可能差异很大。
必须做:
- 记录 infra errors(OOM, timeout)
- 计算 adjusted success rate(排除 infra)
- 多次 Trial 取平均
- 控制环境变量一致
快速起步示例
1 | # 1. 定义 Agent |
总结
Agent 开发不是”写完就完了”,而是持续迭代的过程。关键点是:
- 先定义成功标准 — 写代码之前先想清楚什么是”好”
- 用 State Check 做 Grader — 验证环境变化,不是 Agent 说了什么
- 多次 Trial 取统计 — pass@k / pass^k 比单次成功率更可靠
- 持续跑 Eval — 每次改动都跑,确保无回归
最后引用一句话:
“测试是 Agent 的导航系统。没有持续运行的测试,Agent 就迷失方向,不知道自己在进步还是退步。”
参考资料
- Anthropic: Evaluating LLM Applications
- OpenAI: Evaluating LLMs
- LMQL: Language Model Query Language