严格来讲,本文讨论的不是我心中标准意义下的复利,而只是什么是可以多次被利用,成本可以被均摊的。复利是一些会有相乘效应的内容。
但本文引用的一篇文章就是用复利来描述这些,以及考虑到标题的传播性,我还是在标题中使用了复利这个词。
1、2020年前的软件工程
在手写代码时代,软件工程是一门实践学科,而且其实中有强的把人也作为分析对象的视角。
如果你深入去调研,会发现它实际上也有自己的理论体系。不过更知名的大概是一些经典著作,例如:
(1)《The Mythical Man-Month》人月神话,讲大型项目为什么会失控。
实际上这本书在现在也仍然有深刻的意义,过去单纯给项目加人并非好的方式,那么现在堆更多的Agent为什么就可以?当然我认为多Agent协作也会面对类似的问题,这并非银弹。
(2)《No Silver Bullet》没有银弹。Brooks 的判断是:不存在单一技术或管理方法,能在十年内让软件生产率、可靠性、简单性提升一个数量级。
现在AI Coding就能解决这个问题了么?我认为本质复杂度的问题实际上仍然存在,不过AI Coding正在逐步提升handle复杂度规模的能力。
(3)《Design Patterns》设计模式。
设计模式并不是理论的层面,更多是当时的最佳实践。但最佳设计工具是会变化的,你后来再看这些设计模式时,会感觉“这还需要单独来提?”、“当时的语言居然没这功能?”
但模块化、信息隐藏与架构设计在现在仍然是重要的,即使最佳实践的具体菜谱已经出现了变化。
本节就不过度展开了,写本节只是因为估计大多数读者并不熟悉这些上古经验。
2、AI Coding带来的变化
在过去,软件工程的积累一直没有太多的变化,大部分这方面的理论和最佳实践在很早就已经稳定了,在我入行的时候就已经是这个状态了。先辈们能够在那么早就得出这些经验再次说明了那句话:前人不是傻子。
但估计是再NB的人大概也没有预料到我们在2026年就能用上目前这样的AI Coding工具。很多人,包括我过去在内,都觉得似乎软件工程领域的理论和经验需要彻底改写了。但实际上当我重新列出这些材料时,意识到实际分析框架仍然没变,只是最佳实践随着技术栈和工具的变化在改变。就像我第一次看《设计模式》时感觉这书好像并没有那么有用一样,最佳实践本身是会过时的,但原则不会。
随着AI Coding堆砌代码的能力和速度不断提升,Coding Agent作为一个独立的同事,我们很难对齐它与我们自己的Coding品味。但由于各方面原因,大家虽然实际编码更多了,但精力投入似乎并没有减少太多,甚至说由于开发成本下降反而吸引人投入了更多精力。
开发工作是非常多样的事情,在过去一年中,我们能看到开发者群体对于AI Coding到底有没有用,应该怎么用进行了大量的论战。实际上直到我最近做的一个项目时我都觉得我们都靠AI Coding和AI review就好了。但我错了,我发现我做的项目进入到了一个AI Coding所不熟悉的领域,这个过程体验非常糟糕。这让我重新认识到去年为什么有些人一直说AI Coding对他们用处很小。
最近半年,即使排除最激进和乐观的那波人的声音,我们仍然能够看到一些不错的AI Coding实践经验。例如:
《AI coding 里真正有复利的东西》 https://yage.ai/share/ai-coding-compound-interest-20260429.html
但这些内容总给我一种很碎片化,没能揭示全局的感觉,这也让我思考并来写作本文。
3、如何认识目前的AI Coding能力
3.1、Coding Agent有自己擅长的和不擅长的
目前即使是最强的模型能力很强,但也仍然有自己不擅长的事情。跳出这个框架想一想,这很显然,因为模型厂的RLVR并没有对于太多的任务进行了针对性训练。当你在思考如何自己实现RLVR的任务和reward方式的时候就会注意到这点,模型厂虽然有钱,但并非全能,他们有自己的喜好和能力范围。能力尚且可以采购,但认知和喜好真的是一大阻碍。
估计有很多读者能够提出一些场景目前的Coding Agent并不擅长,需要人做大量的设计和干预。我这里只列一下我当前撞在了什么地方:我在尝试做一个能指导和优化通用Agent执行的Meta Agent,且还是few-shot的。事实上我认为目前Opus 4.7在这方面的能力完全不如我的设计,甚至它经常陷入细节上头痛医头脚痛医脚的状态,我们招一个有编程经验的白板新毕业生,在有指导的情况下都能在一个月内做得更好。
在大量干预和与Agent进行细节设计讨论之后,我认识到目前这种方式是错误的,所以才有了我后面会介绍的一种新的开发方式。
现在研发岗的人容易低估模型某些方面的能力,而非研发岗的人则无法认识到模型在哪些方面能力不行。前者还容易改变,后者真的很难,所谓盲人瞎马,虽然用词有点过重,但大概就是这种意思吧。不过一个差异是,这个盲人有很多条命。
3.2、Coding Agent是一种新时代的编译器
AI Coding是自然语言的编译器。这个说法其实也很常见了,但绝大多数的人并不能充分理解这个视角,因为经历过“新出现一种高级编译器,把开发的层面提升一层”的人并不多。
从我小时候作为兴趣沉迷编程,到现在有超过25年了,到现在我也没有完整经历过出现一种新的编译器把开发层次提升了一个层面。要说的话只有说过去ML方案还不完善,但GBDT之后这方面的抽象层次提升了一级。实际上对我来说我最多只是同时面对一些抽象层次有所差异的语言,例如说我深度使用过Mathematica这种函数式语言,也写过很久的C++这种需要关注内存布局和指针层面的语言,中间的有GC的高级语言也用过很多种(Delphi、Java、Scala、Go)。但我现在不会说我经历过哪种从写汇编到写C甚至C++/Fortran的转变。
所以这种经验的缺失让我们不知道该如何面对新的抽象层面编译器的出现。
现在的代码生成工具已经很多,这里有个标准实践是:不要编辑生成产物。从编程语言编译器的角度,就是:不要直接干预编译器编译的结果。
虽然本文到这里还没开始讨论什么是这个编译器的输入,但大家目前回忆一下自己的使用体验,应该会发现大家很多时候是在做编辑和干预Coding Agent编译结果的事情。而这是不对的,因为这个动作不能被复用,也就是成本不能均摊。
当然我们在更高的层面进行编程不代表不能干预底层,现在的高级语言中,注入汇编代码片段是个很常见的功能。
实际上如果你去看最近FFmpeg作者团队在Lex Fridman播客上的分享,你会发现实际上目前的高级语言并没有我们以为的那么高效,如果你还在手调汇编,你可能能在视频编解码方面获得几十倍的性能提升,这个性能差距之大是让人震惊的。我们是用高级语言降低了开发成本,但也是有所牺牲的。
4、如何复用
本节这里先建议看下 《AI coding 里真正有复利的东西》 https://yage.ai/share/ai-coding-compound-interest-20260429.html 。
不过其中都是一些具体的层面,本节继续来谈一些可以泛化的原则。
复用是个经常被开发者遗忘的视角,或者说不够重视的视角,因为一般开发者对于自己过去的已习惯方式并没有深刻认识。
一个典型的问题是,古法手工编辑代码这件事,到底算不算复用?看起来它一点也不算,特别是修改一些不能复用的组件的时候。但当你以现在的视角来看的时候,它实际上是与分来重新阅读和review这个代码的成本进行了均摊。开发者把代码改成更好的设计、更符合他习惯的设计,都可以降低未来阅读和review这个代码的成本。但这件事在现在则不一定成立,有些项目的代码不会再由开发者进行多次阅读和review了。
如果你的要求不高,或者是在Coding Agent非常擅长的领域,你可能可以一句简单的prompt就直接得到整个方案。但是当做不到这点时候,开发者就需要对Coding Agent的开发过程或结果进行某种干预。如果只是简单的先做计划再实施之类的方法论之类的还好,还能迁移,但很多时候并不是。
无论你是在开发前做了更详细的设计,还是在设计过程中与Agent进行了讨论,还是在代码实现中进行了干预或review,或者是对于结果进行手动测试。这些都有一个问题,这些工作的成本都是与Coding Agent的工作混在一起的,而且往往只在其中占一小部分比例。这导致一些问题:
(1)你很难将这些工作从整体工作中剥离出来,让AI重新编译剩余部分。
(2)AI可能很难记住你的一些习惯,你的要求在指示时也往往很具体,不容易泛化,再加上目前Coding Agent的泛化能力较差,所以你可能不得不就类似的问题做多次干预。这看起来很不复利。
实际上这都是因为我们试图直接编辑编译器结果的二进制代码而导致的问题,而从软件开发中显然可知,我们不应该这么干。
4.1、Coding Agent编译器的输入是什么?
这个事情不显然的原因因为如果把Coding Agent作为编译器的话,它的输入边界到底在哪里这件事很模糊,而且不同的项目也不一样,这导致了整个社区很难建立起明确且容易传播的方法论。而本节则试图提供一个视角,遗憾的是这个视角有点抽象,所以并不是一个容易传播的方法论。
如果自上而下的设计和实施一个项目,实际上往往能找到一些抽象层次,其中一边是人工强干预的,特点是希望其中的几乎每个描述都是人确认过的,而另一边则是人工介入的部分比较少的,希望能按照要求实施即可。这个边界的切分并不是按照完全的抽象层次划分的,回想前面的例子:即使是高级语言,你也可以在其中嵌入汇编代码做细粒度的局部干预。
这个边界的位置跟很多因素有关:需求的明确程度、需求方希望对于实现方式的干预程度、干预成本、编译器作为实施者对需求的熟悉程度和专业性程度。
(A)对于不关注细节的非技术开发者来说,这个边界比较高,只覆盖了他能理解的那部分,剩下的部分都指望Coding Agent完成。
(B)对于正在开发Coding Agent不非常熟悉(专业)领域方案的开发者来说,这个边界大概是在中间左右,会做更多实现方式的计划,但不会干预过度细节的地方,例如某个寄存器应该怎么利用、某个对象什么时候被GC。
(C)一些代码质量要求非常高的工作或领域中,这个边界被推的非常底层,经常以至于所有代码都应该被人review。典型场景是高可靠性场景或组织中的核心业务的逻辑。但这导致了一个问题,Coding Agent无法起到完整的提升抽象层次的功能,它不是一个编译器,只是一个更强大的Cursor Tab一样的自动补全。
这也是代码质量要求越高、开发流程越规范、对问题容忍越低的地方,Coding Agent的实践就越痛苦的原因。大组织内的AI Coding过度推行是一种饮鸩止渴 中提到的问题就是表现。
当然在开发过程中,这个边界也不是固定不变的,可以根据开发过程中的情况进行调整。经常需要人工干预的部分应该提升到干预边界以上,很少需要人工干预模型就能做得比较好的部分可以考虑放在干预边界以下。
4.2、干预边界 与 High-level Spec
上一节我们引入了 干预边界 的概念,那么干预边界之内的部分就需要一个名字。但其实并没有特别适合的已有概念,要说的话它跟Spec驱动的AI Coding中的Spec有点像。但你去看了SDD之后会发现其实并不完全是,SDD一般要求Spec要做足够细致的指定,但本文并非这个意思。Spec的边界是综合考虑才得到的,兼顾可干预性和成本的考虑。所以我暂时将其称为High-level Spec。
在这个模式下,构建Spec就是一个人工为主的工作,可以有AI辅助,但最终结果要有人的背书和负责,最终应该得到开发者可接受的质量。剩下的部分由AI实现。
当然并不是说干预边界外的部分就不能干预了,而是我们应该尽量通过干预边界内的高层次Spec的约束调整来控制外部。实在过于具体不好通过泛化方式控制的,可以进行具体指示,就好像在C++代码中嵌入汇编片段一样。
实际上这种明确区分干预界面的方式之前就已经逐步有一些类似的方式了,例如:目前推荐把需要重复输入的指令写到CLAUDE.md/AGENT.md中;把一些核心设计固化到文档中并即使更新。
Agent试图通过Memory的方式来学习用户/项目偏好也是,但在本文的视角下,隐藏式的Memory并不推荐。因为它们也是干预边界内的一部分,其描述和措辞应该被人review和掌控。
当然这种方式不止限于Coding环节,所有环节都可以参考,核心就是要明确区分需要干预的边界和放手让AI执行的部分,让这两者明确可分,并仍然用古法的工艺来维持前者的质量。
交流与合作
如果希望和我交流讨论,或参与相关的讨论群,或者建立合作,请加微信,联系方式请点击 -> 专栏简介 及 联系方式 2024。
本文于2026.5.13 首发于微信公众号。
夜雨聆风