最近一段时间,一个感受变得非常清晰:AI 写代码的速度,已经远超过去了
一个 CRUD 接口、一个 Controller、一个 SQL,甚至一整个功能模块,AI 都能够很快完成
但是,在真正的业务项目里,我花费时间最多的,却越来越不是写代码
而是:
- 不知道应该改哪里;
- 不知道为什么这里要这样设计;
- 不知道有没有类似实现;
- 不知道修改之后会影响哪些地方;
- 不知道这个看起来无关的模块为什么会一起坏掉。
举一个很常见的例子,一个需求只是:修改退款流程中的某一个逻辑。看起来只是改一个 Service,结果上线测试之后,却发现:
- 积分没有发放;
- 优惠券状态异常;
- 消息通知没有发送。
最后检查代码才发现:退款流程后面还有
- MQ
- Event
- 定时任务
- 另外几个系统的监听逻辑
这些依赖关系,并没有直接写在你修改的代码里
困难的地方,从来都不是:怎么写代码,而是:如何理解这个系统
复杂性的真正来源
前段时间重新阅读 John Ousterhout 的《A Philosophy of Software Design》时,有一个观点让我印象很深,作者认为:
软件真正的复杂性,并不来自代码有多少,而来自理解和修改一个系统需要付出的心智成本(Cognitive Load)
我越来越认同这一点。之前我在《改代码这件事,为什么总是比想象中难》中讨论过书中讲述的复杂度在代码结构层面的解法——深模块、依赖管理、让系统「显然」。但最近我越来越觉得,还有一个更根本的维度:即使代码结构设计得不错,改代码为什么还是难?
回想一下,一个经验丰富的工程师接到需求之后,第一反应通常并不是开始写代码,而是不断回答下面几个问题
1. 改哪里(Where)
真正负责这个功能的是哪个模块?
入口在哪里?
有没有类似实现?
2. 怎么改(How)
应该直接修改?
还是扩展?
有没有历史设计原则?
为什么以前这样实现?
3. 会影响谁(Impact)
修改之后:
有没有其它系统依赖?
有没有 Event?
有没有 MQ?
有没有隐藏调用?
有没有历史兼容逻辑?
4. 如何验证(Verify)
需要测试哪些场景?
哪些边界情况?
哪些地方需要回归?
真正花时间的,其实一直都是这些事情。编码,反而只是最后一步
当然,实际情况很少这么有条理。更多时候是打开五个文件、改了三处、跑了测试、发现又坏了,然后回头再翻代码——但这些反复摸索的本质,仍然是在补全那些代码里没有的知识
我开始意识到一个问题
这些问题,本质上都不是代码问题,而是知识问题
例如:
为什么这里必须异步?
为什么这里不能直接更新数据库?
为什么这里必须保证幂等?
为什么这个 Event 不能删?
为什么这个字段不能修改?
这些答案,大多数都不存在于代码里面
它们存在于:
- 老员工的经验
- 历史线上事故
- 团队约定
- 架构设计决策
- 业务规则
- 项目演进历史
软件开发一直依赖大量代码之外的知识
那为什么以前没有觉得这是问题?
因为过去,这些知识一直都有一个天然的载体,就是:团队里的资深工程师
新人遇到问题时,可以直接问:为什么这里这样写?
老员工回答:因为三年前线上出过事故,或者:这个 Event 后面还有三个系统依赖
于是:知识就在团队成员之间不断传递
很多团队其实一直都是这样工作的
1 | 隐式知识 -> 资深工程师 -> 开发人员 -> 代码 |
所以过去,我们很少主动去讨论:「知识管理」
因为:知识一直都在,只是存在人的脑子里
AI 改变的不是软件开发,而是知识的载体
AI 出现以后,一个很大的变化发生了
AI 不会主动问:为什么这里这样设计?它只能看到代码
看不到:
- 设计意图
- 历史决策
- 隐藏依赖
- 团队经验
于是,一个过去一直存在、却不那么明显的问题,被 AI 放大了
不是 AI 不会写代码,而是 AI 不知道:为什么这样写
举一个例子:比如让 AI 改一个支付回调的处理逻辑。代码写得很快,看起来也没什么问题。但上线前扫了一眼,发现它把回调里的幂等校验去掉了——因为那段校验写在一个看起来毫不相关的 PaymentUtil 里,AI 根本没读到。而那个幂等校验,是两年前一次重复扣款事故之后加上去的
事故的原因、当时的决策、那段校验存在的理由——这些东西不在代码里,AI 自然看不到
这让我开始意识到:AI 并没有让知识变得重要,而是知识一直都很重要
AI 只是让我们不得不正视一个事实:过去依赖「个人记忆」的软件开发,正在逐渐转向依赖「组织记忆」的软件开发
过去:知识 -> 资深工程师 -> 开发人员
未来:知识 -> 组织 -> 人 + AI
知识开始脱离个人,成为团队真正需要管理的资产
这里的「组织」,不是说 HR 部门。而是指知识不再只存在于个人记忆中,转而通过制度化的方式沉淀下来——比如架构决策记录、团队 Wiki、项目上下文文档——成为团队层面可持续获取、持续演进的东西
可以想象一下:一个新同事接到退款需求,不只是看到代码和 PRD。他还能看到一个上下文面板——退款流程涉及哪些系统、过去踩过什么坑、为什么当初选了异步而不是同步。AI 在读了这些之后生成的第一版代码,就不会漏掉积分发放和优惠券处理。这不一定是明天的现实,但它指出了方向
软件开发真正管理的,也许一直都是知识
所以我越来越觉得:软件开发真正管理的对象,也许从来都不是代码
代码只是最终产物。需要持续积累、组织、传递和演进的,是知识
包括:
- 业务规则
- 架构决策
- 系统依赖
- 设计约束
- 历史经验
- 演进过程
这些共同决定了应该改哪里、应该怎么改、改了会影响什么、如何保证修改是正确的
真正影响开发效率的,并不是写代码的速度,而是 获取这些知识的成本
当然,并不是所有知识都需要写成文档。一个命名清晰的函数、一段表达意图的测试,本身就是知识的载体。问题不在于「代码还是文档」,而在于那些代码无法承载的东西——设计意图、历史约束、跨系统的影响链——是否被认真对待
AI 时代,重新理解软件开发
过去我们讨论 AI Coding,更多是在讨论 AI 如何写代码、如何生成测试、如何自动完成开发
但如果未来代码生成越来越廉价,昂贵的事情就会变成:
- 理解系统;
- 做出正确的工程决策;
- 控制修改风险;
- 持续沉淀组织知识
仔细看这四件事——理解系统(改哪里)、工程决策(怎么改)、控制风险(影响谁)、沉淀知识(如何验证)——它们恰好对应了本文开头提出的四个核心问题。这不是巧合:一个工程师接到需求后真正花时间做的事情,和 AI 时代最稀缺的能力,是同一件事
软件开发,也许正在从 Code-Centric,逐渐走向 Knowledge-Centric
从一个小动作开始
如果你读完想立刻做点什么,也许可以从一件小事开始:
下一个需要花几天才能完成的功能上线后,在仓库里写一段话——为什么这样设计、会影响哪些模块。不需要模板,不需要规范。重点不是文档本身,而是把知识从脑子里挪出来,放在团队可以反复读取的地方。
如果你已经在做这件事——比如写 ADR、维护团队 Wiki——那你已经在做「知识工程」了,只是可能没有用这个名字
写在最后
这篇文章是我关于 AI Native 软件开发 的第一篇思考笔记,不是一个结论
目前还有很多问题没有想清楚,例如:
- 什么才是工程知识(Engineering Knowledge)?
- 为什么架构决策记录(ADR,Architecture Decision Record)在 AI 时代会越来越重要?
- 上下文工程(Context Engineering)和知识管理的关系是什么?
- AI 应该如何获取这些知识?
- 如何把团队知识真正沉淀为组织资产?
这些是我接下来准备继续探索的话题。如果你有不同的理解或者实践经验,也欢迎一起讨论。
我相信,AI 改变的不只是 Coding。它很可能正在重新定义整个软件开发
这是 AI Native 软件开发系列的第一篇。后续:软件开发中的「知识」到底是什么? → 从知识到任务上下文 → 工程决策——在不确定中做最好的选择 → Specification——把决策翻译给 AI → Execution 与闭环——从执行到知识的回流。如果你有不同的理解或者实践经验,欢迎一起讨论。