看到一份提交记录里八成以上的代码都带着AI补全的痕迹,不少人的第一反应是"效率真高",第二反应是"那还要我干嘛"。更有意思的是,喊出"代码80%由AI产出"的,恰恰是做AI的那家公司自己,转头却又有人说要放慢AI开发的节奏。这两件事放一起看,其实一点都不矛盾——写出代码和写出能长期维护的代码,从来是两回事。我做过不少带AI参与的开发项目,也踩过一堆看起来很聪明的坑,这篇就把"代码由AI写"这件事拆开讲:它到底覆盖了哪些环节、ai编程和ai agent开发在实际项目里怎么用、哪些地方最容易翻车、以及怎么把AI产出稳妥地塞进工程体系里。不管你是刚接触ai大模型应用开发的新人,还是已经在用ai开发做日常工作的老手,下面这些经验应该都能直接拿去用。
1. "80%的代码由AI生成"这句话,口径比结论更重要
先把最容易误解的地方说清楚:当一个团队说"80%的代码是AI写的",它统计的往往不是"80%的功能由AI独立完成",而是"80%的字符/行由模型补全或生成"。这两者之间的差距,可能比你想象的大得多。业务逻辑怎么拆、模块边界怎么划、异常怎么兜底、上线后怎么回滚,这些没人替你做决策。
1.1 三种常见的统计口径,结果能差出一倍
我见过团队用完全不同的方式算这个比例,结论天差地别:
| 统计口径 | 典型数值 | 说明 |
|---|---|---|
| 补全接受率 | 30%-50% | 编辑器里弹出建议被采纳的比例,含大量重复模板 |
| 提交行归属 | 60%-85% | 按行追溯由AI生成,包含大量getter、配置、样板代码 |
| 需求决策占比 | 5%-20% | 真正决定"写什么、怎么分层"的比重,人依旧主导 |
所以我更愿意这样理解那句标题:AI把"敲键盘"这件事承接走了八成,但"想清楚要敲什么"这件事,人还得负八成以上的责任。理解了这一点,你再看"要不要暂停AI开发"的讨论,就会发现它讨论的不是工具本身,而是当产出速度远超人类审查速度时,风险怎么兜住。
1.2 为什么比例能这么高,却依然离不开人
原因很朴素:现代软件工程里,真正有决策密度的代码占比本来就不高。一个业务功能里,接口定义、数据转换、参数校验、日志埋点、异常处理、单元测试脚手架——这些占了大量行数,但模式高度固定,正是模型最擅长的部分。真正难的是那不到两成的核心逻辑:状态机怎么设计、并发怎么保证、超时和重试的边界在哪、数据一致性靠什么保证。
提示:判断一段代码能不能放心交给AI,有个简单标准——如果这段逻辑你能用三句话讲清输入输出和异常行为,它大概率可以被AI胜任;如果讲了十分钟还没说清边界,那说明你自己都还没想明白,先别让AI接手。
1.3 "暂停"的呼声,对一线开发者其实是提醒
抛开观点之争,这类讨论对写代码的人只有一个实际意义:速度红利已经到手,接下来拼的是治理能力。工具让产出快了,但评审、测试、依赖管理、安全扫描这些环节并没有同等提速,于是瓶颈就从"写得慢"变成了"审不过来"。我后来给自己项目定了个土规矩:AI产出的代码量每上一个台阶,测试覆盖和审查强度必须跟着上一个台阶,否则宁可压着不让合。这条规矩救过我至少两次。
2. AI编码工具在我日常流程里的真实站位
很多人对ai编程工具的想象是"描述需求,它给你一个完整项目"。真跑起来你会发现,它的强项和弱项分布得极其不均匀。用对了位置,它是加速器;用错了位置,它是返工制造机。
2.1 从补全到智能体:三种形态各自适合什么活
现在市面上主流有三类用法,我几乎每天都在混用,但绝不在同一个环节瞎换:
- 行内补全:最适合写重复模式,比如数据类的字段映射、序列化和反序列化、CRUD样板。它的优势是"不打断思路",你手不停,它把机械活填了。
- 对话式生成:适合"给我一个示例代码,演示某库怎么用"。这里要特别小心,因为它最容易一本正经地编造API。我的习惯是拿到示例代码后先做一件事——去官方文档核对函数签名,再跑。
- 智能体式开发(ai agent开发):适合跨文件的小改造,比如"给这个模块的所有公开函数补上参数校验和注释"。它能读多个文件、批量修改,但也最容易改出连锁问题,必须在小范围、有测试的前提下用。
注意:智能体一次改动的文件越多,你审查的成本越接近"重新读一遍整个模块"。我一般把单次改动控制在3个文件以内,超过就拆任务。
2.2 需求拆解阶段:先要设计草案,不要直接要代码
这是我最想强调的一条经验。直接让AI"写一个xxx功能",你拿到的是能跑但结构随机的代码;先让它给出接口设计和数据流草案,你再改,拿到的才是能长期维护的东西。
我的固定开场是这样的:
我在做一个[功能描述],技术栈是[语言+框架]。 先不要写实现代码,请帮我: 1. 拆出需要哪几个模块/类/函数,各自职责是什么 2. 定义关键的输入输出数据结构 3. 指出这个设计里最容易出问题的边界条件 4. 给出接口签名(只要签名和注释,不要方法体)拿到草案我会自己过一遍,砍掉过度设计,再让它逐个接口填实现。这样出来的代码,我基本能预测它长什么样,审查速度快很多。
2.3 提示词怎么写,才能拿到"能跑"的代码
模型给的代码质量,七成取决于你的提示词里塞了多少约束。我总结了一张自己常用的清单:
| 约束类型 | 写法示例 | 作用 |
|---|---|---|
| 技术栈锁定 | "只用标准库和 xxx 1.2 版本" | 防止它用幻觉API或过时写法 |
| 输入输出明确 | "输入是字符串列表,输出是去重后的有序列表" | 减少猜错语义 |
| 异常要求 | "网络失败要抛出自定义异常,不要吞掉" | 补上它默认会省掉的错误处理 |
| 风格要求 | "不要写全局变量,日志统一用logging" | 让它贴合项目规范 |
| 反例约束 | "不要用递归,数据量可能很大" | 提前堵住错误方案 |
这套清单用熟之后,我返工率至少降了一半。核心就一句话:把模型当成一个聪明但完全不了解你项目的新同事,你不说清楚的,它一定会用最省事的方式糊过去。
2.4 拿AI读老代码,比拿它写新代码更值
这一点很多人没想到。面对一个没人维护的祖传模块,我会把关键文件喂给模型,让它做三件事:画调用关系、解释每个函数的真实副作用、标出它认为可疑的分支。它偶尔会读错,但能帮我定位到"这段代码到底在干嘛",比自己一行行啃快太多。读老代码是纯理解任务,不产出新风险,是AI最安全的用法之一。
3. 那八成AI产出的代码,最容易在哪几处翻车
前面讲了怎么用,这一节讲讲怎么不被它坑。我把踩过的坑按发生频率排了个序,都是一线实录。
3.1 幻觉接口:最经典、也最容易被忽略
模型会凭空造出看起来非常合理的函数名和参数。比如某个库根本没有client.query_async_with_retry()这个方法,它写得有模有样,还贴心地加了注释。如果你不核对文档直接跑,报错还算好的,怕的是它编出了一个同名的、语义完全不同的方法。
我的防坑流程固定为三步:先在项目里全局搜索这个函数名,确认是不是已有封装;再去官方文档或源码确认签名;最后写一个最小调用跑通。这三步加起来不超过两分钟,能省掉后面半小时的调试。
3.2 "看起来对"的假象:边界和异常被悄悄省掉
最常见的是空值、空集合、除零、超长输入、并发这些分支被默认省略。因为训练数据里大量示例代码本身就没处理异常,模型学到的就是"happy path"。解决办法是审查时专门盯四件事:
- 输入为空或None时会发生什么
- 网络/IO失败的路径有没有处理
- 循环里的边界会不会越界
- 数值运算有没有除零和溢出风险
我会在提示词里强制要求它"列出这段代码没有处理的异常情况",然后逐个确认。这个动作能让它自己暴露出省略的部分。
3.3 安全问题是重灾区,这几类尤其要查
AI写的代码在安全上经常有固定的几类隐患,我列出来供你对照:
- 字符串拼接SQL:它很爱用f-string拼查询语句,直接埋下注入风险。
- 硬编码密钥:示例代码里塞个假的token,改着改着忘了替换。
- 不校验的输入直接执行:比如把用户输入当命令或表达式执行。
- 弱哈希与不安全随机数:密码场景用普通哈希,令牌用可预测的随机源。
- 不设超时的网络请求:某次下游卡住,整个服务被拖死。
注意:凡是AI产出的、涉及外部输入、认证、加密、文件路径的代码,一律按"高危"处理,必须人工逐行过。这不是不信任模型,是这几类错误的代价太高。
3.4 依赖与许可:被忽略的隐性成本
模型推荐一个"很好用的第三方库"时,它不会告诉你这库多久没更新了、许可证是什么、社区活跃度如何。我吃过一次亏:按建议引入了个小众库,后来发现半年没提交、issue堆了一堆,最后不得不自己重写替换。现在我的习惯是,引入任何AI推荐的依赖前,先查三件事——最近一次发布是什么时候、star和issue趋势如何、许可证是否和项目兼容。
3.5 一次完整的排查链路,演示思路怎么走
说个真实场景。某天线上接口偶尔超时,日志只报了一个泛泛的timeout,代码是AI生成的。我的排查顺序是这样的:
第一步,定位改动范围。用版本记录找出最近这次功能提交里AI参与的部分,圈定嫌疑文件。
第二步,读调用链。让模型帮我梳理这个接口从入口到数据库的完整调用路径,标出所有可能阻塞的点。
第三步,发现根因。链路里有个重试逻辑,是AI写的,它在失败后立即重试、没有退避、也没有总超时控制,下游一抖动就叠加放大,雪崩式拖慢。
第四步,修复并验证。改成指数退避加最大重试次数和总超时,补上单元测试模拟抖动场景,压测确认。
第五步,举一反三。把"重试必须带退避和上限"写进团队的提示词模板和审查清单,防止同类问题再犯。
整个过程最关键的不是修那几行,而是最后一步——把一次翻车沉淀成规则。AI产出比例越高,这种沉淀越重要。
4. 把AI产出的代码安稳纳入工程体系
工具是快,但工程体系不跟着升级,快出来的东西迟早要还回去。下面是我在项目里实际落地的一套做法。
4.1 让测试成为AI代码的第一道闸门
我给AI产出的代码定的规矩是:没有测试就不许合入,而且测试要能覆盖我关心的边界,不是走个过场。具体操作上,我会让模型先根据接口签名生成测试骨架,然后自己补齐这些用例——正常输入、空输入、极值输入、异常路径。骨架它写,用例我来审,效率和质量都保住了。
一个小技巧:让模型同时生成"应该通过的用例"和"应该失败的用例"。很多AI代码的错误恰恰藏在它认为不会出错的路径上,反向用例能逼出来。
4.2 针对AI代码的专项审查清单
普通审查看逻辑,AI代码审查还得加几项"体检"。我把清单贴在团队里,每次提交对照打勾:
| 检查项 | 关注点 |
|---|---|
| 接口真实性 | 所有调用的库函数是否真实存在、签名正确 |
| 异常完整性 | 空值、超时、失败路径是否覆盖 |
| 安全基线 | 注入、密钥、随机数、路径拼接 |
| 依赖健康 | 新增依赖的维护状态与许可证 |
| 可读性 | 有没有过度嵌套、复制粘贴的重复块 |
| 一致性 | 命名、日志、错误码是否符合项目约定 |
这份单子看起来啰嗦,但每一条都对应过一次真实事故,性价比极高。
4.3 提示词和上下文,应该当成团队资产来管
个人用AI靠手感,团队用AI必须靠资产。我们做了一件很值的事:把常用的提示词模板、项目结构说明、编码规范、常见错误清单整理成一份"上下文包",任何人用AI开发时先把它喂进去。效果立竿见影——不同人生成的代码风格趋同了,幻觉API少了,审查也轻了。这份上下文包还会随每次踩坑不断更新,本质上是把团队经验固化下来。
4.4 私有化部署还是直接用云端,看数据敏感度
涉及敏感数据的项目,我会倾向本地部署模型,虽然效果可能略逊,但数据不出内网这条红线不能碰。纯公开代码、脱敏数据的项目,用云端服务更快更省。这个取舍没有标准答案,判断标准就一条:这段代码和数据,泄露出去会不会有实质损失。会,就本地;不会,就怎么高效怎么来。
5. AI参与之后,开发者的能力结构在悄悄变形
工具改变的不只是效率,还有"什么样的人算会写代码"。这几年带人、自己写代码,我观察到的变化挺明显。
5.1 从"会写"到"会判断",重心整体后移
以前评价一个开发者,很大程度看他能不能手写出干净高效的功能。现在这件事模型能代劳一大半,真正的分水岭变成了判断力:这段代码是否有隐患、这个设计是否能扩展、这个依赖该不该引、这个需求是不是本来就理解错了。会写的人很多,能一眼看出问题的人稀缺。所以我给自己的投入方向也变了——花更多时间读源码、读事故报告、读优秀项目设计,而不是背语法。
5.2 新人还要不要从基础语法啃起
要,但方式得变。我见过两种新人:一种完全依赖AI,代码能跑但说不清为什么;另一种坚持手写每行代码,效率低但基础扎实。前者短期快,后期一旦遇到模型没见过的复杂问题就卡死;后者虽然慢,但判断力长得稳。我的建议是,基础语法和数据结构该练还得练,但要配合一个动作——AI写的每段代码,都逼自己讲清楚它的执行过程和潜在问题。能讲清楚,才算真的过了这道题。
5.3 团队协作和知识沉淀的新做法
AI让个人产能上去了,团队层面却容易出现新问题:每个人都在用,但用法不统一,代码风格和风险水平参差不齐。我们的应对是把经验显性化——统一的提示词资产、统一的审查清单、定期的踩坑分享。每周抽十分钟,谁被AI坑了就把案例讲一遍,更新进清单。看着不起眼,坚持半年后团队整体的返工率明显下降。
6. 关于"要不要慢一点",我的一点实操体会
回到那个标题里的争论。工具本身没有立场,快慢也不是目的,能不能稳住质量才是。AI把80%的键盘活接走之后,真正决定项目生死的,恰恰是剩下那20%——你怎么审、怎么测、怎么把一次次翻车变成规则、怎么让团队所有人用同一套标准。我在实际使用中的体会是:别急着追产出速度,先把审查和测试这两条地基铺厚,AI带来的加速才是净收益,否则只是把债提前借了。
最后分享一个我认为最值的小习惯:每次让AI生成代码之前,我会先在心里(或者纸上)回答一句"这段代码出错的话,最可能错在哪"。带着这个问题去看产出,命中率往往高得吓人。工具会越来越强,但"知道该怀疑什么",是它短期内还给不了你的东西,也是行情变化里最保值的那部分能力。