这个标题的第一反应是:一个写了 20 年代码的老程序员,按理说应该是最拥抱 AI 的那批人,为什么反而选择卸载 AI?
如果点进这篇文章是想看“老程序员被时代抛弃”的桥段,可能要失望了。从他的复盘来看,这个决定不算情绪化,反而非常工程化:他卸载的不是 AI 工具本身,而是“AI 自动补全直接进代码库”这套工作流。不信任的也不是大模型的回答能力,而是 AI 生成的代码在真实业务里的可维护性、确定性和安全边界。
这篇文章我会用技术评论的方式,拆解三个问题:他到底卸载了什么、卸载前做了哪些验证、AI 编程工具的真实边界在哪里。最后会给出适合团队落地的 AI 编程建议、代码审查清单和排查方法。
如果你最近也在纠结“用 AI 写代码到底省不省心”“团队引入 AI 之后代码质量有没有下降”,这篇文章可以直接收藏。
1. 核心结论速览
先把他的结论放在最前面,后面再展开细节。
| 维度 | 结论 |
|---|---|
| 是否彻底不用 AI | 不是。他保留了一批低风险场景,卸载的是高风险自动生成链路 |
| 核心原因 | AI 生成代码的“第一眼质量”和“半年后维护质量”严重脱节 |
| 卸载对象 | IDE 自动补全、AI 直接生成生产代码、AI Agent 自动改业务逻辑 |
| 保留对象 | 技术调研、注释文档、测试用例、一次性脚本、正则/文本处理 |
| 判断标准 | 代码是否有明确、可快速验证的正确性标准 |
| 最容易踩的坑 | 把“快速产出”误当成“质量提升”,把 AI 当终审而不是初筛 |
| 可参考的落地策略 | 按风险分层使用 AI,生产代码禁止 AI 直接落地 |
一句话总结:他卸载的是“AI 自动写代码”,保留的是“AI 辅助思考”。这个边界不是按工具分的,是按场景风险分的。
2. 为什么是“20年老程序员”先发现问题
先说一个容易被忽略的事实:写了 20 年代码的人,大多数时间不是在“写”代码,而是在“维护”代码。
从职业经历上看,这种程序员通常经历过单体应用、前后端分离、微服务、容器化、云原生的完整周期。他们开发过一个功能,然后看着它被接手、被重构、被扩展、被排查线上故障。所以他们看代码的眼光,通常是“这个代码三个月后还改得动吗”,而不是“这个代码今天能跑吗”。
AI 编程工具在这两句话之间,刚好踩中了一个巨大的偏差。
对新手程序员来说,AI 补全能快速给出可用代码,体验是正向的。但对老程序员来说,AI 生成代码进入生产库之后,他要面对的是别人留下的“看起来正常、实则脆弱”的维护负担。AI 生成代码的典型问题包括:
- 上下文丢失。AI 只看到当前文件或当前函数,但它不知道这个模块在整个系统中的定位。
- 过度设计。为了一行缓存逻辑,生成了一层抽象工厂。
- 假错误处理。
except Exception: return None,看起来很安全,实际把问题全吞了。 - 重复代码。同一个判断逻辑在多个文件里被复制,改了一处漏了三处。
- 无增量意识。AI 更倾向于生成一段新代码,而不是在小范围里做最小修改。
这些问题的共同点是:不会在编译期暴露,也不会在功能测试里暴露,只会在上线后或大版本重构时集中爆发。
所以老程序员卸载 AI,不是因为他不会用,而是因为他太清楚“代码生成”和“代码维护”之间的成本差距。写一段代码可能只要 5 分钟,但把一段没有业务约束意识的 AI 代码维护到正确,可能需要 5 个小时。
3. 卸载前做的三轮验证
他并不是凭感觉卸载的。在决定停用 AI 自动补全之前,他做了三轮验证。这套验证流程不需要特殊环境,任何团队都可以参考。
3.1 第一轮:代码盲测
操作方式:把两个开发任务分别交给“纯人工”和“AI 辅助”去完成,产出代码后去掉全部注释和作者信息,混合在一起,邀请团队 5 位核心成员进行 Code Review。Review 指标只限三个:
- 边界条件处理是否完整
- 异常路径是否明确
- 后续扩展时改动范围是否可控
直观结果:AI 生成的代码在主流程上表现良好,但在空值、超时、并发、部分失败等边界场景下存在明显短板。单纯看“能跑”看不出问题,但看“不能跑的时候会怎样”,差距就出来了。
这一步的核心思路是:判断 AI 代码质量,不能只看功能是否跑通,要看失败模式是否可预期。
3.2 第二轮:长链路重构压力测试
第二个验证更有针对性:选择一个存量模块,先让 AI 梳理代码结构,再让 AI 直接执行一次跨 8 个文件的重构。
第一步 AI 完成得很好,能快速指出模块之间的依赖关系。但第二步在执行层面出现了明显的失控:AI 在一个文件里修改了接口签名,却没有同步更新另外三个调用方;在另一个文件里删掉了循环里的缓存逻辑,理由是“看起来冗余”,实际上这个缓存是为了减少数据库查询。
这次测试验证了一个关键问题:AI 工具在“分析问题”和“执行修改”两种任务上的可靠性完全不同。分析可以出错,改错代价小;但修改生产代码,出错是要线上背锅的。
3.3 第三轮:批量代码审计
最后一轮是全员执行的批量审计。他把团队一个月内“由 AI 辅助提交”的代码集中拉出来,对照几个固定模式做检查。
# 查看近期提交中疑似 AI 生成的重复代码模式 git log --oneline --since="1 month ago" --name-only > all_commits.txt # 统计高频空异常捕获 grep -rn "except Exception:" src/ | wc -l # 统计无意义注释 grep -rn "这里实现" src/ | wc -l审计结果暴露了两个高频问题:一是异常被无差别吞掉,二是注释只描述“做了什么”而不解释“为什么这么做”。这两类问题在人工提交里也有,但 AI 辅助提交会放大出现的频率,因为 AI 倾向于用最“稳妥”的模板代码。
验证到这里,他下了一个判断:如果继续让 AI 自动补全生产代码,团队会持续产生大量“第一眼合格、第二眼可疑、第三眼要重写”的技术债。卸载不是因为 AI 不行,而是因为当前的接入方式把维护成本转嫁给了整个团队。
4. AI编程工具的能力边界
在“卸载”之前,他先把 AI 能做什么、不能做什么画了一条线。这里整理成一张能力边界表,你也可以按这个表来划分自己团队的 AI 使用范围。
| 使用场景 | 建议 | 原因 |
|---|---|---|
| 技术调研、框架选型对比 | 建议使用 | 信息检索和归纳能力强,结果可交叉验证 |
| 写单元测试、接口测试桩 | 建议使用 | 输出可执行、可验证,失败会立刻暴露 |
| 一次性脚本、正则表达式、文本处理 | 建议使用 | 结果可当场验证,风险低 |
| 写注释、补文档、生成 changelog | 建议使用 | 不进入核心逻辑,修改成本低 |
| 代码 Review 辅助“找问题” | 建议使用 | 只输出怀疑点,不直接改代码 |
| 生产核心业务逻辑 | 不建议 | 幻觉和上下文丢失风险高,维护成本不可控 |
| 存量代码的大范围重构 | 不建议 | 缺少全局约束感知,容易破坏隐式约定 |
| 算法、状态机、资源回收逻辑 | 不建议 | 正确性验证难度高,失败代价大 |
| 安全、支付、权限、数据迁移相关代码 | 严禁直接使用 | 合规风险、数据风险和线上事故风险都不可接受 |
这表的判断标准其实很简单:代码如果出错,能不能在 10 分钟内被发现并修复?如果能,用 AI 没有负担;如果不能,就要人工把关。
具体到 AI 编程工具,常见的能力短板有三个。
第一是对“隐式约束”不敏感。业务代码里大量约束不在代码里,而在需求文档、会议纪要、历史修复记录里。AI 不会知道某个字段为什么不能为空,也不会知道某个接口为什么不能加超时重试。它只会按照代码表面逻辑去生成,结果经常是“语法优雅、业务错误”。
第二是对“改动影响面”缺乏判断。人工改代码时,会先在脑子里过一遍调用链、下游依赖、兼容性。AI 生成代码时,只会对当前输入的上下文做概率预测。所以你会发现 AI 生成的函数单独看没问题,接进系统之后有时会破坏原有约定。
第三是对“技术债务”没有感知。老程序员写代码时会刻意避免给后来者埋坑,比如不写过度抽象、不滥用*args、不把可变对象当默认参数。AI 生成代码更倾向于“完成当前指令”,而不是“给后续维护留余地”。
5. 他卸载的是什么,又保留了哪些 AI 工具
“卸载 AI”这个说法容易让人误解。拆开看,他卸载的是几个具体动作,而不是所有 AI 能力。
5.1 卸载的部分
- 卸载了 IDE 里的自动补全插件,不再让 AI 在输入过程中直接插入生产代码。
- 卸载了“AI 直接生成 PR 内容”的习惯,避免把未经消化的代码直接提交进代码库。
- 卸载了 AI Agent 自动修改业务逻辑的工作流,不允许 Agent 直接修改生产分支。
这些动作的共同特征是:AI 在“写最终代码”的环节里拥有过高权重。而现实中,代码最终是要给编译器和后来者看的,需要的是确定性和可解释性,而不是概率生成。
5.2 保留的部分
- 保留 AI 做技术调研:让大模型整理某类方案的设计思路、优缺点对比,再由人工判断。
- 保留 AI 生成测试用例:先让 AI 根据函数签名和业务描述生成测试场景,人工补充边界值。
- 保留 AI 编写一次性脚本和数据处理逻辑:这类脚本生命周期短、错误可快速发现,适合 AI 生成。
- 保留 AI 做代码 Review 的“第一读者”:把变更代码丢给 AI,让 AI 列出可疑点,再由人工确认。
他特别强调了一条边界:如果涉及企业私有代码、客户数据或安全相关逻辑,不会上传到任何公有模型服务。处理这类需求时,要么在合规前提下使用私有化部署方案,要么直接人工处理。这不是对 AI 能力的不信任,而是对数据安全和合规边界的必要敬畏。
这其实是一种更务实的用法:AI 是思考伙伴,不是自动写码机。
6. 代码审查:识别AI生成代码的实用方法
如果你的团队还在使用 AI 编程工具,与其全面禁用,不如先建立一套针对 AI 生成代码的审查机制。下面是可以直接用的方法。
6.1 常见 AI 代码坏味道
通过大量 Review,可以总结出 AI 生成代码的几个典型模式。看到这些模式,就需要提高警惕。
# 坏味道1:吞掉所有异常 def load_user(user_id): try: user = db.query(User).filter(User.id == user_id).first() return user except Exception: return None # 调用方无法区分“用户不存在”和“数据库连接失败”# 坏味道2:可变对象做默认参数 def append_item(item, cache=[]): cache.append(item) return cache # 多次调用会共享同一个列表,产生隐蔽副作用# 坏味道3:注释只描述“做了什么” def process_order(order): # 获取订单金额 amount = order.amount # 计算折扣 discount = amount * 0.9 return discount # 缺少“为什么打九折”“折扣规则来自哪个活动”等关键信息这些代码单独看都能运行,但进入维护期后,会成为排查问题的障碍。特别是空异常捕获,是所有问题里最危险的:它让系统在错误状态中继续运行,等到问题暴露时,已经很难定位真正的失败原因。
6.2 批量扫描 AI 痕迹
可以在 CI 或提交前脚本里,加入以下扫描逻辑:
# 扫描空 except 和过于宽泛的异常捕获 grep -rn "except Exception" --include="*.py" src/ # 扫描无意义的“做了什么”注释 grep -rn "这里实现\|这里处理\|这里获取" --include="*.py" src/ # 扫描可变默认参数(Python 场景) grep -rn "def .*= \[\]\|def .*={}" --include="*.py" src/扫描出结果之后,不要直接当错误处理,而是作为 Code Review 的强制关注项。如果 AI 生成代码里出现空异常捕获,建议一律打回重写。
6.3 用 AI 做 Review 的正确姿势
在已清理敏感信息的前提下,可以把代码交给 AI 做第一轮检查,但要限制它的输出方式:只输出“可疑点、风险点、建议验证项”,不直接输出“修复后的完整代码”。可以用类似下面的提示词模板:
你是一个代码审查助手,下面我会给出一段生产代码。 请按以下要求输出审查意见: 1. 只指出问题,不要直接重写完整代码。 2. 按“严重/一般/建议”三级分类。 3. 重点检查:异常处理、资源释放、边界条件、并发安全、可维护性。 4. 如果你不确定某项风险是否真实存在,请明确标注“需要人工确认”。 代码: {在这里粘贴代码}这样 AI 的定位就从“替你写代码的人”变成了“帮你发现问题的人”。后者显然更适合生产环境。
7. 团队落地AI编程的工程化建议
“20年老程序员卸载 AI”这件事,对个人是选择,对团队是警示。如果你所在团队已经引入 AI 编程,并且担心代码质量滑坡,可以参考下面的落地策略。
7.1 按风险分层设置 AI 使用权限
把所有代码任务分成三层:
- Level 1 允许直接使用 AI:文档、注释、脚本、测试桩、简单正则。这类代码错误影响小,AI 输出可以快速验证。
- Level 2 允许 AI 辅助、强制人工 Review:业务模块、工具函数、接口封装、数据库操作。AI 可以生成初稿,但必须由对业务有完整认知的人审查后再合入。
- Level 3 禁止 AI 直接修改:安全、支付、权限、数据迁移、鉴权、核心算法。这类代码必须人工编写,AI 只允许在知识补全阶段被使用。
推荐在 README 或团队规范文档里直接写明三层分级,Review 阶段对照执行。
7.2 建立“AI 代码审查记录”
在项目仓库里维护一个简单表格,每次 Code Review 发现 AI 生成代码有问题时记录一行。
| 日期 | 模块 | AI 工具 | 问题描述 | 严重级别 | 处理方式 |
|---|---|---|---|---|---|
| 2026-04-01 | order-service | 某 AI 编程工具 | 空异常捕获掩盖数据库故障 | 严重 | 重写错误处理逻辑 |
| 2026-04-02 | user-service | 某 AI 编程工具 | 调用已废弃的 API 接口 | 一般 | 替换为新接口 |
这个做法的好处是积累真实数据。一个月后可以看到 AI 代码的失败模式集中在哪,然后针对性地调整提示词或使用边界。
7.3 用“可行/不可行”清单控制 AI 输入
在让 AI 生成代码之前,团队可以统一要求:提示词里必须包含“功能边界、输入输出约束、异常处理要求、禁止事项”。更稳妥的做法是使用固定模板:
请帮我实现一个函数,要求如下: 功能:根据用户ID查询订单列表 输入:user_id,字符串 输出:订单列表,空列表表示无数据 约束: - 数据库不可用时抛出明确异常,不要静默返回空 - 只查询未删除的订单 - 限制单次返回最多100条 禁止事项: - 不要引入新的第三方依赖 - 不要修改其他文件 - 不要用可变对象作为参数默认值提示词越接近一份小型 PRD,AI 输出越可能符合生产要求。但仍然需要人工做最终确认。
7.4 数据合规与隐私边界
团队引入 AI 编程工具时,最容易忽略的是代码数据流向。企业私有代码一旦被粘贴到公有 AI 服务,可能在远程服务器上被分析。对于客户数据、公司内部系统逻辑、安全相关代码,在未确认数据合规的前提下,不要直接发送给外部模型。
建议按以下方式处理:
- 代码和 API 密钥需要脱敏后才能进入 AI 工具。
- 涉及客户数据时,优先选择企业合规审查过的私有化部署方案或本地模型。
- 对敏感仓库,可以在 IDE 插件配置里直接排除,不允许提交到 AI 服务。
8. 给普通程序员的建议
如果你还没有 20 年经验,但已经在用 AI 编程,这篇文章不代表你要把 AI 工具全卸了。更合理的做法是参考老程序员的判断标准,重新校准自己和 AI 的关系。
第一,用“能不能正确维护”来评价 AI 代码,而不是“能不能跑通”。能跑通只是第一步,遇到边界情况、并发冲突、依赖升级的时候,AI 生成的代码是否还可靠,才是关键。
第二,把 AI 当“初筛器”,不要当“终审者”。让 AI 给出代码草稿、解决问题思路、检查 bug 清单,但合入生产分支之前,必须有一个人负责理解每一行逻辑。
第三,建立自己的测试基线。哪怕只是一个小工具,也要先写测试再让它进代码库。测试是唯一能抵消 AI 不确定性的工程手段。
第四,不要用 AI 逃避“读代码”的基本功。AI 能生成一段代码,但只有你能判断这段代码是否符合业务约束。如果你发现自己完全不知道 AI 在做什么,说明 AI 使用过度了。
回到那个老程序员的选择。他卸载的是“自动补全”,不是“AI 时代”。他保留的是更理性的使用方式,这比“全盘接受”更难做,也比“拒之门外”更有参考价值。
9. 常见问题与排查方法
最后整理一份常见问题表,适用于正在使用 AI 编程工具的团队。
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| AI 补全代码经常出现空异常捕获 | 模型倾向于生成“稳定可用”的模板代码 | 全局搜索except Exception | 在审查清单中标记为必须重写 |
| AI 修改一个函数导致其他模块报错 | 上下文窗口不够,未理解完整调用链 | 对比 git diff,检查调用方 | 禁止 AI 直接跨文件重构,人工拆分范围 |
| AI 生成的代码使用不存在的依赖 | 模型知识时间线滞后 | 查看 import 和 pip/gradle 依赖树 | 要求 AI 只使用现有依赖,不新增第三方库 |
| 批量生成的测试用例全过了,但功能仍然坏 | 测试只覆盖主路径,未覆盖边界 | 检查测试断言是否真的有效 | 在提示词中明确要求补充边界与异常用例 |
| AI 建议的安全方案不适用于当前权限体系 | 缺少业务上下文 | 对照权限模型逐条确认 | 安全相关代码禁止使用 AI 直接生成 |
| 私有代码被上传到外部 AI 服务 | 违反企业数据合规要求 | 检查 IDE 插件日志和访问记录 | 配置敏感仓库排除列表,启用合规审查工具 |
这些问题的共同根源,并不是“AI 能力不足”,而是“接入方式缺少管控”。只要能提前划定风险等级、建立审查流程、保留人工决策权,多数问题都可以被过滤掉。
10. 总结:AI是筛子,不是锤子
回到题目:一个 20 年老程序员,决定卸载 AI。
他卸载的不是 AI 的能力,而是 AI 在“最终代码”上过高的决策权重。这件事最大的价值,是给所有正在追赶 AI 开发热潮的人提供了一个可复用的判断框架:
- 代码风险低、结果可快速验证,放心用 AI。
- 代码风险高、错误会被放大,人工介入。
- AI 永远做初筛,不能做终审。
- 生产代码的每一行,都必须有一个人能完整解释它为什么存在。
这篇内容最后想留给你的是一份实操清单,而不是一个结论。回到自己的项目,先给代码任务分三档,再给 AI 补全设置边界,最后把“空异常捕获、无意义注释、可疑依赖”加进 Code Review 的“必查项”。这套动作做完,你再判断要不要卸载 AI,结论会清晰很多。