我们的 harness 工程实践

Agent 一上线,最怕两句话:「Demo 很好」「线上很蠢」。中间缺的往往不是更大的模型,而是一套能重复比较版本的壳——我们把这层叫 Eval Harness(评测壳)。

一句话:Harness 在这里不是 Claude Code 那种「装配好的车」,而是把 Agent 放进考场:隔离跑、采轨迹、打分、卡门禁、把坏例送回去。

若你刚看完《Agent 开发面试题目集合》,文里的 Eval Harness 指的就是这一侧;Product Harness(产品壳)是另一回事。

先消歧,免得聊歪

叫法 在干什么 典型问题
Eval Harness 考场与安全带 这个 Prompt 能不能发?退款会不会乱调?
Product Harness 开箱即用的 Agent 壳 Claude Code / Codex 为何同模型表现差一截?

LangChain 有句「Agent = Model + Harness」,那里的 Harness 更接近运行时挽具(提示、工具、中间件),和本文的评测壳同名不同职。聊天时先对齐名词,再谈方案。

我们要解决什么

没有评测壳时,常见场面是:

  1. 改一句 System Prompt,凭感觉说「顺多了」
  2. 线上踩坑,修完不沉淀成用例
  3. 工具一换 Schema,旧轨迹全失效却无人知晓
  4. 用「平均分还行」掩盖政策类硬伤(越权、跨租户)

Eval Harness 要回答的只有一句:换模型 / Prompt / 工具之后,这个 Agent 比上一版更好,还是更危险?

流水线长什么样

1. 版本化用例库

每条用例至少有:

  • 输入:用户话术、租户、角色、前置状态
  • 期望结果:终态字段(工单状态、是否退款、答复要点)
  • 期望轨迹约束:必调工具、禁调工具、关键参数
  • 标签:回归 / 红队 / 权限 / 成本敏感

用例跟代码一样进 Git。谁改 Prompt,谁有义务补或改用例。

2. 隔离执行

离线评测禁止打真实写接口。工具层用:

  • Mock:固定返回
  • 录制回放:线上脱敏轨迹再播
  • 沙箱账号:仅允许打到隔离环境

否则「评测一次改坏一库」,没人敢跑 CI。

3. 采集轨迹

一次 run 是一棵 span 树:模型调用、工具调用、检索、护栏、审批。导出前脱敏。没有 run_id,坏例无法回流,门禁也无从谈起。

可观测栈用 LangSmith、Langfuse 或 OpenTelemetry 均可——重要的是字段约定稳定,而不是品牌。

怎么打分

L1 确定性(能代码判就代码判)

  • 终态字段是否等于期望
  • 工具参数是否过 Schema
  • 是否触达禁调工具 / 禁表 / 超额度

这一层失败 = 硬失败。不要用「法官觉得还行」盖过去。

L2 轨迹

结果对了仍可能路径脏:偷看了别的租户、跳过核身、同参连打五次。用 exact / in-order / any-order、禁调集合、步数与成本上限来卡。

L3 量规法官(LLM-as-Judge)

只用于「礼貌、完整性、是否胡编解释」这类难精确匹配的维度。必须:

  • 细粒度 pass/fail,少用 1–5 分玄学
  • 给人标校准,定期重测法官稳定性
  • 防偏好长文、偏好自家模型文风

政策类(越权、外发、跨租户)永远不要只靠 L3。

门禁怎么设

我们实际采用的分层:

类别 门禁
权限 / 注入 / 跨租户 必须 0 回归,红了直接阻断
主路径任务成功 相对上一 release 不显著变差(看置信区间,不看单次运气)
成本 / 步数 设上限;飙高只告警或阻断视业务而定
软质量(措辞) 可先观察,不单独挡发版

非确定性系统要 N 次重复:同时看「至少一次成功」和「次次成功」。面向用户的 Agent,稳定性往往比峰值聪明更重要。

发布单元捆死四件事:模型 + Prompt/Skill + 工具 Schema + 评测集版本。缺一,出了事无法回答「昨天改了什么」。

坏例怎么回流

线上「很蠢」不是情绪,是原材料:

  1. 拿到 run_id,定位路由 / 检索 / 工具 / 压缩 / 权限哪一层
  2. 复现进隔离环境
  3. 写成用例:期望结果 + 轨迹约束
  4. 修策略或数据后,同一条必须先绿
  5. 再进主干回归集

忌:只改一句 Prompt,宣称已修,用例库纹丝不动。

最小可用版本(两周能落地)

不必一上来造大平台。最小集合:

  1. 20~50 条主路径 + 10 条红队(注入、越权、跨租户)
  2. 工具全 Mock,配置进仓库
  3. CI:每条跑 3 次;权限类全绿才合并
  4. 一份 JSON/HTML 报告:失败用例、轨迹 diff、成本
  5. 发版清单:四元组版本号 + 报告链接

先活着,再谈法官平台、流量回放、自动挖掘难例。

和产品壳、运行时的分工

  • Product Harness:让 Agent 好用(默认工具、Hook、沙箱、Skill)
  • Runtime(如 LangGraph):让 Agent 跑得稳(Checkpoint、HITL、续跑)
  • Eval Harness:让你敢改、敢发(比较、门禁、回流)

三者可以共用同一套工具接口与 Trace Schema,但职责不要揉成一个大泥球。评测环境若偷偷连上生产写接口,考场就变成事故现场。

我们踩过的坑

  1. 只用结果评测 — 退款金额对了,但中间查了别的用户。补轨迹约束后才暴露。
  2. 评测集泄露进 Prompt 示例 — 分数虚高,上线崩盘。示例与考题隔离。
  3. Mock 太假 — 线上错误码、空结果、慢超时从未出现在考场。要注入故障用例。
  4. 法官单独说了算 — 一度放过「礼貌地拒绝查库却编造物流」。L1/L2 收回主权后才稳。
  5. 同名 Harness 扯皮 — 和做 Coding Agent 的同事各说各话一周。后来强制:会上先写 Eval 还是 Product。

小结

Eval Harness 不让模型更聪明,它让「聪明」可以被比较、被否决、被记住。

能过榜,不等于能过门禁;能过门禁,才配上线。

相关阅读:《Agent 开发面试题目集合》(Q66 / Q77)· 《什么是 LangGraph?》 · 《什么是 LangChain?》