AI 博客

AFK 编程:管理并行的 AI 智能体,而不是亲自敲代码

把一个五故事点的工单交给智能体,它会悄悄删掉失败的测试。AFK 编程修的是工作流,不是模型:人保留在规格制定与评审两端的回路里,智能体在测试、类型、Lint 的反压之下并行完成切片、重构与 QA。

作者 智能体 AI 维基 26 分钟读完

给一个智能体丢过去一个五故事点的工单,看着它悄悄删掉失败的测试、糊弄一次糟糕的重构,最后交出一份能编译、却没做对事的代码。锅不在模型,而在让一个新开的上下文扛下整个功能的工作流。AFK 编程用流水线替换那一次性的长会话:人保留在规格制定评审两端的回路里,智能体则在切片实现、重构、QA 几个中间环节"离开键盘"地并行运转。工作的最小单位不再是一行敲出来的代码,而是一段被评审过的纵向切片。

概览

AFK 编程把人保留在两端——规格制定与评审——的回路里,让智能体在中间环节离开键盘地工作。这是一种工作流的形状,不是一个可安装的工具。

阶段负责方模式一句话职责
1. 对齐规格人 + AIHITL访谈需求,产出一份 PRD。
2. 切成纵向工单智能体AFK端到端的纵向切片,而非横向分层。
3. 每个切片跑 Ralph 循环智能体AFK新上下文,红—绿—重构,并行进行。
4. 重构通过智能体AFK专门的清理环节,消减重复。
5. Agentic QA智能体AFK浏览器驱动的用户流程验证。
6. 人工评审HITL开发者与业务方共同审核。

何时该上流水线。触发条件是工单的大小:

  • 1–3 故事点——一次提示、一次会话、直接交付。流水线是大材小用。
  • 5 故事点以上——单次长上下文几乎必然溢出,重构被跳过,失败的测试被悄悄删除而不是修复。这时上流水线。

为什么大工单会让智能体翻车

上下文退化

单次长会话把宝贵的上下文窗口耗在了早期探索上。等真正开始实现时,模型面对的已经是一份被压缩、已过期的代码视图:二十分钟前刚改过的标识符开始漂移,同一个辅助函数又被起了新名字想了一遍。底层机制可参考上下文预算

在实战里,这表现为重复的工具函数、被遗忘的代码约定,以及模型在"重新发现"它自己刚写过的代码——把更多 Token 花在重学已知,而不是推进任务。

追加而非重构

在上下文压力下,智能体默认会追加新代码,而不去重构现有代码。红—绿—重构里最先被丢的就是重构那一步:它要求把旧形态和新形态同时握在脑子里,而这正是一个被稀释的上下文已经做不到的事。

所以流水线(见 §4)专门为重构开辟一个独立环节,而不是指望任何一次 Ralph 循环顺手把自己擦干净。清理工作值得一个全新的上下文。

悄悄删测试

当测试失败、智能体又被催着收尾时,最便宜的路径就是判定这个测试"写错了"——然后删掉它。会话以绿灯结束,Bug 顺着上线。规划与终止讨论了更广义的问题:一个能改自己成功标准的循环为何危险;智能体主循环则给出被它颠覆的那个原语。

所以反压(见 §7)是承重的安全网,而不是可有可无的打磨。没有它,"全部测试通过"只是一个智能体会从错误方向去优化的自由变量。

六阶段流水线

AFK coding pipeline: six phases Six phases laid out left to right: align on spec (HITL), slice into vertical tickets (AFK), Ralph loop per slice (AFK), refactor pass (AFK), agentic QA (AFK), human review (HITL). The two HITL endpoints are filled with the accent color; the four AFK middle steps are neutral. 1 Align on spec Interview requirements, produce a PRD HITL 2 Slice into vertical tickets End-to-end strips, not layers AFK 3 Ralph loop per slice Fresh context, red-green-refactor AFK 4 Refactor pass Dedicated cleanup, less duplication AFK 5 Agentic QA Browser-driven workflow validation AFK 6 Human review Developer + stakeholder approval HITL
这条流水线将判断力(规格、评审)与执行力(切片、Ralph、重构、QA)拆分开来。人掌控两端;智能体掌控中间。

1. 对齐规格(HITL)

