☰
从执行者到决策者:AI Coding工作流实战复盘
2026/10/2 5:07:05 网站建设 项目流程

如果你现在的工作日常还是“把AI生成的代码粘进项目里,改改报错,能跑就提交”,那我劝你停下来,把这篇文章看完。半年多前我也是这么干的,直到有一次AI给我连着改了四版代码都没绕过那个边界条件,我才意识到我一直在当它的“人肉执行器”,而不是程序的拥有者。后来我慢慢把节奏调了过来:先用AI Coding铺路,再用产品思维拆需求,用架构师的眼光定边界,用测试和评审兜底。这半年最大的变化不是手速快了,而是我从执行者变成了决策者。

这篇文章没有什么高深的原理,就是把我这大半年的真实工作流、踩过的坑、以及我从“复制粘贴AI代码”到“指挥AI干活”的转型过程,完完整整讲给你听。适合那些正在用AI写代码、但总觉得代码不可控、不敢上生产、或者想进一步提升效率的同学。

1. 我到底用AI Coding干了什么:过去半年工作流的三个演变阶段

1.1 第一阶段的Copilot式补全:写代码像用输入法

最早我开始接触AI Coding,用的是编辑器里的代码补全类工具,比如GitHub Copilot。那会儿我的工作流很简单:写一个函数名,AI帮我把函数体补全;写一个SQL查询,AI自动帮我补齐where条件;写一个样板代码,AI直接给你整套。说实话,在写CRUD、配置类、重复性的胶水代码时,这工具简直像输入法一样顺滑,敲几个字母就能“联想”出大段内容。

但那个时候我只是把它当成加速器。我的角色依然是执行者——每一行代码都需要我读过、理解过、确认过,才能进代码库。AI补全了80%的冗余代码,我却还是要花100%的精力去review、调试、改边界条件。它真正能帮我节省的,只有敲键盘的时间,没节省任何思考的时间。

现在回头看,这个阶段的本质是“人机结对编程”,但主导权完全在我。我的大脑依然在处理每个变量、每个分支、每个异常。说实话,这个阶段对我的效率提升有限,顶多从“一天写200行”变成“一天写300行”,但我依然被代码细节绑架,根本腾不出手去关心业务逻辑、模块设计和系统演进。

1.2 第二阶段的对话式生成:从函数到模块的跨越

真正让我感觉到AI Coding价值上升的,是从“自动补全”过渡到“对话式生成”。我常用的方式是直接打开AI对话窗口,把需求描述给它:比如“帮我写一个将订单列表导出为CSV文件的函数,要考虑大文件内存问题,同时包含列映射配置”。它不再只补全一个函数体,而是能给我生成一个带注释、带依赖、带异常处理的完整模块。

这个阶段我开始产生一种错觉:AI已经能承担“写代码”的工作,我可以从执行者退一步了。于是我开始让AI生成接口、实体类、Mapper、Service,再批量贴进项目里。结果很快发现问题:生成的代码风格统一,但它对项目上下文的理解几乎为零。它不知道我的项目里已经有ToolUtil工具类,不知道公司内部框架的返回体是Result ,不知道数据库表里某些字段是枚举值存的还是字符串存的。

于是我被迫变成一个“翻译官”,把所有上下文手动塞进提示词里。经常一个任务要和AI来来回回对话十几轮,它每一次给出的代码还是会有几个地方不合我的项目预期。说实话,那段时间我对AI Coding是失望的,觉得它只能写面试题,不能写真实业务。现在想想,问题不在AI,而在我还在用执行者的身份跟它协作,没切换到决策者的角色。

1.3 第三阶段的Agent式协作:AI开始自己跑测试、改报错

转折点是后来出现的Agent式工具。所谓Agent式,就是它不只是生成一段代码等你复制,而是能拿到一个任务后自己读代码库、自己定位文件、自己改代码、自己跑测试、自己根据报错重试。早期我尝试过一些命令行Agent工具,也用过能直接操作工作区的IDE插件,比如Cursor的Agent模式、Cline、开源的Aider这类方案。

