评估
一次评估会拿真实模型去跑 T3 Code 里真实的文本或代码,并对模型的行为打分。单元测试使不上力的地方就用它:模型输出每次运行都会变,文案稍改几个字,结果也会跟着动。
当一项改动会影响模型看见什么、做什么时,就去编写或运行评估:智能体指令、MCP 工具的描述和 schema、工具结果、生成出来的标题,或者智能体在某项功能上得到的指引,例如设备管理器(Device Manager)。
| 评估 | 衡量 |
|---|---|
| mcp-tool-use | 在虚构的对话线程(thread)里,智能体是否正确使用 T3 的 MCP 工具,包括设备路由和恢复。 |
| thread-titles | 生成的对话线程标题是否点出了正确的主题。 |
| pr-content | 当项目(project)指令试图把生成带偏时,拉取请求(pull request)的生成是否仍在描述这次 diff。 |
| voice-cleanup | 可选的听写清理是否只改口述文本,并保留原意。 |
| test-signal | 运行 test-signal 检查的低成本模型,会不会把低信号的测试标出来。 |
运行评估
- 在仓库根目录运行
vp i。 - 把评估需要的 API 密钥放进仓库根目录的
.env。这个文件在 gitignore 里,评估脚本会加载它。不要打印密钥,也不要提交密钥。 - 在
evals/下运行pnpm <eval> --out runs/<name>。runs/在 gitignore 里。
每份评估的 README 会列出它用的模型、标志和费用。先跑一个用例、一个样本,确认配置已经就绪。
评估会调用付费模型,所以 CI 不跑它们。CI 会对这个包做类型检查,并运行评分器的单元测试。
一份评估的形态
每份评估都是同一个形态,所以新的好写,旧的好跑。
evals/<eval>/run.ts是入口。package.json里有一个以这份评估命名的脚本。evals/<eval>/README.md说明这份评估衡量什么、怎么跑、怎么加用例,以及跑一次要花多少。- 用例是数据,放在
cases/或cases.ts。每个用例都有一个id,写明来源(拉取请求(pull request)、issue 或对话线程(thread)),并带上它的检查项或评分标准。 - 评估从源码导入被测代码。不要把提示词、工具描述或 schema 复制进评估。这样评估测到的始终是当前的文本。
- 标志:
--out <dir>(必填)、--model <id>,以及用来对比的--baseline <earlier results>。完整跑一遍又慢又贵时,加上--case <ids>。 - 一次运行会把结果行写到
--out,并另写一份给人看的摘要或审阅文件。 - 评估自己打分时,
run.test.ts测试评分器。评分器是普通逻辑,在 CI 里运行。由人打分时,这次运行会藏起哪一份输出是新的。
用例规则
- 用例要么复现一次真实的糟糕体验,要么守住一次真实的良好体验。写明来源。
- 先加用例,再做修复。它必须在旧文本上失败,在新文本上通过。
- 如果改了用例,改过的用例仍然必须在它当初针对的那份文本上失败。优先修 T3 Code,不要把用例放宽。
- 加上对照:正确做法就是平常工作的那些用例。它们用来抓住矫枉过正的修复。
- 模型输出会波动。每个用例多跑几次。样本里有一半或更多失败时,这个用例判定为失败。和同一模型上的基线比,不要和绝对分数比。
- 用例、夹具和模板里都不要放用户数据。使用
/home/user和acme/app。提交之前,把每一份捕获下来的夹具读一遍。 - 已提交的文件里不要放未发布的模型细节,某份评估的模型表里的模型 id 除外。
费用
只跑你的改动碰到的用例,直到它们通过。然后在拉取请求(pull request)合并之前,每个模型做一次完整运行。每份评估的摘要会记下这次运行的费用。
添加一份评估
- 从最接近的那份评估,把上面的形态照搬过来。
- 往
package.json加一个脚本,写一份 README,并在上面的表格里加一行。 - 当第二份评估需要第一份已经有的代码(模型客户端、shell 模拟器、采样、摘要)时,把那段代码挪到
evals/shared/,两份都用它。在第二份评估真正需要之前,不要先做共享代码。