先写测试,再写代码,再跑测试,再改代码——这个流程对 LLM 同样有效

背景:直接生成的瓶颈

大多数代码生成方法是这样工作的:给模型一个问题描述,让它直接输出代码。这种方式简单,但对于复杂问题(比如编程竞赛题目),准确率不高。

AlphaCodium(Ridnik et al., 2024)的观察是:直接生成的主要问题不是模型能力不够,而是生成过程的结构不对。人类解决复杂编程问题时,通常不会直接上手写代码,而是先理解问题、想清楚边界情况、列出测试用例,再写代码,跑测试,改代码。AlphaCodium 把这个流程显式地编进了 Agent 的工作方式里。


AlphaCodium 的两阶段流程

阶段一:问题理解(Pre-Processing)

在写任何代码之前,Agent 先做几件事:

1. 理解问题

用自然语言重新描述问题,确认理解正确:

问题要求:给定一个整数数组,找出所有满足条件的子数组...
我的理解:需要遍历所有连续子数组,检查...
边界情况:空数组、单元素数组、全负数数组...

2. 生成候选测试用例

不等题目给测试,Agent 自己生成几个:

# 基本情况
assert solve([1, 2, 3]) == ...

# 边界情况
assert solve([]) == ...
assert solve([-1, -2]) == ...

# 特殊情况
assert solve([0, 0, 0]) == ...

3. 给测试用例排序

按照"最可能区分正确答案和错误答案"的能力,给测试用例打分,把最有区分度的测试放在前面。在后面的迭代里,优先用这些测试来驱动修正。

阶段二:迭代代码生成(Code Iterations)

有了测试用例之后,进入迭代循环:

生成代码
   ↓
跑公开测试(题目给的)
   ↓
通过?→ 跑 AI 生成的测试
   ↓
通过?→ 提交
   ↓
没通过?→ 分析失败的测试,修改代码 → 返回顶部

这个循环最多跑几轮(论文里是 3-5 轮),每一轮都针对具体失败的测试用例来修正,而不是盲目重写。


和直接生成的对比

论文在 CodeContests(竞赛编程题目)上的结果:

方法pass@1
GPT-4 直接生成19%
GPT-4 + 少样本28%
AlphaCodium(GPT-4)44%
AlphaCodium(GPT-4 Turbo)46%

在同样的模型上,流程设计的差异带来了约 2 倍的提升。这个结果说明,对于结构化的编程任务,生成流程的设计和模型本身的能力一样重要。


几个关键设计细节

为什么先生成测试再写代码

测试是对问题理解的一种验证。如果 Agent 对问题理解有偏差,生成测试的过程往往会暴露出来(比如测试的预期输出本身就是错的)。先生成测试,相当于强制 Agent 在写代码之前把问题想清楚。

为什么给测试排序

不是所有测试都同样有用。assert solve([]) == [] 可能很多实现都能通过,但 assert solve([1, -1, 1]) == 1 可能更能区分正确与错误的实现。把有区分度的测试放在前面,迭代修正的效率更高。

为什么限制迭代轮数

无限迭代并不比有限迭代好。超过一定轮数后,Agent 往往会在几个方案之间来回切换,而不是真正改进。固定上限,迭代不成功就换一个初始方案重新开始,比无限调试一个方案更有效。


和测试驱动开发(TDD)的对应

AlphaCodium 的流程和软件工程里的测试驱动开发(TDD)在结构上很像:

TDDAlphaCodium
先写测试AI 生成候选测试
跑测试(失败)跑测试(失败)
写代码让测试通过迭代生成代码
重构继续迭代直到通过

区别在于 TDD 里测试是人写的,AlphaCodium 里测试是 AI 生成的。AI 生成的测试可能有错(预期输出错误),这是这个方案的一个风险点。AlphaCodium 通过给测试排序和多轮验证来缓解这个问题,但没有完全解决。


适用范围

AlphaCodium 对有明确正确答案的任务效果好——编程竞赛、算法题、有单元测试的功能需求。对于开放式的代码生成任务(比如"写一个网页"),没有明确的测试标准,这套流程的优势就不那么明显了。

这也是大多数代码生成研究的共同局限:benchmark 上效果好的方法,在实际开发中不一定同样有效,因为真实开发任务的评价标准往往是模糊的。

版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:10. AlphaCodium:用测试驱动的迭代流程生成代码

本文链接:https://www.sshipanoo.com/blog/ai/code-agent-harness/10-AlphaCodium/

本文最后一次更新为 天前,文章中的某些内容可能已过时!