最近我们在一个内容系统里加博客管理功能,本来以为是个很顺手的小需求:博客列表只展示可见内容、菜单补几个状态按钮、编辑页把 UI 对齐现有风格。结果第一轮直接把需求丢给 AI,让它一把梭改代码,最后看起来像是“已经完成”,但一进测试就发现问题很多:接口字段没对齐、published 过滤忘了做、菜单按钮状态也没处理完整。
这件事让我又确认了一次:AI 最擅长的是“加速表达”和“生成草案”,但一旦进入长期演进的软件系统,真正贵的错误往往不是某个变量名写错,而是状态放错层、职责切错位置、接口边界理解错。代码能跑,不等于方案合理,更不等于能交付。
后来我们把这类需求固定成一个很朴素的工作流:三次对话,分别处理信息收集、代码实现、测试验收。这个流程不神秘,本质上只是把人的判断插到代码生成之前,而不是等它生成完再被动补锅。
先别急着写代码,问题通常出在信息不完整
我们一开始走过一段弯路。
当时的做法很直接:把需求说明、几个接口名字、一个页面路径丢给模型,然后让它“直接完成开发”。它确实能很快吐出一版实现,甚至改动文件还不少,看起来像模像样。但问题也正出在这里:它在信息不够的时候,会自动脑补。
比如博客列表那个需求,模型默认认为“拿到博客数据就直接渲染”,但我们的业务规则其实是:
- 列表页默认要过滤掉未发布内容;
- 菜单项要根据发布状态展示不同按钮;
- 某些状态按钮不是纯 UI 行为,还会触发已有接口;
- 现有项目里已经有一套菜单状态组件,不能再发明一套新的。
这些规则,只要漏一个,后面就不是“修个小 bug”这么简单,而是要把前面生成的代码重新拆开。
所以我们后来不再追求“一次对话全做完”,而是要求模型先理解,再动手。这里的关键不是“AI 能做什么”,而是什么时候不能只依赖 AI。原型、草稿、课堂演示当然可以让它冲在前面;但只要进入工程项目,代码组织方式、数据边界、错误处理方式、依赖耦合方式,最后都得有人负责,这个责任不该让模型替我们承担。
我们早期最常见的误判,就是看见页面能出结果,就默认这轮改动已经接近完成。实际上很多返工,都是因为状态归属、接口契约、已有组件复用关系在一开始没有讲清楚。等到第三轮才修这些问题,成本会明显更高。
三次对话,不是技巧,是把工程决策拆回正确顺序
我们内部把这个流程叫做 planning + working horse。
planning 负责问问题、暴露约束、拆模块、指出风险;working horse 负责在边界明确后按要求写代码;第三次对话不再把模型当“写代码的人”,而是把它当成测试工程师和审查者。
整个流程压缩下来,就是这三步:
- 第一次对话:只做需求采访和信息收集,不写代码
- 第二次对话:只做单模块实现,不顺手扩改其他东西
- 第三次对话:只做测试、验收、截图纠偏和回归修复
我们后来发现,只要顺序不乱,很多需求真的可以在三轮内落地。反而一开始想“省一次沟通”,最后通常会多出三倍返工。
第一次对话:让 planning 像接手需求的工程师一样采访你
第一次对话我们故意不让模型产出任何代码,而是要求它先把信息问全。
这一步特别适合两种情况:一种是需求本身有业务规则,你没法一次写全;另一种是你自己也不确定应该先给哪些上下文,那就别靠猜,让模型反过来采访你。
我们常用的起手式很简单:
你现在先不要写代码。
把自己当成接手这个需求的工程师,逐条采访我,直到你确认下面这些信息足够完整:
1. 项目结构
2. 相关页面和组件
3. API 和数据库字段
4. 业务规则
5. 这次允许改动的边界
6. 需要覆盖的测试点
当你认为信息足够后,再输出一版开发计划,但仍然先不要写代码。
这类 prompt 的重点不在于“格式漂亮”,而在于明确限制它:先提问,后规划,不许直接产出实现。
在这一轮里,我们通常会把下面这些信息补完整:
- 页面路径和相关组件
- API 返回结构,尤其是状态字段
- 数据库或 ORM 模型里哪些字段是真正可信的
- 是否允许改接口,还是只能适配现有契约
- 是否存在复用组件,避免新造状态层
- 本次需求的完成标准
比如博客列表那个需求,第一次对话里如果没有明确“published 是真实业务开关,不是单纯显示字段”,模型大概率会只在前端做显示判断,而不会把过滤逻辑放进正确的位置。
很多人给 AI 上下文时,默认自己知道哪些信息重要,结果往往是把“看起来重要的描述”写了一堆,却漏了真正决定实现方式的约束。采访式提问的价值就在这里:它会逼出那些平时容易省略的条件,比如现有组件能不能复用、接口能不能改、某个字段是展示态还是业务态。
第一次对话的产出,不是代码,而是一份可审的计划
这一轮真正有价值的输出应该是计划,而不是实现。
我们要求它最后给出类似这样的内容:
- 这次改动涉及哪些模块
- 哪些地方必须读现有代码再动
- 哪些地方存在接口理解风险
- 哪些测试点必须覆盖
- 哪些内容不在本轮范围内
这一步其实特别像资深工程师带人:先看思路,再看落地。因为真正昂贵的错误通常不是某行代码,而是方向走偏。
我们后来会自己先审这份计划。只要发现方向不对,就在这里改掉,而不是等它改完十几个文件再返工。
第二次对话:把 working horse 限制在一个模块里干活
计划确认后,第二次对话才开始写代码。
这里我们有一个很硬的约束:一次对话只做一个模块,或者一组强相关改动,不让它横向扩散。
原因很现实。现在的模型已经很强,但功能需求开发里最容易出错的地方,仍然是接口、数据源 and 项目结构的细节对齐。如果让它一口气改很多模块,它会更容易在局部正确的基础上,拼出一个全局不协调的结果。
所以我们的做法通常是:
- 列表过滤是一轮;
- 菜单状态按钮是一轮;
- 编辑页 UI 校正是一轮。
如果这些改动必须算同一个需求,我们也会在第二次对话内部,把任务拆成非常明确的执行顺序,而不是一句“把这个功能全部做完”。
典型输入会长这样:
基于以下已确认上下文执行开发。
不要重写项目结构,不要新增状态管理方案,不要改动未提及的页面。
目标:
1. 博客列表默认过滤 published=false 的数据
2. 复用现有 menu 状态组件
3. 给 menu 增加缺失的状态按钮
4. 保持现有接口契约不变
上下文:
- 页面文件:...
- 组件文件:...
- API 返回:...
- 业务规则:...
- 不允许改动范围:...
请先输出你要修改的文件列表和每个文件的改动意图,再给出代码。
这里看起来只是“多写了几句”,但效果差别很大。我们不是让模型自由发挥,而是在告诉它:
- 只能在哪些地方动手;
- 不能顺手重构什么;
- 输出前先暴露改动面;
- 一旦要改的文件超出预期,我们就立刻拦住。
我们最常见的一类错误:AI 会把“缺字段”误当成“缺设计”
博客需求里我们就碰到过这个问题。
模型第一次输出时,忘了给博客列表过滤已发布标识。它看到数据里有 published,但没有把这个字段作为列表构建规则的一部分。另一处则是 menu 少了一些状态按钮,它也没有去对照现有组件的状态流转,而是按照表面 UI 自己补了一套。
这反映了工程上下文里有太多“默认约定”。人类同事会从已有代码里闻出来,模型不一定会。
很多时候,不是模型不够聪明,而是它没有背景知识。在第二次对话里,把这些“不许新造”和“必须对齐”的约束写得越直白越好。
第三次对话:别再让它写新功能了,让它帮你做测试和纠偏
第三次对话的角色要切换。
这时候它不再是开发者,而是测试工程师、验收者和 UI 审查者。目标不再是“继续补代码”,而是验证这次改动有没有真的覆盖需求。
我们通常会把第三轮分成三个动作:
- 根据改动内容生成测试路径
- 根据实际运行结果和截图做 UI/交互验收
- 根据发现的问题做小范围修复,不扩需求
这一轮我们常用的 prompt 是:
基于这次改动,站在测试和验收的角度输出:
1. 功能测试清单
2. 接口契约检查点
3. 回归风险点
4. UI 验收项
5. 最可能漏掉的边界情况
如果我给你页面截图、控制台输出、接口返回,请你根据这些信息定位问题,并只建议最小改动修复。
这一步对前端尤其有用。因为很多问题不是读代码就能看出来,必须结合截图、实际按钮状态、页面结构来判断。
UI 问题经常卡在“文字描述不够精确”上。截图能把布局、按钮位置、状态缺失一次性交代清楚。对模型来说,这比你写一大段“看起来有点不对劲”的描述更容易形成可执行的修复建议。
这套流程为什么能把对话压到三次
我们后来复盘过很多次,发现“三次对话”能成立,不是因为模型突然理解力暴涨,而是因为我们把每次对话只留给一种职责。
- 第一次对话只解决“信息够不够”:不写代码,所以不会因为早产出的实现污染判断。
- 第二次对话只解决“方案怎么落地”:计划已经审过,working horse 只需要按边界执行。
- 第三次对话只解决“结果对不对”:这时讨论的是测试路径、截图反馈和局部修复,不再重新发明方案。
本质上,我们只是把需求开发重新拆成了软件工程里原本就该有的三个阶段:需求澄清、实现、验证。
什么类型的需求,最适合用这个节奏
这套做法并不适合所有事情,但对下面这几类任务特别有效:
- 现有系统里的功能增量开发
- 页面 + 接口 + 状态联动的小中型需求
- 需求边界清楚,但上下文复杂的项目
- 容易因为接口契约和业务规则出错的改动
反过来,如果是下面这些情况,我一般不会强行套三次:需求目标不稳定、项目历史包袱极重、改动触及核心架构调整、或者涉及数据库权限重构等高风险变更。
我们最后沉淀下来的最小模板
如果要把整个流程压成一套最小可复用模板,大概就是下面这样。
第一轮:采访和计划
先不要写代码。
像接手需求的工程师一样采访我,直到你确认以下信息完整:
- 项目结构
- 相关模块
- API 和数据源
- 业务规则
- 改动边界
- 测试要求
信息足够后,输出:
1. 需求理解
2. 风险点
3. 模块拆分
4. 文件改动计划
5. 测试点
第二轮:按模块实现
基于已确认计划执行开发。
限制:
- 只改指定文件
- 不重构无关模块
- 不发明新的状态方案
- 保持接口契约不变
先列出要改的文件和改动意图,再给出实现代码。
第三轮:测试与修复
基于这次改动,从测试和验收角度输出:
- 功能测试项
- 回归测试项
- UI 验收项
- 边界条件
- 最可能遗漏的问题
我会补充截图、日志、接口返回,你根据这些信息定位问题,并给出最小修复方案。
这套流程目前还不够完美的地方
尽管这套流程帮我们省掉了很多重复表达和修复逻辑的时间,但它依然有局限性。
第一,它依赖人能看懂计划。如果审计划的人本身对模块边界、接口设计不敏感,后面照样会跑偏。 第二,它对项目文档质量有要求。如果现有代码本来就糊成一团,模型也只能在模糊信息上做模糊判断。 第三,截图驱动的 UI 修复很有用,但不能替代真实交互测试。复杂的异步链路和错误提示恢复,还是要自己走一遍。
所以我们现在的态度很明确:这不是一种“AI 自动开发法”,而是一种把 AI 纳入工程节奏,但把关键判断留在人手里的协作方式。它帮我们省掉了逻辑和代码的“表达”时间,但不会替我们完成“判断”。