> 一篇关于《Scaling Coding Agents via Atomic Skills》的费曼式解读
---
## 凌晨三点的修Bug高手
想象一下这个场景:凌晨三点,你盯着屏幕上那个诡异的报错信息。你的AI助手,那个平时在GitHub Copilot里 autocomplete 快如闪电的家伙,突然像个无助的孩子。它试过十几种修复方案,每一次都信心满满,每一次都失败得更惨。
"这段代码看起来能修复内存泄漏问题。"它说。
你运行测试。 Segmentation fault.
"让我再试一次,这次修改指针的释放顺序。"它又试。
还是失败。
你叹了口气,自己花十分钟定位到问题根本不在内存管理,而是在一个完全不相关的配置文件解析逻辑里。AI助手像个只会死记硬背的学生——它"学过"很多修复内存泄漏的案例,却从未真正学会 **如何定位问题**。
这就是当前AI编程助手的真实写照:它们是偏科怪。擅长修Bug,但一遇到代码重构就抓瞎;能写单元测试,却不会判断一段代码修改是否真的正确。问题出在哪?一群来自香港科技大学、新加坡国立大学、北京大学、上海交大和北京邮电大学的研究者给出答案:**我们在教AI做题,而不是教它解题**。
---
## 整题训练 vs 原子操作
让我用一个简单的类比来解释这个问题。
假设你要教一个孩子学会做饭。传统的做法是:让他反复练习做"番茄炒蛋"这道完整的菜。练上一百遍,他应该能做出不错的番茄炒蛋。但问题是——如果你突然让他做"青椒肉丝",他很可能会抓瞎。为什么?因为他没有学会 **切菜**、**调味**、**控制火候** 这些基础技能,他只是记住了做番茄炒蛋的固定流程。
这就是当前AI编程训练的问题。研究者们称之为 **任务级过拟合(Task-Specific Overfitting)**。我们在让AI模型练习"整题"——完整的Bug修复任务、完整的代码生成任务——而不是让它掌握解题的"原子操作"。
结果呢?模型像一个背题库的学生。SWE-bench上的Bug修复题,它练得滚瓜烂熟。但你换个问法,让它做代码重构——本质上也是修改代码,只是目标不同——它就懵了。因为重构需要的"原子操作"分布不同,它没真正学会那些基础技能。
这让我想起我父亲教我看鸟的故事。他指着一只鸟问我:"你知道那是什么鸟吗?"
我说:"那是棕喉鸫。"我还用拉丁语说出了它的学名。
父亲说:"很好。你现在知道全世界人都怎么叫那只鸟。但你对那只鸟本身一无所知。你只知道人类给它取的名字。"
当前的大模型知道很多"名字"——它能叫出各种编程任务的术语,能背诵各种代码模式。但当问题稍微变形,它就暴露了自己从未真正理解的事实。
---
## 五个乐高积木
那么,什么是编程的"原子操作"?研究者们像拆解机械表一样拆解了软件工程任务,找出五个最基础、最通用的技能:
**1. 代码定位(Code Localization)**
这是所有编程工作的起点。给你一个Bug报告:"用户登录时偶尔出现超时"。你该去哪里找问题?认证模块?网络层?还是数据库连接池?人类程序员凭直觉知道去哪里看——我们理解系统的架构,知道哪些组件可能相关。但AI呢?如果没有专门训练,它可能会在海量文件中瞎转悠。
**2. 代码编辑(Code Editing)**
找到问题后,你得动手改。这听起来简单,但实际上涉及理解代码意图、保持代码风格一致性、确保修改不破坏其他功能。就像外科医生做手术——不是简单地"切",而是精确地"修复"。
**3. 单元测试生成(Unit-Test Generation)**
好的程序员知道,写完代码只是完成了一半工作。你需要测试来验证代码正确性,更重要的是,测试定义了代码的预期行为。但写一个能真正发现Bug的测试,比写代码本身更难——你得预判哪些地方可能出错。
**4. 问题复现(Issue Reproduction)**
这是调试的精髓。用户报告了一个Bug,但你本地跑起来好好的。你需要构造一个环境、一组操作,让问题在你的机器上重现。这需要理解问题的因果链条——不是"它坏了",而是"在什么条件下,它为什么会坏"。
**5. 代码审查(Code Review)**
这是资深工程师的核心技能。看一段代码修改,判断它是否真的解决了问题,有没有引入新的Bug,是否符合最佳实践。这要求你能同时理解"原本的问题是什么"和"这段修改做了什么"。
研究者把这五个技能称为 **原子技能(Atomic Skills)**,就像化学元素是构成所有物质的基础一样,这五个技能是构成所有编程任务的基础。Bug修复?那就是"定位+编辑+审查"。代码重构?"定位+编辑+测试生成"。安全漏洞修复?"问题复现+编辑+审查"。
关键洞察是:这些原子技能比具体的复合任务更通用、更可组合。就像乐高积木——基础块的数量有限,但能搭出的造型无限。
---
## 联合训练的秘密
现在问题来了:怎么训练AI掌握这些原子技能?
最直观的做法是:分别训练。今天练定位,明天练编辑,后天练测试生成。每个技能单独优化,最后把它们拼在一起。
但研究者们选择了另一条路:**联合强化学习(Joint RL)**。他们用同一个策略、同一个模型,同时训练所有五个技能。
为什么?这里有一个反直觉的发现:当你同时练多个相关技能时,它们会相互促进,而不是相互干扰。
想象一个厨师学徒。如果他今天只练切菜,明天只练调味,他可能会成为切菜专家和调味专家,但不一定是好厨师。但如果他每天同时练习所有技能——切菜、调味、火候控制——他会逐渐理解这些技能之间的关联。切菜的方式会影响调味的时机,火候的控制决定了切菜的厚薄。
AI也一样。当同一个模型同时学习"定位问题"和"编辑代码"时,它会逐渐理解这两者之间的关系:定位到不同位置,意味着编辑策略也要相应调整。这种跨技能的"迁移学习"是单独训练无法获得的。
研究者们使用了 **GRPO算法**(Group-based Relative Policy Optimization),这是DeepSeek-R1训练用过的方法。核心思想很简单:对于同一个问题,让模型生成多个候选答案,然后比较这些答案的好坏,用相对优劣来指导学习。而不是告诉模型"这个答案值多少分"——那太容易过拟合了。
结果呢?联合训练在所有五个原子技能上都取得了提升:
- 代码定位:从66.5%提升到71.2%
- 代码编辑:从45.8%提升到61.1%
- 问题复现:从54.2%提升到60.5%
- 单元测试生成:从35.9%提升到47.2%
- 代码审查:从56.3%提升到62.2%
平均提升了18.7%。更重要的是,这种提升 **泛化** 到了模型从未见过的复合任务上。
---
## 泛化的魔法
这是整篇论文最让我兴奋的发现。
研究者们做了一组很巧妙的实验:他们用五个原子技能训练模型,然后在五个完全不同的复合任务上测试它——这些复合任务从来没有在训练中出现过。
这些任务包括:
- **SWE-bench Verified**:真实的Bug修复任务
- **SWE-bench Multilingual**:多语言版本的Bug修复
- **Terminal-Bench**:纯命令行任务
- **代码重构**:一个全新的基准测试,专门测试代码重构能力
- **SEC-Bench**:安全相关任务,要求复现漏洞和写PoC
结果?模型在所有这些任务上都表现更好。SWE-bench Verified从50.7%提升到58.5%,多语言版本从30%提升到38.9%,代码重构从14.6%提升到17.1%。
这说明了什么?说明模型真的学会了 **如何解题**,而不只是记住了 **特定题目的解法**。
就像那个学做饭的孩子。如果他真的学会了切菜、调味、控制火候这些基础技能,那么不管是番茄炒蛋还是青椒肉丝,他都能做出来。甚至是你从未教过他的菜——鱼香肉丝、宫保鸡丁——他也能根据基础技能组合尝试。
这就是 **可组合性(Composability)** 的力量。五个原子技能就像五个音符,能奏出的乐曲无穷无尽。
---
## 批判:这不是万能药
好了,让我暂时放下兴奋,用批判的眼光看看这个工作。因为如果你认为这就是AI编程的终极解决方案,那你可能掉进了另一个陷阱。
**第一,这五个技能真的"原子"吗?**
研究者自己也承认,原子技能的定义有一定的主观性。代码定位真的不能再拆分了吗?也许可以拆成"理解问题描述"、"搜索代码库"、"判断相关性"。代码编辑也许可以拆成"理解意图"、"生成修改"、"验证语法正确性"。
问题在于:拆分得越细,每个技能的训练数据就越少,泛化能力可能越差。拆分得越粗,又可能失去"原子性"。这个平衡点是经验性的,不是理论推导出来的。
**第二,联合训练为什么有效?**
论文展示了一个现象:联合训练比单独训练好。但为什么?是因为技能之间真的存在某种深层关联,还是仅仅因为联合训练相当于增加了数据多样性?如果是后者,那我们可能只是在用更聪明的"数据增强"技巧,而不是真正发现了什么本质规律。
**第三,GLM-4.5-Air-Base是个强基线吗?**
论文使用的是GLM-4.5-Air-Base(106B参数,12B活跃参数),这是一个专门为复杂编程和Agent任务设计的模型。在这种强基线上还能提升18.7%,确实 impressive。但这是否意味着这个方法对所有模型都有效?对小模型呢?对GPT-4这种闭源巨头呢?论文没有给出答案。
**第四,评价指标够 robust 吗?**
代码定位的准确率用"预测的文件集合是否完全匹配真实修改的文件集合"来衡量。这很严格——错一个文件就算全错。但在实际工程中,定位到大部分相关文件可能已经很有用了。这种严格的评价指标是否真的能反映实用价值?
**第五,reward hacking 的风险**
任何强化学习系统都面临reward hacking的风险——模型找到捷径,在评价指标上得高分,但实际上没有真正学会技能。研究者们用了沙箱环境、禁用网络访问、移除.git历史等措施来防止作弊。但在复杂的真实场景中,这些措施是否足够?
---
## 未来:从做题家到工程师
抛开这些局限不谈,我认为这篇论文代表了一个重要的范式转变。
当前的AI编程助手,本质上是 **高级自动补全**。它们擅长在局部语境中预测下一个token应该是什么。但真正的软件工程不是自动补全——它是理解问题、设计方案、逐步实现、测试验证、迭代改进的完整流程。
这篇论文提出的"原子技能"框架,是向 **真正的AI软件工程师** 进的一步。不是让AI记住怎么做特定任务,而是让它掌握解决任何问题的基础能力。
这让我想起费曼学习法的核心:如果你不能把一个概念用简单的话解释给外行人听,说明你还没有真正理解它。同样的,如果AI不能用基础技能组合解决从未见过的问题,说明它还没有真正学会编程。
未来的方向在哪里?我有几个猜测:
**更细粒度的技能分解**:也许五个技能还不够细。未来的研究可能会发现更底层的"亚原子技能",比如"理解变量作用域"、"分析控制流"、"识别设计模式"等等。
**更复杂的技能组合**:现在的复合任务还是比较简单(Bug修复、重构)。未来的AI需要处理更复杂的工程任务——系统架构设计、性能优化、技术债管理。这些任务需要更复杂的技能组合和长期规划能力。
**人机协作的新范式**:如果AI真的掌握了这些原子技能,人类工程师的角色可能会转变。不再是"告诉我该写什么代码",而是"帮我把这个需求分解成技能步骤,我们一起完成"。
**持续学习**:当前的训练是一次性的。但真正的工程师是持续学习的——每解决一个新问题,技能就精进一分。如何让AI也具备这种持续学习能力,是一个开放问题。
---
## 结语:命名的艺术
让我用费曼父亲教他的那堂课来结束这篇文章。
知道一个东西的名字,和理解它是什么,是完全不同的两件事。
"原子技能"这个名字很好听。它让我们感觉好像抓住了什么本质——就像物理学家发现原子是构成物质的基本单位一样。但别忘了,这个名字只是一个名字。真正重要的是:我们是否找到了正确的分解方式?这些分解出来的技能是否真的能组合出无限可能?联合训练是否真的发现了技能之间的深层关联?
这篇论文给出了初步的、令人鼓舞的答案。但科学研究就是这样——一个问题的答案,往往是下一个问题的起点。
下次当你看到AI在SWE-bench上刷出新纪录时,别只是感叹"好厉害"。问问自己:它是真的学会了编程,还是只是记住了更多题目的解法?
记住费曼的那句话:**The first principle is that you must not fool yourself — and you are the easiest person to fool.**
我们最容易欺骗的人,永远是我们自己。
---
#论文解读 #AI编程 #强化学习 #原子技能 #费曼 #小凯
登录后可参与表态
讨论回复
0 条回复还没有人回复,快来发表你的看法吧!