欢迎光临
我们一直在努力

AI 编码完整工作流:Matt Pocock 的工程化方法论实录

文章目录

  • 一、引言
  • 二、所有设计都绕不开的底层约束:Smart Zone 与 Dumb Zone
  • 三、对齐阶段:用 Grill Me 把模糊需求逼出真相
    • 1. 不要进 Plan Mode,要进 Interview Mode
    • 2. 一次像样的 Grilling 长什么样
    • 3. Grilling 是「人在回路」的硬约束
  • 四、从对齐到目的地:PRD 该怎么用,又不该怎么用
  • 五、垂直切片 vs 水平分层:Tracer Bullet 不是新概念,却是 AI 时代的救命稻草
    • 1. 切片要满足的硬性条件
    • 2. HITL 切片 vs AFK 切片
    • 3. 看板用本地 Markdown,而不是某个 SaaS
  • 六、夜班:Ralph 循环把 agent 变成自走的工程师
    • 1. 实施提示词里写了什么
    • 2. 实施沙箱:每个 agent 都关进 Docker
    • 3. 实施用 Sonnet,评审用 Opus,而且必须在新会话里
    • 4. Push 与 Pull:把规则放在它该在的地方
  • 七、TDD 不是仪式感,是 AI 时代的质量杠杆
  • 八、Deep Modules:agent 喜欢的代码长什么样
  • 九、Sand Castle:把夜班从单线升级成多线
  • 十、夜班结束之后:代码评审、QA、文档保鲜
    • 1. AI 越能写,人类越要会审
    • 2. QA 反哺看板,形成闭环
    • 3. 文档腐烂(Doc Rot)是隐藏炸弹
  • 十一、完整流水线总览与可复用模板
  • 十二、未解决的张力:这套方法没说出来的限制
  • 十三、给工程师的几句具体建议
  • 十四、写在最后:工程基本功才是这一波的真护城河

在这里插入图片描述

把含糊的需求变成 agent 可执行的计划,把 agent 关进 Docker,把 TDD 当作质量杠杆——这是一份关于「如何让自主编码 agent 真正交付生产代码」的工程化指南。


一、引言

2026 年 4 月底,Matt Pocock 在 AI Engineer 大会上完成了一场 96 分钟的工作坊。两周时间,视频播放量越过六十五万次,GitHub 上的配套 skills 仓库突破九万颗星。这种热度的背后,并不是又一次「vibe coding」式的炫技,而是一位长期做 TypeScript 教育、做过 Vercel DevRel、又重新投入 AI 工程的工程师,把过去几十年软件工程的硬功夫,重新映射到 LLM 时代后给出的完整流水线。

这场分享真正值钱的地方有两点。

  • 第一,它讨论的不是「该用哪个模型」「该买哪家 IDE 插件」,而是把 idea → PRD → issues → 看板 → Ralph 循环 → 人工 QA 这一整条链路全部摆到桌面上,每一段都给出可复现的提示词、技能脚本和组织约束。
  • 第二,它对 LLM 的底层假设非常清醒:上下文越长,推理越蠢;每个会话都是失忆症患者;agent 天生喜欢写浅模块、横向分层、过度详尽——所有这些缺陷决定了工作流的形态,而不是反过来。

这篇文章会沿着 Matt Pocock 在工作坊中的主线一路推进:先解释「smart zone / dumb zone」这条最底层的约束,再依次展开对齐、规划、实施、评审四个阶段,最后落到代码架构、并行化、文档保鲜与团队协作这些容易被忽视的工程问题。读完之后,你应该可以拿着自己的 .claude 目录,直接动手改造一条属于自己的 AFK 流水线。


二、所有设计都绕不开的底层约束:Smart Zone 与 Dumb Zone

HumanLayer 的创始人 Dex Horthy 提出过一个特别朴素的概念:smart zone 和 dumb zone。Pocock 在工作坊中用一个足球联赛的比喻把它解释得很到位——每往 LLM 的上下文里塞一个 token,它和其他 token 之间产生的注意力关系不是线性增长,而是接近二次方的扩张。就像一支球队加入联赛,它要与所有现存球队两两比赛,赛程随队伍数量平方放大。token 越多,注意力网络越拥挤,推理质量越差。

这条规律决定了一个非常反直觉的结论:厂商宣传的「百万 token 上下文」并不等于「百万 token 可用上下文」。真正能维持高质量推理的窗口,大约在十万 token 上下;再往上,就是 Pocock 所说的「shipping more dumb zone」——卖给你更多的笨区。

区域行为特征实际可用上限
Smart Zone 推理清晰、约束遵循好、输出稳定 ~100K token,与厂商标称的最大窗口无关
Dumb Zone 出现「弱智决策」、丢失先前结论、风格漂移 超过 100K 后逐步劣化,即便理论窗口达到 1M+

这里需要做一个澄清:超长上下文窗口并不是没用,只是它的最佳场景是检索类任务——把五本《战争与和平》塞进去,问其中某个角色叫什么名字,模型完全胜任。但写代码不是检索,它要求模型在一段连续推理中维持复杂状态、做出权衡决策、对照规则与约束。这种工作,只有 smart zone 撑得住。

