最近我用 AI 完成了一个高性能 Golang JSON 库的开发。这不是简单的 CRUD 应用,涉及到了字节码定义、解释、内存管理、Golang 运行时集成等系统编程工作。结合对比之前使用 AI 完成的业务功能,我产生了一个直觉:AI 写所谓”底层代码”和”业务代码”,没有明显的能力差距。
这个直觉初看有点反常识,但仔细分析后我认为它成立。原因是:AI 的难度感知和人类对难度的感知不是同一个东西。
底层代码更难?
仔细想想,我们说”底层代码难”,这个判断的主语是人类。人类觉得编译器比 Web 后端难,很大程度上是认知结构决定的:
- 工作记忆瓶颈。 例如,编译器各个 pass 之间的状态变换链条很长,人脑难以同时持有全部上下文。虚拟机的指令分派、栈帧管理、对象布局之间的关系也是如此。
- 直觉缺失。 人对”用户点击按钮 → 页面跳转”有天然直觉,对”SSA 形式中的 φ 节点”或”标记-清除 GC 的三色抽象”没有。
- 反馈周期长。 改一行前端代码刷新浏览器就能看到效果,优化一个算法细节需要跑 设计好的benchmark 才能感知。
但这三点对 AI 都不构成障碍。AI 没有工作记忆的 7±2 限制,不依赖视觉直觉来理解代码语义,也不需要”感受”反馈来维持注意力。
更深一层看,人类在这里混淆了两个概念:“学习一个领域”的难度和”在这个领域执行任务”的难度。人类程序员花了数年才建立起对编译器或虚拟机的心智模型,因此把建立心智模型的痛苦投射到了任务本身。但一个人类专家理解了 GC 的三色标记法之后,实现它并不比实现一个复杂的表单验证更难。难的是理解的过程,不是理解之后的执行。 AI 不存在”学习过程”这个瓶颈,它在训练阶段已经完成了。所以人类感知的难度中有很大一部分(学习成本)对 AI 根本不存在。
从信息结构看,代码就是代码
如果尝试把所有代码(无论是 React 组件还是字节码解释器)都看作某种信息拓扑结构,一个可能的推论是:所谓”上层”和”底层”的区分,也许更多是人类认知习惯的投射,而非信息本身的固有属性。
举一个具体的例子:一个虚拟机的指令分派循环,和一个 Redux reducer 的 action 分派,在抽象结构上有相似性,都是”根据输入类型选择处理路径,更新状态”。人类觉得前者难后者易,是因为前者的输入类型是操作码,后者是更直观的业务 action。当然,真实的虚拟机指令分派在工程细节上远比 Redux reducer 复杂(涉及栈管理、异常处理等),但这种复杂性更多是量的累积而非质的跃迁,每个子问题的推理模式并没有本质不同。
对 AI 来说,操作码和业务 action 都是 token。
换句话说,底层算法之所以显得”复杂”,很大程度上是因为它操纵的对象(寄存器分配的干涉图、GC 的对象可达性、指令流水线的冒险检测等)不映射到人类日常经验中的任何直观形象。人类的认知天然偏爱能”看到”、能”比拟”的东西:一个购物车页面、一条 REST 请求的生命周期,这些和现实世界的因果链相似,所以理解起来毫不费力。而一个 SSA 图的支配边界计算,逻辑上并不比购物车结算更复杂,只是它的结构不”形似”任何日常事物,人脑缺少现成的认知锚点去挂靠。
AI 没有这个偏好。它不需要把抽象结构映射到视觉直觉上才能处理,无论信息拓扑长什么样,对它来说都是同一种操作:在 token 序列上做条件概率推断。人类觉得困难的底层算法,可能只是人类直觉上不容易”看见”的算法,而非本质上更难生成的算法。
以 Kolmogorov 复杂度的视角可以看得更清楚:代码的”本质难度”可以用生成该程序的最短描述长度来近似。业务代码往往有高偶然复杂度(框架样板、约定、适配层),但较低的本质复杂度(核心逻辑可能一句话说清)。底层代码反过来,偶然复杂度低(没有框架包袱),本质复杂度高。对 AI 来说,偶然复杂度几乎是免费的,模式匹配即可。本质复杂度才是真正的挑战。但关键是:底层系统代码的本质复杂度虽然高,却往往是局部的、数学化的、有明确边界的,这恰好是神经网络比较擅长压缩和泛化的结构。
底层知识更稀缺吗?
这是一个自然的疑虑:训练数据中 Express 代码可能远多于 GC 实现,AI 对底层代码的”经验”理应更少。
但仔细一想,这个担忧在计算机领域站不太住。计算机科学可能是人类文档化最彻底的工程学科之一。操作系统、虚拟机、编译器、数据库内核,每一个经典主题都有大量的高品质资料:
- 多本权威教科书(Dragon Book、“Engineering a Compiler”、CMU 15-445……)
- 多个开源实现的完整源码(LLVM、V8、SQLite、LuaJIT……)
- 详细到证明级别的学术论文
- 大量设计文档和技术博客
诚然,训练数据中可编译、可运行的底层完整项目在数量上仍然远少于 Web 应用。但底层资料的信息密度极高。一份 LLVM 源码蕴含的结构知识,可能抵得上成百上千个样板式 Express 应用。对神经网络来说,高质量的样本往往比低质量的海量样本更有效。
“底层知识稀缺”更多是从业者视角的错觉:学的人少,不等于写下来的少。 恰恰相反,因为这些领域的重要性,前人留下了异常丰富的文字记录。
即使知道,也容易出错?
另一个常见的直觉是:底层代码的容错空间小,差一个 memory barrier 就是 bug,所以即使 AI”知道”相关知识,微小的偏差也会导致错误。这个直觉隐含了一个对神经网络的错误模型,好像 AI 是在背诵某段代码,稍有记忆偏差就会出错。
但实际上,当训练数据中存在足够多的变体实现时,网络学到的不是某个特定实现的
token 序列,而可能是结构性的理解。比如对 B-Tree
的分裂操作,模型捕获的是”中间 key
上提,左右子树维持有序性不变量”这样的结构规律,而不是某一份特定源码的逐字复述。这种结构性理解对局部扰动是鲁棒的,就像一个理解了快速排序原理的程序员,不会因为变量名从
i 改成 left 就写不出来。
强约束是 AI 的盟友
底层代码通常有更严格的形式化约束:类型系统、不变量、前置/后置条件。而业务代码的正确性标准往往是模糊的(“用户体验要好”、“产品经理觉得对”)。严格约束对人类是负担,但对 AI 可能是福利。约束越强,合法程序的搜索空间越小,越容易命中正确解。一个有完整类型签名的 Rust 函数,比一个”随便怎么写都能跑”的 JavaScript handler 更容易被 AI 写对,因为类型检查器帮它剪掉了大量错误分支。
更多约束 = 更小的搜索空间 = 对 AI 更友好
这和人类的感受完全相反。同样的逻辑延伸到验证环节,底层系统代码和业务代码在可验证性上存在显著的不对称:
| 底层系统代码 | 业务代码 | |
|---|---|---|
| 正确性标准 | 精确、可形式化 | 模糊、依赖人类判断 |
| 验证方式 | 单元测试、fuzzing、property-based testing、形式化证明 | “点一点看看对不对”、用户反馈 |
| 回归检测 | 确定性的 | 经常需要人工判断 |
这意味着 AI 写底层代码即使出错,也更容易被自动化地发现和修复。而业务代码的错误(逻辑不符合产品意图)可能悄无声息地上线。从整个”AI 生成 → 验证 → 修复”的闭环来看,底层代码可能反而更适合 AI 参与。
AI Coding 的真正瓶颈在哪?
如果知识不稀缺,结构理解也是鲁棒的,强约束还能帮忙剪枝,为什么人们仍然感觉 AI 写”复杂系统”时不太行?根据实际经验,问题不在理解深度,而在一致性广度。
AI 理解一个 B-Tree 的 insert 操作,和理解一个 REST API 的 POST handler,可能确实没有本质难度差别。但当你需要这个 B-Tree 模块和 WAL 模块、Buffer Pool、并发控制层同时正确交互时,错误率会显著上升。
这不是因为 AI 不理解任何单个组件,而是因为当前的生成架构是自回归的,逐 token 生成,上下文窗口有限。跨模块的不变量维护,本质上要求同时持有多个约束并保持全局一致,这是一个工程局限,不是知识局限。这也解释了为什么在实现 JSON 虚拟机项目中,AI 在单个模块内的表现往往很好,但在模块集成时需要更多的人工把控。
比知识更关键的,往往是反馈循环
如果把人类在 AI 编程中的作用拆开,大致有两类:
- 给出方向:定义目标、约束、优先级,决定什么值得做。
- 提供环境:让修改、运行、验证、定位错误的成本足够低。
前者当然更根本,但后者的重要性可能仅次于前者,而且在实践里经常被低估。对 AI 来说,一个好的工程环境不是锦上添花,而是能力放大器。所谓”好的环境”,通常意味着:
- 改完代码后能立刻运行测试,而不是等半小时集成构建
- 性能、正确性、边界条件都有可重复的验证手段
- 错误信息足够明确,能把问题定位到具体模块或不变量
- 模块边界清晰,修改的影响范围可控
为什么这件事这么重要?因为 AI 的强项不是靠直觉拍脑袋,而是在反馈中快速搜索和收敛。只要环境允许它低成本试错、快速验真,它就能把许多原本模糊的设计问题转化为一连串可验证的小问题。
这也是为什么很多人会产生一种错觉:AI 在新项目、玩具项目、结构清晰的代码库里显得很强,一进入复杂遗留系统就突然变弱。这里的差别往往不完全是问题本身更深,而是反馈循环断裂了。改动之后跑不起来、验证太贵、错误信号含糊、模块依赖纠缠,这些都会让 AI 的有效能力急剧下降。
从这个角度看,影响 AI 编程效果的关键因素,可能可以粗略排序为:
- 人类是否给出了清晰的目标和边界;
- 系统是否提供了便宜、稳定、可自动化的反馈循环;
- 问题本身的跨模块约束复杂度有多高。
近年来的实践正在从多个方向验证这一判断:
- AI 辅助的数据库查询优化(learned index、learned cardinality estimation)
- LLM 直接生成编译器;
- DeepMind 的 AlphaCode 在竞赛编程中展现了处理复杂算法问题的能力
- 越来越多的开发者正在用 AI 完成曾经被认为”只有顶级开发者才能做”的系统级开发
这些都指向同一个方向:底层系统并非 AI 的禁区,只是人类的心理禁区。
总结
AI 和人类的难度认知不完全重合。一个涉及复杂分布式事务的业务系统,可能比一个自包含的 GC 实现更让 AI 为难;很多看起来高深的经典算法(红黑树、标记-清除 GC),因为结构自包含、约束边界清晰,AI 反而写得很可靠。人类觉得前者简单后者难,AI 觉得恰好相反。
所以,不要因为这是底层系统就不敢让 AI 做,也不要因为这是业务代码就盲目信任 AI 修改它。按真实的约束结构来判断,而不是按人类直觉中的难度等级。
如果想把 AI 真正用在复杂工程里,除了人类提供方向之外,最值得投入的一件事就是:建设一个让 AI 容易开发、容易验证、容易收敛的反馈环境。完善的测试、清晰的模块边界、快速的构建流程、明确的错误信息,这不是可选的锦上添花,而是决定 AI 能力上限的基础设施。