跳到主要内容

数据截至 (上游 commit 8b292c9f1b14)

Verifiers — 架构与原理

30 秒导读: Prime Intellect 出的「agent 考场」框架——你定义任务集(taskset),它把任务装进隔离的运行时(runtime),让真实 harness(Claude Code、Codex 这类真程序)去做题,所有模型流量从它的拦截服务器过境并被逐笔记账,最后产出既能量分又能直接训练的记录。评测和强化学习(RL)用的是同一套东西

1. 这是什么(零基础也能懂)

一句话定义: verifiers 是一个「定义任务 → 让 agent 在隔离环境里做 → 打分」的框架;打分结果可以直接当评测报告,也可以当 RL 的训练样本。

解决什么问题 / 给谁用: 假设你想知道「Claude Code 换上某个新模型后,修 bug 能力是涨了还是跌了」,或者你想用 RL 训一个会用终端的 agent。两件事都需要:一批标准化任务、一个让 agent 真刀真枪干活的考场、一套可信的记分。verifiers 把这三样做成可复用的库,供评测团队和 RL 研究者使用(它是 Prime Intellect 训练栈 prime-rl 的环境层)。

它能做什么(功能):

  • 用 Python 类定义任务集(prompt、文件、参考答案、资源需求、打分函数),uv run init 一键脚手架;
  • 把任务跑在真实 agent 程序里(Claude Code、Codex、mini-swe-agent、bash 等 14 种内置 harness),而不是自己拼的简化循环;
  • 四种隔离级别任选:本地子进程(调试)→ 本地 Docker → Modal / Prime 沙箱(生产级并发);
  • 所有模型调用经过内置拦截服务器:实时落轨迹、统一改采样参数、改写可疑的工具返回(防 reward hacking);
  • 多 agent 编排:单个解题、模拟用户多轮对话、best-of-N、裁判 agent 评判;
  • 结果写到 outputs/<任务集>--<模型>--<harness>/<uuid>/traces.jsonl,--resume 只补跑失败/缺失的。

用起来什么样: 安装后一条命令就能拿公开的终端任务集评测一个模型:

uv run eval primeintellect/terminal-bench-2 \
--env.agent.harness.id codex --env.agent.runtime.type docker

一句话直觉/类比: 把 RL 训练想成「组织一场大规模考试」:taskset 是题库,runtime 是考场隔间,harness 是考生自带的文具和答题习惯,而拦截服务器是监考+阅卷记录员——考生(模型)写的每一笔都先经过它,再送到真正的阅卷处(模型 API),所以它手里有最完整的原始记录。

2. 顶层全景(它大概怎么转)

verifiers 当前的主栈是 verifiers/v1/(旧的 v0 栈整体搬进 verifiers/legacy/,见第 6 章)。v1 把「跑一次评测」拆成四个正交的角色:

taskset(题库) env(编排:谁上场) interception server(监考/记账)
┌────────────┐ ┌────────────────┐ ┌──────────────────────┐
│ TaskData×N │─────▶│ run(task, │──────▶│ 每个 rollout 注册槽位 │
│ +Task 行为 │ │ agents) │ │ 按 secret 认领请求 │
└────────────┘ └───────┬────────┘ │ 改采样/防作弊/记 trace│
│ └─────────▲────────────┘
每个 agent = harness × 模型 × runtime │
│ │ 模型流量必经
┌─────────▼─────────┐ │
│ rollout(执行单元)│─────────────────┘
│ runtime 里起盒子 │ endpoint+secret
│ harness 在里面跑 │
└───────────────────┘
部件干什么在哪个文件
Taskset从数据集/生成器产出一个个 Taskverifiers/v1/taskset.py:38
Task / TaskData行为(搭环境、打分)/ 数据(题目卡)两半verifiers/v1/task.py:137 / :80
Env多 agent 控制流;默认 SingleAgentEnvverifiers/v1/env.py:73
Harness驱动真实 agent 程序的适配器verifiers/v1/harness.py:33
Rollout一道题 × 一个 agent 的完整执行verifiers/v1/rollout.py:54
Runtimerollout 的隔离盒子(进程/容器/沙箱)verifiers/v1/runtimes/base.py
InterceptionServer模型流量关口 + trace 记录员verifiers/v1/interception/server.py:139
Trace / Episode单 agent 记录 / 多 agent 一局记录verifiers/v1/trace.py:357 / verifiers/v1/episode.py:22

主线走一遍(一次 uv run eval <taskset-id>):

  1. 客户端加载 taskset,把任务一个个发给 worker;
  2. 每个任务在 env 里变成一局(episode):默认一个 agent 上场;
  3. 这个 agent 的一次执行 = 一个 rollout:开 runtime 盒子 → 装 harness → 拉起该 rollout 专属的拦截槽位和工具服务器 → harness 开跑;
  4. harness 里的程序想调模型,只能打向拦截服务器的 endpoint(配 secret);服务器代它调真实 API,顺手把这次问答记进该 rollout 的 trace;
  5. 跑完:task 的 @reward/@metric、harness 的 @metric、judge 三路打分写进 trace;trace 汇成 episode,落盘 traces.jsonl

3. 阅读地图

8. 代码地图(导航索引)

主题文件路径符号名
任务数据卡verifiers/v1/task.pyTaskDataWireTaskData
任务行为/打分verifiers/v1/task.pyTask.scoreTask.hooks
题库加载verifiers/v1/taskset.pyTaskset.loadheadshuffle
多 agent 编排verifiers/v1/env.pyEnv.runEnv.finalize
harness 契约verifiers/v1/harness.pyHarness.launchHarness.resume
执行生命周期verifiers/v1/rollout.pyRollout.open/step/close
预算/钩子路由verifiers/v1/session.pyRolloutLimitshook_boundary
拦截服务器verifiers/v1/interception/server.pyInterceptionServer.handle_request
轨迹结构verifiers/v1/trace.pyTraceModelCallBranch
一局记录verifiers/v1/episode.pyEpisodeWireEpisode
预制 envverifiers/v1/envs/SingleAgentEnvUserSimEnvBestOfNEnv
v0 兼容层verifiers/__init__.pyLegacyAliasFinder
示例任务集environments/alphabet_sort/alphabet_sort/taskset.pyAlphabetSortTaskset