我第一次用Agent做需求的时候,给了它一个任务:“在订单模块中新增一个按状态筛选的列表方法,要求支持分页、排序、并补充单元测试。”我原本以为它会跟对话式AI一样只给出代码,结果它做了四件事:先搜索了订单模块现有的Repository和Service结构,然后在合适位置加入了新方法,再调用项目里的分页工具类,最后还补了一个测试并执行了。整个过程我只看了几眼输出日志,它自己把编译错误改掉了。

那一刻我开始明白,AI Coding的进化方向不是“更聪明的代码生成器”,而是“能独立执行任务的数字员工”。也正是从那一刻起,我的角色被彻底推向了决策者:我不需要决定这个方法内部怎么写,我需要决定的是——这个需求该不该做、做成什么样子、怎么验收、哪些边界条件不能让步。

2. 执行者时期的真实状态:AI代码“能用但不敢用”的坑

如果你也和我以前一样,处于“AI写代码、我负责复制粘贴”的阶段,下面这几个坑大概率你都踩过。我不是劝你少用AI,而是想让你知道,执行者视角下的AI Coding,效率再高也掩盖不了质量风险。

2.1 最大的问题不是代码质量,而是“我不知道它在干什么”

很多人吐槽AI生成的代码没有质量,但我的真实体会是:最大的问题不在于代码写得烂,而在于我完全不理解它为什么要这么写。举个例子,我让AI写一个Redis分布式锁的工具类,它给我生成的代码里加了一个自旋等待循环。代码能跑,功能也对,但我无法回答以下问题:自旋时间为什么是100毫秒?如果锁等待时间超过30秒怎么办?这个循环会不会导致CPU占用过高?

如果是自己手写的代码,我会知道每一个特殊分支都是从哪些业务场景里推出来的。但AI写出来的代码,我只能看到一个“合理”的成品,却看不到背后的取舍过程。这就导致当业务场景变化时,我根本不敢去改它的代码,因为我不知道改了以后会破坏掉什么隐含逻辑。这种“不敢动”的状态,比“不会写”更可怕。

在这个阶段,我逐渐意识到:AI执行得越多,我对系统的理解就越稀薄。我以前是代码的主人,后来变成了代码的搬运工,再这样下去,整个项目的知识会变成一块块黑盒。这不是效率问题,是生存问题。

2.2 上下文窗口幻觉:AI会一本正经地编造不存在的API

第二个大坑是AI的幻觉问题。它不是在“查资料”,而是根据概率生成最像样的代码。所以它的输出里经常混着一些看起来合理、实际不存在的API。我有一次让它对接某个第三方支付网关的退款接口,它给我写出一个PaymentClient.createRefundWithAutoRetry方法,还附带了参数注释。结果我在依赖包里翻了半天,根本没这个方法,实际接口是RefundService.submitRefund。

这种幻觉在执行者阶段特别致命,因为执行者的习惯是“代码能跑就行”。每当AI给出一个不存在的方法,编译器会直接报错,报错后你可能习惯性让AI继续修,它修的时候可能会引入更多虚构依赖,陷入死循环。有多少人曾经被AI带偏,去安装一个根本不存在的npm包?我在网上见过有人让AI生成图片处理代码,结果AI建议安装一个虚假的第三方库,那个库实际是一个恶意包。幸好我用了公司内部的镜像源才没中招。

面对幻觉,执行者只会抱怨AI不靠谱;决策者则会要求自己先建立“接口事实清单”,把需要使用到的第三方SDK、内部工具类的真实签名列出来,再喂给AI。你越是在一个盘根错节的老项目里,越不能依赖AI对你项目内容的“猜测”。

2.3 维护成本的隐性炸弹:生成代码的债,最后都要自己还

再聊一个很多AI Coding实践者不敢承认的事实:生成代码很爽,但维护代码很苦。我以前让AI帮我写了一个报表导出功能,它洋洋洒洒生成了300多行代码,包含多层嵌套循环、动态拼接SQL、以及一个复杂的映射表。当时跑起来一切正常,我也觉得很开心。两个月后,业务要求增加一个过滤条件,我拆那个方法拆了整整一个下午。

原因很简单,AI写代码时没有“未来三个月后会有另一个人来维护”的概念。它的代码风格是模块化也好、命名规范也好,但对业务逻辑的抽象方式,往往是过于局部、过于具体。它不会为了未来的扩展性去预留接口,更不会为了可读性去牺牲一点执行效率。这些债务在生成的那一刻就已经注入了,只不过要等到需求变更时才会爆炸。

