青蛙小白

Long-running Agent Harness

Long-running Agent Harness 是本知识库对一类长时任务执行外壳的归纳:当 AI Agent(智能体) 的工作跨越多个 上下文窗口 时,harness 不能只依赖自动压缩或聊天历史续接,而要把任务规格、进度、验证证据和下一步入口写到外部环境里,让每个新会话都能像接班工程师一样快速恢复状态。

Anthropic 2025 年 11 月的工程文章把这个问题放在 Claude Agent SDK 场景中讨论:即使有 compaction,单纯让强模型循环执行一个高层目标,仍会出现两类失败:一是试图一次性做太多,耗尽上下文后留下半成品;二是在项目已经有部分进展时提前宣布整体完成。解决方向不是把上下文窗口塞得更满,而是设计一个能跨会话交接的 Harness Engineering(驾驭工程)

OpenAI 的 Codex 长程实验提供了同一模式的另一侧证据:GPT-5.3-Codex 连续约 25 小时构建设计工具,期间发生 13 次自动上下文压缩、2,106 次工具调用和约 26k 行 patch。真正支撑这次长跑的不是单个巨大 prompt,而是写入仓库的规格、计划、执行规则、状态日志和验证命令。这说明长时 harness 的共同核心是外部化控制状态:让下一轮循环从文件、git 和测试结果恢复,而不是从模型记忆里猜。

两阶段模式

Anthropic 的方案把第一次会话和后续会话分开:

阶段角色产物目的
Initializer agent第一次运行的专用 promptfeature_list.jsoninit.shclaude-progress.txt、初始 git commit把模糊需求展开成可验证功能清单,并建立可复跑环境
Coding agent后续每个新上下文窗口单个功能的实现、测试证据、git commit、进度更新小步推进,同时留下下一轮可读的交接材料

这个划分的关键是:初始化不是开始写代码,而是给未来所有 Agent 建工作场地feature_list.json 是任务范围的结构化来源,init.sh 是环境恢复入口,claude-progress.txt 和 git history 是 Agent Memory(Agent 记忆),初始 commit 则把“环境从何处开始”变成可审计事实。

Codex 的 durable project memory

Codex 长程实验没有使用 Anthropic 示例中的 feature_list.json / claude-progress.txt 命名,但文件栈承担了相同职责:

文件Harness 职责
Prompt.md冻结目标、非目标、约束、交付物和 “done when”
Plan.md将开放任务拆成 milestone,每个 milestone 带验收标准和验证命令
Implement.md规定执行协议:按计划推进、保持 diff scoped、失败先修复、持续更新文档
Documentation.md保存当前状态、决策记录、运行方法、demo flow 和 known issues

这组文件构成了文章所说的 durable project memory。它和自动 compaction 互补:compaction 帮助当前上下文继续容纳历史摘要,project memory 则把关键控制状态放进仓库,使 Agent 能反复回读稳定定义的目标和完成标准。

flowchart LR
    SPEC["Prompt.md\n目标与边界"] --> PLAN["Plan.md\nmilestone + 验收"]
    PLAN --> RUNBOOK["Implement.md\n执行协议"]
    RUNBOOK --> LOOP["Codex loop\n实现/验证/修复"]
    LOOP --> DOC["Documentation.md\n状态与决策"]
    DOC -.-> PLAN
    LOOP --> VERIFY["lint/typecheck/test/build/export"]
    VERIFY -->|"失败"| LOOP
    VERIFY -->|"通过"| DOC

Codex 实验的截图还暴露了一个重要细节:验证不是一次总验收,而是 milestone 后的持续质量门。示例命令包括 npm run lintnpm run typechecknpm run testnpm run build、导出 CLI、snapshot-focused tests、replay-focused tests 和 persistence-focused tests。长时 harness 的可靠性来自这些外部失败信号;没有它们,Agent 只能靠自我叙述判断是否完成。

交接流程

一个典型后续会话的启动顺序是:

flowchart LR
    PWD["确认工作目录"]
    STATE["读取 progress file"]
    GIT["查看 git log"]
    FEATURES["读取 feature_list.json"]
    INIT["运行 init.sh"]
    SMOKE["浏览器端到端 smoke test"]
    PICK["选择一个未通过功能"]
    WORK["实现、验证、提交、更新进度"]

    PWD --> STATE --> GIT --> FEATURES --> INIT --> SMOKE --> PICK --> WORK

这条流程把 Context Engineering(上下文工程)里的 Write / Select / Compress 原则落到编码任务上:长期状态写入文件和 git;新会话只选择当前需要的高信号材料;上一轮详细工具轨迹不再依赖 compaction 传递。

Feature list 作为外部规格

