claude-quickstarts 仓库 autonomous-coding 目录。读它之前建议先理解「agent = 模型 + 挽具(harness)」这个基本框架;读完你应该能徒手复述整套机制并在自己的 agent 里复刻。随着模型能力提升,开发者开始让 agent 承担需要数小时甚至数天的复杂任务(文中的实验载体是「从零构建一个 claude.ai 的克隆」这样的全栈 Web 应用)。核心矛盾在于:上下文窗口(context window)是有限的,长任务必然被切分为多个离散会话(session),而每个新会话开始时,agent 对之前的工作毫无记忆。
文章用了一个精准的类比:这就像一个软件项目由「轮班工程师」接力完成,而每位新工程师上岗时,完全不知道上一班发生了什么。
值得注意的是,Claude Agent SDK 本身已经具备压缩(compaction)等上下文管理能力,理论上可以让 agent「无限期」工作。但作者明确指出:仅靠压缩不够。即使是 Opus 4.5 这样的前沿模型,如果只给一句高层提示(「构建一个 claude.ai 的克隆」),然后让它跨多个上下文窗口循环运行,也产不出生产级的 Web 应用。压缩产生的摘要不总能给下一个会话传递清晰的行动指令——它是「被动记忆」,而长任务需要的是「主动交接」。
作者把问题拆解为两个子问题:(1)如何建立一个为全部需求功能打好地基的初始环境,让 agent 可以逐个功能地推进;(2)如何让每个会话都做增量进展(incremental progress),并在结束时把环境留在「干净状态」——即「可以合并进主分支的代码」:没有重大 bug、代码有序、文档完善,下一位「工程师」可以直接开新功能,不用先收拾烂摊子。
解决方案由两种 agent 组成(这是全文最核心的机制,务必记住细节):
init.sh 脚本(能一键启动开发服务器);② 一个 claude-progress.txt 进度文件(记录 agent 工作日志);③ 一次初始 git 提交(把新增文件纳入版本管理)。此外它还要生成功能清单(见下节)。一个容易误解的点,原文用脚注专门澄清:所谓「两个 agent」,区别仅在于初始用户提示不同;系统提示、工具集和整体挽具完全相同。也就是说这不是多智能体架构,而是同一个挽具在「第一班」和「后续班次」用不同的开工指令。
整套设计的关键洞察是:让 agent 在新上下文窗口启动时,能快速理解工作状态——通过 claude-progress.txt 加 git 历史实现。灵感直接来自优秀人类软件工程师的日常实践(commit 记录、交接文档、README)。
本节对应 Claude 4 提示指南中「多上下文窗口工作流」的最佳实践:为第一个上下文窗口使用不同提示的框架结构,由 initializer 一次性把环境铺好。
initializer agent 被要求把用户的初始提示扩写成一份全面的功能需求文件。在 claude.ai 克隆的例子中,这意味着超过 200 个功能条目——比如「用户可以打开新聊天、输入查询、按回车并看到 AI 回复」。所有功能初始一律标记为 failing(未通过),让后续 coding agent 对「完整的成品长什么样」有清晰的靶子。
原文给出了功能条目的 JSON 结构示例,要点如下:
functional)、描述(如「新聊天按钮创建新会话」);passes 布尔字段,初始为 false。两条配套的硬约束:
passes 字段,并且提示词里用措辞极强硬的指令钉死:「It is unacceptable to remove or edit tests...」(删除或编辑测试是不可接受的,因为那可能导致功能缺失或有 bug)。这是为了防止 agent「改考卷来通过考试」。coding agent 被明确要求每次会话只做一个功能——这是治「一次做太多」的关键处方。保持环境干净的最佳做法是:要求模型把进展用描述性 commit message 提交进 git,并在进度文件里写摘要。git 在这里不只是备份:它让模型可以回滚坏的改动、恢复到可工作状态。这些做法同时提升了效率——agent 不用再猜「之前发生了什么」,也不用花时间摸索怎么把应用跑起来。
另一大失败模式:Claude 倾向于在没有充分测试的情况下把功能标记为完成。没有明确提示时,Claude 会改代码,甚至会跑单元测试、对开发服务器发 curl 请求——但这仍不足以发现「功能端到端不可用」的问题。
对策:对 Web 应用,明确提示 agent 使用浏览器自动化工具(文中用 Puppeteer MCP 服务器),像人类用户一样完整走一遍。一旦这样提示,Claude 基本能做好端到端验证。原文配了一张图:Claude 在测试 claude.ai 克隆时通过 Puppeteer MCP 截取的浏览器截图——图表结论是:agent 确实在「亲眼看」自己做的界面,并借此发现了只看代码根本看不出来的 bug。
但也有诚实的局限声明:Claude 的视觉能力和浏览器自动化工具本身有限制,某些 bug 仍难以发现。原文举例:Claude 无法通过 Puppeteer MCP 看到浏览器原生的 alert 弹窗,因此依赖这类弹窗的功能更容易残留 bug。
每个 coding agent 会话开头,都被提示执行一套固定的「上岗步骤」:
pwd 确认工作目录(且只能编辑该目录内的文件);git log --oneline -20)和 claude-progress.txt,了解近期工作;这套流程每个会话都在省 token:agent 不必重新摸索「这项目怎么跑、怎么测」。initializer 写好的 init.sh 负责启动开发服务器;coding agent 在实现新功能之前,先跑一遍基本的端到端测试(smoke test)。在 claude.ai 克隆案例中,agent 总是先启动本地开发服务器,再用 Puppeteer MCP 开一个新聊天、发一条消息、收到回复——确保能立刻识别应用是否处于损坏状态。如果应用已经坏了,先修,再做新功能;否则直接叠加新功能只会让问题恶化。
原文附了一段典型会话开场的消息记录,流程是:助手说要先了解项目当前状态 → 依次调用 pwd、读 claude-progress.txt 和 feature_list.json → 查看 git log --oneline -20 → 检查 init.sh 并重启服务器 → 导航到应用验证基本功能 → 确认核心聊天、主题切换、会话加载和错误处理都正常 → 这才开始审阅测试文件、决定实现哪个新功能。
原文用一张表总结了四种失败模式在两类 agent 上的对策,这张表可以视为整篇文章的「速查卡」:
| 问题 | initializer agent 的行为 | coding agent 的行为 |
|---|---|---|
| 过早宣布整个项目胜利 | 基于输入规格建立结构化 JSON 功能清单 | 会话开始时读功能清单,选一个功能开工 |
| 留下有 bug 或未记录进展的环境 | 建立初始 git 仓库和进度笔记文件 | 开始时读进度文件和 git 日志、跑基本测试;结束时提交 git 并更新进度 |
| 过早把单个功能标记为完成 | 建立功能清单文件(含验证步骤) | 自我验证所有步骤,仅在仔细测试后才标记为 passing |
| 花时间摸索如何运行应用 | 编写能启动开发服务器的 init.sh | 会话开始时读取并运行 init.sh |
注意这张表的结构:每一行都是「一次真实观察到的失败 → initializer 铺设的基础设施 → coding agent 的行为契约」。这正是后来 Osmani 总结的「棘轮机制」——每个失败都固化为一条挽具规则——在 Anthropic 内部的原型形态。
文末致谢部分提到,这项工作体现了 Anthropic 多个团队(尤其是 code RL 和 Claude Code 团队)的集体努力——这也侧面印证了 Osmani 文中提到的「模型—挽具联合训练循环」:挽具里验证有效的原语,会回流进下一代模型的训练。
读完后你应能不看原文复述以下链条:
claude-progress.txt(人话日志)+ git 历史(可回滚的事实记录)+ init.sh(环境一键复原)。这三者共同构成「给下一班工程师的入职简报」,是对纯压缩(compaction)的替代/补充——Osmani 称之为「完全上下文重置(full context reset)」技术。