执行者最危险的状态,就是把AI当成“免维护的队友”。实际上你每一次让AI写代码,都是在签发一张远期支票,还款人是你自己。所以后来我给自己定了一条规矩:凡是AI生成的核心逻辑,我必须自己完整重读一遍,并且画出它的流程,确保下一个人(包括未来的我)能看懂。

3. 逼我从执行者变成决策者的三个转折点

说了这么多坑,那到底什么契机让我真正转变?不是看了某篇文章,也不是听了某场演讲,而是三个真实到骨子里的项目经历,一次一次把“执行者心态”打碎重组,我才被迫站到了决策者的位置。

3.1 第一次:AI连续改了四版,还是没绕过那个边界条件

第一个转折点来自一个权限过滤需求。我希望实现“普通用户只能看到自己的订单,管理员能看到全部订单”。很简单的功能对吧?我让AI去改一个查询列表的接口,AI给了第一版,实现了WHERE user_id = ?,我把需求补了一句“管理员除外”,它改成if (isAdmin) 不添加过滤条件。看起来没问题,但测试时发现如果普通用户传了userId=另一个用户ID作为查询参数,它依然把别人的订单查出来了。

我又让AI修正:要求服务端强制使用当前登录用户ID,忽略客户端传入的用户ID。AI给了第二版,确实强制覆盖了。但管理员模式下,它用当前管理员ID去做数据范围判断,导致管理员只能看到属于自己ID的订单。我又让它改成“管理员不追加用户ID过滤”,它给了第三版。结果管理员搜索指定用户订单时,其它用户的订单又全都漏出来了。

前前后后我改了四版,每一步都像是在打地鼠。我终于意识到,问题根本不在AI的代码能力,而在我自己根本没有把需求定义清楚。我一直用“实现功能”的方式在描述任务,但没有把“角色、数据范围、参数来源、异常输入”这些决策项固化成一条不可违背的规则。当规则不清晰时,AI只能猜,猜就得靠运气,运气不好就会反复翻车。从那一刻起,我开始要求自己先把需求变成决策树,再让AI去实现。

3.2 第二次:我把任务描述从“实现功能”改成“满足验收条件”

第二个转折点是我调整了给AI下任务的方式。以前我写提示词都是“实现一个用户注册接口”,后来我改为“实现一个用户注册接口,并在以下条件下返回特定状态码:手机号格式非法时返回400;手机号已存在时返回409;验证码错误时返回403;成功时返回200并附带用户摘要”。

第一次这样写的时候,我明显感觉AI的产出质量跳了一档。它不再是自由发挥,而是在一组验收条件内做选择。更关键的是,为了满足这些条件,它自己会去设计校验逻辑、异常分支、状态码映射,而这些以前都需要我事后手动补。

这个过程让我彻底想明白:“实现功能”是执行者思维,“满足验收条件”是决策者思维。验收条件本质上就是你对系统行为的定义。你定义得越精确,AI的执行越有方向。那天之后,我不再花时间写“具体怎么实现”,我开始花时间写“怎么算完成”。代码怎么写,AI发挥;要求怎么定,我来。

3.3 第三次:让AI写测试用例,反向纠正了我自己的需求漏洞

第三个转折点更意外。有一次我让AI帮我为一个复杂订单折扣计算逻辑写单元测试。我原以为它只是把我口述的几条用例转成JUnit测试,结果它生成的测试里有一条我完全没想到的场景:折扣券和会员折扣同时生效时,两个折扣率是直接叠加还是先算一个再算另一个。

我一看这个测试就愣住了,因为我从来只想到“叠加”和“取最大值”两种情况,完全没想过“叠加的顺序”。那条测试直接暴露了我需求里的未定义区域。我去产品和业务那边确认,业务自己也没想清楚,最后我们补了一条规则:先算会员折扣,再对折后金额使用折扣券。也就是说,是AI生成的测试倒逼我把需求漏洞补上了。

如果没有这个转折,我那套折扣逻辑上线后大概率会在某个用户组合下算错,而且一时半会儿测不出来。这次经历让我对测试的认知完全刷新:测试不再只是验证代码的工具,而是把需求变成可验证契约的过程。我作为决策者的核心职责,就是维护这份契约。AI可以帮我生成大量测试样例,但它必须由我来审,因为是它发现了我没想到的维度。

