AI辅助编程阶段化SOP:从翻车到可控开发

发布时间:2026/10/3 4:54:22
AI辅助编程阶段化SOP:从翻车到可控开发
我真正开始把 AI 用进日常开发是从一次“看起来很成功”的翻车开始的。当时我接过一个结算模块需求描述得也算清楚我直接把整个模块丢给 AI让它“一次写出来”。AI 给了我将近 2000 行的代码文件整洁、注释规范、结构完整看起来像个正经的开源项目。结果跑起来以后优惠券优先级算错、缓存装饰器装饰错了函数、重复工具函数跟另一个模块冲突我修了两天最后还是推倒重来。复盘之后我才意识到问题不在于 AI 蠢而是我的工作方式蠢我把“生成代码”当成了“完成开发”全程没有阶段划分也没有在任何节点做验证。这之后我慢慢整理出一套 AI 辅助编程阶段化开发 SOP把它用在日常项目里一次生成通过率大幅提升返工时间也压缩了一半以上。这篇文章就是把这套 SOP 完整拆开讲清楚每个阶段该做什么、为什么要这样做、哪些地方最容易出问题。1. 没有阶段化 SOP 时的典型失败从完整生成到推倒重来1.1 一个“教科书级翻车”的结算模块我做结算模块时的原需求其实不算复杂核心是订单金额计算叠加多种类型的优惠券按照一定的优先级规则做折扣叠加最后把扣减结果传给支付接口。我用一句话把它交给 AI“请帮我实现一个订单结算模块技术栈是 Python 和 Django。”AI 返回的内容让我第一眼很满意有 models、services、utils、payment callback handler甚至贴心配好了 mock 支付接口还顺手加了几个缓存装饰器。但进入验证环节就彻底麻烦了。优惠券的优先级规则跟产品经理定的完全不一致金额计算里把本应“减去”的折扣写成了“加上”缓存装饰器装饰的不是目标函数而是另一个毫不相干的工具函数utils 里的日期工具函数又跟另一个老模块里已有的函数重名且逻辑冲突。这些 bug 单独拎出来都不难修但当它们混在 2000 行代码里时我面对的已经不只是改错而是要先花大量时间理解 AI 自创的这一套内部结构。对于一个运行了一年多的老项目来说这种“AI 风格结构”跟现有代码生态完全是两个世界。这个案例典型在哪里它把“生成代码”和“做成产品”之间的空隙暴露得很彻底。AI 很擅长根据提示词统计上最合理的代码形态但它不知道你的业务规则、也不知道你的代码库里有哪个旧函数和它的生成结果会打架。它只是根据一个长提示词写了一个概率上最顺滑的长文本。如果你不把大任务拆碎、不在每一段之后验证风险就会全堆在最后一起炸。1.2 把“让 AI 写代码”换成“让 AI 参与分段开发”那次翻车之后我把工作流改成了阶段制并给了每个阶段明确的定义需求澄清阶段负责把模糊描述变成可验证的输入输出和验收标准任务拆解阶段负责把模块拆成独立可控的子任务编码生成阶段只解决一个文件、一个函数级别的改动测试审查阶段先写测试再写实现重构回归阶段则严格限制 AI 的改动范围防止它越界搞破坏。这个流程设计最核心的变化是把“结果验收”提前到了“每一步验收”。不做阶段化时你只能在完整模块跑起来之后才知道好没好做阶段化之后每一步都有一个中间产物小到可以快速人工确认再小到可以单测覆盖。换句话说SOP 的本质不是控制 AI而是控制你自己接受 AI 输出的方式。可以拿做菜类比。以前的我是让 AI 直接把一整桌菜端上来而现在的流程更像是让 AI 当后厨助手他负责洗菜我就只给他菜和洗菜规则他负责切配我就只给他切配标准真正下锅调味、控制火候的人是我。这样即使哪一步出了错问题也只会在很小的范围内排查不会跟前一步的烂摊子纠缠在一起。1.3 这套 SOP 适合什么项目不适合什么场景我当然不会说所有开发场景都该套全套 SOP。它最适用的是那些要求长期维护、稳定演进的业务系统、服务端模块、中间件和工具库。这类项目的真正成本不在于“多快生成代码”而在于代码进入仓库之后后续是否有人能读懂、敢修改、可依赖。一套严格流程会大幅降低后面这些风险。反过来如果只是一次性的脚本、原型验证、临时数据清洗那阶段化 SOP 完全可以精简成三步写清需求、让 AI 生成、跑通验证。没必要为一个用完就删的脚本开五阶段流程。还有一种情况连人也说不清业务规则时也不能指望 AI 帮你发明规则。AI 只能处理已经被明确描述出来的逻辑无法验证某个金额到底该不该免税。这类规则的定义工作永远属于人这也是任何 SOP 都绕不开的底线。另外现在不少团队开始尝试 AI agent 全自动完成端到端开发或者用多 AI 协作并行处理任务。方向确实有想象空间但我的实际感受是自动化程度越高出错后追溯的成本越大。如果没有阶段验收点一个自信的错误会顺着 agent 自动执行流程一路扩散到多个文件。阶段化 SOP 的意义正是给这种自动化踩刹车。2. 阶段一需求澄清与任务拆解——SOP 的质量上限2.1 把一个“我想做……”改写成验收标准清单我见过更常见的把需求文件原文直接粘贴给 AI 的情况。AI 确实能读懂不少中文但“读懂描述”和“理解需求的边界”是两回事。需求澄清阶段的目标是先由人整理出一份可验证的验收标准并且明确“什么不该做”然后再考虑编码。我常用三个问题来逼自己把需求说清楚核心价值这个功能给谁的什么场景提供便利核心目标是“算清楚金额”还是“快速完成下单”输入输出输入从哪里来有哪些字段哪些字段可能为空输出是落库还是返回给前端边界排除明确写下“本期不做的事项”。这是大多数人最容易忽略的。以登录功能为例。模糊的写法是“帮我写一个登录功能”。经过澄清之后的写法是支持邮箱或手机号加密码登录校验通过后返回 jwt 令牌本期不做第三方 OAuth、不做注册流程、不做找回密码且密码连续错误五次触发临时锁定。你会发现后面这版描述直接把 AI 的发挥空间收窄了很多生成结果里的“惊喜”也会少很多。2.2 任务拆解的粒度控制一个子任务只解决一件事需求澄清之后是拆任务。我的拆解原则非常朴素一个子任务应该能在一个文件内完成并且最多依赖三个外部接口。拆出来的每个子任务都要能独立验证。还是说登录功能。如果按这个原则拆可能的拆法是登录接口报文校验子任务负责检查字段是否缺失和格式是否合法密码校验策略子任务负责读取用户密码哈希并比对令牌签发子任务负责生成 jwt 并设置过期时间登录日志记录子任务负责落库存下登录成功或失败的时间与来源。这四个子任务单独测试起来都很容易。报文校验给一个缺手机号的请求看它是否返回 400密码校验给一个错误密码看它是否返回失败结果令牌签发给一个用户 ID看 token 能否解开。反过来如果你把“整个登录模块”作为一次任务丢给 AI它生成的 500 行代码交织在一起任何一环出错排查链路都会长得多。我把拆解粒度理解为项目的“安全绳”。拆得越细单个环节的验证成本越低出错后的定位半径也越小。这个原则对 AI 辅助项目和传统开发其实完全一致只是 AI 生成得太快更需要这种人为颗粒度来兜底。2.3 用 AI 辅助产需求说明书时的提示词模板需求澄清阶段AI 不是完全没事干。我一般会让它基于原始需求先产出一版结构化说明书然后在它的基础上人工修订。提示词模板长这样角色你是一位资深业务分析师 任务基于下面的原始需求产出一份结构化的功能需求说明书 原始需求粘贴原始需求描述 输出格式 1. 功能概述不超过200字 2. 用户场景至少列出3个典型场景 3. 输入与输出定义表格列出 4. 核心业务规则 5. 本期不做事项必须列出 6. 验收标准至少5条 约束不要擅自增加未提及的模块不要假设第三方服务如不确定请标注“待确认”这个模板的价值在于对输出格式做了强约束避免 AI 把需求说明书写成一篇看似全面实则没有边界的散文。但我要提醒的是AI 生成的“本期不做事项”经常漏掉一些领域属性的边界。比如登录功能里它会漏掉“要不要限制同一 IP 的登录频率”这种安全类边界。这些内容需要人工在领域知识上补齐所以我会把需求澄清阶段牢牢定义为“人主 AI 辅”。3. 阶段二编码生成前的上下文封装与提示词设计——让 AI 只干一件事3.1 上下文封装把项目背景压缩到一个“信息卡片”AI 本身没有项目记忆每一轮的输出只取决于你喂给它的上下文。所以在编码阶段我坚持给每个子任务做一张“信息卡片”而不是直接粘整个 README 或者一大段项目文档。信息卡片一般包含四部分技术栈与框架、目录约束、本次任务的描述、硬性约束。比如一个接口开发任务我会这样写[项目技术栈] Python 3.11, FastAPI, SQLAlchemy 2.0, PostgreSQL 15 [目录约定] 业务逻辑放 app/services路由放 app/api [本次文件] app/api/orders.py [任务描述] 新增订单查询接口输入参数 order_id输出订单详情以及最近一次状态变更时间 [硬性约束] 1. 不新增第三方依赖 2. 不修改 models 下的表结构 3. 只更新 app/api/orders.py 这一个文件 4. 保持现有响应格式不变 [验收条件] 调用 GET /orders/{order_id} 返回 200响应结构符合 response_model 定义这张卡片的原理很简单把项目背景压缩到与当前任务直接相关的范围让 AI 在有限的上下文里做决定。上下文里塞的项目信息越多AI 越容易在输出的中途丢失早期约束最后写出来的东西看着面面俱到实际上哪一头都没贴紧。3.2 “一次只改一个文件”的生成 Prompt 写法编码生成阶段我最常用的提示词框架是这个文件路径{实际路径} 当前代码粘贴现有关键函数代码 任务描述需要新增/修改的功能给出输入输出示例 约束 1. 只修改上述文件不新增文件 2. 不修改函数签名 3. 不引入新的第三方依赖 4. 不添加与本任务无关的注释 5. 请输出完整代码不要省略 验收条件{列出可运行的行为示例}“一次只改一个文件”不是说永远不能动多个文件而是说在你建立足够的控制力之前把范围收到最小。每个文件单独成批diff 小、回滚快、审查也快。等到你对某个 AI 的代码风格和工作模式有了稳定的信任度再逐步放宽到“一次改两三个相关文件”。最关键的约束其实就两条不修改函数签名不增加新依赖。这两个问题是我踩过最多坑的地方。AI 出于“优化”或者“更好的抽象”会擅自调整公共接口、改变参数默认值、引入新的工具库。这类改动往往表面合理但回归成本极其惊人。加上这两个约束后风险会降低一大截。3.3 为什么小的子任务能显著提升正确率关于为什么拆小会让 AI 生成质量更高有个并不算神秘的原因。大语言模型在生成每个 token 时都会把此前所有 token 当作依据。模型本身没有真正意义上的“工作记忆”它的注意力在超长文本里会逐渐分散越靠后出现的约束越容易被后文覆盖甚至遗忘。你可以把上下文想象成一张不断被填满的白板。提示词短小时关键约束始终在显眼位置提示词一旦变长早期约束就被后来的描述挤到边缘。等代码写到后半段模型可能已经不太“记得”你开头强调的“不要修改签名”了。任务拆得越小提示词就越短约束保持存在的概率就越高。我自己统计过一组数据把一个结算模块拆成 4 个子任务每个控制在 40 到 200 行以内AI 一次通过率大概在 70% 左右整包一次性生成一次通过率只有 25%。这个差距不是靠提示词魔法能补上的它就是流程拆解的收益。还有一点当你面对异步编程这类天然复杂的任务时拆解显得更重要。我一般会让 AI 先写接口定义和数据模型再写任务处理逻辑再补补偿逻辑和超时控制。每一层都有独立的验证面不会出现“一个并发 bug 掩埋在一大段各自看起来合理但互相矛盾的逻辑里”的悲剧。4. 阶段三生成、测试与人工审查——正确率不等于正确性4.1 生成顺序接口先行、骨架先行、逻辑填充我见过不少新人把最终业务逻辑作为第一句话直接甩给 AI这其实是把压力全留给了最后一步。我现在的习惯是三层递进第一轮只让 AI 给出函数签名、类结构和主要依赖关系。这个阶段的核心是确认输入输出定义和分层是否合理几百字的输出很快就能人工看完第二轮基于签名让 AI 生成骨架代码包括异常处理分支、超时处理和错误返回但不填充业务细节用 TODO 占位第三轮才针对具体函数填充业务逻辑并且在拿到结果后立刻做局部测试。这种方法最大的好处是每轮输出都能独立审查。接口定义不合理第一轮就能拦截而不是等 500 行代码写完再回头重构。异步任务尤其依赖这种递进方式并发问题、超时问题、异常传播问题往往藏在骨架而不是业务表达式里如果逻辑和结构一次性生成问题定位的难度会成倍上升。4.2 让 AI 先写测试再写实现整套 SOP 里我认为最有效的单条规则是先让 AI 写测试再让 AI 写实现。反过来做的时候AI 会像学生一样先把答案写出来再想办法补一段“证明自己正确”的测试这毫无约束力。先写测试则不同测试是把行为期待变成机器可验证的约束。比如异步任务处理函数我会先给 AI 这样一个测试任务角色高级 Python 开发者 请先为我生成如下场景的测试用例代码 模块异步任务队列消费者 process_tasks 用例覆盖 - 正常消费多条任务 - 某条任务抛异常时不影响后续任务 - 超过 timeout 仍未完成时标记失败并退出 请直接输出 pytest 风格测试文件不要实现。拿到测试用例以后人会先审查这些用例有没有覆盖边界条件空队列、任务内部异常、超时、依赖服务失败、并发竞争。如果用例只覆盖了 happy path就要求 AI 补充。等用例通过审查再让它基于测试写实现。后期的验证就不再依赖 AI 自我评价了直接跑 pytest绿了就过红了就打回。有人会质疑测试也是 AI 写的它自己给自己出题能算数吗答案是测试需要人审。只要审查住了边界覆盖这个自证循环就是可控的。4.3 人工审查的“五不放过”清单即便有了单测守护人工代码审查依旧不能被省掉。AI 生成代码的质量瓶颈通常在业务理解和设计意图而不在语法错误。我给自己定了一份“五不放过”清单不放过突然出现的抽象层。AI 喜欢为你新建基类、工厂类、装饰器如果这些抽象不能显著降低后续维护成本就要求删除项目已经够复杂了不放过看不懂的分支。看到一段不知为何要存在的 if 分支要让 AI 解释判断逻辑解释不通就直接删掉不放过新依赖。AI 自动引入的第三方库版本兼容性和安全风险未知没有明确理由就不合入不放过未处理的异常路径。AI 写的代码非常容易只处理顺利路径要主动追问依赖挂掉、超时、入参为空时怎么办不放过与项目风格不一致的代码。如果整个项目统一使用仓储模式AI 却直接操作数据库必须把它拉回原有风格。审查时间也要设下限。我的经验是100 行以上生成代码至少花 5 分钟读。如果时间不够就说明这个子任务拆得还是太大应该继续缩小而不是在有损状态下赶上线。5. 阶段四迭代重构与回归控制——让 AI 给已有代码库做手术5.1 大范围重构必须切成“行为保持”的小步重构比新功能开发更依赖阶段化。因为重构的本质不是重写而是在改变内部结构的同时保持外部行为不变。一旦这个前提被打破你得到的就不再是“优化后的模块”而是一个新的灰色地带。我处理历史遗留模块时会把重构拆成四个阶段每个阶段都有独立提交和回归测试第一步重命名把函数名、变量名、文件改名完全不碰逻辑第二步迁移调用点把调用旧名字的地方全部改到新名字第三步拆分函数或提取模块第四步才做行为调整和性能优化。这样拆分的原因很简单每一步的 diff 都很干净出了问题可以直接定位到某个动作。一旦你让 AI 同时做“重命名加改变逻辑加优化性能”输出的 diff 就是一团乱麻即使回归测试挂了你也很难判断是哪一段改动引发的。5.2 三个防回归手段版本控制、差异审查、单测回归重构阶段有三个标配动作有经验的开发者看着会觉得熟悉但 AI 辅助开发环境下每个动作都值得强化第一版本控制。每一次 AI 改动都单独开分支、单独提交提交信息里写清楚哪些代码是 AI 生成的哪些是人工修改的这样才有快速回滚的底气。第二差异审查。不要只看最终文件要看 git diff尤其是那些“没有被任务描述覆盖但被改动”的行。AI 经常顺手改点别的这种改动最容易带来隐蔽回归。第三全量回归。AI 没有全局副作用概念它看不出自己改了一个函数会让另一个模块的调用出错。合并前全量跑测试不要只跑当前文件相关的测试。这三个动作组合起来的效果是给 AI 的高速生成配上了一组“刹车片”。没有刹车的车越快越危险开发也一样。5.3 一次重构翻车复盘AI 悄然改了公共签名讲一个具体翻车案例。当时我让 AI 优化一个工具函数的时间复杂度提示得很简单代码也不长。AI 很快给出优化版本单元测试也绿了。合并之后第二天运维报告线上某块缓存任务不更新我定位了两个多小时才发现AI 优化后的版本悄悄改掉了公共函数的参数默认值把原来的timestamp: int 0改成了timestamp: int | None None。调用方按旧签名传参传进来的0被新逻辑判断成空值直接导致缓存键变成 None缓存系统静默失效。编译没问题测试也只是覆盖了 happy path所以直到运行期才暴露。复盘后我把两条教训写进了自己的 SOP第一提示词里必须明确“禁止修改函数签名如确实需要修改先说明并等待确认”第二审查重构代码时必须看完整文件 diff尤其是没有被要求的改动行。从那以后同类型问题我再没遇到过。6. AI 帮倒忙的常见症状与排查路径6.1 症状一输出很完整但跑不通最典型的情况是 AI 生成一个看起来很完整的模块但一运行就报错。遇到这种症状不要第一时间把报错丢回给 AI 让它“修一下”而是先做最小化复现。把生成的代码切到一个独立脚本里手动构造最小输入观察报错栈到底在哪一层。我的排查链路是最小化复现 → 看到具体异常位置 → 检查 imports 是否存在 → 检查数据类型在流转中是否保持一致 → 再决定是人工修还是让 AI 重写。如果自己一时找不到问题根因可以用“追溯性提示词”向 AI 要它的假设条件比如让它列出“你认为输入数据应该长什么样”或者让它给出三个不同的修复方案并说明取舍。大部分时候你会发现问题出在一个 AI 自己编出来的假设上而这个假设和你的真实业务数据并不一致。6.2 症状二AI 反复生成同一个错误试错成本很高调试场景里AI 还会出现一种让人崩溃的情况连续三次给出同一种缺陷代码换着法问也是一样。这时候别再顺着当前上下文继续“再试一次”立刻清空对话开新会话把已验证的事实、错误栈和边界条件直接喂给它。我把这种情况总结成“人给证据AI 给候选方案”。比如这样说传入空列表时这一行会报 IndexError错误在 line 34我希望空列表返回空结果请给出满足行为的实现和对应测试。这种方式比“刚刚那段不对帮我改一下”要有用得多。因为 AI 是一个概率模型在确定性证据越多的条件下它的输出越容易收敛到正确答案。6.3 症状三AI Agent 自动改动过多文件流程失去控制现在不少开发者开始用 AI agent 直接读代码库并自动改代码。小型任务里agent 确实效率极高但任务一旦跨模块、跨边界自动化带来的失控感就来了。我给团队的建议是给 agent 定三条规则第一不能直接动公共代码和接口定义第二每改一个文件必须有独立 commit第三关键合并点必须有人工否决权。如果你在尝试多 AI 协作比如让不同模型分别生成方案再由人选优这个思路没问题但阶段边界不能省。多模型解决的是单模型的系统性偏见但几个模型叠加出来的组合如果没有人工验收点一致性风险会更高。你依然需要严格定义每个阶段的输入输出才能避免多智能体协作变成多个未知 bug 的组合戏。7. 把阶段化 SOP 沉淀成团队可落地的模板7.1 五阶段 SOP 总表为了方便团队直接上手我把整套 SOP 浓缩成了一张表格阶段输入AI 做什么人做什么主要交付物验收标准需求澄清原始需求描述生成结构化需求说明书补充领域规则、确认边界需求说明书和验收清单每条验收标准可测试任务拆解需求说明书建议拆解方案和文件级位置调整粒度、确认依赖关系子任务列表子任务独立可完成编码生成上下文信息卡片和子任务完成一个文件或函数实现加载上下文、审查 diff代码变更单测通过无越界修改测试审查新代码和原有测试生成单测、补边界用例审查覆盖度、运行全量测试测试与审查记录覆盖正反边界回归全绿重构回归已有代码和优化目标完成行为保持型小步重构控制范围、监督签名和接口行为保持和适当优化多次全量回归通过这张表可以直接打印出来贴工位也可以作为团队评审会议的框架。每个团队可以根据自身技术栈追加特定约束比如涉及数据库变更必须人工评审涉及金额计算的模块必须双人复核。7.2 提示词库和编程学习记录的版本管理阶段化 SOP 跑得越久你手上会积累越多的提示词模板。这些模板是团队的重要资产不要散落在个人聊天记录里。我会用一个 Git 仓库统一维护目录结构大致如下ai-coding-sop/ ├── phases/ │ ├── 01-requirement-clarify.md │ ├── 02-task-decompose.md │ ├── 03-codegen-prompt.md │ └── 04-review-checklist.md ├── cases/ │ ├── 2024-refund-regression.md │ └── 2023-auth-timeout.md ├── metrics/ │ └── acceptance-rate.md每个提示词文件都配上使用场景、版本历史和失败案例记录。这样团队新人接手时不用从零摸索只要按模板走一遍流程就能获得和你接近的下限质量。对于正在用 AI 学习编程的初学者我也建议用四段式记录自己的编程学习记录目标、AI 方案、人的判断、验证结果。比如想学异步编程就先写目标“理解并发和并行的区别”让 AI 给出一段对比示例然后用自己的话解释一遍再亲手运行一个实验记录观察。这种方式看起来比“让 AI 直接解释”慢但留存率高得多。7.3 团队推进的渐进路线先试点再推广最后聊聊怎样把这套 SOP 真正带进团队。我的建议是别指望一步到位先从一条小业务线试点跑两三周记录三个量化指标AI 生成代码的一次接受率、修复平均耗时、合并后的缺陷率。然后把这些数据拿出来给团队看再补上最贴合自身痛点的约束条款。SOP 本身应当是活的。每发现一个新的翻车模式就往对应阶段的约束里加一条防坑规则。过一段时间这份 SOP 就不再是个人的经验文件而会变成团队轮换时真正的交接载体。它会随着项目复杂度增长而增长也会随着团队对 AI 的熟悉度提高而逐步放宽限制。在我自己一年多的实践里最大的体会是阶段化开发 SOP 带来的最大收益并不是代码生成速度而是“可控性”。我依然信任 AI 能快速完成很多日常需求但我不再信任它一次性给出的“完整方案”。每次把任务拆小、把验收标准写清楚、把边界约束放进去它产出的代码就越来越像“为我定制的”。如果只让我分享一条最重要的建议我会说先把一次要改的范围缩小到你能在短时间人工审查完的程度再谈效率优化。这条看似保守的规则实际节省的时间比任何提示词魔法都多。