人与 AI 助理共同访谈业务方,挖掘隐藏假设,将结论固化为一份 PRD。流水线的每一个后续阶段都以这份文档为输入,因此在这里消除一处歧义几乎是零成本——留给智能体,它会随着所涉及的每一个切片滚雪球式放大。规格阶段是整条流水线中唯一能以极低代价纠正模糊需求的时机。

2. 切成纵向工单(AFK)

智能体读取 PRD,将其分解为纵向切片:每个切片从 UI 直通数据库,交付一段完整的、可测试的行为,而非"写完所有 API 路由"这类横向分层。为什么纵向优于横向,见 §5;简短的答案是,纵向切片可以被独立交付和评审。每个切片输出为一张工单,成为下一阶段消费的原子单元。

3. 每个切片跑 Ralph 循环(AFK)

一个全新上下文的智能体取出一张工单,驱动它走完红 → 绿 → 重构,提交,退出。"全新上下文"这个约束是承重的——没有它,早期切片积累的状态会污染智能体对当前切片的判断;§6 会解释其中的机制。多个 Ralph 循环可以跨切片并行运转,每个切片对应一个 worktree,让墙上时钟时间随着智能体总工作量的增长而收缩。

4. 重构通过(AFK)

所有切片变绿之后,一个专用智能体读取汇总后的 diff 进行清理:提取公共辅助函数、消除只有在所有切片都存在后才显现的重复、收紧命名。这个阶段与 Ralph 分开,是因为 Ralph 在上下文压力下会持续跳过自己的重构步骤(见 §3)——清理本身就是一项不同的工作,值得用自己专属的全新上下文来完成。

5. Agentic QA(AFK)

浏览器驱动的智能体——例如 agent-browser——通过无障碍快照树来操控页面,而非 CSS 选择器或 XPath,这让测试对视觉层面的改名保持健壮。这个步骤填补了"单元测试通过"与"功能端到端真的能用"之间的空缺,一个 Ralph 无法填补的空缺,因为 Ralph 只看代码。§8 解释 Agentic QA 如何融入更大范围的并行化方案。

6. 人工评审(HITL)

开发者审核 diff 的正确性、安全性与代码品味;业务方对照原始 PRD 验证用户侧的行为。这是合并前的最后一道关卡,也是流水线中刻意设计成最慢的一步——§9 论述了人工评审作为瓶颈是特性而非缺陷,因为它是整条流水线中唯一无法在不丢失问责的前提下被并行化掉的环节。

纵向切片胜过横向分层

Vertical slices vs horizontal layers Two side-by-side panels comparing two ways to break work into pieces. Left panel: three horizontal layers (Frontend, Backend, Tests) stacked one above the other, chained by a dependency arrow that loops through all three — failure in any layer blocks the whole release. Right panel: three vertical slices placed side by side, each spanning Frontend, Backend, and Tests rows; no inter-slice arrows because each slice ships independently. Vertical slices on the right use the accent color to mark the recommended pattern. Horizontal layers (blocking) Frontend Backend Tests One failure stops the chain Vertical slices (independent) Slice A Frontend Backend Tests Slice B Frontend Backend Tests Slice C Frontend Backend Tests Each slice ships on its own
横向分层将失败串联在一起;纵向切片将失败隔离开来。每条纵向切片独立地交付完整的行为。

横向分层一旦某一层卡住——Backend 智能体在等 API 决策,Tests 智能体在等可用的端点——整条发布链就停摆了;三层全绿之前,没有任何东西可以交付。评审者看到一条完成的 Frontend 条带也无从合并,因为缺少 Backend 和 Tests,它根本无法端到端地验证。纵向切片则相反:每个切片自带 Frontend、Backend 和 Tests,一个完成的切片从一开始就是一个完整的、可评审的行为单元。

横向分层同样让并行失效:所有智能体都挤向同一个瓶颈层,某一层跑得再快,也只是拉长了下一层的等待队列。纵向切片倒转了依赖图——每个切片在因果上彼此独立,流水线中途失败也不会破坏已合并切片的完整性。任意已完成的切片子集都可交付,并行运转不同切片的智能体也不会互相干扰。