围绕这条约束,Pocock 还提出了另一个值得记下来的隐喻——Memento(记忆碎片)模型。每一次 /clear 都会把 agent 重置到系统提示词的初始状态,先前会话彻底清零。社区里流行的「compact」(把会话压缩成短摘要继续使用)在他看来是反模式:行为不再确定,问题难复现,远不如从干净状态重启来得清爽。他宁可丢掉部分中间结论,也要保住「行为可重复」这个工程属性。

所有后面要讲的工作流——为什么任务必须切薄、为什么 reviewer 必须在新会话里启动、为什么 Ralph 循环每一轮都要重新加载——都是这条 smart/dumb zone 约束在不同位置的具体应用。


三、对齐阶段:用 Grill Me 把模糊需求逼出真相

大多数 AI 编码失败都不是技术失败,而是沟通失败。需求看起来很清楚,但你和 agent 对「清楚」的理解是错位的。这一点在传统软件团队里就已经成立——Pragmatic Programmer 早就写下那句名言:「没人真正知道自己想要什么」。换成 LLM 之后,问题只会更尖锐,因为 agent 不会像人类同事那样在咖啡机旁追问你三遍。

1. 不要进 Plan Mode,要进 Interview Mode

Claude Code 自带的 plan mode 看似贴心:你给一句话,它生成一份漂亮的实施计划。但 Pocock 直白地评价过这种做法——它生成的是一种「热切但偏离」的方案,因为它根本没有质问过你。真正需要的不是计划,是「同频」。

所以他干脆写了一个极短的技能,放在仓库的 .claude/skills/grill-me/ 下,核心提示词只有两段话:

Interview me relentlessly about every aspect of this plan
until we reach a shared understanding.

Walk down each branch of the design tree,
resolving dependencies one by one.
For each question, provide your recommended answer.
Ask the questions one at a time.

短到不像一个产品,却几乎重塑了对齐流程。它逼 agent 做三件事:一次只问一个问题、遍历设计树的每一条分支、对每个问题先给出自己的推荐答案。最后那一点尤其关键——它把 agent 从「被动问询」变成「主动方案者」,你只需要在「同意/修正/反驳」三档之间做选择,而不是从零开始构造答案,沟通速度因此提升一个量级。


2. 一次像样的 Grilling 长什么样

以工作坊中演示的「为在线课程平台加一个游戏化系统」为例,grilling session 会从这种问题开始:

  • 哪些行为获得积分?每种行为各多少?
  • 历史数据要不要回填积分?如果回填,以哪天为切点?
  • 连续学习(streak)算积分吗?中断后是衰减还是清零?
  • 游戏化的 UI 放在仪表盘、课程页,还是单独一个 profile 面板?
  • 是否需要排行榜?排行榜的可见范围是按课程、按团队,还是全局?

一次完整 grilling 通常会问到 40-80 道题,大概消耗 25K token 上下文——还稳稳落在 smart zone 内。Pocock 给的一个非常实用的小技巧是用语音听写代替键盘输入,因为这一阶段你需要的是流畅地讲清楚自己的判断,而不是反复推敲字句。

更深层的依据来自 Frederick Brooks 的 The Design of Design:一支团队真正共享的,从来不是某份文档,而是**「设计概念」(design concept)** 这件存在于多个大脑里的同一幅图。grilling 的产物不是会话日志、不是 markdown 文件,而是「你和这个 agent 现在处在同一张设计图上」这件不可见、却决定后续一切产出质量的东西。


3. Grilling 是「人在回路」的硬约束

这一阶段是整条流水线里唯一无法 AFK 的环节。它依赖产品判断、领域经验、对用户的直觉——这些都还不属于 LLM 的可靠能力圈。Pocock 在工作坊里反复强调:不要妄想把对齐也外包给 agent,否则你只是把一份糟糕的需求加速成了一份糟糕的代码。


四、从对齐到目的地:PRD 该怎么用,又不该怎么用

grilling 结束,接下来是 /to-prd 或 /write-a-prd——把刚才那场对话整合成一份产品需求文档。和很多团队对 PRD 的理解不同,Pocock 把它定位成一份**「目的地文档」(destination document)**:它不是用来反复阅读的合同,而是把 design concept 序列化下来,喂给下游的工具链。

一份典型 PRD 至少包括下面几块:

  • 问题陈述(Problem statement):为什么要做这个东西。
  • 解决方案概述(Solution description):整体形状。
  • 用户故事(User stories):游戏化案例里大约写出 18 条。
  • 实施决策(Implementation decisions):等级阈值、积分经济、回填策略等具体数字。
  • 测试决策(Testing decisions):哪些行为必须有自动化覆盖。
  • 不做的事(Out of scope):这一节往往比「要做的事」更值钱。

值得注意的是,Pocock 公开承认自己几乎不通读 PRD:「LLM 擅长总结,我已经通过 grilling 和它同频了,我没必要再花半小时核对它的复述。」这种态度听起来鲁莽,但背后的逻辑严密——他真正要验证的不是「PRD 文字是否准确」,而是「下一阶段的输出是否符合设计概念」。PRD 只是一个中转站,质量验收点在后面。

这里他特意把自己的流派和**「Specs-to-Code」(规格驱动编码)做了切割。所谓 specs-to-code,就是先写一份极其详尽的规格,把它丢给 agent,人类不再触碰代码——这条路线在社区里相当流行,但他亲身实验后给出的判断很直接:「it sucks」。原因不是规格不重要,而是代码本身才是战场**。脱离了对代码结构的持续感知,你最终拿到的只是一个无法演化、无法调试、无法重构的黑盒。