4. 我现在的工作方法:决策者的四层拆解框架

经过这几次折腾,我总结了一套自己用了大半年的工作方法。每次接到一个需求,我不再直接打开编辑器,而是先做四层拆解。这套框架不复杂,但确实让我的AI Coding从“碰运气”变成了“可交付”。

4.1 第一层:目标定义——把“做什么”翻译成“可验证的结果”

这是最关键的一层,也是执行者和决策者之间最明显的分界线。目标定义不是一句话需求,而是把“做某事”翻译成一组可以跑起来验证的结果。

举个例子,如果一个普通开发者听到“给订单列表加分页”,他心里想的是“查数据库时加上limit和offset”。但如果是我现在来定义,我会写成:

  • 当page=1时,返回前20条订单,按创建时间倒序;
  • 响应体中必须包含total(总订单数)、hasMore(是否还有下一页)、items(当前页数组);
  • 当page小于1时,后端按1处理;
  • 当超过最大页数时,返回空数组但hasMore为false。

当我给AI输入的是这样的目标定义时,它几乎不会跑偏。因为所有它可能自由发挥的关键分叉点,都被我提前锁死了。当然,并不是所有需求都需要定义得这么细,但是对于关键业务逻辑和对外接口,这个功夫绝对不能省。

4.2 第二层:边界圈定——明确AI不能碰的部分

目标定义完之后,我还会单独写一段“边界约束”,明确告诉AI哪些地方不允许AI发挥。如果我说“这里调用公司内部的SensitiveDataUtil工具类做脱敏”,那AI就没有任何理由自己写一段正则去脱敏;如果我说“所有数据库操作必须走现有的BaseRepository”,那AI就不能图省事直接用JdbcTemplate。

为什么要做这一步?因为AI在追求“完成功能”时,倾向于选择它训练数据里最常见的实现路径,而不是你项目里已经存在的惯例。你在边界约束里每多写一条“不能碰”,AI就会少一个机会在核心代码上放飞自我。

边界圈定还要包括“人机责任边界”。比如密钥管理、支付回调验签、数据迁移脚本这类敏感或一次性操作,我通常直接自己写,不让AI碰。这些代码出错成本太高,AI试错的机会成本不可接受。作为决策者,你要清楚哪些可以交给AI试错,哪些必须人来兜底。

4.3 第三层:验收标准——用测试和人工评审兜底

目标定义再清晰,AI也可能在实现时出幺蛾子,所以验收标准必须前置写进提示词里,不能等代码写完再想。我自己最常用的验收标准有三个级别:

验收级别验收动作通过标准
级别一编译与静态检查项目可以正常构建,没有新增编译器警告,主要依赖锁定在pom/package.json中
级别二单元测试与边界用例关键逻辑覆盖正常、异常、边界三条路径,全部测试通过
级别三人工审查核心契约我亲自review接口行为,确认异常处理、权限校验、日志记录都符合约定

这里尤其要说一下第三级。人工评审不是把AI生成的代码从头到尾读一遍,而是回到接口契约层面去审:入参出参是否和行为定义一致?异常是否需要被捕获还是应该抛出?并发场景是否被人为忽略了?这种评审比逐行读代码快得多,而且更能发现问题。

4.4 第四层:反馈循环——带着结果复盘的决策闭环

最后一层是闭环。任务交付完之后,我会记录两件事:一是AI生成过程中返工过几次,返工的原因是需求定义不清还是AI能力不足;二是我在评审中发现哪些高频问题,比如AI总是不处理空列表、总是忘记幂等控制、总是直接用魔鬼数字。

带着这些记录,我会不断更新我给AI下达任务的模板。现在我常用的提示词模板里已经默认加入了几个约束:“不要假设输入非空,请显式处理null值”“不要在业务代码里直接创建线程池”“所有外部调用必须加超时时间”。这些规则不是哪本AI编程书教我的,是我在一次又一次反馈循环里沉淀出来的。

决策者的优势就在这:你不是给AI派一个任务就结束了,你会带着每次的真实结果去调整下一步的决策质量。你的判断越来越准,AI的执行也越来越高效,整个系统是持续进化而不是原地打转的。

