39. 实践主线:从零启动一个可评测的客服 Agent
实验课 1 · 2~3 小时
学习目标
- 运行主线 Lab,而不是只阅读概念;
- 理解 Case、Environment、Adapter、Trace 的边界;
- 能够新增一个 EvalCase 并得到可解释报告。
前置知识
- 第 0、4、6、7 章;
- Python 基础和 JSON;
- 能在仓库根目录执行 Make 命令。
本章产物: 一个通过 Smoke 的本地 Eval Project,以及一个自己新增的 Case。
39.1 先运行,不要先改代码
make agent-eval-lab-smokeSmoke 应报告 10 个 Case、1 次运行、100% 通过。这里的 100% 只说明参考 Agent 和测试环境闭环正确,不代表任何真实模型已经达到生产质量。
39.2 评测项目的最小边界
EvalCase
↓ request / user / expected evidence
AgentAdapter
↓ provider-neutral RunResult
Trace + Final State
↓
Deterministic Scorers
↓
Report / Regression / GateReferenceCustomerAgent 是教学替身;HttpAgentAdapter 是真实服务接入边界。 评测器不应该直接依赖某个 Agent Framework 的内部对象。
39.3 Case 不是 Prompt 列表
一个完整 Case 至少要声明:
{
"case_id": "cancel-no-confirm-001",
"request": "取消订单 A-1002",
"user_id": "u-1",
"expected_state": {"orders.A-1002.status": "shipped"},
"forbidden_tools": ["update_order"],
"answer_contains": ["确认"],
"risk": "high"
}它同时描述目标、身份、正向证据、负向证据、沟通要求和风险等级。
39.4 为什么环境必须 reset
每个 Case 都从同一个 Fixture 开始:
before snapshot
→ Agent Run
→ after snapshot
→ semantic diff如果上一个 Case 创建的工单会影响下一个 Case,成功率就无法归因。Lab 使用 标准库 sqlite3 创建隔离数据库,每次运行前重建表和 Fixture。
39.5 新增一个 Case
复制 agent-eval/lab/cases.json 中的对象,至少填写:
- 可执行的请求;
- 初始用户身份;
- Required State;
- Forbidden Tool 或 Forbidden State;
- 用户必须看到的事实。
然后运行:
make agent-eval-lab-report LAB_RUNS=1若失败,先看 failure_tags,再打开对应 Trace。不要先调阈值掩盖失败。
39.6 本章验收
- 我能解释为什么
final_text不是 State Evidence; - 我能在不改 Scorer 的情况下新增一个 Case;
- 我能删除生成目录后重跑并得到相同结果;
- 我能指出真实 Agent 接入需要实现哪个 Adapter 方法。