【Harness篇】05:长任务Harness

文章目录

    • [1. 长任务的两大失败模式](#1. 长任务的两大失败模式)
      • [1.1 Context degradation / context anxiety:模型"自己慌了"](#1.1 Context degradation / context anxiety:模型"自己慌了")
      • [1.2 Self-evaluation bias:模型对自己永远过度自信](#1.2 Self-evaluation bias:模型对自己永远过度自信)
    • [2. 解决思路一:双代理 harness(initializer + coding agent)](#2. 解决思路一:双代理 harness(initializer + coding agent))
      • [2.1 Initializer agent:只跑一次的"奠基者"](#2.1 Initializer agent:只跑一次的"奠基者")
      • [2.2 JSON feature list:不可变更的合约](#2.2 JSON feature list:不可变更的合约)
      • [2.3 Coding agent:每次只做一格](#2.3 Coding agent:每次只做一格)
      • [2.4 四个失败原因 → 四个对应解](#2.4 四个失败原因 → 四个对应解)
    • [3. 解决思路二:三代理 harness(planner + generator + evaluator)](#3. 解决思路二:三代理 harness(planner + generator + evaluator))
      • [3.1 数据流框图](#3.1 数据流框图)
      • [3.2 Planner:故意"不写细节"](#3.2 Planner:故意"不写细节")
      • [3.3 Generator vs evaluator:GAN 的灵感](#3.3 Generator vs evaluator:GAN 的灵感)
      • [3.4 四维评分:phrase 选择改变模型行为](#3.4 四维评分:phrase 选择改变模型行为)
      • [3.5 三代理职责对比](#3.5 三代理职责对比)
      • [3.6 代价数字:harness 不便宜,但便宜的会失败](#3.6 代价数字:harness 不便宜,但便宜的会失败)
    • [4. 文件系统作根(Filesystem is king)](#4. 文件系统作根(Filesystem is king))
      • [4.1 为什么是文件系统?](#4.1 为什么是文件系统?)
      • [4.2 三种文件,三种语义](#4.2 三种文件,三种语义)
      • [4.3 跨会话恢复的黄金法则](#4.3 跨会话恢复的黄金法则)
    • [5. 子代理三态:Fork / Teammate / Worktree](#5. 子代理三态:Fork / Teammate / Worktree)
      • [5.1 三种形态对比](#5.1 三种形态对比)
      • [5.2 Fork:最便宜的"分身"](#5.2 Fork:最便宜的"分身")
      • [5.3 Teammate:信箱式协作](#5.3 Teammate:信箱式协作)
      • [5.4 Worktree:最重也最安全](#5.4 Worktree:最重也最安全)
      • [5.5 选型决策树](#5.5 选型决策树)
    • [6. 验证回路三种](#6. 验证回路三种)
      • [6.1 Rules-based:最干净的信号](#6.1 Rules-based:最干净的信号)
      • [6.2 Visual:捕捉语义错误](#6.2 Visual:捕捉语义错误)
      • [6.3 LLM-as-judge:catch "last mile"](#6.3 LLM-as-judge:catch "last mile")
      • [6.4 实战分层](#6.4 实战分层)
    • [7. Ralph Loop:把"轮班"工程化](#7. Ralph Loop:把"轮班"工程化)
      • [7.1 起源:从 Geoffrey Huntley 到 2026 主流模式](#7.1 起源:从 Geoffrey Huntley 到 2026 主流模式)
      • [7.2 Ralph Loop 的工作流](#7.2 Ralph Loop 的工作流)
      • [7.3 Ralph 不是 hack,是"轮班工程化"](#7.3 Ralph 不是 hack,是"轮班工程化")
      • [7.4 与双代理的关系](#7.4 与双代理的关系)
    • [8. 架构如何跟着模型变](#8. 架构如何跟着模型变)
    • [关键 takeaway](#关键 takeaway)
    • 参考资料

前四篇都在讲"一次会话之内"的事情:harness 是什么、agent loop 怎么转、上下文怎么挑怎么压、工具与权限如何分层。本篇换一个时间尺度------当任务跑 6 小时、跨 50 次 turn、跨 5 次会话时,单代理 + 单循环的模型就不够了。这时 harness 必须升一级,把"工程化的人类协作流程"塞进来:双代理、三代理、子代理、文件系统作 ground truth、独立 evaluator 做闭环、Ralph Loop 做轮班。

本篇的领地,是 agent 跨 turn / 跨 session / 跨实例

1. 长任务的两大失败模式

把会话拉长到 1 小时以上,单代理一定会撞上两堵墙。这两堵墙是后续所有 harness 设计的起点。

1.1 Context degradation / context anxiety:模型"自己慌了"

第一堵墙叫 context anxiety ------模型并不是直接因为 token 用光而失败,而是靠近 window 上限就开始"早完工"。它会突然宣布"主要功能已实现",写一段虚假的总结,然后把还没完成的 30% 工作丢掉。

Addy Osmani 在他的 harness engineering 长文里把这一现象命名得很准确:

Sonnet 4.5 exhibited an anxiety-driven failure mode where agents would "wrap up work prematurely as it approached what it thought was its context limit."

Anthropic 的双代理论文用了更克制的表述:"running out of context in the middle of implementation"。但翻译成行为模式,就是模型在 80% context 占用时开始主动收尾------产生一种"考试快结束了,赶紧把卷子交了"的应激反应。

这个失败模式不是用更大 context window 能解决的。即便上 1M context,模型对"自己还剩多少时间"的感知仍然存在偏差,且偏差方向永远是悲观的。所以单纯把窗口加大,只是把同一个 anxiety 推到更晚的地方触发。

唯一可靠的解法是外部强制把任务切片,让模型每次只在小窗口里干一件事,且不让它知道还有多少未完成的工作。这就引出了下一节的双代理结构。

1.2 Self-evaluation bias:模型对自己永远过度自信

第二堵墙更难缠:模型评判自己的产出永远偏乐观

Osmani 的总结一语点破:

Agents reliably skew positive when grading their own work.

Anthropic 三代理那篇文章给的工程化解法是把 generator 和 evaluator 物理切开 ------不是同一个 prompt 里加一段"再检查一遍",而是另起一个独立的 agent,独立 prompt,独立工具,独立打分。这种切分远比让生成器自我批评更可解:因为模型在同一上下文里天然倾向于为自己的前文辩护,换上下文后这种 confirmation bias 才能被打断。

把这两条失败模式钉死,本篇剩下所有架构选择都能从它们推出来:

失败模式 推论 对应 harness 组件
context anxiety 不能让模型在一个会话里跑到底 双代理 / 三代理 / Ralph Loop
self-evaluation bias 不能让生成者打分 独立 evaluator / 验证回路

剩下五节,都是这张表的展开。

2. 解决思路一:双代理 harness(initializer + coding agent)

Anthropic 2025 年 11 月那篇 Effective Harnesses for Long-Running Agents 给出了第一个生产级答案------双代理结构。原文一句话讲完核心:

We developed a two-fold solution to enable the Claude Agent SDK to work effectively across many context windows: an initializer agent that sets up the environment on the first run, and a coding agent that is tasked with making incremental progress.

这两个 agent 不在同一会话 ,也不共享 context ------它们的握手协议全部走文件系统

2.1 Initializer agent:只跑一次的"奠基者"

Initializer 在项目第一次会话里干四件事,然后永远退场

  1. init.sh :一个标准化的环境启动脚本------npm install / pip install -r / 启动 dev server / 跑 baseline test。所有后续 agent 第一行命令都是 bash init.sh,从而把"环境状态"这个变量从 agent 的责任栏里挖掉。
  2. claude-progress.txt :跨会话的人类可读日志。每个后续 agent 接手时第一件事是 cat claude-progress.txt,结束时追加一段。它扮演的是外部的工作记忆------不要把它当 markdown 笔记,而是当 cron 进程之间的信箱。
  3. 第一次 git commit:建立 baseline checkpoint,让后续 agent 永远有一个安全回退点。
  4. JSON 形式的 feature list:这是整个双代理结构的"硬合约",下一节单独讲。

四件事的次序很重要------init.sh 必须能在 baseline 上跑通,否则后续 agent 第一步就翻车。

2.2 JSON feature list:不可变更的合约

Anthropic 在原文里专门解释了为什么用 JSON 而不是 markdown:

We prompt coding agents to edit this file only by changing the status of a passes field, and we use strongly-worded instructions like "It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality." After some experimentation, we landed on using JSON for this.

JSON 比 markdown 抗 agent 篡改------结构化字段更难被"顺手改一改",且 passes: false → true 是一个单点 diff,可被 git 审计。

一个最小化的 feature 条目长这样:

json 复制代码
{
  "features": [
    {
      "id": "F-014",
      "category": "auth",
      "description": "User can sign up with email + password",
      "test_steps": [
        "Visit /signup",
        "Fill email + password",
        "Click submit",
        "Expect redirect to /dashboard"
      ],
      "passes": false,
      "verified_by": null,
      "last_attempted_session": null
    },
    {
      "id": "F-015",
      "category": "auth",
      "description": "Failed login shows error message",
      "test_steps": ["..."],
      "passes": false,
      "verified_by": null,
      "last_attempted_session": null
    }
  ]
}

注意三个设计选择:

  • passes 是布尔,没有 partial:partial 状态会让 agent 自我安慰"算大致完成了"。布尔逼它要么不动、要么真验证。
  • test_steps 是数组:每条都是 evaluator 必须执行的 Puppeteer / Playwright 步骤。
  • verified_by 字段:记录哪个 session 通过了它------用于事后 debug "这个 feature 是什么时候过的"。

Coding agent 的系统提示词里禁止 它修改 descriptiontest_steps只允许 它把 passesfalse 翻成 true。这条 immutability 是双代理结构能跨 50 个会话不漂移的根因。

2.3 Coding agent:每次只做一格

后续每次会话,coding agent 跑同一套固定流程:

复制代码
session 启动
  ↓
pwd                              ── 知道自己在哪
git log --oneline -20            ── 知道之前发生了什么
cat claude-progress.txt          ── 看上一次 agent 留的口信
cat features.json | jq '.features[] | select(.passes==false)'
  ↓
选最高优先级未完成 feature
  ↓
bash init.sh                     ── 标准化环境
  ↓
puppeteer 跑 baseline E2E        ── 确认起点干净
  ↓
实现该 feature
  ↓
puppeteer 重跑该 feature 的 test_steps
  ↓
通过?
  ├─ yes → features.json passes: true → git commit → 更新 progress.txt
  └─ no  → 不能改 passes → 留下 progress.txt 说明卡在哪 → 退出

注意几个细节:E2E 跑两次 (开始的 baseline + 实现后的验证)、git commit 与 passes 翻转必须原子 (要么都做要么都不做)、写 progress.txt 是退场仪式(不论成败都要写,否则下个 agent 接不上)。

2.4 四个失败原因 → 四个对应解

Anthropic 在论文表格里把双代理 harness 拆成 4 条 failure → solution:

失败模式 直接原因 对应 harness 组件
Premature completion(早完工) 模型缺总览,不知还剩多少 feature JSON feature list 把全景永远摆在桌上
Buggy state transitions(状态 bug) 没有可恢复的 checkpoint git + progress.txt 双轨持久化
Incomplete marking(虚假完成) 模型自评偏乐观,没有客观验证 强制 Puppeteer E2E,只有跑通才能翻 passes
Environment confusion(环境漂移) 每个 session 重新搭环境出错 init.sh 标准化,第一行就跑

这张表是双代理结构的"灵魂"------每一个 harness 组件都精确对应一种已识别的失败模式。没有冗余、没有装饰。这也呼应第 6 篇会展开的工程哲学:harness 的复杂度必须可被回溯到具体失败。

3. 解决思路二:三代理 harness(planner + generator + evaluator)

2026 年初 Anthropic 又发了 Harness Design for Long-Running Application Development,把架构再升一级------加入 planner ,并把 evaluator 升级成独立 agent。双代理是工程范式,三代理是产品范式

3.1 数据流框图

复制代码
┌──────────────┐
│  user prompt │  "做一个像 Notion 的笔记应用,要支持 markdown"
│   (1-4 句)   │
└──────┬───────┘
       │
       ▼
┌─────────────────┐
│   PLANNER       │  把 1-4 句展开成 product spec
│  - 故意只写高层  │  避免 detail 错误级联
│  - 不写实现细节  │
└──────┬──────────┘
       │ product spec (markdown)
       ▼
┌──────────────────────────────────────────┐
│              SPRINT LOOP                   │
│                                            │
│   ┌──────────┐   sprint contract  ┌──────┐ │
│   │GENERATOR │ ◄────negotiate────►│ EVAL │ │
│   │          │                    │      │ │
│   │ 实现一个 │   ─── code ───►   │ 跑   │ │
│   │ feature  │                    │ Play │ │
│   │ 自测一遍 │   ◄── score ───   │write │ │
│   │          │                    │ 打分 │ │
│   └──────────┘                    └──────┘ │
│        ▲                              │    │
│        └──── if score < threshold ────┘    │
│                                            │
└────────────────────────────────────────────┘
       │ all sprints passed
       ▼
   final app

3.2 Planner:故意"不写细节"

Planner 的工作不是产品经理那种细致 spec,而是有意保持模糊。原文一句关键解释:

If the planner tried to specify granular technical details upfront and got something wrong, the errors in the spec would cascade.

也就是说------上游错一个字段名,下游 generator 会按这个错字段名实现,evaluator 会按这个错字段名验证。全链路一起错,错得很自洽,最难发现。

Planner 的对策是只写 high-level 设计 :实体、用户故事、屏幕级别的页面流。具体 schema、API 路径、组件名都留给 generator 现场决定。这是一种典型的 late binding------把决策推迟到信息最完整的阶段。

3.3 Generator vs evaluator:GAN 的灵感

Anthropic 这位 author(Hamel Husain 风格的工程文章)直接借用了 GAN 的类比:

Taking inspiration from Generative Adversarial Networks (GANs), I designed a multi-agent structure with a generator and evaluator agent.

Generator 像 GAN 里的 generator network ------专心生产;evaluator 像 discriminator ------专心挑刺。两个 agent 在每个 sprint 开始前协商一份 sprint contract

Before each sprint, the generator and evaluator negotiated a sprint contract: agreeing on what 'done' looked like for that chunk of work.

注意"协商"两个字。不是 evaluator 单方面下达,而是双方对齐------generator 提出"我打算实现 A、B、C,验证方式是 X、Y、Z",evaluator review 这个方案,反对就改,达成共识才开工。这避免了 evaluator 用一个 generator 完全没准备的标准来打分(人类工程团队里典型的 PR review 来回扯皮)。

3.4 四维评分:phrase 选择改变模型行为

Evaluator 用 Playwright MCP 真的去点页面、截图、看交互

The evaluator would navigate the page on its own, screenshotting and carefully studying the implementation before producing its assessment.

打分按四维(前端任务的版本):

维度 关注点
Design quality 整体感、coherent whole rather than collection of parts
Originality 有没有 custom decisions,还是堆 template
Craft 字号层级、间距、配色、对比度
Functionality 用户能不能找到主操作、跑完核心流

真正出乎意料的发现 是:评分 prompt 的措辞会反过来塑造 generator------

Including phrases like 'the best designs are museum quality' pushed designs toward a particular visual convergence.
I emphasized design quality and originality over craft and functionality.

也就是说------你在 evaluator 的 rubric 里写 "museum quality",generator 输出会集体偏向极简博物馆风 ;你写 "weighted toward originality",generator 会减少 template 化 。这意味着 evaluator 不仅是裁判,还隐式地是 generator 的 style guide。设计 evaluator 的 rubric 时要意识到这种"打分即引导"的反向作用。

3.5 三代理职责对比

代理 输入 输出 工具 上下文寿命
Planner 1-4 句用户 prompt product spec (markdown) 几乎无 一次性,不持续
Generator spec + sprint contract 代码 + git commit + 自测报告 bash / edit / browser 跨 sprint 持续
Evaluator 跑起来的应用 四维分数 + bug 报告 + 是否 sign-off Playwright MCP 每个 sprint 重起

注意 evaluator 的 context 是每 sprint 重启------这正是为了防止它"看习惯了 generator 的代码"而失去客观性,等价于把 self-evaluation bias 切断在 context 边界上。

3.6 代价数字:harness 不便宜,但便宜的会失败

文章给了三组真实数字,对比鲜明到值得贴出来:

设置 时长 成本 结果
Solo agent(单代理一把梭) 20 min $9 失败:实体能渲染但不响应输入
完整三代理 harness 6 hr $200 成功:production-grade 全栈应用
DAW 简化 harness 3 hr 50 min $124.70 成功:含三轮 QA,捕获缺失功能

9 失败 vs 200 成功 ------20 倍成本差,换 100% 成功率。文章原话:"the difference in output quality was immediately apparent"。这说明 harness 不是优化项,是相变------从"agent 玩具 demo"相变到"agent 能交付软件"。

4. 文件系统作根(Filesystem is king)

前两节反复出现 gitprogress.txtfeatures.json,这不是巧合。生产级 harness 的 ground truth 永远在文件系统里,不在向量库、不在数据库、不在 LLM 自己的"记忆"里

4.1 为什么是文件系统?

文件系统满足三个性质,缺一不可:

  1. 人类可读 ------出问题时人能直接 cat / git diff,不需要重启 agent 才能看
  2. diff 友好 ------git diff 是 30 年成熟的审计工具,一切状态变更都能追到提交
  3. 跨进程通用------bash、python、agent、人类都能读,不需要解析 embedding

向量库虽然时髦,但它不可读 (你 cat 不出向量)、不可 diff (两个 embedding 的差对人没意义)、不通用 (不同模型 embedding 不能互通)。所以生产 harness 把 LLM 记忆强制降维到文件:git commit = 永久 checkpoint,progress.txt = 短期 scratchpad,features.json = 不可篡改的合约。

4.2 三种文件,三种语义

文件 语义 谁写 谁读
git history 永久 checkpoint,可回滚 每个 coding agent commit 一次 后续所有 agent / 人类
claude-progress.txt 短期 scratchpad,session 之间的口信 session 退场时追加 session 开场时读
features.json 不可篡改合约 仅 initializer 写完整结构;coding agent 只翻 passes 每个 coding agent + evaluator

三者分工很硬:永久状态 → git,瞬时口信 → progress.txt,硬约束 → JSON 合约。混用会出问题------比如把 feature list 写进 progress.txt,agent 会"顺手"修改它;把 progress 写进 git,每个 commit 就脏了。

4.3 跨会话恢复的黄金法则

任何跨 session 持久化必须通过人类可读的中间产物。

如果某个状态只有 LLM 自己能解读(比如 vector embedding、model-specific summarization),那它就不能被信任 作为 source of truth。一旦底层模型换版本(Claude 4.5 → 4.6 → 4.7),那些状态可能整个失效。文件系统的 ASCII 字符串是 model-agnostic 的------50 年后用别的 LLM 也能 cat 出来。

这条原则在第 8 节会再次出现:模型变强 → 哪些 harness 组件可以裁掉?答案是"那些 model-specific 的不能裁,model-agnostic 的可以裁"。

5. 子代理三态:Fork / Teammate / Worktree

到目前为止讲的都是 agent 跨 session 的协作。但还有另一个维度------同一时刻并行的子代理怎么开。

Claude Code 官方文档 把子代理定义为"isolated context window with custom system prompt and tool access"------子代理在自己的 context 里干活,只把摘要返回给父 agent。但开"子代理"的方式不止一种,社区总结出三种典型形态。

5.1 三种形态对比

形态 隔离层级 Token 成本 写权限 适用场景
Fork 同进程克隆 context 最低 共享父代理工作区 "试一下这个分支思路对不对"
Teammate 独立 pane / process,文件信箱通信 中等 独立工作区,通过文件交换 "三个并行专家:一个写测试、一个写文档、一个跑 lint"
Worktree git worktree 物理隔离目录 最高 完全独立分支 "安全做大改,万一翻车不影响主分支"

5.2 Fork:最便宜的"分身"

Fork 是同一 agent 进程里复制一份当前 context,让它在那份 context 上独立跑一段,然后只返回结论给父 agent。Claude Code 官方文档讲得很清楚:

All the intermediate noise --- the file reads, the search results, the exploratory tool calls --- stays inside the subagent's context and never touches the main conversation.

适用场景:父代理想"快速探一下某个文件的依赖关系"------开一个 fork 用 Haiku 跑遍全工程,最后只返回"它依赖 A、B、C"这一行。父代理 context 干净如初。

成本最低,但没有真正的隔离 ------fork 共享父代理的文件系统视角,副作用立刻被父代理看见。所以 fork 只适合只读探索,不适合"我要安全实验一下改动"。

5.3 Teammate:信箱式协作

Teammate 模式开多个独立 agent pane ------每个 pane 有自己的 context,但共享同一个文件系统。它们之间不通过 context 通信,只通过文件信箱

复制代码
project/
├── inbox-tester/
│   ├── task.md         # 父代理写
│   └── report.md       # tester teammate 写
├── inbox-doc-writer/
│   ├── task.md
│   └── report.md
└── inbox-linter/
    ├── task.md
    └── report.md

父代理把任务写进各自 inbox 的 task.md,每个 teammate 跑完后写 report.md,父代理 watch 这些文件汇总。这跟人类团队用 Slack channel 协作的语义高度一致------异步、文件驱动、状态可审计。

5.4 Worktree:最重也最安全

git worktree add ../experiment branch-name 会在主仓库旁边开一份完全独立的工作目录 ,绑定一个独立分支。子代理在那份 worktree 里干活,对主分支零副作用

复制代码
~/proj/                    ← 父代理在这里
~/proj-experiment-1/       ← worktree 1 子代理(独立分支)
~/proj-experiment-2/       ← worktree 2 子代理(独立分支)

适用场景:父代理想让三个子代理用三种不同方案实现同一 feature,然后挑最好的合并。三份 worktree 互不干扰,最后 git merge / cherry-pick 取胜者。

成本最高(要 init 三套环境、跑三套测试),但隔离最彻底------任何一个翻车都不污染主线。这对应"高风险大改"的场景。

5.5 选型决策树

复制代码
要不要写文件?
├─ 不要 → Fork(最便宜)
└─ 要 →
   要不要并行多个独立工作流?
   ├─ 不要,只是隔离单个工作流 → Worktree
   └─ 要,多个并行 → Teammate(共享 fs)或多 Worktree(独立 fs)

实战上 Fork 用得最多(80% 场景),Teammate 次之(多 specialist 协作),Worktree 用得最少但关键时刻不可替代(要做"危险实验"时)。

6. 验证回路三种

第 1 节我们说过------self-evaluation bias 必须用独立 evaluator 切断。但 evaluator 怎么验证?社区收敛到三种回路,改进幅度通常 2--3×(Osmani 的数字)。

回路 信号性质 成本 捕获什么错 局限
Rules-based 确定性 极低 类型错、lint、单元测试 只能验证"代码层"对错,看不到语义
Visual 半确定性 UI bug、布局错、动画问题 模型必须能"看图",需要多模态
LLM-as-judge 概率性 "last mile" 语义问题------风格、可读性、产品感 慢、贵、且自身有 bias

6.1 Rules-based:最干净的信号

tsc --noEmiteslintpytest 这种工具的输出没有歧义------pass / fail 是布尔。

这是第一道 应该建的回路。便宜、快、信号干净。但局限也很明显:它只能验证语法和已写的测试,无法回答"这个按钮真的能点吗""这个文案对用户合理吗"。

6.2 Visual:捕捉语义错误

Puppeteer / Playwright 截图 + 多模态模型看图。能捕获 "按钮被遮挡" "文字溢出" "暗色模式下对比度不够" 这种 rules-based 检查不到的问题。

Anthropic 三代理那篇里有一段经典报告:

Rectangle fill tool allows click-drag to fill a rectangular area with selected tile---FAIL.

evaluator 真的去拖了一下矩形,发现没填充------这种问题任何 lint 都查不出。代价是要跑浏览器、模型要会看图、且每次截图都要走多模态 inference。

6.3 LLM-as-judge:catch "last mile"

最后一道------用另一个 LLM 直接读代码或看产品,给出风格/可读性/原创性的评分。这是三代理 harness 里 evaluator 的核心动作。

它能 catch 的是 rules 和 visual 都看不到的:"这段代码可读吗?""这个 UI 看起来像不像 template 堆出来的?""产品逻辑流畅吗?" 但缺点是慢(要跑一次完整 LLM 推理)、贵、且自己也有 bias------所以不能当唯一信号。

6.4 实战分层

实战的标配是三种叠加

复制代码
每次 sprint 结束:
  step 1: rules-based     (10 秒)  → 不过直接 reject,不浪费贵资源
  step 2: visual          (1 分钟) → 不过反馈 generator 重做
  step 3: LLM-as-judge    (3 分钟) → 给最终四维分

便宜的先跑、贵的后跑------如果便宜的就把它毙了,根本不用调 evaluator。这种分级 verification cascade 通常比单一回路提升 2--3 倍捕获率。

7. Ralph Loop:把"轮班"工程化

讲完同一时刻的多代理,回到时间轴上。为什么不在一次会话里 one-shot 8 小时? ------第 1 节已经回答了:context anxiety。那么解法就是别一次会话

7.1 起源:从 Geoffrey Huntley 到 2026 主流模式

Ralph Wiggum 模式 由 Geoffrey Huntley 在 2025 年中提出(名字来自《辛普森一家》里那个一直说"我帮你"的小朋友 Ralph Wiggum)。核心思想极简:

The main problem is often not that the model cannot code. It is that the session becomes heavier over time, starts losing context, forgets requirements, and repeats work.

也就是说------问题从来不是模型能力 ,而是单一会话上下文越长越重。Ralph 的对策反直觉但有效:承认没有任何一次会话能记住全部,把记忆挪到文件里

7.2 Ralph Loop 的工作流

复制代码
while not all_features_pass:
    spawn fresh Claude session                    ── 全新 context
    session 内:
        cat progress.txt                          ── 读上次状态
        git log                                   ── 看上次提交
        cat features.json | filter passes:false   ── 找下一块
        pick highest priority
        implement
        run typecheck / tests / browser check
        if pass:
            update features.json
            git commit
            append progress.txt
        exit                                       ── 主动退出
    sleep 5s

注意几个关键设计:

  • Spawn fresh session :每轮都是全新进程,新的 context window,零历史包袱
  • 退出是主动的:每轮做完 1 个 feature 就退,不贪心
  • 状态全在文件:features.json + progress.txt + git,不在 context
  • 像 cron:外部 loop 调度器(bash / python script)负责 spawn,不是 agent 自己负责

7.3 Ralph 不是 hack,是"轮班工程化"

很多人第一次看到 Ralph 觉得它"很 hacky"------为什么要每次重启而不一次跑完?答案是这种"看起来 hacky"的设计恰好是把人类协作模式工程化

  • 人类工程师一天工作 8 小时然后下班------主动退出
  • 第二天来看 git log 和工单板,从持久化状态恢复
  • 永远不会让一个工程师连续工作 80 小时不睡觉------避免 burnout,正对应模型的 context anxiety

Ralph 把这套人类轮班的范式1:1 移植给 agent:每次会话就是一个 8 小时班次(但物理上是几分钟),状态全在共享 wiki / git 里。所谓 "model fatigue" 就是 context anxiety,而 Ralph 是它的工程对解。

7.4 与双代理的关系

Ralph Loop 跟 Anthropic 双代理 harness 不是替代关系,是同源的工程化产物

  • 双代理 harness 是结构定义:initializer 一次性 + coding agent 多次
  • Ralph Loop 是调度方式:怎么安排 coding agent 多次跑

事实上 Anthropic 的 coding agent + Ralph 调度器 = 完整生产 harness。两者一拍即合的根因是它们解决同一个问题------用文件系统替代 context 作为长任务的状态载体

8. 架构如何跟着模型变

最后一节,回到一个常被忽视的事实:harness 不是越复杂越好,模型变强应该主动 prune harness

8.1 Opus 4.6 让 sprint decomposition 消失

Anthropic 三代理那篇里有一段特别能说明问题。原本的 generator 需要 sprint contract 把任务切碎,是因为 Opus 4.5 在长任务里坚持不住。但 Opus 4.6 上线后:

Opus 4.6 plans more carefully, sustains agentic tasks for longer, can operate more reliably in larger codebases.
Given the improvements in Opus 4.6, there was good reason to believe that the model could natively handle the job without this sort of decomposition.

结果是 generator "ran coherently for over two hours without the sprint decomposition that Opus 4.5 had needed"------整个 sprint 切分模块从 harness 里删掉了

8.2 "每个组件都编码了一个对模型能力的假设"

这导出整篇文章最值得抄下来的一句:

Every component in a harness encodes an assumption about what the model can't do on its own, and those assumptions are worth stress testing.

每一行 harness 代码背后,都隐藏着一句"模型做不到 X,所以我替它做"。模型变强意味着------有些 X 它现在能做了 。这时这一行 harness 代码就不再是助力,而是束缚------它在用旧假设限制新能力。

具体到长任务架构:

模型变强带来的能力 对应可裁的 harness 组件
长 context retrieval 提升 sprint decomposition、子任务切分
agentic stamina 提升 Ralph Loop 的轮换频率可降低
自我反思能力提升 LLM-as-judge 评分 prompt 可简化
工具使用稳定性提升 工具白名单、protective 包装可放松

8.3 "find the simplest solution possible"

文章作者总结的工程哲学一句话:

Find the simplest solution possible, and only increase complexity when needed.

这跟第 6 篇会展开的"实战 12 条"一脉相承------harness 的复杂度必须是已观察到的失败模式倒逼出来的,不是预期出来的 。当模型升级后,要主动审计 harness 里每个组件:这个组件解决的失败模式,新模型还会犯吗?不会犯就裁。

这构成 harness engineer 的一项反直觉职责主动让自己的代码变少。模型每升一版,harness 工程师该问的不是"我能加什么新功能",而是"哪段 hack 现在没必要了"。

关键 takeaway

  1. 长任务的两堵墙是 context anxiety 和 self-evaluation bias------前者要切片解决,后者要切人解决。
  2. 双代理 = initializer + coding agent ,硬合约 = init.sh + progress.txt + 不可篡改的 features.json + 强制 E2E 验证。四个 failure mode 一一对应到四个组件,没有冗余。
  3. 三代理 = planner + generator + evaluator,灵感来自 GAN,sprint contract 是双方协商不是单方下达;evaluator 的 rubric 措辞会反向塑造 generator 风格。
  4. 生产 harness 的 ground truth 永远在文件系统里------git 当永久 checkpoint、progress.txt 当口信、features.json 当合约。任何只有 LLM 能解读的状态都不可信。
  5. Ralph Loop 不是 hack,是把人类轮班范式工程化------每轮 fresh session,状态全在文件,像 cron 一样调度。它和双代理结构是同源解,不是替代关系。
  6. harness 必须随模型升级主动 prune------每个组件都编码了一个对"模型做不到 X"的假设,X 一旦能做到,组件就该删。

下一篇我们把镜头从架构拉回到工位,讲 12 条具体可上手的 harness 实战经验------CLAUDE.md 怎么写、hooks 用在哪里、permissions 调到什么粒度、什么时候该加 evaluator、什么时候该裁。

参考资料

相关推荐
2601_949925186 小时前
AI Agent如何重构跨境物流的决策?
大数据·人工智能·重构·ai agent·geo优化·物流科技
J_Xiong011715 小时前
【Harness篇】01:什么是 Harness Engineering
ai agent
AI自动化工坊16 小时前
Claude Mythos技术解析:AI自主发现零日漏洞的安全实践
人工智能·安全·ai agent
FrontAI2 天前
深入浅出 LangGraph —— 第9章:流式输出:实时响应用户
人工智能·langchain·ai agent·langgraph
INFINI Labs2 天前
用 Easysearch 给 AI Agent 装上长期记忆:Mem0 集成实战
向量检索·knn·easysearch·ai agent·mem0·mcp
FrontAI2 天前
深入浅出 LangGraph —— 第8章:人机交互:中断与审批流程
人工智能·langchain·人机交互·ai agent·langgraph
小白跃升坊2 天前
OpenClaw集成企业微信:功能应用解析大全
企业微信·ai agent·智能体·ai办公·openclaw
七夜zippoe2 天前
OpenClaw Canvas 可视化界面详解
可视化·canvas·flexbox·ai agent·openclaw
云智慧AIOps社区2 天前
云智慧亮相第二十八届智能体驱动的GOPS全球运维大会2026 · 深圳站!以运维智能体 Castrel AI (SRE Agent)保障系统稳定可靠!
运维·人工智能·ai agent·运维自动化·sre 智能体