5. 决策者的技能迁移:我花大半年才想明白的评审技巧

身份转变之后,我最直接的感受是:以前我的核心技能是“写代码”,现在我的核心技能是“评审AI写的代码”。但这里的“评审”跟传统代码评审完全不是一回事。

5.1 代码评审从“读代码”变成“审接口契约”

传统代码评审里,我会一行一行看变量命名、循环逻辑,甚至挑缩进风格。但AI生成的代码如果不符风格,一键格式化就好了,逐行看它没有意义。真正需要关注的是AI有没有实现接口契约。

比如,一个获取用户信息的接口,我的契约是“输入userId,输出用户脱敏信息;如果用户不存在,返回null但不抛异常;如果userId为空,直接抛参数异常”。评审的时候我就检查AI生成的代码是否遵守这三个行为,而不必关心它是用Optional还是用if判断。

我还养成了一个习惯:在review AI代码时先看它的测试,再看实现。因为AI生成的测试反映了它对需求的理解。如果测试里没有覆盖“用户不存在”这种分支,我就要警觉,它可能根本没考虑这个场景。这时候我不需要去改代码,我只需要补充一条验收条件,让AI自己把测试和实现补上。这个方法论用熟了以后,我每天的代码评审时间反而比过去减少了30%,因为AI的大部分机械错误在自带测试阶段就被干掉了。

5.2 架构决策必须提前,AI不会替你作权衡

“让AI写代码,自己做架构”听起来很容易,但真正做到需要很强的克制力。AI最擅长的,是在你给定的模块边界内快速生成实现。但如果模块边界本身画错了,AI生成得越快,后患越大。

我就犯过这个错。有一次我让AI写一个报表模块的存储层,它默认使用了JDBC加手写SQL,因为它觉得这样“直接、简单”。可当时我们项目里已经启用了JPA,统一了事务和审计字段。后来为了接入自定义审计日志,我把那部分代码全部重写了。问题不在AI的选择是错的,而在于AI根本不知道整个系统未来要朝哪个方向演进,它只会选“最容易写”的方案,不会选“最不后悔”的方案。

所以现在我每次动手之前,都会先把模块的依赖方向定死:上层接口长什么样,下层数据仓库用什么规范,领域对象要不要跨层传递。我甚至会把整体结构写成注释放在提示词里,告诉AI“这是既定设计,你只负责填充实现”。这个习惯让我把AI的能力牢牢锁在可控范围内。

5.3 兜底思维:你始终要为AI的结果负最终责任

还有一件事是我反复提醒自己的:不管AI Coding再怎么进化,线上出故障的时候,老板和客户找的是我,不是AI。所以我的兜底思维永远在线。

具体来说,我会给所有AI生成的核心代码做两件事。第一,强制掌握核心路径:比如如果AI生成了密码加密的逻辑,我哪怕不自己写,也必须能徒手画出一个加解密流程图,并指出密钥存储在哪个配置项、是否落盘、轮换怎么处理。第二,给AI生成逻辑外圈加保护:比如在AI实现的方法入口加上参数校验,在调用外部服务时统一包一层超时和重试,在写入数据库前增加幂等判断。我不要求AI自己考虑这些,因为我的兜底责任本来就不在AI那边。

如果你也想完成从执行者到决策者的转变,这里最关键的心理建设就是:不要再对着AI的代码高呼“它写得真好”或痛骂“它写得好烂”。你应该把它当成一个执行力很强、但全局判断力为零的初级工程师,你的价值就是给它划好跑道,并负起最终责任。

6. 如果你也想从执行者变成决策者:一条可复制的路径

最后聊点实在的,如果你已经被我说动了,想开始尝试跳出“复制粘贴”模式,我给你一条我自己验证过、身边几个同事也在用的路径。它不是玄学,全是粗糙但有效的实操。

6.1 先别急着上Agent,从单文件重构开始练手

我看到很多人看完Agent演示视频以后,直接把整个项目的核心模块丢给AI,让它自己改。这跟让刚拿驾照的人直接上高速没有区别。我的建议是先拿一个你完全熟悉的、没有依赖复杂度的单文件做练习,比如把一个工具类里的重复代码重构为通用方法。