feature_list.json 的设计不是普通 TODO,而是可执行验收清单。Initializer agent 会把最初的高层 prompt 展开为大量端到端功能描述,每项包含类别、用户步骤和 passes: false。后续 Coding agent 只能在验证后把 passes 改为 true,不应删除或重写测试描述。

用 JSON 而不是 Markdown 有两个工程含义:

  • 结构更难被随意改坏:模型更容易把 Markdown checklist 当作可编辑叙事,JSON 则更像数据文件。
  • 状态与验收绑定passes 字段把“是否完成”从自然语言总结变成可检查状态,降低 Agent 自称完成的空间。

这与 Evals(评估)的原则一致:评估条件要客观、难作弊、可回归。只让 Agent 写“我做完了”没有价值;让它在端到端测试后改变明确字段,才是可追踪的进度。

干净状态与小步提交

长时 Agent 最大的隐患不是某一轮失败,而是失败被下一轮继承却没有说明。Anthropic 因此要求每个 Coding agent 只做一个功能,并在结束时把仓库留在接近可合并的干净状态:没有明显 bug,代码整洁,有清楚的 progress update 和描述性 git commit。

git 在这里不只是版本控制,而是 harness 的恢复机制:

  • 下一轮 Agent 可以通过 log 理解最近改动;
  • 当前轮改坏时可以回滚到已知好状态;
  • 人类可以审查每个增量,而不是面对一次巨大 diff;
  • commit message 与 progress file 形成双轨记忆,一个记录代码事实,一个记录任务意图。

这也是 Loop Engineering(循环工程)里“外部状态文件 + 质量门 + 路由”的具体实现。没有小步提交,长时循环会把多轮错误堆成一个难以诊断的状态。

端到端测试是启动条件

文章强调,Coding agent 不应一启动就写新功能,而要先恢复环境并跑基本端到端 smoke test。例如 web app 场景下,用 Puppeteer MCP 像真实用户一样打开新聊天、发送消息、等待响应。这样做能先发现上一轮留下的未记录破坏,避免在坏状态上继续叠加功能。

页面中的截图主要说明这个验证形态:Claude 通过 Puppeteer MCP 捕获浏览器截图来检查 claude.ai clone 的界面行为。它不是新的算法,而是一个 harness 设计原则:给 Agent 接近真实用户路径的验证工具。单元测试、curl 或代码阅读不足以证明 UI 功能真的可用;浏览器自动化把失败信号移动到用户体验层。

仍有边界:Puppeteer MCP 这类视觉/浏览器工具可能看不到浏览器原生 alert modal,依赖这些原生弹窗的功能仍容易漏测。因此长时 harness 需要把已知测试盲区写入进度文件或功能清单,而不是假设端到端测试覆盖一切。

失败模式对照

失败模式Initializer agent 的职责Coding agent 的职责
过早宣布全项目完成建立完整 feature list,让未完成范围显式存在每轮读取清单,只选择一个未通过功能
留下 bug 或未记录进度初始化 git repo 和 progress file启动时读进度与 git log,结束时 commit 并更新进度
未测试就标记通过所有功能初始为 passes: false只有认真自测后才能改为 true
不知道如何运行应用写出 init.sh启动时先读并运行 init.sh

这个表格的价值在于把“模型行为问题”转译成“环境中缺什么控制状态”。当 Agent 试图 one-shot、忘记测试、或提前收工时,修复点往往不是再写一句更凶的 prompt,而是补一个外部规格、质量门或交接产物。

OpenAI 和 Anthropic 两个案例的差异也有价值:Anthropic 更强调跨多个新会话 的小步接力,Codex 文章更强调单个长会话 在 compaction、工具调用和持续验证下保持连贯。但两者收敛到同一工程判断:长时 Agent 的状态必须落到可审查的外部介质里,且每个阶段都要有机器可验证的通过条件。

与持久执行的边界

Long-running Agent Harness 解决的是跨上下文窗口的认知续接Durable Execution(持久执行)解决的是进程崩溃或部署后的步骤级恢复。两者相邻但不等价。

feature_list.json、progress file 和 git commit 能让下一次 Agent 会话理解“现在做到哪了”;持久执行引擎则保证“步骤 3 成功、步骤 4 失败后,重启时不会重跑步骤 1–3”。生产系统通常需要两者:外部状态让 Agent 接得上任务,步骤级 checkpoint 让运行时接得上流程。

相关概念

参考来源
  1. 1. https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
  2. 2. https://github.com/anthropics/claude-quickstarts/tree/main/autonomous-coding
  3. 3. https://developers.openai.com/blog/run-long-horizon-tasks-with-codex
评论