Skip to content

自我改进的编码智能体

作者:Addy Osmani

原文:查看原文

想象一下:你结束一天工作,第二天醒来,新功能已经完成编码、通过测试,并进入待审查状态。这就是自主编码智能体最吸引人的地方——借助 Claude Code 这类工具,把编码、验证与交付组织进一个持续循环里,即使你离线,它也能继续推进工作。

这篇文章会拆解这类“自我改进循环”怎么搭:从任务编排、上下文文件、内存持久化,到 QA 验证、扩展方式、调试方法和风险控制。

这篇文章也是对 Ryan Carson 那篇《如何让你的智能体在你睡觉时学习和交付》的补充。我们最近聊了很多关于智能体编码未来的想法,这篇文章主要是把其中一些技术层面的要点展开讲清楚。

“持续编码循环”(Ralph Wiggum 技术)

这套方法的核心,是一个不断迭代的智能体循环,也常被称为 “Ralph Wiggum” 技术(由 Geoffrey Huntley、Ryan Carson 等人推广)。关键思路很简单:把开发工作拆成一批小任务,再让编码智能体逐个处理。

每轮迭代通常遵循同一套周期:

  1. 选择下一个任务:从待办列表里挑出尚未完成的任务(例如一个任务 JSON 文件)。
  2. 实现任务:围绕这个具体功能或修复改代码。
  3. 验证更改:运行测试、类型检查或其他质量检查。
  4. 提交代码:验证通过后,把更改提交到仓库。
  5. 更新任务状态:标记完成,并记录这轮学到的内容。
  6. 重置智能体上下文:用新上下文进入下一轮,直到所有任务完成,或触发停止条件。

这种做法的关键价值,是每轮都重新开始,但不会重新失忆。上下文不靠一段越来越长的对话来硬撑,而是靠外部文件和结构化状态来传递。这样能有效避免长上下文不断膨胀之后的混乱,也能让每次执行都更聚焦。

与其用一个巨大提示去要求模型“一次做完整个功能”,不如不断给它一个边界清晰、目标明确的小任务。这样通常更稳,也更容易验证。

把任务切得足够小,而且标准明确

工作拆分是这类系统成败的第一步。每个任务都应该足够小,小到能在一次 AI 会话里完成;同时也要有明确的通过/失败标准。

例如,与其写“做完整个仪表板”,不如拆成类似这样的任务:

“新增一个导航栏,包含首页、关于、联系三个链接;当前页面对应链接高亮显示。”

这种粒度有两个好处:

  • 智能体更容易知道“做完”到底长什么样
  • 一旦结果不符合预期,系统也更容易回滚、修正、重试

落地建议:先写清楚规格,再转成任务列表。 先把功能需求写成清晰的规格说明,再把它拆成结构化任务列表,例如 prd.json。像 Carson 提供的 /prd 和 /tasks 技能 就是在做这件事。

最终,你需要的是一份机器可读、验收标准明确、可逐步执行的待办清单。

编排循环

驱动循环本身,其实不一定复杂。Carson 的实现本质上就是一个不断调用智能体的脚本,可能是 Bash,也可能是 Python。

下面是一个很简化的伪代码示意:

bash
while :; do
   amp run -s prompt.md -o progress.txt  # 使用提示运行 Amp,并保存输出
   if grep -q "<promise>COMPLETE</promise>" progress.txt; then break; fi
done

真实流程里,脚本通常会完成这些事:

  • 读取任务列表
  • 选出下一个待办任务
  • 拼装提示词与相关上下文
  • 调用模型执行
  • 跑验证脚本
  • 更新状态文件与日志

关键点在于:每一轮都是隔离的。你不是让同一个对话无限延长,而是让智能体在每次迭代时带着外部上下文重新开始。

复合循环也是常见进阶做法。比如 Compound Product 会先跑分析循环,再跑规划循环,最后才进入执行循环。也就是说,智能体不仅负责写代码,还能先参与判断“应该先做什么”。不是每个项目都需要这么完整的自动化,但它很好地展示了:多个循环完全可以首尾相接,形成持续交付管线。

上下文与内存的最佳实践:AGENTS.md 手册

这类循环最强的机制之一,是把经验显式写进持久化文件,而不是指望长对话自己记住一切。

最常见的文件就是 AGENTS.md。它本质上是一份持续更新的运行手册:记录项目约定、踩过的坑、需要反复提醒智能体的注意事项,以及最近新增的重要上下文。