之所以强调“你完全熟悉”,是因为你要有能力判断AI每一步是对是错。只有当你对原始代码了如指掌时,你才能快速建立“AI生成的代码是否存在行为变化”的感知力。等你连这种单文件重构都能轻松驾驭,对AI的输出质量和偏差模式有了体感,再逐步扩大到多文件模块、再到Agent式任务。进度慢一点没关系,这个阶段的核心是建立你自己的判断标准。

6.2 给AI写提示词的进阶心法:说结果,不说过程

很多人的提示词之所以翻车,是因为他把自己脑子里的过程一股脑塞给AI,比如“先建一个DTO、然后写一个Controller、再调Service、最后用MyBatis查库”。这种做法不是不行,但会严重浪费AI的灵活性。AI看的是你的步骤,不是你的目标;一旦你中间有一句话描述偏了,后面的实现就会跟着偏。

更好的方式是这样:先描述输入和输出,再描述约束条件,最后补充几条具体的验收用例。比如:“写一个订单取消接口。输入:订单ID、操作人ID、取消原因;输出:取消成功返回true,订单不存在返回false,已发货订单返回异常。约束:需要记录取消日志。验收用例:未付款订单取消成功;已发货订单取消抛异常。” 你会发现AI给出的实现路径往往比你预想的更简洁,因为它会在约束空间里自己找最优解。

6.3 建立自己的AI代码评审清单

不要每次都用感觉来评审AI代码,一定要形成清单。我目前的个人清单大约十条,每一条都是踩坑踩出来的,分享给你做个参考:

  • 是否直接使用了硬编码的密钥、IP、数据库地址?
  • 是否有不必要的第三方依赖被引入?
  • 是否考虑了空集合、null参数和极端大输入?
  • 异常是吞掉了还是转换成了合理错误码?
  • 是否对耗时外部操作设置了超时控制?
  • 是否在循环里执行了数据库查询或远程调用?
  • 权限相关逻辑是否放在了Controller层而不是Service层?
  • 生成的日志级别是否合适,有没有打印敏感字段?
  • 是否按要求复用了项目现有的工具类和设计模式?
  • 是否补了单元测试,测试是否覆盖了边界路径?

这条清单我每隔一段时间就会往里面加一条。它不是固定的,而是活的。你也可以从十条开始,慢慢沉淀出适合自己的版本。

6.4 什么情况下应该果断放弃AI,手写更快

最后还要说一个反直觉的经验:我虽然大量使用AI Coding,但几乎每周都会遇到“我应该自己写”的场景。这类场景通常有几个特征:性能调优的细粒度代码,比如一段需要极致优化的热路径算法;深度框架定制,比如要继承某个框架的内部类并改写核心回调;强一致性的分布式事务代码,这种地方AI很难理解你对时序和补偿的要求;以及任何涉及合规审计的逻辑,比如日志脱敏、权限越权判定。在这些场景里,AI顶多当一个参考资料生成器,核心代码请自己写。

我自己现在的决策标准是:如果这个模块后续迭代频率高、或者出错会造成重大影响,那我宁愿自己把骨架搭好,再让AI去填充那些不太重要的部分。如果模块本身是低风险、独立、一次性使用,那整个交给AI都没问题。这种“分而治之”的决策能力,也算是我这半年最大的收获之一。

说实话,从执行者到决策者的转变并不容易,它需要你暂时放下“手写代码的安全感”,去拥抱“定义需求的掌控感”。这半年里我有过很多次不适应,甚至有一阵子觉得AI让我变成了一个只会提需求的“假开发”。但后来我想通了:工具替我把代码敲出来,不等于工具替我把架构想清楚,也不等于工具替我对线上负责。真正的核心竞争力,永远是你判断“什么是对的”的能力。

这半年我自己的体会是,现在我和AI的关系,更像是一个技术负责人和它的程序员员工。我会花很多时间把为什么、边界、验收条件解释清楚,然后看着它把代码交付出来,再亲自签字验收。有时候它做得好,我赞美它;有时候它犯低级错误,我会回头反思:是不是我又少定义了某个边界条件。AI Coding大半年,键盘敲得越来越少,脑子用得越来越多。我不再执着于每一行都出自我的手,而是执着于每一段代码都在我的掌控之中。这个转变,可能才是AI时代程序员最该跨出的一步。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询