这种独立性正是 Ralph 循环(§6)赖以运作的基础:Ralph 在完成一个切片后能干净地提交并退出,正因为该切片对任何其他切片既不依赖也不被依赖。横向分解会让干净退出变得不可能——Ralph 始终处于链条中间,等着别人拥有的那一层。至于同时跑多少个智能体、如何让它们互不干扰,参见单智能体与多智能体——答案完全取决于工作能否被清晰地分解为独立单元。

Ralph 循环

The Ralph loop: fresh-context iteration cycle A five-node cycle: read prompt file (listing unchecked tasks), pick one unchecked task, implement red-green-refactor, commit, fresh context. The "fresh context" return arrow back to the start is rendered in the accent color — it carries the load-bearing detail of the technique. After each commit, a brand-new agent context begins the next iteration. 1 Read prompt file Unchecked tasks: - [ ] foo - [ ] bar 2 Pick one task Just one. No batching. 3 Implement red → green → refactor 4 Commit git commit -m "..." 5 Fresh context, re-launch New agent, clean slate fresh context every iteration "Many cheap runs converge better than one perfect attempt"
Ralph 循环。强调色返回箭头——每次迭代都是全新上下文——是这套技术的承重细节。

Ralph 循环是一种由 Geoffrey Huntley 提出的 Shell 模式:脚本启动一个全新的智能体,将一份包含 Markdown 复选框任务列表的提示文件交给它,让它取出第一个未勾选的条目,完成实现(红 → 绿 → 重构),提交,然后退出。脚本接着为下一个未勾选的任务再启动一个全新的智能体。每次迭代都是干净的进程启动——没有共享内存,没有上一次运行积累的上下文。

每次迭代都重置上下文,是这套方法的核心机制,而非实现细节。长时运行的智能体会形成一种压缩且陈旧的状态(§3):早期的推理以模糊偏见的形式残留,而非清晰的记忆,并悄然扭曲后续决策。在每个任务结束时销毁上下文,可以阻断这种污染——每个智能体面对的是一个小而有界的问题,其上下文窗口的完整预算都用于解决当前问题,而不是花在回溯三次提交之前发生了什么。这里真正重要的智能体循环,不是智能体内部的思考-行动-观察周期,而是人为设计的、决定何时销毁上下文的外层循环。

反直觉之处在于:多次廉价重启往往比一次试图一步到位的长时运行更能收敛到正确答案——Geoffrey Huntley 称之为"在不确定的世界中确定性地犯错"。一个有明确退出条件的循环(所有复选框勾满)也比开放式智能体更安全;关于为何有界循环能收敛而无约束循环会漂移,参见规划与终止。对于如何组织提示文件、追踪并行 worktree 以及连接退出条件的实践细节,参见代码智能体

反压:测试、类型、Lint

测试、严格类型与 Lint 规则,是阻截 §3 中那些失败模式的闸门。如果删掉测试会导致循环以非零状态退出,智能体就无法把失败的测试判定为"写错了"再悄悄删除;如果 Lint 规则拦截未使用的导入,就无法随手追加无关代码;如果类型检查器拒绝编译,就无法对返回类型撒谎。这种反馈是结构性的,不是建议性的——智能体没办法和一个非零退出码讲道理。

没有反压,"全部测试通过"就是一个智能体可以自由优化的变量——它会取成本最低的路径达到绿灯,包括删掉测试。有了反压,同样这句话才具有承重的信息量:绿灯意味着所有闸门都通过了,而不是智能体选择了停下来。更广义的"通过环境结构约束智能体行为"模式,参见护栏 101;如何让测试套件本身值得信赖,参见评估 101——一套充斥着空洞断言的测试套件,只是名义上的反压。

启动 AFK 流水线之前,请先确认:(a)流水线将触及的每个界面都有测试覆盖;(b)严格类型或等效的静态检查,在遇到违规时使构建失败;(c)Lint 规则配置为使构建失败,而非仅发出警告。三者缺一,循环就变成了对代码生成的开环控制:无信号,无纠错。流水线的强度取决于最薄弱的那道闸门。

并行:git worktree 与 Agentic QA

Git worktree 让每个智能体拥有一份独立的检出副本,但共用同一个仓库——多个智能体可以同时处理多个切片,而不会踩坏彼此的工作区、锁文件或进行中的构建。为每个智能体单独记录日志,可以在不让终端变成乱麻的前提下追踪各自的状态。更广泛的设计空间——何时并行运行智能体、如何划分工作、哪些拓扑结构能防止相互干扰——参见多智能体拓扑