每完成一个任务,你都可以把关键信息追加进去。例如:

  • “这个仓库统一用某个库处理表单,不要另起一套方案。”
  • “更新用户模型时,记得同步更新审计日志,否则测试会失败。”
  • “某个旧接口已弃用,统一改走新路径。”

随着时间推移,AGENTS.md 会逐渐变成一个高价值的项目知识库。它不是“给人看的说明书”这么简单,更是下一轮智能体执行时的重要约束来源。

一个实用的组织方式,是把 AGENTS.md 拆成几类内容:

  • 模式和约定:比如目录结构、组件组织方式、常用架构模式
  • 陷阱:容易遗漏、但一旦遗漏就会出错的点
  • 风格与偏好:例如测试风格、代码风格、依赖使用原则
  • 最近变更:最近踩过的坑、做过的修正和原因

这里有个很重要的原则:条目要短、要准、要可执行。 它不是百科,不需要写成长文。你写进去的内容,最好是一条智能体在下一轮就能直接据此行动的规则。

同时也要注意上下文大小。AGENTS.md 不是越长越好;如果越积越多却没人整理,最后也会变成噪声。一个更稳妥的做法是只保留当前最重要、最容易反复踩坑的信息,把过时内容清掉或归档。

内存持久化与复合学习策略

除了 AGENTS.md,成熟的循环通常还会维护多条“外部记忆通道”。Carson 的 Ralph 体系里,至少会用到以下几类:

  • Git 提交历史:每轮迭代都提交代码。下一轮如果需要了解之前改了什么,直接看 git diffgit log 就行。
  • 进度日志(progress.txt:记录每轮做了什么、哪里成功、哪里失败、错误信息是什么。
  • 任务状态文件(如 prd.json:记录每个需求是否完成,避免重复劳动。
  • 长期知识文件(AGENTS.md:沉淀更长期、跨任务复用的约束与经验。

这些外部工件共同构成了一种“复合学习”机制。它不是机器学习意义上的在线训练,而是通过不断把结果写回系统,让后续迭代站在前面工作的基础上继续推进。

例如,一轮迭代里发现某个 API 已废弃,下次再遇到相关任务时,智能体就不必重新踩一次同样的坑;如果测试日志已经记录过某个失败模式,后续也可以直接参照处理。

你当然也可以做得更复杂,比如用向量数据库存错误模式和 diff 摘要,再在新任务开始前检索相似案例。但很多时候,只要 AGENTS.md、任务状态文件和日志维护得足够好,复杂记忆层并不是必需品。

一个值得反复确认的点是:这些记忆只有在下一轮真的被注入上下文时才有价值。 文件写在那里,不等于模型就一定会用到。你需要确保提示模板或运行脚本确实会把它们带进下一轮。

质量保证:测试与验证循环

如果没有自动验证,自主编码智能体很容易把“看起来像完成了”的东西误当成“真的完成了”。所以,测试与检查必须是循环中的一等公民。

  • 单元测试与集成测试:如果仓库里已经有稳定的测试套件,让智能体在实现任务后跑 npm testpytest,这是最基础也最有效的反馈机制。
  • 类型检查与 Lint:像 tsc、MyPy、ESLint 这样的静态分析工具,可以快速拦住很多低成本错误。
  • 模拟 CI 检查:即便不是正式 CI 环境,你也可以在本地把构建、测试、检查串起来,当作循环的一部分。
  • 必要时让智能体自己验收:如果是 UI 改动,可以让它启动浏览器或使用相应技能做页面检查,确认交互和视觉状态是否达标。

Simon Willison 提到过一个很实用的经验:如果仓库本身已经有高质量测试,智能体通常会自然模仿这些测试风格。因此,想让智能体写出更可靠的测试,最稳妥的办法之一不是多讲大道理,而是让代码库里已经存在值得模仿的范式。

扩展:从单循环到多循环

很多人会自然想到:既然一个循环能跑,那多个循环是不是能并行跑得更快?答案是可以,但复杂度会迅速上升。

最简单的扩展方式,是让不同循环跑在不同范围里:

  • 一个循环专做前端
  • 一个循环专做后端
  • 或者多个功能分支各跑一个夜间循环

但一旦多个智能体开始同时修改同一片代码,问题就会变成典型的分布式协调问题:文件冲突、重复劳动、互相等待、任务边界不清,都会出现。

实践里更有效的一种模式,是规划者 - 工作者分层。一个更高层的智能体负责理解全局、拆分任务、决定优先级;下层智能体只负责执行局部任务。这样比让多个智能体自由竞争同一组任务更稳。

不过,对大多数独立开发者来说,现阶段真正高回报的通常不是把规模盲目扩大,而是把单个循环做得足够稳、足够长、足够可恢复。很多时候,一个可靠的夜间循环,比一群难以管理的并行循环更有价值。

监控、调试与反馈仪表化

既然你把一部分开发工作交给了智能体,就必须对它的行为保持可观察性。最常见也最有效的做法包括:

  • 实时日志:让循环持续输出当前任务、测试结果和错误信息,方便你判断它有没有卡住。
  • 检查点提交:每轮都提交代码,这样你可以随时用 git loggit diff 回看最近发生了什么。
  • 任务状态概览:准备一条能快速查看所有任务状态的命令或脚本,随时判断整体进度。
  • 性能指标:记录每轮耗时、token 成本和失败重试次数,帮助你识别瓶颈。
  • 停止条件:比如最大迭代数、最长运行时间、连续多轮无提交时自动停止,避免系统空转。

必要时,你也可以让智能体输出简短的“失败原因与下一步计划”,帮助定位它为什么卡住。但这类内省信息要适度使用,太多反而会污染主循环上下文。

风险管理与保障措施

给编码智能体写权限、执行权限,确实很强大,但也一定要配套边界。

防止破坏性动作

  • 只在功能分支或隔离仓库里运行:不要直接对 main 下手。
  • 权限分级:只读操作尽量自动放行,写操作、外部发布、删除操作则保留人工确认。
  • 沙箱运行:最好在容器或虚拟机里执行,尤其是它需要跑代码、跑测试时。
  • 随时可中断:你必须清楚知道怎么第一时间停掉循环。

处理错误假设与任务偏移

编码智能体的真实风险,往往不是“它很笨”,而是需求约束不够清楚,或者长时间运行后逐渐偏离原目标。对应的缓解方式通常包括:

  • 把规格写清楚:验收标准越明确,偏移空间越小。
  • 用验证抓问题:测试、类型检查和运行反馈,能抓住很多不真实的调用、错误接口和逻辑偏差。
  • 定期重新聚焦:循环跑得太久时,可以暂停、重新规划剩余任务,再继续执行。
  • 必要时多模型交叉检查:关键节点可引入第二个模型做 diff 审查或结果复核。

这里要特别强调一点:很多“智能体没做到 X”的情况,根因并不是它能力低,而是规格、提示或上下文里根本没有把 X 说清楚。循环设计得越严谨,这类偏差就越少。

上下文膨胀与优化

随着项目增长,AGENTS.mdprogress.txt 和任务文件都会越来越大,不可能每次都原样塞进上下文。常见优化方式包括:

  • 总结旧内容:保留关键结论,把原始长日志归档。
  • 按任务裁剪上下文:与当前任务无关的历史内容不要强行带入。
  • 依靠模型已有通用知识:项目特有信息优先,通用文档不必一股脑重复喂给它。

例如,如果这是一个使用 React Hooks 和 Vite 的项目,你通常没必要把整份 React 文档都塞给模型;真正更值钱的是项目自己的边界、约定和坑点。

人工监督与持续改进

最后,把整个系统当作一个持续演进的过程来看。它不是“搭完就自动完美运转”的装置,而是一套需要不断调参、不断校准的工作流。

你的角色也会随之变化:你不再主要花时间逐行敲代码,而是更像在设计流程、写规格、看结果、做关键判断的那个人。

还要持续关注成本。循环一旦卡住,token 消耗会迅速放大,所以预算上限、停止条件和异常告警都很有必要。但如果整体工作流设计得好,回报也会非常明显:很多重复而细碎的执行工作,会被可靠地压进一个可以持续运行的系统里。

自主编码智能体已经不再只是概念。只要流程设计得足够扎实,它们确实可以承担持续编码、持续验证和持续推进交付的那部分工作。

每一轮迭代,系统和你的工作方式都会一起变得更成熟。

这篇文章使用 Gemini 做了可读性整理。

Alpha内测提示:当前为早期内部构建版本,部分章节仍在完善中,也可能存在问题,欢迎在下方评论区留言。