软件:从 1.0 到 3.0,以及未来
分享我们对 AI 重塑软件开发范式的观察,以及我们在这一浪潮中的思考与实践。
本文由杨柳撰写,撰写过程中与组员于宗民有深入讨论和交流。以下“我”指代杨柳。我绝非软件开发领域的专家,仅仅想分享一下我们最近的工作“Evolutionary Ensemble (EvE) of Agents” (arXiv, GitHub)背后的思路。
软件 1.0: 工程师迭代传统代码
我的思考始于我博士毕业后,在一家优秀的自动驾驶初创公司工作的经历。当时是2021年,在那个阶段,行业的主流并非像特斯拉后来推崇的端到端(End-to-End)神经网络,而是极其精密的专家逻辑。
那时我观察到,研发的本质其实是在进行一种极其艰苦的迭代。有人称之为“人工梯度下降”(Humanized Descent),在学术界,它有时被戏称为“研究生梯度下降”。简单来说,就是给定一个评价指标(Metric),工程师凭借经验去反复调整那些复杂的代码逻辑,目标只有一个:让指标上涨。
这种“人工梯度下降”的模式支撑了早期的技术爆发。它拥有极佳的可解释性,处理特定需求时(比如客户要求在某种特定路况下增加一个逻辑分支)只需加几行 if-else 即可快速上线。但弊端也显而易见:
- 开发昂贵:这种模式是一种极其昂贵的智力消耗。可以说,软件工程位于“可规模化智力”的边界,软件工程师的智力是稀缺资源,工资也相当高。
- 迭代迟缓:每次修改都需要人工分析和调整,迭代周期长。
- 能力局限:随着系统规模的扩大,代码逻辑变得越来越庞杂,最终演变成了难以追溯归因的复杂系统,新增功能或修复问题时可能引入新的 bug。这个复杂最后可能超过人类工程师的处理能力,因此局限了系统的能力上限。
软件 2.0: 神经网络替代传统代码
随后,行业开始转向以特斯拉为代表的端到端(End-to-End)神经网络路线。这也就是 Andrej Karpathy 当时提出的 Software 2.0 愿景。它主要的想法是:我现在有一大块逻辑,我要拿一个神经网络来替代它。如果说 Software 1.0 是人类手工编写逻辑,那么 Software 2.0 则是通过整理数据、设计模型和目标函数来“训练”出逻辑。
Software 2.0 基本可以克服上面说的 Software 1.0 的弊端,但也有自己的问题:
- 对海量数据的依赖
- 黑盒化的解释性困局和可靠性问题
- 在进行“定向修改”时的力不从心: 比如我突然要加一个 feature,它没那么好加。我只能去 fine-tune,但 fine-tune 会不会改了其他地方?这很难说,神经网络很难保证这一点,甚至可能出现“灾难性遗忘”(Catastrophic Forgetting)的问题。
在某个阶段,Software 2.0 在不断侵蚀 Software 1.0 的领域,很多“提升指标”的工作,都可以让神经网络来做。神经网络的强大,让很多事情的默认选择变成了训练神经网络。但神经网络可能并不是最优选择,比如,Gaussian Splatting 其实比神经网络更适合拟合一个场景的光照和几何信息。
Software 2.0 愿景给我带来的最大启发在于,对“编程”概念的更高层的理解。什么是编程?编程的定义不是敲入特定的字符,而是告诉计算机“要做什么”。很早以前用打孔卡编程,打孔也是编程,后来用汇编语言和高级语言编程,那训练神经网络怎么就不是编程了呢?载体在变,核心始终是人类意图的表达。
软件 3.0: 大语言模型带来的冲击
我最早看到软件 3.0 的概念,是从这里。其主要观点是,LLM让软件开发的含义变得更加广泛。说实话,我至今不清楚软件 3.0 的严格定义,但肯定围绕着“Coding Agent的兴起”和“自然语言成为新的编程语言”。2023年prompt engineer兴起的时候,Andrej Karpathy就说:目前最流行的编程语言是英语。现在coding agent兴起之后,我们提供的不仅仅是prompt,还有一些文件来指导Agent。说到底,编程就是告诉计算机我们要做什么。
未来会发生什么?以下是个人的想法。
-
传统代码用新的方式回归,甚至有可能夺回被神经网络侵蚀的领地。
Coding Agent很擅长“优化代码来提升指标”,它几乎完美解决了 Software 1.0 的核心问题:
- 开发不再昂贵,Coding Agent 可以提供廉价的智力。
- 迭代不再迟缓,Coding Agent 可以在几秒钟内完成修改和测试,迭代周期大大缩短,甚至比训练神经网络更快。
- 能力不再局限,Coding Agent 可以处理大规模的代码库,未来有可能可以处理人类无法处理的复杂系统。
而Coding Agent写出来的代码,又很大程度上规避了神经网络的缺陷:
- 不再需要海量数据,因为LLM里有人类的先验知识和推理能力。
- 可解释性和可靠性更好,因为代码的逻辑是显式的。无论代码多么复杂,其可解释性也依然超过神经网络。
- 定向修改更容易,因为我们可以直接修改代码逻辑,而不是微调一个黑盒模型。
我觉得当下很多软件开发,都可以重新审视一下,在训练神经网络,和让 Coding Agent 来写一段传统代码之间,哪个更合适。最近Weng Jiayi在这篇博客里也有类似的观点。他讲述了coding agent替代deep reinforcement learning的可能,但其实coding agent强行写传统代码替换神经网络,应该不仅仅发生在控制。
简单的函数,比如低维函数,或者input每一个维度都有合理解释的函数,根本不需要神经网络来拟合。神经网络有着所谓的universal approximation,但是让coding agent针对每一个问题,去找更具可解释性、更适合问题的参数化表达(比如Gaussian Splatting),或者一段代码逻辑,也可以产生universal approximation。神经网络真正的领地是极度复杂的函数,尤其是foundation model。
-
绝大多数人力会集中到定义评价标准(metrics)。
在过去的软件工程里,制定metric也是很重要的,但大多数人力并不在此。Software 1.0 时代,大多数工程师在编写提升metrics的代码,2.0时代,大多数工程师在训练提升metrics的神经网络,尤其是清洗数据。但只要目标明确,这些工作原则上都可以交给Agent去做,也许只有少数极难的问题,还需要顶级的人类大脑。但metric的定义,因为需求只有人类知道,以及伦理问题,等等原因,短时间内还是需要人类来完成。我们上面说“编程就是告诉计算机要做什么”,定义metric,就是在告诉机器“做什么”,至于“怎么做”,很大程度都可以交给Agent去探索了。
-
AI的自指迭代
既然AI如此擅长迭代软件,AI本身也是软件,为什么不让AI开发出更聪明的自己,然后更聪明的AI再开发出进一步更聪明的AI?这就是自指迭代。读过“哥德尔,埃舍尔,巴赫:集异璧之大成”的朋友应该对这个想法不陌生。甚至可以说,这就是AI的圣杯。
自指迭代是一个正在发生的,连续的,不断补全的过程:
- AI已经在加速AI开发了,只不过还不能完全脱离人类的干预。
- 可以固定AI的一部分,自指迭代其余的部分。比如,我们可以固定LLM,然后自指迭代外层的Agent。
我估计几年内,就会看到AI自己训练出一个更聪明的AI模型,以及编写外围的Harness system,而不需要任何人类的干预。我看不到任何本质的困难。
我们的探索
2023年LLM as Optimizers范式的提出,已经预示了软件的迭代模式会发生巨大的变化。后来的FunSearch和AlphaEvolve的工作,更加确认了这个趋势。
FunSearch和AlphaEvolve在LLM-as-Optimizer的基础上,进一步引入了进化算法的思想。进化算法和LLM真的是天生一对,LLM解决了进化算法里最难的“遗传和变异算子的设计”问题,而进化算法提供了LLM需要的“版本管理”,也就是说不用再担心LLM把代码搞得一团糟了,因为每次修改都会生成一个新的版本,而进化算法会自动选择出表现更好的版本继续迭代。但我认为这里有两个问题没有解决:
- LLM-as-Optimizer的元提示词(meta prompt),也就是告诉LLM根据examples去做优化的那段提示词,依然是人类设计的。这里其实有巨大的设计空间,比如让LLM对比不同的example,优化的方向,等等,这些会影响优化的效率。上面说可以固定AI的一部分,自指迭代其余的部分。按照这个逻辑,我们可以固定LLM,而自指迭代这段meta prompt。需要指出的是,AlphaEvolve文章里其实说了他们会进化meta prompt,但我没有完全理解他们的实现方式。
- 从LLM-as-Optimizer到Agent-as-Optimizer的进化。LLM-as-Optimizer很难处理复杂的代码库,利用Agent来管理context和workflow,是必须走的一步。
我在2025年夏天把这两个目标告诉了合作者。总之,我们要做一个既能优化下游任务代码,也能优化自己的agent。最后我们写出了Escher-Loop这篇文章。这里的Escher(埃舍尔)致敬我学到自指迭代思想的地方,也就是“哥德尔,埃舍尔,巴赫:集异璧之大成”这本书。这个工作里,同台竞技+Elo rating的机制,简单而有效地解决了比较“从60分优化到70分”和“从90分优化到95分”哪个更厉害的问题,是我比较得意的设计。在我看来,这个工作是一次有意思的探索(感谢我的合作者们)。它部分实现了自指迭代,验证了有效性,但没有完全解决从LLM-as-Optimizer到Agent-as-Optimizer的进化。
就在我忧愁如何做出真正能解决复杂问题的,自指迭代的Agent-as-Optimizer时,我的组员于宗民指出,我们其实不需要自己造轮子,而应该借助现有的coding agent,比如Claude Code和Codex。这个想法太好了,拼图已经补完了,我们可以基于上面说的所有思考,做我们能做的最正确的事情了!
- 既然coding agent崛起,而自然语言成为新的编程语言,那么自指迭代的目标,就完全可以是给coding agent看的自然语言,包括一些对优化的指导,skills.md 等等。我们的体验是,自然语言对Agent行为的影响力相当大,自由度是足够的。
- 人类要做的,就是给下游任务一个具体的评价标准,可以给Agent写出来的代码打分。
- 我们需要一个能兼容所有其他agent,还能无限scalable的框架。我们最终选择一种彻底去中心化的集群(ensemble)架构。EvE 摒弃了教条式的角色划分(如“管理者”与“工人”),从而获得了普适的兼容能力。从原理上讲,任何现有的 Agent 或多 Agent 系统,都能被无缝集成并视为该集群中的一个个体。
- 对下游任务,我们挑选一个我们能做的,距离完全的AI自指迭代最接近的任务:设计foundation model网络结构。我们的兴趣是in-context operator networks,一种科学计算foundation model框架,用它来做testbed也就顺利成章了。
最后这些实践变成了Evolutionary Ensemble (EvE) of Agents (arXiv, GitHub)。结果相当惊艳,EvE可以真正解决AI研究中遇到的难点,甚至比我们组内部所有的人类设计都要好。
结语
我们预言,人类所有的智力活动,会收缩到最本质的环节:定义要做什么,以及什么是“好”(也就是metrics)。但做这件事并不trivial,它需要极广的视野和敏锐的直觉。也许最后正如乔布斯所言:Ultimately it comes down to taste。