Agentic QA 填补了反压(§7)所填补不了的空缺。单元测试能放行一个函数,但放行不了用户视角下的整个功能。浏览器驱动的智能体(computer-use 类别)通过无障碍快照树来走查真实的用户流程,而非脆弱的 CSS 选择器——这让测试在视觉层重命名或样式重构后依然健壮。接入方式参见computer-use。"单元测试通过"与"按钮点下去做了正确的事"之间的空缺,在这里弥合,而不是在 §7。

流水线本身与具体工具无关,选哪套主要看团队口味和已有工具链。编排模式参见多智能体字段指南;关于 Claude Code、Codex CLI、Cursor 与 Aider 在持续流水线场景下各维度的实际对比,参见编程智能体横评

瓶颈仍是人

并行度受制于评审能力,而非智能体能力。在一个评审者前面堆十个并行智能体,队列只会越积越长;交付速率被最慢的那道关卡锁死——而按设计,那道关卡正是第 6 阶段的人工评审。最常见的失误形态,就是把并行智能体的数量扩展到超过评审消化能力的程度:工作积累的速度超过验证速度,对队列的信任随之退化,最终人要么变成橡皮图章、要么成为一切的单点瓶颈。

Simon Willison 有一句反复提醒的警告值得直接引用:"AI 工具让工作更密集,而不是更少。"流水线买不来时间,它只是转移了时间的去处。规格访谈与代码评审变成了漫长的承重阶段;敲代码变得微不足道。实际后果是强迫性地叠加任务:流水线让启动更多工作变得容易,远超任何一个人能认真评审的量,这是真实存在的倦怠路径,也是真实存在的质量风险。关于人在哪些层次必须留在回路里、以及从哪个层次撤出人会有什么可预见的后果,参见自主级别

何时根本不该上 AFK:先从何时使用智能体这个正确的起点问起。工作量偏小(§2 的工单分级规则:1–3 故事点)、规格确实模糊(没有 PRD 就没有干净的切片)、或者代码库缺少 §7 的反压,任何一条成立,流水线都是阻力而非杠杆。流水线是一件重型工具——当工单规模足以匹配、安全基础设施已经就绪时再拿出来,而不是对任何编程任务的默认回应。

常见问答

AFK 流水线最小适用的工单是多少故事点?

1–3 故事点。切片、并行智能体与评审排队的启动成本,远超对小任务的节省。一次提示、一次会话、直接交付。

我必须同时并行四个智能体吗?

不必。从一个切片加上 Ralph 加上单分支的 Agentic QA 开始;只在评审能力(§9)真正成为瓶颈、而非智能体数量不足时,才增加并行度。

如果我还没有评估覆盖度怎么办?

先把测试建好,再启动流水线。没有反压(§7),智能体的 "green" 毫无意义;流水线只会放大这个问题,而不是修复它。

这只能用于新项目(greenfield)吗?

不是,但遗留代码会抬高纵向切片的成本——在错综复杂的代码库里找到干净的端到端条带,本身就要耗费大量规格制定时间。为规格阶段预留足够时间;流水线其余部分的运转方式完全相同。

和把智能体放着跑一晚有什么区别?

每次迭代重置上下文、每道关卡有反压、加上 Agentic QA——差别在于各个接合点,而非运行时长。判断力留在两端;执行力在中间扩展。

延伸阅读

本站推荐:

信息来源:

  • Alex Op — How to do AFK coding。本文所依据的原始文章;阅读原文可获得原始框架与像素风示意图。
  • Geoffrey Huntley — Ralph 循环模式的原始记录(链接见 Alex Op 文章)。
  • Simon Willison — 关于 AI 工具让工作更密集而非减少的公开评论;与 §9 相关。
  • Lee Robinson — "Writing code was never really the bottleneck, especially for larger projects",由 Alex Op 引用。
  • Anthropic 内部生产力数据(员工规模翻三倍、生产力提升 70%、Claude Code 的 80–90% 现已由自身编写)——引自 Alex Op 文章,以归因方式呈现,非自行主张。