传统软件有单元测试。AI Agent 有 Eval——但大部分团队的 Eval 停留在「手动试几个 case」。这篇讲怎么建一套像样的 Agent 质量体系。
为什么 Agent 特别难测
传统函数: input → f() → output ✅ 确定性,assert 就行
LLM 调用: input → LLM → output ⚠️ 非确定性,同样输入不同输出
Agent: goal → loop(tool×N) → result ❌ 路径不确定,步骤数不确定
Agent 的测试难点:
- 输出不唯一——「修复 bug」可能有多种正确方案
- 路径不固定——可能 3 步完成,也可能 15 步
- 副作用——Agent 改了 5 个文件,怎么判断改对了?
- 回归——换了 Prompt / 模型 / Skill,之前能过的 case 可能挂了
Eval 的三个层次
L1:输出 Eval(最基础)
给 Agent 一个输入,检查输出是否满足条件:
def eval_summarize():
result = agent.run("总结这篇文章的三个要点")
assert len(result.bullet_points) == 3
assert result.language == "zh"
assert no_hallucination(result, source_doc) # 和原文交叉验证
适合:RAG 问答、文本生成、分类任务。
L2:过程 Eval(Agent 特有)
不只看最终结果,还看 Agent 的执行过程:
def eval_code_fix():
trace = agent.run("修复 login 页面的 404 错误")
# 过程检查
assert trace.used_tool("read_file") # 应该先读代码
assert trace.used_tool("grep") # 应该搜索相关文件
assert "auth.ts" in trace.files_modified # 应该改 auth 模块
assert trace.total_steps <= 15 # 不应该循环太久
assert trace.tests_passed # 改完测试应该过
适合:代码 Agent、自动化工作流。
L3:端到端 Eval(最真实)
在接近生产的环境中跑完整流程:
真实代码仓库 + 真实 bug report → Agent 修复 → CI 通过?
真实客服问题 + 真实知识库 → Agent 回答 → 人工评分 ≥ 4/5?
成本最高,但最接近真实表现。
测试集怎么建
起始:20 个 case 就够
测试集结构:
├── easy/ (5 cases) 单一工具调用,预期 1-3 步
├── medium/ (10 cases) 多步推理,预期 5-10 步
├── hard/ (3 cases) 需要跨文件/跨系统操作
└── adversarial/ (2 cases) 故意误导/边界情况
每个 case 包含:
name: "fix-login-404"
input: "用户报告 /login 页面返回 404,请修复"
expected:
files_modified: ["src/pages/login.astro"]
tests_pass: true
max_steps: 15
grading:
type: "process + output"
rubric: "修改了正确文件且测试通过 = pass"
来源
- 真实失败 case——线上 Agent 做错的,加入测试集(最有价值)
- 用户反馈——差评的对话,复现为 test case
- Synthetic——用 LLM 生成变体(扩展现有 case)
- Regression——每次 fix 一个 bug,就加一个 case 防止再犯
在线监控
离线 Eval 是快照,在线监控是实时:
关键指标:
├── 任务成功率 用户认为「完成了」的比例
├── 平均步数 步数突然增加 = 可能退化
├── Tool 调用成功率 MCP / 内置工具的 fail rate
├── Token 消耗 成本异常检测
├── 用户干预率 用户中途手动修改 / 取消的比例
├── 延迟 P50/P99 响应时间
└── 差评率 显式 negative feedback
告警规则示例
IF 任务成功率 < 80% (1h 滑动窗口) → PagerDuty
IF 平均步数 > 2x 基线 (24h) → Slack 通知
IF Token 消耗 > 3x 日均 (1h) → 成本告警
IF 同一用户连续 3 次差评 → 人工 review
工具选型
| 工具 | 适合 | 特点 |
|---|---|---|
| LangSmith (LangChain) | LangChain 生态 | Trace 可视化、Eval 数据集、A/B 对比 |
| Braintrust | 通用 | Eval + 回归 + 生产监控一体 |
| Weights & Biases | ML 团队 | 实验追踪,偏模型训练 |
| 自建 | 小团队 | PostgreSQL + 简单 dashboard 够用 |
小团队建议:先用 LangSmith 或 Braintrust 免费 tier,跑通流程后再决定是否自建。
真实案例:Cursor 怎么做 Eval
Cursor 没有公开细节,但从产品行为可以推断:
- Tab 补全——大量隐式 feedback(用户接受 = positive,删除 = negative)
- Agent 模式——Undo 率、任务完成率、步数分布
- 模型 A/B——不同用户群分配不同模型/Prompt,对比留存和满意度
- Nightly eval——内部 repo 上的自动化 Agent 任务套件
Eval 驱动的开发流程
改 Prompt / Skill / MCP / 模型
↓
跑离线 Eval 套件(20-100 cases)
↓
通过率 ≥ 基线? ── 否 → 回滚,分析 fail case
↓ 是
灰度发布(5% 用户)
↓
在线指标正常? ── 否 → 回滚
↓ 是
全量发布 + 持续监控
没有 Eval 的 Agent 迭代 = 盲人开车。 改 Prompt 可能 10 个 case 好了、20 个 case 坏了,你完全不知道。
小结
| 阶段 | 做什么 | 最低投入 |
|---|---|---|
| 起步 | 20 个手动 test case + 每次改动跑一遍 | 1 天 |
| 成长 | 自动化 Eval + LangSmith/Braintrust | 1 周 |
| 成熟 | 在线监控 + 回归 + A/B + 自动告警 | 持续 |
Agent 系统的工程质量,最终体现在 Eval 体系上。模型会换代,Harness 会演进,Eval 是唯一的 ground truth。