「AI 帮你写代码总跑偏?你缺的不是更好的模型,是一套软件工程思维」
你有没有发现一件怪事?
AI 编码工具越来越强,上下文窗口从 8K 涨到百万,模型推理能力一年翻几番。但你用它写项目的体验,好像并没有同比例变好。
小功能它写得飞快。但一旦项目复杂起来,它就开始:写着写着跑偏了、生成一大坨你看不懂的代码、或者自信满满交出来的东西根本跑不通。
问题不在模型。问题在你没给它一套工程流程。
这个结论来自一场 96 分钟的技术演讲(AI Engineer Europe 2026),演讲者用一个真实案例演示了完整的 AI 协作开发流程。他的核心论点只有一句话:
Agent 不替代软件工程基本功。它奖励基本功的实践。
下面这套五步流程,就是把传统软件工程里的需求对齐、PRD、任务拆分、TDD、Code Review 迁移到人和 AI Agent 协作中的具体做法。
先搞懂一件事:AI 的"聪明区"只有 100K
在讲五步之前,有个底层约束必须先交代。
不管宣传的上下文窗口多大(100 万、200 万),LLM 在大约 100K token 内表现最好。超过这个阈值,注意力质量开始下滑。你可能没注意到,但 Agent 的产出质量已经在悄悄变差了。
这就像你的工作台。物理上能堆满东西,但真正能同时处理的,只有面前那一小块区域。堆太多,你就找不到东西了。
所以整套工作流的所有设计决策,都在优化一件事:让 Agent 始终在"聪明区"内工作。
怎么做?两个原则:
第一,清除优于压缩。 与其让 AI 把之前的对话"总结"成摘要(有损的),不如把重要信息写到文件里(PRD、Issue),然后彻底清空上下文,让下一个阶段在干净状态下启动。
第二,把状态外化到文件。 人脑里的想法、会话里的共识,必须变成持久化的文档,才能在清空上下文后传递给下一个阶段。
搞懂这个,下面五步的衔接逻辑就顺了。
第一步:对齐追问——在写一行代码前达成共识
使用场景:你有一个新功能要做,脑子里有大概想法,但没细想过所有分支。
做法:启动一个"追问"技能(/grill-me),让 Agent 扮演产品经理,对你穷追猛打地提问。不是问三五个问题就完事——是 30 到 100 个以上,沿着决策树的每个分支一路往下钻,直到每个分支都"关闭"了。
案例:假设你的课程平台要加游戏化功能。产品经理在 Slack 里丢了一句"学生留存率低,想加积分激励"。
如果你直接让 AI 开写,它会按自己的理解实现一套积分系统。大概率跑偏。
用追问技能,Agent 会逼你回答:积分模型是按完成课程给分还是按连续学习给分?排行榜公开还是私有?积分会过期吗?要不要设成就徽章?新用户注册送分吗?……
内部逻辑:Agent 使用一个可复用的"访谈循环"引擎,系统性地遍历决策树。它不是随机问,而是先问大方向,确认后再钻分支,直到所有叶子节点都有了答案。
产出:你和 Agent 之间形成了共享的心智模型。不是一份文档,而是对话上下文中的共识。
"Because the code is your battleground." ——你得先在脑子里打完仗,再让 Agent 去代码里实现。
为什么这一步不能跳过:没有对齐就开写 = Agent 按未验证的假设快速产出错误代码。修复成本远高于花 30 分钟提前对齐。
第二步:生成 PRD——把共识凝固成文件
使用场景:追问完成了,你们达成了共识。现在需要把这个共识"存档",这样即使清空对话也不会丢。
做法:使用 /to-prd 技能,让 Agent 综合刚才的对话内容,自动生成一份 PRD(产品需求文档)。
关键观念:PRD 是灯塔,不是编译器输入。
这份 PRD 故意写得松散:问题陈述、解决方案概述、15-20 条 User Stories、实现决策、测试范围、不在范围的事项。但不会指定函数名,不会定义数据库 schema。
为什么?因为代码实现过程中会发现新的 trade-off。PRD 是方向标,告诉你"目的地在哪",而不是逐字逐句的施工图纸。
"Without that you just end up with slop." ——没有方向标的 Agent 产出就是 slop。
内部逻辑:技能自动从对话历史中提取 problem/solution/stories,结构化后发布到 Issue Tracker(比如 GitHub Issue)。发布后,关键动作:清空上下文。
因为 PRD 已经在文件里了。下一步不再需要对话记忆,从文件重新加载就行。
衔接逻辑:
没有第一步的追问,PRD 就是未验证假设的序列化,必然返工 PRD 是第一步→第三步的"状态检查点":清空上下文后,第三步从 PRD 文件出发
第三步:垂直切片——把 PRD 拆成可抓取的任务
使用场景:PRD 有了,但它是一个整体。你需要把它拆成 Agent 能独立完成的小任务。
做法:使用 /to-issues 技能,把 PRD 转化成一组 Kanban 卡片式的 Issue,每个 Issue 之间标注了依赖关系(哪个必须先做,哪些可以并行)。
核心设计决策:垂直切片,不是水平分层。
这是整套流程里最重要的理念之一,来自《The Pragmatic Programmer》里的"Tracer Bullets"。
错误做法(水平分层):先做完整个 gamification service 的数据库 schema → 再做完整个 API 层 → 再做完整个前端。
问题在于:每一层做完之前,你看不到任何端到端的效果。集成问题被推迟到最后才爆发。Agent 在每一层里也没有反馈信号,它不知道自己做得对不对,因为要等所有层都拼起来才能验证。
正确做法(垂直切片):第一个 Issue 是「完成一节课后获得积分,在 dashboard 上显示」。
这一个 Issue 就穿透了数据库、service、API、前端四层。完成后,你立刻可以测试:课程完成 → 积分到账 → 界面显示。如果有问题,马上就能发现。
内部逻辑:技能读取 PRD 的 User Stories,按"端到端功能"而非"技术层"来划分。每个 Issue 包含清晰的 acceptance criteria 和 blocker 关系,形成一个有向无环图(DAG),支持后续的并行调度。
衔接逻辑:
PRD 回答"做什么",Issues 回答"怎么拆" 精心策划的 Issue 列表是第四步 AFK 执行的前提条件:Agent 需要清晰边界才能自主执行 Issue 拆分完成后,再次清空上下文。第四步在全新的聪明区中启动
第四步:AFK 执行——人去睡觉,Agent 上夜班
使用场景:前三步完成了所有需要人类判断力的工作。现在可以安全地把执行权交给 Agent。
做法:使用 Sandcastle(一个 TypeScript 并行执行引擎),或者更简单的 ralph-once.sh 脚本,让 Agent 按依赖顺序自动抓取 Issue 并实现。
执行循环是标准的 TDD(测试驱动开发):
按依赖图抓取下一个 Issue 先写一个会失败的测试 写代码让测试通过 重构 跑全量测试确认没破坏别的 抓下一个
这就是所谓的"夜班"。你去睡觉,Agent 按照这个循环一直跑。
为什么必须是 TDD:测试是 Agent 的反馈信号。没有测试,Agent 自己觉得写完了就是写完了,没有验证机制。测试套件的质量就是 Agent 产出质量的天花板。
"If you are having bad results with your AI, you need to create better feedback loops." ——Agent 写出 slop,不是它笨,是你没给它反馈信号。
串行 vs 并行:
串行( ralph-once.sh):一个 Agent 按依赖顺序逐个做 Issue,适合小项目并行(Sandcastle):每个 Issue 在独立的 Docker 容器 + 独立 Git 分支中执行,多个 Agent 同时工作,完成后自动合并。适合 Issue 多且互相不阻塞的情况
内部逻辑:Sandcastle 提供五种编排模板:blank(最小)、simple-loop(串行)、sequential-reviewer(实现后跟审查)、parallel-planner(并行规划执行)、parallel-planner-with-review(并行+每个分支审查后再合并)。分工上,实现用快模型(Sonnet),审查用强模型(Opus)。
衔接逻辑:
没有第一步的对齐 → Agent 理解偏差,自主实现只会快速产出垃圾 没有第三步的垂直切片 → 水平任务无法独立测试,Agent 中间没有反馈 没有 TDD → 没有反馈信号,产出不可信
第五步:新上下文审查——人工回归
使用场景:Agent 的夜班结束了,代码写完了。但你不能直接合并,需要验证。
做法:在一个全新的上下文窗口中审查代码。不复用实现阶段的上下文。
为什么要新上下文?因为实现过程中积累了大量噪声(调试记录、中间尝试、失败回滚),如果在同一个上下文中审查,审查者也处于"聪明区"之外,判断力会下降。
审查分两轴:
标准合规:代码风格、架构规范、命名一致性。这些是 push rules,写在 AGENTS.md 里,所有 Agent 自动遵守 规格合规:是否正确实现了 Issue 的 acceptance criteria?测试覆盖了边界情况吗?
人工 QA 负责"品味":自动测试覆盖不到的交互体验、视觉一致性、产品直觉。
发现的问题变成新的 Issue,回到第三步,形成增量循环。不需要推倒重来。
内部逻辑:审查 Agent 在新上下文中加载 diff + Issue spec + push rules,独立评判。人工 QA 补充机器判断不了的东西。两者结合覆盖了"正确性"和"品味"两个维度。
步骤间的衔接:为什么是这个顺序?
回头看一下五步之间的传递关系:
第一步产出:人脑中的共享理解(对话上下文) 第二步消费第一步产出,产出 PRD 文件 → 清空上下文 第三步消费 PRD 文件,产出 Issue 列表 → 清空上下文 第四步消费 Issue 列表,产出实现代码 → 清空上下文 第五步消费代码 diff + Issue spec,产出审查结论或新 Issue → 回到第三步
每一步之间都有一次"状态外化 + 上下文清空"。这不是麻烦,是刻意为之。保证每个阶段的 Agent 都在聪明区内运行,不被上一个阶段的噪声污染。
工具清单
/grill-me | ||
/grill-with-docs | ||
/to-prd | ||
/to-issues | ||
/tdd | ||
/triage | ||
/code-review | ||
/improve-codebase-architecture |
全套 Skills 一行安装:npx skills@latest add mattpocock/skills
Sandcastle 安装:npm install -g @ai-hero/sandcastle,项目内运行 sandcastle init 选模板。
怎么开始
如果你今天就想试,不用全套上。三个层次,按你的阶段来:
最轻量:下次开新功能前,别急着让 AI 写代码。先用 /grill-me 花 15 分钟让它追问你。光这一步,就能显著减少返工。
系统化:装全套 Skills,在项目里跑一遍完整流程:追问 → PRD → Issues → TDD 实现 → Review。跑通一轮你就会明白,为什么"给 AI 写好 prompt"远不如"给 AI 一套工程流程"有效。
并行化:当你的 Issue 列表够多、互相不阻塞时,用 Sandcastle 把它们丢进并行沙箱。你去睡觉,早上起来看合并结果。
关键不在工具。在于你愿不愿意接受一个事实:AI 编码的天花板,是你自己的工程素养。
工具只是让这件事变得可操作。
夜雨聆风