很多人觉得用 AI 编程就是“把需求发给 ChatGPT,然后把代码复制过来”,真这么做的人大多会碰一鼻子灰——生成的代码要么不符合现有项目结构,要么缺了边界处理,要么压根跑不起来。我这些年的体会是,AI 编程想要稳定地产出高质量代码,靠的不是“问一嘴”,而是把协作过程拆成一套固定的、可以反复执行的工作流。
这篇文章准备分享 3 个我目前在日常项目中真正会复用的 AI 编程工作流:一个管新功能从需求到落地,一个管改代码时的正确性验证,还有一个管接手存量代码时的审慎重构。三个流程覆盖了开发过程中最常遇到的三种场景,不存在什么高端技巧,全都是可以直接照抄的提示词结构和操作步骤。不管你是刚接触 AI 编程,还是已经在用但总觉得效果不稳定,都值得对照着试一遍。
1. 新功能开发:从需求澄清到代码落地的“结对编程”流
1.1 为什么直接让 AI 写代码总是翻车
我先说一个最常见的误区。很多人给 AI 的指令是“请用 Python 写一个订单导出功能”,然后 AI 噼里啪啦输出一大段代码,看起来有模有样,一放到项目里全是问题:用了不存在的依赖、没接现有的日志框架、没考虑空订单列表、数据库事务没有处理。为什么?因为 AI 在没有上下文的情况下会把“你觉得差不多的功能”理解成“它认为合理的功能”,而你真正在意的工程约束它完全不知道。
所以我在新功能开发时不直接让 AI 输出代码,而是让它按一个固定流程走:先提问,再出方案,然后分步实现,最后自检。这个过程本质上就是把“结对编程”中人类搭档会做的事——问需求、理思路、写代码、自查——复制到 AI 身上。
1.2 第一步:让 AI 先问问题,而不是先写代码
我用的第一个提示词模板是这样的,你可以直接保存成自己的常用提示词:
你是本项目的资深工程师,技术栈是【技术栈】,当前项目已有代码风格是【描述风格】。 现在我需要开发一个新功能,先不要写代码。请按以下顺序响应: 1. 列出你认为必须先确认的问题,最多10个,必须是我需要拍板的问题,不要问废话。 2. 基于我给出的需求描述,输出技术方案,包括:模块划分、核心数据结构、主要接口签名、涉及的外部依赖。 3. 在我确认方案之前,不要输出任何实现代码。这个模板的关键在于两个约束:第一,让 AI 把自己定位成“项目里的资深工程师”,而不是“一个通用的代码生成器”,这会影响它后续所有的输出语气和判断基准;第二,明确禁止它在方案确认前写代码,这一步能拦住 80% 的跑偏。
实际用的时候,AI 列出来的问题质量一般都不错,比如“订单导出的时间范围如何确定”“导出文件大小有没有上限”“是否需要支持异步导出并通知用户”。这些问题确实都是需要人工决策的点。你逐条回答完,它就能带着这些约束进入方案阶段,后面写出来的代码贴合度会高很多。
1.3 第二步:确认方案,而不是确认代码
这个阶段我要求 AI 输出方案而非代码,有两个原因。一是方案比代码容易审查,模块划分和一目了然,我能快速判断它的思路对不对;二是方案阶段发现设计问题,修改成本远低于代码写完之后返工。
我会要求 AI 把方案输出成固定结构:
- 模块划分:列出新建/修改的文件清单 - 核心数据结构:关键 class/struct、字段说明 - 接口签名:函数名称、参数、返回值 - 外部依赖:是否需要新增依赖,为什么 - 不做的事情:明确列出边界,防止过度设计最后一条“不做的事情”是我特别加的。AI 特别容易在实现过程中自己加戏,比如加了一堆当前需求根本用不上的缓存机制。让它明确列出“不做什么”,等于给它的想象力上了个锁,后面实现阶段自控力会明显好很多。
1.4 第三步:按文件粒度分步实现,一次只喂必要上下文
方案确认后,我在实现阶段会刻意控制节奏。很多人一次把方案丢给 AI,让它一次性把全部代码写出来,结果上下文一超,后半段就开始胡写。我的习惯是:一次只让它实现一个文件或一个模块,并在提示词里明确“只实现 X,不要动其他文件”。
这个步骤的提示词模板:
方案已确认。现在只实现文件 【文件路径】 中的【模块/函数描述】: - 已有的相关代码请在下方粘贴 - 实现时遵循项目现有的错误处理和日志风格 - 不要新增依赖 - 完成后列出你做的假设和需要我确认的点注意最后一条“列出假设”,这一步容易被忽略但非常重要。AI 在实现过程中一定会遇到方案阶段没覆盖的细节,比如某个参数为空的场景、某种异常类型怎么处理。让它显式地列出这些假设,你只需要快速扫一眼就能发现它有没有擅自做主。
分步实现还有一个额外好处:每个文件都能独立编译/运行验证,问题能早暴露。如果让 AI 一次性生成 20 个文件,任何一个文件出错,排查起来都是灾难。
1.5 第四步:验收阶段,让 AI 自己按需求清单逐项自检
代码写完之后,我不会直接信任“代码看着没问题”。我会把需求描述原封不动地丢回去,让 AI 自己逐项核对:
以下是最初的需求描述:【粘贴需求】 你刚完成了实现。请按需求逐项检查你的实现: 1. 每一项需求对应的代码位置和应用逻辑 2. 有没有漏掉的需求点 3. 有没有实现但需求中未要求的内容 4. 边界条件有没有处理 最后输出一个自查报告。这一步本质上是让 AI 换一个角度审视自己的输出。AI 生成代码时是“写作模式”,站在设计者立场;让它自查时是“评审模式”,站在验收者立场。两种模式下它往往能发现自己刚写的 bug。我实测下来,十次里有六次能自己找出遗漏的边界条件,这就已经值回票价了。
提示:整个流程中最大的原则就是“一次只让 AI 做一件事”。它擅长的是把单点任务做得很快,而不是自己规划整个项目节奏。节奏必须由你来掌握。
2. 修改存量逻辑:测试驱动的“红绿循环”流
2.1 为什么修改老代码时容易越改越糟
新功能写完后面临的另一类场景就是修改已有逻辑。大致分成两种:修 bug,或者调整原有需求。这类任务的特点是不确定性高:你可能不完全记得这块代码当初为什么这么写,改了会不会影响别的地方。这时候直接让 AI “请帮我修复这个问题”风险极高——AI 可能会改好一处,却在另一个分支上引入新问题,而且你很难发现。
我自己测试下来最可靠的方式是把验证标准前置:先让 AI 写测试,再让它改代码或写代码,然后运行测试直到通过。这里的思路其实是从 TDD 借来的,但重点并不是“测试驱动开发”这个方法论本身,而是因为 AI 的短板恰好是“不知道自己错在哪”,测试刚好能补上它缺失的自我验证能力。
2.2 让 AI 先产出覆盖正常、边界、异常三条路径的测试用例
我用的提示词大致是这个结构:
现在我们要修改/实现如下需求:【需求描述】 请先不要修改任何实现代码。先编写测试用例,要求: 1. 使用 pytest/【项目测试框架】编写 2. 覆盖三块:正常路径、边界情况、异常路径 3. 测试数据必须使用真实语义的数据,不要用 mock 糊弄 4. 对每个用例,用注释说明它在验证什么行为 5. 如果现有接口需要调整,请在测试中先写出你认为合理的接口,并在注释中标注这里“测试数据必须使用真实语义”是我吃过亏之后加的。早期 AI 经常写出类似input = dataclass()这种 mock,测试跑绿了但什么也没验证。约束它用真实数据,逼着它去理解业务逻辑。
举个例子,假设你要修一个“计算订单总价”的 bug,AI 生成的测试可能是:
def test_order_total_with_discount(): items = [ Item(name="苹果", price=10, quantity=2), Item(name="香蕉", price=5, quantity=3), ] order = Order(items=items, discount_rate=0.8) # 验证行为:折扣价是按商品小计总额整体打折,不是单件打折后求和 assert order.total_price() == (20 + 15) * 0.8这样的用例密度和语义都比 mock 好太多。它帮你隐式地定了一个业务合约:折扣作用于小计总和,不是单件折扣后的累加。后面 AI 写实现代码时必须匹配这个合约,跑不通就说明实现错了。
2.3 先看测试失败,再驱动实现,循环直到全绿
测试写完之后,我会让 AI 先运行测试,展示“当前代码在这些用例下失败”,然后把实现代码发回去让它补齐。这一步提示词:
测试用例已经写好。现在执行 pytest 跑一遍,先输出失败结果。 然后根据失败原因实现/修改【目标函数】,要求: - 只修改必要的位置,不要大范围重构 - 修改后在失败用例中贴上通过结果 - 如果某个用例你认为设计不合理,不要直接改测试,而是说明理由,等我确认为什么要“先看失败”再让 AI 来实现?因为现实中我发现 AI 的“身份感”很强:它一旦知道自己马上要写实现代码,测试用例就会不自觉写得宽松,甚至会迎合实现代码。但如果让它先跑一遍看到失败,它就站在了“验证者”的位置,后面再切换成“实现者”,角色转换带来的严格性是很明显的。
这个流程在修改老代码时还有个额外好处:哪怕改动过程中引入问题,测试集能立刻抓出来,而不是等发布之后线上反馈。我去年处理一个支付模块的老 bug 时就是用这套流程,前后改了三个版本,每个版本跑一次测试,第三个版本才全绿,但这个过程非常平滑,因为每次改动我都能看到具体的失败点在哪,不会陷入“盲目调参”的泥潭。
2.4 这个流程最常见的翻车点
用这套流程我踩过几次坑,值得提前说。
第一,测试覆盖不足。AI 生成的用例看起来很多,但可能全在同一个语义分支里。我后来会在审核用例时问自己一句话:如果我把实现代码删掉一半,这些测试会不会立刻失败?如果不会,说明覆盖还不够。我在提示词里会额外加一句“确保每个分支都有至少一个用例”。
第二,AI 为了跑绿测试反而去改测试。它发现测试不过时,本能反应是把测试放宽而不是修代码。所以我在提示词里已经明确说了“不要直接改测试”,但还是要留个心眼。每次它说“我把测试调整了一下”时,我都会警惕地追问一句“为什么调整,改了哪些断言”。
第三,边界条件写得太抽象。有些边界是“列表为空”,有些是“列表中有空值”,这两者测试代码完全不一样。让 AI 列出的每个用例都必须配具体数据,而不只是类型。你可以要求它把测试写成表格形式:
| 场景 | 输入数据 | 期望结果 |
|---|---|---|
| 正常全价 | 3个商品无折扣 | 各自价格之和 |
| 折扣叠加 | 4个商品,满减+折扣率 | 先减后折 |
| 空订单 | quantity=0 | 抛参数异常 |
| 折扣上限 | 折扣率为1.5 | 按1.0封顶计算 |
这个表格是我人工审核时的抓手,比看代码快得多。AI 输出表格后,你一眼就能看出某个场景覆盖遗漏了,再补一句“增加一个混合折扣场景”就能让它补齐。
3. 接手存量代码:地图导航与“审查-重构”流
3.1 面对陌生代码库,AI 的正确用法是当“导游”
第三个高频场景是接手别人的项目,或者改自己几周前写的代码。这类任务的痛点不是写不出来,而是“看不懂”。我曾接手过一个内部报表系统,几千行代码挤在几个大文件里,函数互相牵连,注释几乎没有。硬啃文档效率太低,直接问 AI “这个项目是干什么的”又只会得到泛泛而谈的答案。
后来我总结出一个流程:先让 AI 生成代码地图,再按清单做审查,最后小步重构。核心思路是把 AI 当作一个“读过全部代码但刚上任”的导游,你不指望它直接改代码,而是让它帮你把思路理顺,你来决定往哪走。
3.2 第一步:生成代码地图,搞清数据流和调用链
代码地图这一步的提示词:
请阅读以下项目【项目路径/粘贴关键文件】,输出代码地图,包含: 1. 模块清单:每个文件/模块的职责,用一句话概括 2. 核心数据流:数据从哪里进入系统,经过了哪些模块,最后输出到哪里 3. 关键调用链:从入口函数出发,逐层调用到哪些函数 4. 外部依赖:数据库、消息队列、第三方 API 等 5. 你觉得最奇怪、需要重点理解的代码位置 不要修改代码,只输出分析。这一步的意义在于我不用逐行读代码,却能快速建立“全局认知地图”。比如 AI 会告诉我“这个模块虽然叫 ReportService,但真正干活的是 utils 里的两个函数,数据库查询在 service 里直接写 SQL,没有走 repository 层”。这些信息能帮我快速锁定后续排查的方向,而不是像无头苍蝇一样到处翻。
有一个操作细节:如果你能拿到代码,建议不要把全部源代码一次性粘贴给 AI,上下文窗口有限,粘贴一两个核心文件比塞 50 个文件效果更好。我会先让 AI 扫一眼项目结构(目录树 + 入口文件),然后让它告诉我“哪些模块和当前任务相关,把相关文件的内容贴给我”。这样既省了上下文,又精准。
3.3 第二步:按四大维度做代码审查,问题分级输出
有了地图,就可以进入审查阶段。我让 AI 按四个维度输出问题清单,顺序是:正确性问题 > 安全问题 > 性能问题 > 可读性问题。这个优先级是刻意设计的,前面两项是关键红线,后面两项是优化项。
基于你生成的代码地图,现在对【指定模块】做深度审查,输出问题清单: 1. 按严重程度分:严重(会导致错误结果或崩溃)、中等(异常场景未处理)、轻微(可读性/规范问题) 2. 每一条问题必须给出:问题代码位置、问题的具体表现、触发场景、修复建议 3. 性能问题单独列出,标注是否在关键路径上 4. 最后给出你的整体评价:这个模块的健康度打分(1-10)和理由实际操作时我发现,AI 对“正确性问题”的识别通常比较扎实,比如竞态条件、空指针、时区处理这类,它经常能把我忽略的细节抓出来。但可读性类的意见有点水,经常把“变量名可以更清晰”这种正确但无用的建议排在前面。所以后来我会限制每类问题的数量上限,比如“正确性问题最多列5条,可读性问题最多列3条”,逼着它把最重要的问题排到前面。
3.4 第三步:每次只重构一个小点,并要求 AI 给出影响面分析
审查完拿到问题清单,接下来才是动手改。但这里有个极其重要的原则:千万不能让 AI 一次性重构一大堆东西。我用过更激进的方案——把整个模块让 AI 重写,结果一半业务逻辑在重写过程中被巧妙地“优化”掉了。从此以后,我只允许小步重构。
每次重构的提示词结构:
现在准备重构问题清单中的【某一条问题】。重构前先回答: 1. 影响面分析:这个改动会影响哪些调用方?哪些测试用例可能失败? 2. 重构方案:具体的改动点,保持原有逻辑不变的前提下 3. 列出你确认不会动到的部分 确认后,再输出重构代码,并运行相关测试验证。影响面分析这一步是强制性的。它逼着 AI 在动手之前先把“雷达”扫一圈,而不是一上来就埋头写。我测试过,如果跳过这一步,AI 改完代码后经常出现“这里引用变了但那边没有同步改”的情况。而有影响面分析后,它至少会主动检查调用方和测试,错误率明显下降。
提示:存量代码的重构目标是“让代码变好”,而不是“证明 AI 厉害”。每次改动越小,越容易回滚,越容易测试。哪怕一次只删掉一个重复分支,也比“把模块重写一遍”安全得多。
4. 把三个流程串成一天:一个可执行的日常节奏
4.1 早中晚怎么安排最省力
上面三个流程单独拿出来都能用,但把它们串在一起形成节奏,是我觉得效率提升最明显的地方。分享一个我目前比较顺畅的安排:
- 早上精力最好的时候处理存量代码的审查重构流,因为这段时间判断力最好,能做得住代码审查这种需要全局视野的工作。
- 上午十点左右进入新功能开发的结对编程流,这个流程最耗时间,但产出最直接,适合状态稳定时做。
- 下午做一些修改逻辑类的任务,用测试驱动的红绿循环流,因为这个时候注意力已经有点下降,把验证工作交给测试,自己不需要高度紧绷就能改代码。
工具上我推荐组合使用:编辑器内置的 AI(补全、生成小函数)负责日常编码,独立对话式 AI(处理多文件分析、方案设计)负责上面流程中的重活。前者依附于你正在编辑的文件上下文,后者能处理更大范围的项目分析。两种工具不冲突,反而互补。
4.2 三个流程中每个流程最关键的卡点
用久了之后,我把每个流程中最容易失败的关键卡点总结成了一张表,贴在桌面上提醒自己:
| 流程 | 最关键步骤 | 最容易出错的点 |
|---|---|---|
| 结对编程流 | 方案确认阶段 | 让人工确认方案后立即写代码,没有等到方案彻底定稿 |
| 测试驱动流 | 测试用例设计和审核 | 测试覆盖不深、AI 偷偷改测试 |
| 审查重构流 | 重构前的影响面分析 | 一次性改动过大、跳过影响面分析 |
这张表的价值不在于“记住了什么”,而在于每次启动流程前都手背提醒自己一下:我在使用的这个流程,最需要盯紧的是哪个环节。有了这张表,出错率会低很多。
4.3 什么时候不要用工作流
最后说一个反向的观点:工作流不是万能的,也不是所有任务都值得套流程。以我的经验,下面这几类情况直接用 AI 做“自由聊天”反而更好:
第一,非常小的改动,比如改个文案、加一个字段,10 秒钟的事。真走完整个流程反而浪费时间,AI 问三个问题后你自己改了都十遍了。
第二,探索性问题,比如“随便给一个实现方向看看”。这种时候我根本不会要求 AI 输出正式方案,直接对话聊思路就行,等方向明确了再启动正式流程。
第三,安全关键代码。比如支付、权限、数据删除这类核心逻辑,AI 可以参与分析和测试编写,但最终代码我会亲自手工审查和改,不会让 AI 直接改线上逻辑。这不是信不信任的问题,而是安全责任的边界必须清晰。
4.4 这个流程组合的实际收益
按这套组合跑了几个月,我的体感是:新功能从需求到代码的时间压缩了约三分之一,但最明显的不是速度,而是返工次数。以前改完代码走查时经常被同事挑出一堆边角问题,现在因为流程里自带“AI 自检”和“测试验证”环节,交给人的代码质量明显高了很多。同事经常问我“是不是偷偷找了外包”,其实就是流程的功劳。
当然也有局限。这套流程对“业务规则极其复杂、需要大量领域知识判断”的任务帮助有限,因为 AI 毕竟不掌握你说的隐性知识,比如“为什么这个老客户必须走折扣 A 而不是折扣 B”,这种规则你必须在方案阶段显式告诉它,否则它会自由发挥。所以在启动流程之前,你自己得先想清楚哪些约束是必须写进去的。
5. 最后再补充几个让流程效果翻倍的通用细节
三个流程之外,我还攒了一些通用的操作细节,无论哪个流程都适用,分享给你们。
第一,每段对话开始前都明确告诉 AI 你希望它以什么身份工作。比如“你是审查者”“你是结对编程搭档”“你是代码导游”,身份设定会显著影响输出风格。别小看这个操作,我自己试过,设置身份后输出的质量稳定性明显好于直接裸问。
第二,把自己的常用约束整理成一段固定的系统提示词,放在每个项目对话开头。比如“不要引入新依赖”“保持现有代码风格”“总是先输出分析再输出代码”。这段提示词相当于给 AI 立了工作章程,省得每次重复唠叨。
第三,善用“先写分析再写代码”这个通用规则。上面三个流程其实都踩在这条规则上:先分析需求、先写测试、先做影响面分析,然后再动手。AI 的输出质量本质上取决于它在动手前完成了多少推理步骤。你强制它先分析,它就多推理一步,输出质量就上一个台阶。
第四,每次关键时刻都让它“输出假设”。让 AI 在执行重要任务时列出它做的所有假设,然后你来一条条确认。很多 bug 的根源就是 AI 在某个隐藏假设上做了错误选择,但如果你不显式问它,它永远不会自己说出来。
这些细节看起来零零碎碎,但叠加在三个工作流之上,效果会是乘法而不是加法。我现在几乎每开一个 AI 会话都离不开它们,顺手就带上了。
我个人在实际操作中最大的体会是:这些工作流的本质不是“让 AI 更聪明”,而是“把不确定性前置成确定性”。当你能在提示词阶段明确边界、在测试阶段锁死行为、在审查阶段框住风险,AI 就不是一个随机输出代码的摸奖箱,而是一个有章法的协作对象。希望这三套流程和配套的提示词模板能真的帮你省下一些时间——我自己的时间就是这么省出来的。