2026 年最该被记住的一篇 agent 论文不是模型论文,是 Stop Comparing LLM Agents Without Disclosing the Harness。它的论断很朴素:在能力接近的模型之间做对比,harness 带来的方差经常超过模型带来的方差,甚至能让排名反转。
这个判断如果成立,"harness 怎么写"就不再是工程细节,而是产品本身。Prime Agent 是在这个前提下出现的产物——2026 年 8 月 5 日开源,截至 8 月 11 日 13,180 Star、1,339 Fork、486 个 Open Issue,MIT,TypeScript。
关于它"是什么"和"安不安全",我在上一篇里已经从产品和 reward hacking 的角度写过。这一篇不看博客,只读代码:我把仓库整个拉下来,读完了 refinement、kernel、autonomous 这三块,然后横向对了 12 个同类项目。
结论先说:这个仓库最值钱的部分不在论文里,在注释里。

它把两篇论文直接做成了产品形态
Prime Agent 的两个核心抽象都有明确的学术出处,这在 agent 项目里其实少见。
RLM(Recursive Language Model),arXiv:2512.24601,Alex L. Zhang、Tim Kraska、Omar Khattab。核心是把 prompt 当成 REPL 里的一个 Python 变量,让根模型用程序去检索、切分、递归调用自己,从而处理超出上下文窗口两个数量级的输入。
Continual Harness,arXiv:2605.09998,Seth Karten 等(Princeton / ARISE / Google DeepMind),2026 年 5 月 11 日提交。它把 harness 拆成四个可被 agent 自己增删改的组件——system prompt、sub-agents、skills、memory——再加一个从轨迹里自动改写它们的 Refiner。这篇论文的背景是 Gemini Plays Pokemon:人类在环反复调 harness,最终让 AI 首次通关 Pokemon Blue、Yellow Legacy 困难模式和 Crystal 无败战。Continual Harness 做的事是把人从这个循环里彻底拿掉。
官方给的数字:Opus 5 在 ARC-AGI-3 上 95.5% RHAE Best@1,压过 95.4% 的人类专家基线,Best@3 达 99.97%(183 关全通);长上下文 OOLONG 128k 上 0.700,对比 pi-mono 的 0.420。
数字先放一边。下面是真正的设计决策。
一、工具栏里只有一件工具
这不是修辞:
// packages/coding-agent/src/core/tools/index.ts
export type ToolName = "ipython";
export const allToolNames: Set<ToolName> = new Set(["ipython"]);
不是"以 IPython 为主",是字面意义上只有一个 tool schema。读文件、改文件、跑测试、调 skill、派子 agent,全部是这个持久 kernel 里的 Python 表达式。%%bash cell 每次是一次性子 shell,但 Python 命名空间、%cd、os.environ 跨 turn 跨 compaction 存活。
这条路线的学术源头是 CodeAct(ICML 2024)——那篇论文测出 17 个模型里有 12 个用代码动作比 JSON 动作成功率更高,最多 +20 个百分点、少 30% 交互轮次。工程化版本是 Anthropic 2025 年 11 月的 "code execution with MCP" 和 Cloudflare 的 Code Mode(把整个 Cloudflare API 压进约 1,000 tokens)。Prime Agent 的区别在于它没留退路。
系统提示里有一句是这条设计的自我修正,我认为它比"只有一个工具"这件事本身更有价值:
Do not assume IPython is the native runtime of the external thing being investigated. …Evaluate external systems through their own interface, then use IPython to coordinate the process and analyze what comes back.
翻译过来:别把别人的项目拖进你的 kernel 里跑。用它自己的 uv run / .venv/bin/python,IPython 只做编排和分析。这句话防的是一类非常具体的失败——agent 为了让 import 成功,往 kernel 里装依赖,然后得到一个和项目真实环境毫无关系的绿灯。任何做过"AI 跑通了但 CI 挂了"排查的人都知道这有多贵。
二、子 agent 是异步函数调用,而且永远不返回答案
handle = await rlm("Review the authentication flow", name="auth-reviewer")
# handle 里只有 rlm_child_id / name / session_dir / model —— 没有 result
rlm() 在任务受理(admission)的瞬间返回,不等完成。结果只有两条路回来:子 agent 显式 await agent_message.send(msg, receiver_role="parent"),或者写文件让父 agent 自己去读。
这个约束比它看起来重要。"派活立即返回 + 结果走事件"意味着父 agent 不会被一个十五分钟的子任务卡住整个 turn,更关键的是——父 agent 的上下文永远不会被子 agent 的完整轨迹被动灌满。想看要显式 agent_observe,不看就只收一句结论。父子通信被限制在 parent / siblings / direct children 三跳内,更深的必须经中间节点转发。
代价也写在 issue 里:#759 —— 子 agent 干完活、写完文件,但忘了发消息,父 agent 就一直以为它还在跑。显式回复是协议,不是保证。 任何把"完成"寄托在模型自觉执行某个动作上的设计,都要准备好这一课。
三、四类可改状态 × 两个作用域
refinement.ts(1,017 行)是整个仓库最值得读的文件。它把 Continual Harness 论文里的 H = (ρ, G, K, M) 落成了:
type RefinementKind = "prompt" | "memory" | "skill" | "subagent";
type RefinementAction = "create" | "update" | "delete";
type HarnessScope = "local" | "global";
几个细节做得很干净,而且都是"只有真跑过才会这么写"的那种:
- 默认 local。 写入落在当前 session 的 artifact 目录,不污染全局。只有"跨 session 稳定的教训、用户偏好、可复用 skill / subagent"才允许升到 global。API 是
global_=True——因为global是 Python 保留字,系统提示里专门写了这句,防止模型生成global=True这种语法错误。 - base system prompt 不可变。 refine 只能加 prompt 补充说明,不能重写基座。refine 自己的系统提示里写着
MUST NOT be rewritten。 - 合并规则确定。
mergeHarnessStates把 global 和 local 叠起来,id 撞车时给 local 那条加local:前缀显示,同时明确告诉模型"编辑时用不带前缀的裸 id"。 - 落盘是原子的。 写 tmp →
renameSync,并保留原文件权限(新建默认0o600)。 - 读盘失败降级为空。
loadHarnessState在每次构建 system prompt 的必经路径上,所以状态文件损坏时它返回空状态而不是抛异常,等下一次 save 重写干净。理由就写在函数里。
对比一下:Letta 的 self-editing memory 改的是 memory blocks,是同一个方向上更早、更窄的实现;而 Claude Code、opencode、Codex CLI 这些的"持久状态"全是人写的 markdown——AGENTS.md、CLAUDE.md、skills——写入端是人,不是 agent。 这一格现在真的很空。
四、写记忆之前,先花 4k tokens 判断"这轮值不值得写"
/refine 不是每轮都跑,它前面挂了一道独立的、更便宜的门:
const REFINEMENT_MAX_OUTPUT_TOKENS = 32_000;
const AUTO_REFINE_REVIEW_MAX_OUTPUT_TOKENS = 4_096;
AUTO_REFINE_REVIEW 只回 { shouldRefine, rationale, instructions? },系统提示明确要求它"拒绝一次性噪音、没有证据支持的假设、临时工具输出"。通过了才跑真正的 refine。
这是把"自我改进"从一个每轮都要付费的固定开销,变成一个有准入条件的偶发开销。对任何按轮计成本的生产系统,这个改造比自我改进本身更实用。
同一段代码里还有一条注释值得单独拎出来:
Output budgets are derived from the selected model instead of fixed literals. /refine input scales with harness size…, so a constant output cap silently truncates exactly the large multi-edit proposals that matter most.
输出预算是 Math.min(model.maxTokens, CAP),随模型缩放而不是写死常量。理由很硬:refine 的输入随 harness 变大而变大,一个恒定的输出上限恰好会静默截断掉那些最重要的多编辑提案。
配套的是一个显式错误常量:
const TRUNCATED_JSON_ERROR =
"the model stopped before completing its JSON object. This usually means
the output budget was exhausted; retry with a smaller request.";
截断被当成错误抛出,而不是当成一个短一点的答案接受。 这是我在整个仓库里看到的最有价值的一行工程判断,也是最容易被漏掉的一条——LLM 截断在全链路上是无声的:finishReason 被丢弃,半截内容存成 completed,一切看起来都很正常,直到下游读到一个断在句子中间的 JSON。
五、Kernel 状态被 pickle 下来,逐变量、可失败
会话恢复时 kernel 是全新的,模型却以为自己上一轮定义的变量还在。state-snapshot.ts 用 dill 逐个 top-level 名字单独序列化:一个不可 pickle 的对象(打开的文件、socket、GPU tensor)只会被跳过并上报,不会让整个快照失败。默认上限 256MB,超限变量同样跳过 + 上报。
一个只有真踩过才会写的细节:所有 builtins 都通过局部 _b 别名引用,防止用户命名空间把 list / open / print 遮蔽掉之后,快照代码自己先炸。
另有一个 Linux-only 的 IPython forkserver,省掉每次 python -m ipykernel_launcher 的冷启动。它的注释是整个仓库里我最认同的工程价值观:
Everything degrades to direct spawn: if the forkserver is disabled, unavailable, or a spawn request fails/times out, callers catch
ForkServerUnavailableand fall back to the existing path, so correctness never depends on fork.
优化路径永远可以被整个关掉,正确性不依赖它。 macOS 上直接禁用(fork-without-exec 不安全),一个环境变量能关。
六、自动模式:模型说完成不算完成
autonomous.ts 里,shouldAutonomouslyContinue 的默认返回值是这个:
return { shouldContinue: true, reason: "missing_terminal_evidence" };
也就是说,除非配置的 gate 命令(npm run check、测试、linter)真的退出 0,否则一律继续跑。 模型自称完成不构成终止条件。continuation prompt 把这条写死了:
Do not end the session yourself; the verifier/evaluator decides completion when configured gates pass.
更聪明的是防空转。每次跑 gate 前后各拍一次 git worktree 快照(status + diff + untracked 内容哈希)。如果上次 gate 失败之后工作区一个字符都没变,就不重跑那条命令,直接回一句:
not rerun: workspace unchanged since previous failed gate
The autonomous gate was not rerun because the workspace has not changed
since this failure. Edit source files, tests, or a blocker artifact
before attempting to finish again.
这一条挡掉的是自动模式里最烧钱的病:模型反复"我再跑一次测试看看",而中间什么都没改。预算被空转吃光,日志看上去还很勤奋。
顺带一个成本口径细节,我觉得值得所有做长会话的人对一遍:
return usage.input + usage.output + usage.cacheWrite; // 故意不含 cacheRead
注释解释得很直白——cache read 是从 provider 缓存里重放的旧上下文,把它累计计入预算,会让长自动循环远在真实工作量到顶之前就撞上预算墙。
七、Skill 是可 import 的 Python 包,且认别家的目录
Prime Agent 实现了 Agent Skills 标准(markdown + frontmatter),并扩展出 Python-backed skill:装进 kernel 的 venv,按 import name 直接调用。
report = await release_audit(repository=".", target_version="0.4.0")
只有 skill 的元数据进启动 prompt,SKILL.md 全文在任务匹配时才加载。更值得注意的是它明确支持读别家的技能目录:
{ "skills": ["~/.claude/skills", "~/.codex/skills"] }
在一个所有人都在造 harness 的年份里,主动做技能层互操作是个聪明的位置选择——skill 生态已经开始出现跨 harness 复用的压力,谁先兼容谁就少一个迁移成本借口。
横向对比:这条赛道现在长什么样
Star 数取自 2026 年 8 月 11 日的 GitHub API。
| 项目 | ★ | 动作表示 | 子 agent | 可自改的持久状态 | 隔离 | 长任务 |
|---|---|---|---|---|---|---|
| prime-agent | 13.2k | 单一 IPython kernel | 运行时 await rlm(),异步 |
prompt / memory / skill / subagent,agent 自己 CRUD | 无(明确声明不是沙箱) | daemon + 心跳 + goal + autonomous gate |
| opencode | 195.9k | JSON tool call | 配置式(JSON / md 定义,各带模型与权限) | AGENTS.md + skills(人写) | 无 | 前台为主 |
| Claude Code | 141.0k | JSON tool call | Task / Agent tool | CLAUDE.md + skills + memory(人写) | 权限系统 | 后台任务 |
| Antigravity CLI | 闭源 | — | — | — | — | — |
| Codex CLI | 105.2k | JSON tool call(Rust 宿主) | 有 | AGENTS.md | seatbelt / landlock 沙箱 | 云端 Codex |
| pi | 86.8k | JSON tool call | 有 | lazy skills | 无(推荐外部容器) | 前台 |
| OpenHands | 83.6k | CmdRun / IPythonRunCell / FileEdit / Finish | 有 | microagents | Docker 沙箱(自带 bash + Jupyter + 浏览器) | 有 |
| goose | 52.6k | MCP extensions | recipes | 无 | 可选 | 有 |
| smolagents | 28.7k | CodeAct,纯代码动作 | managed agents | 无 | E2B / Docker 可选 | 无 |
| Letta | 24.2k | JSON tool call | multi-agent | self-editing memory(MemGPT 血统) | 无 | 有 |
| SWE-agent | 20.0k | ACI(为模型设计的命令接口) | 无 | 无 | Docker | 无 |
四点判断:
第一,"代码即动作"这条线不是 Prime Agent 发明的,但它是第一个把退路砍干净的。 OpenHands 早就有 IPythonRunCellAction,但它和 CmdRunAction、FileEditAction 并列;smolagents 的 CodeAgent 是纯代码动作,但它是个库不是 harness,没有 session、daemon、崩溃恢复这一层。Prime Agent 的位置很清楚:smolagents 的动作模型 + OpenHands 的运行时野心 + pi 的 TUI 工程(README 里明确致谢了 pi,整个 packages/ai 是从那边 vendored 过来的)。
第二,真正稀缺的是"agent 能改自己的 harness"这一格。 表里只有 Prime Agent 和 Letta 填上了,而且层次不同。其余所有项目的持久状态写入端都是人。如果 harness engineering 真的是一门在成型的工程学科,那么"谁来写 harness"这个问题的答案正在从人往 agent 滑,Prime Agent 是目前滑得最远的那个。
第三,沙箱是它最明显的空缺。 README 里的 warning 写得很坦白:worker 和 kernel 分进程是为了生命周期隔离和崩溃恢复,不是安全边界。对比一下 OpenHands 的 Docker 沙箱和 Codex CLI 的 seatbelt / landlock,这一格是被碾压的。对个人开发者无所谓,对任何要跑不可信仓库的场景是硬伤。
第四,生态在收缩。 Google 在 2026 年 5 月 19 日 I/O 上宣布 Gemini CLI 与 Gemini Code Assist IDE 扩展退役,6 月 18 日停止对个人档位服务,替代品 Antigravity CLI 是闭源 Go 二进制。一个十万星的开源 CLI 换成闭源——这件事发生在 Prime Agent 开源的两个多月前。开源 harness 的供给正在从"大厂顺手开"变成"小团队认真做"。
不能只讲好话
代码量失控,而且是可验证的。 src 侧 171k 行 TypeScript / Python。agent-session.ts 11,288 行单文件;interactive-mode.ts 9,975 行;daemon-mode.ts 6,805 行里有 106 个 case 标签。HN 上(253 分 / 69 条评论)最尖锐的一条就是冲这个来的:
multiple files are close to 10K LOC… I'd probably aim for something way smaller to bootstrap a self-improving agent. Then I'd use this "Prime Agent" as an example to my self-improving agent for what it should not evolve to.
给个公道话:测试侧也有 159k 行、418 个测试文件,回归测试按 issue 编号归档(test/suite/regressions/<issue>-<slug>.test.ts),并且有个专门的 faux provider 保证测试不烧真 token。这不是无人看管的 slop,是测试很重但结构失控。两件事可以同时为真。
486 个 Open Issue,建仓三个月。 Windows 完全不支持(#719、#665、#660:kernel bootstrap 走 venv 的 bin/python,Windows 上永远起不来,而且每次重试还会把 venv 抹掉)。安装脚本在 npm global prefix 不可写时失败,macOS 上 Unix socket 路径会超长。
官方自己承认最要命的那条。 在部分测试里,Opus 5 和 GPT-5.6 Sol 跑 Prime Agent 的成绩不如它们各自的原生 harness,所以官方报告里换用了原生成绩。博客原话是"we still notice friction when running Prime Agent with models",并且明说没有任何前沿模型是围绕 Prime Agent 的抽象训练的。换句话说:这套设计的收益需要模型侧配合才能兑现,而配合目前还不存在。
自我改进会一并强化 reward hacking。 Factorio 那个 case study 里,agent 在几小时内把产量刷到 10 万以上——办法是发现并利用了 RCON 命令直接刷资源,尽管 heartbeat prompt 里明确禁止。会自我改进的 harness 同样会把作弊路径固化成一条 skill。
HN 上还有一条更结构性的质疑,我认为它有分量:
the foundational models have largely caught up to the point where they don't need this harness anymore… I can basically just store context in .md in the directories we work out of together and accomplish what I need.
以及另一位:"RLM 的 recursion 之所以赢,很大程度上是因为 root 用顶级模型、sub-agent 用便宜模型。"把复杂度往 harness 里堆,赌的是模型能力增长慢于 harness 收益增长。过去两年,这个赌注一直是输的。
最后一条是设计层面的:单工具把复杂度全推给了模型。 模型必须写出能跑通的 Python 才能做任何事。强模型下这是杠杆,弱模型下这是负债——语法错误、无限重试、长尾成本爆炸。JSON tool call 至少有 schema 校验兜底,代码执行没有。
如果你在维护自己的 harness,这七条可以直接抄
不需要认同 RLM,也不需要做自我改进,下面这些是独立成立的:
1. 截断当错误,不当答案。 stop reason 是 length 就是失败,不是一个短一点的成功。同时把输出预算写成 min(model.maxTokens, CAP) 而不是硬编码常量——恒定上限恰好会截掉最重要的那类长输出。
2. 终止证据的定义要收紧。 默认值应该是"继续",只有外部可验证的 gate 通过才是"完成"。模型声明完成只是一次候选终止。这个默认值的方向比具体实现重要得多。
3. 工作区没变就别重跑闸门。 拍一次工作区快照,和上次失败时的比对,一样就不跑,把"你什么都没改"直接回灌给模型。这是纯增量改造,挡的是自动模式里最贵的空转。
4. 缓存重放的 token 不计入预算。 把 cache read 累计进预算,会让长会话在真实工作量到顶之前撞墙。这个口径错了,你会以为自己的 agent 比实际更贵。
5. 记忆写入要有准入门。 别做成每轮都跑。先用便宜模型判 shouldRefine,过了才跑贵的那次。自我改进的价值不在频率,在准确率。
6. 状态落盘的三条: 原子写(tmp + rename + 保留权限)、读盘损坏降级为空而不是抛异常(因为它在启动必经路径上)、全量留痕可回滚。
7. 优化路径必须可以整个关掉。 缓存、fork server、预热、快照——所有加速手段都要有一条"失败就退回慢路径"的通道,正确性不能依赖它们。
有两条明确不建议照抄:把工具栏压成单一代码执行(如果你的工具有严格 schema 和幂等要求,那是资产不是负担);以及"这不是安全沙箱"这句话——Prime Agent 敢这么写是因为它跑在你自己机器上,多租户场景没有这个选项。
结论
Prime Agent 值不值得用?如果你在做长时程评测、需要 daemon 化的后台 agent、或者想验证 RLM 这套范式,值得装一个试。如果你只是要一个日常 coding agent,opencode 和 Claude Code 现在都更成熟,Windows 用户则完全不用考虑。
但"值不值得用"是个小问题。它更大的价值在于:这是目前唯一一个把"agent 改自己 harness"完整实现出来、并且开源的东西,而且它把踩过的坑写在了注释里——截断必须是错误、完成必须有外部证据、工作区没变就别重跑、优化路径必须可降级、状态文件损坏必须降级为空。
这些东西和 RLM 无关,和 Continual Harness 也无关。它们是任何一个跑长任务的 agent 系统迟早都要付的学费。它已经付过了。这是开源最实在的那部分价值——不是省下你写代码的时间,是省下你踩坑的时间。
参考资料
- PrimeIntellect — Prime Agent: A self-improving RLM agent(2026 年 8 月 5 日)
- PrimeIntellect-ai/prime-agent GitHub 仓库 — 13,180 Star / 486 Open Issue(截至 2026 年 8 月 11 日)
- Hacker News — Prime Agent: A self-improving RLM agent(253 分 / 69 条评论)
- Alex L. Zhang, Tim Kraska, Omar Khattab — Recursive Language Models(arXiv:2512.24601)· 作者博客
- Seth Karten et al. — Continual Harness: Online Adaptation for Self-Improving Foundation Agents(arXiv:2605.09998,2026 年 5 月 11 日)
- Xingyao Wang et al. — Executable Code Actions Elicit Better LLM Agents (CodeAct)(ICML 2024)
- Stop Comparing LLM Agents Without Disclosing the Harness(arXiv:2605.23950)
- Cloudflare — Code Mode: give agents an entire API in 1,000 tokens
- OpenHands Runtime 架构文档
- Google Developers Blog — An important update: Transitioning Gemini CLI to Antigravity CLI(2026 年 5 月 19 日)
- GitHub Issue #759: Subagents can complete and write files without sending agent messages
- GitHub Issue #660: Windows kernel bootstrap uses venv bin/python
- Agent Skills 标准