五、垂直切片 vs 水平分层:Tracer Bullet 不是新概念,却是 AI 时代的救命稻草

拿到 PRD,下一步是把它拆成可执行的 issue。这里又出现了一个非常典型的 agent 失败模式:它天生喜欢横向分层。如果不加约束,agent 会按这种顺序铺工作量——

  • 第一阶段:把所有数据库 schema 改完;
  • 第二阶段:把所有 API 接口写完;
  • 第三阶段:把所有前端界面拼完。
  • 这套做法对人类团队也常常出问题,在 agent 主导的世界里更是灾难:直到第三阶段你才有任何可演示、可验证的东西,前面所有产出都没有 end-to-end 反馈,任何一处认知偏差都要等到最后才被发现。

    Pocock 重新祭出 Pragmatic Programmer 里的老术语——Tracer Bullet(曳光弹):与其打一发只在一层留下痕迹的子弹,不如打一发能穿透 schema、service、API、UI、test 所有层的曳光弹,看着它划出完整的弹道。每一颗曳光弹对应一个可独立 demo、可独立验证的功能切片。

    #mermaid-svg-j536HUGTt4nWkphm{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j536HUGTt4nWkphm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j536HUGTt4nWkphm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j536HUGTt4nWkphm .error-icon{fill:#552222;}#mermaid-svg-j536HUGTt4nWkphm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j536HUGTt4nWkphm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j536HUGTt4nWkphm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j536HUGTt4nWkphm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j536HUGTt4nWkphm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j536HUGTt4nWkphm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j536HUGTt4nWkphm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j536HUGTt4nWkphm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j536HUGTt4nWkphm .marker.cross{stroke:#333333;}#mermaid-svg-j536HUGTt4nWkphm svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j536HUGTt4nWkphm p{margin:0;}#mermaid-svg-j536HUGTt4nWkphm .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-j536HUGTt4nWkphm .cluster-label text{fill:#333;}#mermaid-svg-j536HUGTt4nWkphm .cluster-label span{color:#333;}#mermaid-svg-j536HUGTt4nWkphm .cluster-label span p{background-color:transparent;}#mermaid-svg-j536HUGTt4nWkphm .label text,#mermaid-svg-j536HUGTt4nWkphm span{fill:#333;color:#333;}#mermaid-svg-j536HUGTt4nWkphm .node rect,#mermaid-svg-j536HUGTt4nWkphm .node circle,#mermaid-svg-j536HUGTt4nWkphm .node ellipse,#mermaid-svg-j536HUGTt4nWkphm .node polygon,#mermaid-svg-j536HUGTt4nWkphm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j536HUGTt4nWkphm .rough-node .label text,#mermaid-svg-j536HUGTt4nWkphm .node .label text,#mermaid-svg-j536HUGTt4nWkphm .image-shape .label,#mermaid-svg-j536HUGTt4nWkphm .icon-shape .label{text-anchor:middle;}#mermaid-svg-j536HUGTt4nWkphm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j536HUGTt4nWkphm .rough-node .label,#mermaid-svg-j536HUGTt4nWkphm .node .label,#mermaid-svg-j536HUGTt4nWkphm .image-shape .label,#mermaid-svg-j536HUGTt4nWkphm .icon-shape .label{text-align:center;}#mermaid-svg-j536HUGTt4nWkphm .node.clickable{cursor:pointer;}#mermaid-svg-j536HUGTt4nWkphm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j536HUGTt4nWkphm .arrowheadPath{fill:#333333;}#mermaid-svg-j536HUGTt4nWkphm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j536HUGTt4nWkphm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j536HUGTt4nWkphm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j536HUGTt4nWkphm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j536HUGTt4nWkphm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j536HUGTt4nWkphm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j536HUGTt4nWkphm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j536HUGTt4nWkphm .cluster text{fill:#333;}#mermaid-svg-j536HUGTt4nWkphm .cluster span{color:#333;}#mermaid-svg-j536HUGTt4nWkphm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j536HUGTt4nWkphm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j536HUGTt4nWkphm rect.text{fill:none;stroke-width:0;}#mermaid-svg-j536HUGTt4nWkphm .icon-shape,#mermaid-svg-j536HUGTt4nWkphm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j536HUGTt4nWkphm .icon-shape p,#mermaid-svg-j536HUGTt4nWkphm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j536HUGTt4nWkphm .icon-shape .label rect,#mermaid-svg-j536HUGTt4nWkphm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j536HUGTt4nWkphm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j536HUGTt4nWkphm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j536HUGTt4nWkphm :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    纵向切片(推荐)

    Issue 1:完成一节课时奖励积分,并在仪表盘可见

    Issue 2:连续学习 streak 跟踪

    Issue 3:排行榜上线

    横向分层(反模式)

    阶段 1:全部 Schema

    阶段 2:全部 API

    阶段 3:全部前端

    落到具体例子上,游戏化系统的第一颗曳光弹不是「建好 gamification 服务的 schema」,而是「完成一节课时给用户加积分,并在仪表盘上把积分显示出来」。这一颗子弹同时触及数据库、业务逻辑、API、前端、测试,但每一层都只切了最薄的一片。第一颗弹道一旦走完,后面所有切片都站在一个端到端可演示的基线之上。

    1. 切片要满足的硬性条件

    Pocock 在 to-issues 技能里把规则写得非常具体:

    • 每个切片必须穿越所有集成层,而不是停留在某一层。
    • 切片完成后必须可演示、可验证——不能是「这一段函数写完了但没人能看到效果」。
    • 优先切得多而薄,而不是少而厚。哪怕拆出 12 个切片,只要每一个都能独立合并,就比 3 个大切片要好。

    2. HITL 切片 vs AFK 切片

    切片再分两种:

    类型含义典型场景
    HITL(Human in the Loop) 必须人类介入 涉及架构决策、UI 视觉评审、不可逆数据迁移
    AFK(Away From Keyboard) agent 可独立完成并合并 纯粹的功能实现、按既有架构的扩展、CRUD 类工作

    默认优先选 AFK,只在确实必须人类介入的时候才标 HITL。这条原则会直接影响后面的并行度——AFK 切片越多,夜班调度器(Ralph + Sand Castle)能跑满的并发就越高。

    3. 看板用本地 Markdown,而不是某个 SaaS

    切完之后,所有 issue 会被组织成一个看板。Pocock 选择用本地 markdown 文件 + 阻塞关系字段来表达这个看板,而不是 Linear、Jira 或 GitHub Projects。原因有三:

    • agent 读 markdown 比读各种 API 更便宜、更可靠。
    • 阻塞关系直接写在文件里,Ralph 循环能轻松解析。
    • 版本控制天然就是看板的审计日志——谁在什么时候动过哪个切片,git log 一目了然。

    一份典型的本地看板大概长这样:

    Issue 1: Schema + gamification service (AFK, blocked by: none)
    Issue 2: Streak tracking (AFK, blocked by: 1)
    Issue 3: 把积分/streak 接入课时与小测完成事件 (AFK, blocked by: 1, 2)
    Issue 4: 历史数据回填积分 (AFK, blocked by: 1)
    Issue 5: Polish & review (AFK, blocked by: 1, 2, 3, 4)

    这种结构让 issue 4 和 issue 2/3 可以同时被两个 agent 各自挑走——并行化的基础在这一步就已经埋下。

    六、夜班:Ralph 循环把 agent 变成自走的工程师

    看板就位之后,真正的「不在场实施」开始了。Pocock 把这一阶段称作night shift——夜班,使用的核心机制是一个改良过的 Ralph 循环(名字来自《辛普森一家》里那个永远傻笑的 Ralph Wiggum,寓意是「在一个不确定的世界里持续地、笨笨地、不知疲倦地推进」)。

    Ralph 循环最早由 Geoffrey Huntley 提出,它的核心哲学只有一句话——「Sit on the loop, not in it」(坐在循环之上,而不是循环之内)。开发者不再去手动驱动每一步,而是写一份提示词,让 agent 自己反复跑:读看板 → 挑下一条任务 → 实现 → 跑反馈 → 提交 → 回到看板。每一轮都从全新上下文开始,因此每一轮都稳稳在 smart zone 内。

    1. 实施提示词里写了什么

    Ralph 实施循环的提示词,经过工作坊精简后大约长这样:

    1. 从看板里挑一条尚未完成、未被阻塞的 issue。
    2. 优先级:critical bug fixes > developer infrastructure > tracer bullets > polishing/quick wins > refactors。
    3. 用 TDD 实现:先写一个失败的测试,然后让它通过,再 refactor。
    4. 在标记完成前必须跑过所有反馈回路(type check、tests、lint)。
    5. 如果所有 AFK 任务都做完,输出「no more tasks」并退出。

    这里需要单独强调的几点:

    • 优先级顺序经过深思:线上 bug 永远第一,然后是让流水线本身更稳的「开发者基础设施」,再是新功能,接着才是小优化,最后才是 refactor。这条顺序避免了 agent 一开心就把整个仓库重写一遍的风险。
    • 强制 TDD让 agent 在每条切片里都必须先写一个会失败的测试,然后再让它绿掉——这条规则一旦写进提示词,几乎能杜绝「测试是凑出来的」这种最常见的偷懒模式。
    • 强制跑完所有反馈循环:类型检查、单测、lint 都必须绿,否则不能 commit。这是 agent 自检的硬底线。
    • 退出条件清晰:循环不是无限跑,而是看板见底就停。这一点对 Sand Castle 调度器至关重要。

    2. 实施沙箱:每个 agent 都关进 Docker

    夜班最容易翻车的地方是 agent 误改文件系统、误调外部 API、误花一张 token 巨账单。Pocock 的做法是把每个实施 agent 都丢进一个 Docker 容器 + git worktree 的隔离环境里:每条切片对应一个独立分支,容器是即抛即用的,出问题最多损失这一支分支的工作量。

    这套隔离策略和 smart/dumb zone 模型形成了一个意外契合——既然 agent 在某一轮可能犯傻,我就要确保它的犯傻不会越过沙箱的边界。容器化是工程上廉价、有效、可复制的隔离手段。

    3. 实施用 Sonnet,评审用 Opus,而且必须在新会话里

    模型选择上,Pocock 给出了一个非常实用的分工——

    角色模型原因
    Implementer Claude Sonnet 速度快、成本低,适合大量重复编码
    Reviewer Claude Opus 推理深度高,适合在新会话里冷启动评审

    这里有一条容易被忽视、但极其关键的规则:reviewer 永远在新会话里启动,而不是和 implementer 共享上下文。逻辑很简单——如果 reviewer 看着 implementer 在同一份长上下文里产出的代码,它就已经在 dumb zone 里了,它会比被评审的对象更蠢。只有强制清空上下文,让 reviewer 以纯净的 smart zone 状态重新打开仓库,评审才有意义。

    4. Push 与 Pull:把规则放在它该在的地方

    工作坊里有一段对话很有启发:同样一份「编码规范」,该塞给 implementer 还是塞给 reviewer?Pocock 的判断是——

    • Implementer 用 pull:它在需要的时候自己去拉规范,避免上下文里塞满未用到的规则。
    • Reviewer 用 push:把规范主动推到 reviewer 的会话里,确保它一开始就照规则审。

    用他自己的话讲:「I would push the coding standards in the implement, I would allow it to pull.」——只在评审端用 push,实现端用 pull。这条原则同样源自 smart zone 的容量管理:能省的 token 一定要省。

    七、TDD 不是仪式感,是 AI 时代的质量杠杆

    传统团队对 TDD 的接受度一直不高——很多人觉得它仪式感太重、节奏太慢。但在 agent 主导的世界里,TDD 突然变成了一根非常硬的杠杆。它解决了几个让 AI 编码一直翻车的老问题:

    问题TDD 的解法
    agent 写出来的测试什么都没测 每个测试都必须先于实现存在并失败,空测试在 red 阶段就会暴露
    agent 写的测试碰巧通过(实质作弊) 当测试在「待实现代码」之上落地时,作弊难度显著上升
    代码库缺少测试覆盖 TDD 本身就是顺带积累覆盖率的过程
    agent 在前端代码上「看不见」自己的产出 测试提供一种无需人类目视检查的反馈回路

    Pocock 在演示里跑完游戏化系统之后,测试套件累积到 284 个。他对代码评审的态度也因此发生了变化——第一步不是看实现,而是先看测试:先确认这些测试在「测有意义的事情」,再去检查实现是否合理。这种顺序背后的假设很直接:测试是 agent 自己定义的合同,合同本身先要靠谱,合同的执行才有意义。

    值得单独点出来的是前端测试这个老大难。模型「看不见」UI,直接让它写完前端再去测,基本是盲飞。Pocock 给出的折衷方案是原型法(prototype 技能)——

    给我做三个可在同一条 throwaway route 下切换的 UI 原型,
    我点完之后告诉你选哪个,你再把这个版本接到主流程里。

    这把「视觉判断」这件 agent 不擅长的事情交还给人类,但把「构造可选方案」这件 agent 擅长的事情留给 agent。两边都做了自己最有比较优势的工作。

    八、Deep Modules:agent 喜欢的代码长什么样

    这是整场分享里最容易被低估、但回报最高的一段。agent 输出的质量上限,本质上由你的代码结构决定。

    Pocock 直接引用了 John Ousterhout 的《A Philosophy of Software Design》中那个老结论——好模块是「深」的,坏模块是「浅」的。

    维度Shallow Modules(浅模块,反模式)Deep Modules(深模块,推荐)
    模块尺寸 大量极小文件 数量更少、单个更大
    接口 暴露众多导出 接口窄、签名小
    内部复杂度 几乎为零,逻辑被切得太碎 内部承担显著的业务复杂度
    测试边界 难定——到底测哪一层? 易定——围着模块边界包一圈测试就行
    Agent 可导航性 差——必须沿着依赖图反复跳转 好——理解了模块形状就够用

    这里有一个非常微妙的现象:agent 如果不加约束,天然会写出浅模块——它倾向于一文件一函数,每个文件都极薄,因为它在生成时只关心眼前那个具体的指令,不会自发地考虑「这个文件和旁边几个文件其实应该合并」。

    这种倾向有两个后果:

  • 测试边界被切碎,导致每个模块都需要海量 mock,而 mock 本身就是 agent 高频出错的区域。
  • 认知地图变成依赖图,新进入这段代码的 agent 必须遍历依赖才能理解上下文,token 消耗暴增、推理质量下滑。
  • 应对策略也很直接——在提示词、issue 描述、ADR、Skill 文件里反复明示「优先做深模块」,并定期跑 improve-codebase-architecture 这类技能去识别耦合度高的浅模块簇,把它们合并成单个深模块,在模块边界外面包一圈端到端测试。

    Pocock 在自己那套 video editor 项目里就这么做过:把前端到后端的一整条管线压成一个深模块,外层端到端测试覆盖。结果是——agent 改动这块时,既能看清整体形状,又不需要把所有依赖文件都拉进上下文,smart zone 利用率直接上去。

    这套方法还有一个对人类的红利:开发者只需要知道模块的「外形与接口」,而不需要随时记住内部实现——把模块当作灰盒看待。代码库再大,大脑的工作负载也能被压住。

    九、Sand Castle:把夜班从单线升级成多线

    单 agent 的 Ralph 循环已经能跑通完整流水线,但产线再往上走一档,就需要并行。Pocock 为此写了一个叫 Sand Castle 的 TypeScript 库,负责调度多个 AFK agent 同时干活。

    Sand Castle 的内部分工是这样的:

    #mermaid-svg-o6XQDi6iwR9Qch1L{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-o6XQDi6iwR9Qch1L .error-icon{fill:#552222;}#mermaid-svg-o6XQDi6iwR9Qch1L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-o6XQDi6iwR9Qch1L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-o6XQDi6iwR9Qch1L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-o6XQDi6iwR9Qch1L .marker.cross{stroke:#333333;}#mermaid-svg-o6XQDi6iwR9Qch1L svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-o6XQDi6iwR9Qch1L p{margin:0;}#mermaid-svg-o6XQDi6iwR9Qch1L .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L .cluster-label text{fill:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L .cluster-label span{color:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L .cluster-label span p{background-color:transparent;}#mermaid-svg-o6XQDi6iwR9Qch1L .label text,#mermaid-svg-o6XQDi6iwR9Qch1L span{fill:#333;color:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L .node rect,#mermaid-svg-o6XQDi6iwR9Qch1L .node circle,#mermaid-svg-o6XQDi6iwR9Qch1L .node ellipse,#mermaid-svg-o6XQDi6iwR9Qch1L .node polygon,#mermaid-svg-o6XQDi6iwR9Qch1L .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-o6XQDi6iwR9Qch1L .rough-node .label text,#mermaid-svg-o6XQDi6iwR9Qch1L .node .label text,#mermaid-svg-o6XQDi6iwR9Qch1L .image-shape .label,#mermaid-svg-o6XQDi6iwR9Qch1L .icon-shape .label{text-anchor:middle;}#mermaid-svg-o6XQDi6iwR9Qch1L .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-o6XQDi6iwR9Qch1L .rough-node .label,#mermaid-svg-o6XQDi6iwR9Qch1L .node .label,#mermaid-svg-o6XQDi6iwR9Qch1L .image-shape .label,#mermaid-svg-o6XQDi6iwR9Qch1L .icon-shape .label{text-align:center;}#mermaid-svg-o6XQDi6iwR9Qch1L .node.clickable{cursor:pointer;}#mermaid-svg-o6XQDi6iwR9Qch1L .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-o6XQDi6iwR9Qch1L .arrowheadPath{fill:#333333;}#mermaid-svg-o6XQDi6iwR9Qch1L .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-o6XQDi6iwR9Qch1L .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-o6XQDi6iwR9Qch1L .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-o6XQDi6iwR9Qch1L .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-o6XQDi6iwR9Qch1L .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-o6XQDi6iwR9Qch1L .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-o6XQDi6iwR9Qch1L .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-o6XQDi6iwR9Qch1L .cluster text{fill:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L .cluster span{color:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-o6XQDi6iwR9Qch1L .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-o6XQDi6iwR9Qch1L rect.text{fill:none;stroke-width:0;}#mermaid-svg-o6XQDi6iwR9Qch1L .icon-shape,#mermaid-svg-o6XQDi6iwR9Qch1L .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-o6XQDi6iwR9Qch1L .icon-shape p,#mermaid-svg-o6XQDi6iwR9Qch1L .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-o6XQDi6iwR9Qch1L .icon-shape .label rect,#mermaid-svg-o6XQDi6iwR9Qch1L .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-o6XQDi6iwR9Qch1L .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-o6XQDi6iwR9Qch1L .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-o6XQDi6iwR9Qch1L :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Planner Agent读全量看板,挑可并行切片

    Implementer #1Sonnet + Docker

    Implementer #2Sonnet + Docker

    Implementer #3Sonnet + Docker

    ReviewerOpus + 新会话

    ReviewerOpus + 新会话

    ReviewerOpus + 新会话

    Merger Agent合分支、解冲突

    每个角色的职责清晰可分:

    • Planner:读完整个看板,根据阻塞关系算出当前可并行启动哪些切片。
    • Implementer:每个都跑在自己的 Docker 容器和 git worktree 上,独立分支,互不打扰。
    • Reviewer:每个 reviewer 在全新会话里启动,审查对应 implementer 的产出。
    • Merger:负责把通过评审的分支合回主干,顺手处理类型冲突、测试冲突、lint 冲突——这些「合并阶段才会暴露」的小麻烦,过去靠人类工程师在 PR 上修,现在交给 merger agent 去搞。

    这套结构带来三个工程红利:

  • 吞吐量随 AFK 切片数量线性上升,而不是受限于单 agent 的串行速度。
  • 每个 agent 都活在 smart zone,因为 Planner、Implementer、Reviewer、Merger 各自上下文都被切割得很短。
  • 故障半径可控:某个 implementer 翻车,顶多损失它那条分支,主干不动。
  • Pocock 把它公开成开源库 Sandcastle,核心理念依旧是:让 agent 干 agent 擅长的事(写代码、跑测试、解机械冲突),让人类干人类擅长的事(对齐、设计、视觉判断、最终决策)。

    十、夜班结束之后:代码评审、QA、文档保鲜

    这套流水线最后,还有几个被很多介绍文章忽略,但 Pocock 在工作坊里非常坦白地展开的问题。

    1. AI 越能写,人类越要会审

    工作坊现场,他抛出过两个让全场举手的问题:

    觉得自己用了 AI 之后比以前更累的,请举手。 觉得自己对自家代码库的熟悉程度比以前下降的,请举手。

    两次几乎全场举手。这是一个让人警醒的信号:agent 把「编码」这件事的边际成本压低之后,代码评审反而成为新的瓶颈。「小而独立的 PR」这条行业惯例,撞上「一个 Ralph 循环连续合并 4 个 issue」的现实,产生了非常具体的痛点——评审者打开 PR,看到的不是一次干净的提交,而是 agent 一晚上的全部产出。

    Pocock 没有给出干净的解决方案,他自己的话是:「we just need to be ready to do more code review」。但他在工作流里加了一个缓冲:自动 reviewer(在新会话里运行)先把一遍,把明显的烂代码、违规、未覆盖路径标出来,然后人类才介入。自动评审不能替代人审,但能把人审的负担压到「值得人审的部分」。

    2. QA 反哺看板,形成闭环

    QA 阶段发现的 bug 不会直接修——它们会被回写到看板里,变成新的 issue,等待下一轮 Ralph 循环挑走。整条系统因此变成一个永不收敛的回路:plan → implement → QA → re-plan。这种结构表面上反直觉(为什么 bug 不立刻修?),但和「smart zone + 干净会话」的整体哲学完全一致——临时跳出循环去补丁,会污染当前会话;把它变成一条标准 issue,下一轮干净上下文里再处理,更稳。

    3. 文档腐烂(Doc Rot)是隐藏炸弹

    PRD 和实施计划在项目里要不要保留?这是工作坊里一个引发了较多讨论的细节。Pocock 的立场偏激进:实施完成后,planning 文档应当被丢弃。理由是文件名、代码结构、需求口径都会随时间漂移,如果未来某个 agent 翻到一份过时 PRD 并把它当成权威,它会基于错误事实生成新代码。

    他的折衷方案是把 PRD 落地为GitHub issue 并标记为 closed:agent 依然能访问历史信息,但 closed 状态像一个明显的视觉标记,提醒它「这是已完成、可能过时的设计」。这套做法不一定适合所有团队,但它指出了一个非常实在的风险——长期保留的过时文档,会反过来污染 agent 行为,值得每个团队都认真对待。

    十一、完整流水线总览与可复用模板

    把前面所有阶段串起来,整套工作流大约长这样:

    #mermaid-svg-OfIsc1o1zD6F9J3B{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OfIsc1o1zD6F9J3B .error-icon{fill:#552222;}#mermaid-svg-OfIsc1o1zD6F9J3B .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OfIsc1o1zD6F9J3B .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OfIsc1o1zD6F9J3B .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OfIsc1o1zD6F9J3B .marker.cross{stroke:#333333;}#mermaid-svg-OfIsc1o1zD6F9J3B svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OfIsc1o1zD6F9J3B p{margin:0;}#mermaid-svg-OfIsc1o1zD6F9J3B .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B .cluster-label text{fill:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B .cluster-label span{color:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B .cluster-label span p{background-color:transparent;}#mermaid-svg-OfIsc1o1zD6F9J3B .label text,#mermaid-svg-OfIsc1o1zD6F9J3B span{fill:#333;color:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B .node rect,#mermaid-svg-OfIsc1o1zD6F9J3B .node circle,#mermaid-svg-OfIsc1o1zD6F9J3B .node ellipse,#mermaid-svg-OfIsc1o1zD6F9J3B .node polygon,#mermaid-svg-OfIsc1o1zD6F9J3B .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OfIsc1o1zD6F9J3B .rough-node .label text,#mermaid-svg-OfIsc1o1zD6F9J3B .node .label text,#mermaid-svg-OfIsc1o1zD6F9J3B .image-shape .label,#mermaid-svg-OfIsc1o1zD6F9J3B .icon-shape .label{text-anchor:middle;}#mermaid-svg-OfIsc1o1zD6F9J3B .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OfIsc1o1zD6F9J3B .rough-node .label,#mermaid-svg-OfIsc1o1zD6F9J3B .node .label,#mermaid-svg-OfIsc1o1zD6F9J3B .image-shape .label,#mermaid-svg-OfIsc1o1zD6F9J3B .icon-shape .label{text-align:center;}#mermaid-svg-OfIsc1o1zD6F9J3B .node.clickable{cursor:pointer;}#mermaid-svg-OfIsc1o1zD6F9J3B .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OfIsc1o1zD6F9J3B .arrowheadPath{fill:#333333;}#mermaid-svg-OfIsc1o1zD6F9J3B .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OfIsc1o1zD6F9J3B .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OfIsc1o1zD6F9J3B .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OfIsc1o1zD6F9J3B .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OfIsc1o1zD6F9J3B .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OfIsc1o1zD6F9J3B .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OfIsc1o1zD6F9J3B .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OfIsc1o1zD6F9J3B .cluster text{fill:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B .cluster span{color:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OfIsc1o1zD6F9J3B .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OfIsc1o1zD6F9J3B rect.text{fill:none;stroke-width:0;}#mermaid-svg-OfIsc1o1zD6F9J3B .icon-shape,#mermaid-svg-OfIsc1o1zD6F9J3B .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OfIsc1o1zD6F9J3B .icon-shape p,#mermaid-svg-OfIsc1o1zD6F9J3B .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OfIsc1o1zD6F9J3B .icon-shape .label rect,#mermaid-svg-OfIsc1o1zD6F9J3B .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OfIsc1o1zD6F9J3B .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OfIsc1o1zD6F9J3B .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OfIsc1o1zD6F9J3B :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    新 issue

    原始想法

    Grill Me 会话(必须人在回路)

    PRD(目的地文档)

    切分 Tracer Bullet本地 Markdown 看板

    Ralph + Sand CastleAFK 实施 + 自动评审

    人类 QA & 代码评审

    如果你想直接套用,可以按下面这份「最小可行配置」起步:

  • 在仓库根目录建立 .claude/skills/ 目录,先装三个核心技能:grill-me、to-prd、to-issues。
  • 在 docs/adr/ 下沉淀架构决策,在 CONTEXT.md 中建立共享术语表。
  • 用本地 markdown 文件(例如 backlog.md)管理看板,每个 issue 至少包含「类型(HITL/AFK)、阻塞项、验收条件」三个字段。
  • 写一个最小的 Ralph 实施提示词,跑在 Docker 容器里,绑定 git worktree。
  • 用 Sonnet 跑 implementer、用 Opus 跑 reviewer,reviewer 强制走新会话。
  • 等流水线稳定后,再引入 Sand Castle 那样的并行调度,实现夜班并发。
  • 这个顺序的好处是风险可控:你先在单线流水线上跑通自己的项目,等沙箱、看板、评审都顺手了,再去开多 agent 并发。一上来就堆并发,大概率会在调度与冲突管理上栽跟头。

    十二、未解决的张力:这套方法没说出来的限制

    这场分享最难得的一点,是 Pocock 没有把它讲成「我已经把一切都搞定」的胜利演讲,而是诚实地把目前还没解决的几个张力摆出来。

    • 代码评审体量与小 PR 文化的冲突:夜班一晚跑出来的合并集,常常和「小步快走、易评审」的工程文化撞车。这是组织流程问题,不是模型能力问题,目前没有干净答案。
    • 前端测试的盲点:模型看不见 UI 这件事,在视觉密集型场景里依然致命。原型法是缓解,不是治本。
    • Specs-to-Code 路线之争:是否完全脱离代码、只在规格层面工作,业内分歧很大。Pocock 押注「代码是战场」,但他承认对面阵营有自己的逻辑。
    • 团队场景的适配:目前的工作流是面向单人或小组的。多个产品负责人、多个领域专家、并存的 agile 流程,如何接入这一套,他没有给出系统答案。
    • 文档保鲜与可追溯之间的取舍:扔掉 PRD 避免 doc rot,但也丢失了一部分历史追溯。哪种更值,要看团队的合规与审计需求。
    • 角色变化的不确定性:被问到「产品经理这个岗位在 AI-augmented 开发里会怎么演化」时,他直接拒绝预测——「I’m not a pundit」。这种克制,在一个普遍喜欢预言未来的圈子里,反而更可信。

    十三、给工程师的几句具体建议

    如果只想从这场工作坊里带走最具操作性的几条,大致是这些:

    • 把上下文当成稀缺资源管理。永远在 smart zone 内工作,该清空就清空,不要迷信百万级窗口。
    • 任何一次新功能,先 grilling 再 plan。提示词只要那两句,但你需要预算 30-60 分钟,认真把设计树走完。
    • PRD 不必精读,但必须存在。它的价值是给下游工具链,而不是给你自己。
    • 切片永远纵向,优先 AFK。横向分层是 agent 默认的偷懒模式,要在提示词层面主动反向。
    • TDD 是 agent 时代的最优策略,而不是历史包袱。它把「agent 自检」从口号变成机械的红绿循环。
    • 代码架构主动做深。在评审、PRD、ADR、Skill 里反复提示「优先深模块」,定期跑架构改善。
    • Reviewer 永远在新会话。这是一条不容妥协的规则,违反之后整条流水线的质量保证都会塌。
    • 沙箱化你的 agent。Docker + git worktree 是最便宜的隔离方式,出问题止损在分支级别。
    • 承认评审会变多。不要假装 agent 会让你工作更少;它让你的工作重心向上挪了一档。
    • planning 文档要么扔,要么打 closed 标记。不要让明天的 agent 被昨天的过时文档带歪。

    十四、写在最后:工程基本功才是这一波的真护城河

    回到最开始那句话——这场分享真正的价值,不是它告诉你「该用哪个新工具」,而是它把过去三十年软件工程沉淀下来的硬功夫重新组合了一遍:Pragmatic Programmer 的曳光弹、Refactoring 的小步前进、Domain-Driven Design 的共享语言、A Philosophy of Software Design 的深模块、Brooks 的 design concept、TDD 的红绿循环。这些东西在 LLM 出现之前就已经是好实践,在 LLM 出现之后,它们成为让 agent 真正能跑起来的前提条件。

    那些断言「软件工程过时了」的声音,某种意义上恰恰最危险:它们鼓励你用 agent 在浅模块、横向分层、无测试覆盖的环境里裸奔——结果往往是一个跑不动的 demo 加一份焦灼的 oncall 排班表。Pocock 给出的另一条路线相反:把基本功练扎实,把流水线做规范,然后让 agent 在这条干净的轨道上把生产力释放出来。

    这条路线不性感、不戏剧化,但它经得起两点检验:第一,它真的把项目交付到了生产环境;第二,它没有把今天的速度建立在明天的技术债之上。对于真正要长期做工程的人来说,这才是值得押注的方向。


    参考来源:Matt Pocock 在 AI Engineer 大会的分享《Full Walkthrough: Workflow for AI Coding》,以及其开源仓库 mattpocock/skills 中的相关技能定义与文档。

    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » AI 编码完整工作流:Matt Pocock 的工程化方法论实录
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址