第 10 讲:软件工程的 Agent 框架——CodeMonkeys、KernelBench 与 Agent–System Interface

Self-Improving AI Agents · Lecture 10。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应:Stanford CS329A Autumn 2025 Lecture 13(Mon 11/3,Agentic Frameworks for Software Engineering;10/2410/31 是期中展示)。阅读材料:CodeMonkeys: Scaling Test-Time Compute for Software Engineering(Ehrlich et al. 2025)、KernelBench: Can LLMs Write Efficient GPU Kernels?(Ouyang et al. 2025)、Improving Parallel Program Performance with LLM Optimizers via Agent-System Interfaces(Wei et al. 2024)。前两篇来自讲师 Azalia Mirhoseini 的实验室。幻灯片没有公开,本讲依据这三篇论文编写。 配套代码:code/lecture10/(只用 Python 标准库,每个文件 1 秒以内) 预计阅读时间:2.53 小时(含运行代码)


0. 本讲导航

0.1 学完本讲,你应该能够

  1. 说出为什么软件工程是 agent 最先变得可靠的领域,以及 SWE-bench 是什么、怎样评估。
  2. 说出 CodeMonkeys 怎样组合三种 test-time compute:读整个代码库找上下文(可以被多个样本分摊的固定成本)、并行的轨迹、每条轨迹里串行的”写测试 → 修改 → 跑测试”;以及怎样用模型写的测试投票 + 选择 agent 挑选。
  3. 说出 CodeMonkeys 的主要数字(coverage 69.8%、最终 57.4%、约 2300 美元、合并多个系统得到 66.2%)和”挑选收回了约一半的差距”。
  4. 说出 KernelBench 的设计(250 个任务、三个级别)和 fast_p 指标的定义;说出前沿模型的表现和”执行 + 性能分析反馈”带来的提升。
  5. 说出 Agent–System Interface 的两个组件:领域专用语言(缩小、规整搜索空间)和 AutoGuide(把原始的执行输出翻译成”解释 + 建议”);以及”10 轮胜过 OpenTuner 1000 轮”的结果。
  6. 总结一条贯穿本讲的经验:给 agent 设计的接口(动作空间和反馈)和模型本身一样重要。

0.2 先修知识

知识点用在哪里最低要求
第 2、3 讲第 2 节并行 vs 串行、coverage 与挑选的差距、verifier
第 4 讲第 3、4 节执行反馈、RLEF
第 8 讲第 2 节AlphaCode 的过滤与聚类
GPU 的基本概念第 3 节知道 kernel 是”在 GPU 上运行的一个函数”;显存、共享内存的直觉(不熟也能读懂)

0.3 本讲地图

第1节  为什么是软件工程;SWE-bench 与 agent 的脚手架
第2节  CodeMonkeys:串行 + 并行 + 挑选                         ← 代码 01
第3节  KernelBench:又对又快的 GPU kernel                      ← 代码 02
第4节  Agent–System Interface:为优化任务设计接口和反馈         ← 代码 02
第5节  共同的经验
第6–9节 小结、练习、延伸阅读、下一讲预告

0.4 本讲的代码

  • 01_codemonkeys.py:一个”issue”是第 1 讲的一道算术题。每条轨迹先让模型自己算一遍、写出”复现测试”(测试也会写错),再写修复、跑自己的测试、不通过就修改(第 2 讲的 revise)。挑选时用所有轨迹写的测试投票,再让一个更强的模型(100B)在前 3 名里选。
  • 02_kernel_optimization.py:一个有 5 个旋钮(tile、融合、向量化、共享内存、展开)的”kernel”,每个任务有隐藏的特性(会不会算错、会不会编译失败、瓶颈在哪里)。比较不同反馈下的迭代优化。不同反馈下”提议者怎样利用信息”是设定的。

关于本讲的数字:论文里的数字注明出处;模拟实验的数字都来自 01、02 号代码的实际输出(固定随机种子,Python 3.9 与 3.13 逐字相同)。


1. 为什么是软件工程

1.1 有测试,就有可靠的反馈

第 1 讲第 6.8 节说过:自我改进最先在”容易验证”的领域成功。软件工程正是这样的领域:

  • 代码可以运行:编译器、解释器、运行时错误都是即时、精确的反馈。
  • 很多项目有测试:一个修改对不对,跑一下测试就知道(在测试覆盖的范围内)。
  • 任务有明确的目标:修好这个 bug、让这个函数快一倍。

所以 coding agent 是最早变得真正可用的 agent(第 1 讲第 6.2 节),也是 test-time compute 和 RL 最容易发挥作用的地方。

1.2 SWE-bench

Jimenez et al. 2023 的 SWE-bench 从 12 个流行的 Python 开源项目里收集了 2294 个真实的 GitHub issue 和对应的修复。任务是:给定代码库和 issue 的描述,生成一个补丁;评估时运行项目的测试,看原来失败的测试是否通过、原来通过的测试是否仍然通过。

它比 HumanEval 这类”写一个函数”的任务难得多:要在几百上千个文件里找到相关的代码,理解项目的结构,写出和现有代码一致的修改。论文发布时,最好的模型只能解决不到 2% 的 issue。2024 年 OpenAI 和 SWE-bench 的作者一起发布了 SWE-bench Verified:人工筛选出的 500 个描述清楚、测试合理的 issue,成为最常用的版本。到 2025 年,前沿系统在 Verified 上已经超过 70%。

1.3 Agent 的脚手架

解 SWE-bench 有两类做法:

  • agent 式:给模型一组工具(浏览文件、搜索、编辑、运行命令),让它自己决定下一步(ReAct 式的循环)。SWE-agent(Yang et al. 2024)提出了 ACI(agent–computer interface)的概念:为 LM agent 专门设计的命令和反馈格式(例如带行号的文件查看器、会检查语法的编辑命令),比直接让它用 bash 好得多。
  • 流水线式:固定的几个阶段——定位相关的文件和函数 → 生成修复 → 用测试验证。Agentless(Xia et al. 2024)显示,这样一个简单的流水线可以和复杂的 agent 竞争,而且便宜得多。

这正是第 1 讲第 6.3 节”workflow vs agent”的区别。CodeMonkeys 介于两者之间:整体是固定的流水线,每个阶段内部是一个小的 agent(状态机)。


2. CodeMonkeys:串行 + 并行 + 挑选

2.1 问题

第 2 讲研究了 test-time compute 的几种扩展方式:并行采样、顺序修改、搜索。在 SWE-bench 这样的真实任务上,怎样把它们组合起来?Ehrlich et al. 2025(作者包括讲师 Azalia Mirhoseini)的 CodeMonkeys 给出了一个具体的系统。

2.2 第一步:找上下文——让 LLM 读每一个文件

一个代码库可能有几百万个 token,放不进上下文。CodeMonkeys 的做法简单粗暴:

  1. 用一个本地运行的小模型(Qwen2.5-Coder-32B-Instruct)读代码库里的每一个文件,判断它和 issue 是否相关。平均每个问题要读 294 万个 token。
  2. 用 Claude 3.5 Sonnet 给相关的文件排序。
  3. 按排名把文件的完整内容放进上下文,直到 12.8 万个 token。上下文缩小了约 50 倍(平均 7.5 万个 token),92.6% 的问题里,需要修改的文件都在上下文里。

为什么可以这么”浪费”?因为这是固定成本:每个问题只做一次,之后所有的并行轨迹都共用这份上下文。并行采样越多,分摊到每个样本上的成本越低。这是并行扩展的一个重要的经济学优势。

2.3 第二步:并行的轨迹,每条轨迹串行地修改

每条轨迹包含两个状态机(小 agent):

  • 测试状态机:生成一个复现 issue 的测试脚本,根据执行结果反复修改,直到它在未修改的代码上能正确地暴露问题。
  • 编辑状态机:根据 issue、上下文和测试的输出生成修改(diff),运行测试,根据结果继续修改。它也可以回头修改测试(“双向调试”:确保测试在修改前失败、修改后通过)。

每个问题并行跑 10 条轨迹,每条最多 8 轮。这样就有两个扩展的旋钮:轨迹数(并行)和每条轨迹的轮数(串行)。在 SWE-bench Verified 上,10 × 8 的配置得到 69.8% 的 coverage(10 个候选里至少有一个正确的比例)。

2.4 第三步:挑选

有了 10 个候选修改,怎样挑一个?

  1. 用模型写的测试投票:把每条轨迹生成的测试,都在所有候选上跑一遍,选通过最多的。这和第 8 讲 AlphaCode 的”按行为聚类”思想相通:不只看候选自己的测试,而是看它和其他轨迹对”正确行为”的理解是否一致。
  2. 选择状态机:投票的前 3 名交给一个专门的 agent,它可以写新的测试来区分这几个候选,最后选出一个。

最终得分 57.4%。论文的总结是:挑选收回了”随机挑一个”到”oracle 挑选”之间大约一半的差距——coverage 是 69.8%,挑选仍然丢掉了约 12 个百分点。第 2、3 讲的 generation–verification gap 在这里依然存在。

2.5 成本与合并

  • 总成本约 2300 美元(500 个问题):生成修改占 59.6%,生成测试 19.2%,读文件找上下文 14.6%,挑选 5.8%。换成 DeepSeek-V3,可以用低得多的成本达到 86.8% 的得分。
  • Barrel of Monkeys:挑选方法可以用来合并不同来源的候选。把 SWE-bench Verified 排行榜上几个顶级系统的候选和 CodeMonkeys 的候选放在一起,用同样的挑选方法,得到 66.2%,超过了其中最好的单个系统。

2.6 toy world 里的 CodeMonkeys

演示 1:coverage 随并行和串行的变化(10B 模型,150 个 issue)

轨迹数 TT \ 每条轨迹的轮数 LL1248
10.3800.5800.6330.647
20.6200.7470.6870.727
50.7600.8600.8470.853
100.8670.9070.9000.900

(相邻格子之间 0.03~0.05 的差别可能只是随机波动。)

  • 并行和串行都能提高 coverage。串行的收益来得快、但很快饱和:第一次修改的收益最大,之后几乎不再提高——修改是朝着模型自己写的测试去改的,测试写错了,越改越偏。并行的收益更持久:不同的轨迹写出不同的测试、不同的修复。

演示 2:挑选(TT = 10)

挑选方法不迭代(LL = 1)迭代 4 轮(LL = 4)
随机挑一个0.4530.673
模型写的测试投票0.6730.627
投票 + 选择状态机(100B)0.7530.680
oracle(coverage)0.8730.887
收回的差距71%3%
  • 不迭代时,测试投票和选择 agent 很有价值:从随机的 0.453 提高到 0.753,收回了 71% 的差距。
  • 迭代 4 轮之后,投票反而比随机还差。每条轨迹都已经朝着自己的测试修改过,候选和测试高度一致;模型最常犯的那个错误,同时占据了很多候选和很多测试,投票就会偏向它。这又是第 1 讲”self-check 是一种软的 majority vote”的问题:测试和修复出自同一个模型,错误是相关的。
  • CodeMonkeys 的选择状态机能写新的测试来区分候选,比 toy 里”自己算一遍”的选择者强得多;这是它能收回一半差距的关键。

演示 3:合并几个系统的候选

单独挑选
系统 A:30B,温度 0.70.867
系统 B:30B,温度 1.00.907
系统 C:20B,温度 0.70.807
三个系统合在一起0.833

在 toy world 里,合在一起挑选没有超过最好的单个系统。三个系统是同一个”模型家族”,共享同样的系统性错误;合并之后,这些共同的错误在测试投票里更占优势。论文合并的是来自不同团队、不同方法的顶级系统,它们错得不一样,选择 agent 又很强。合并的价值取决于多样性和挑选的能力——又是”错得不一样”的原则。


3. KernelBench:又对又快的 GPU kernel

3.1 为什么是 kernel

深度学习的速度很大程度上取决于 GPU kernel:在 GPU 上执行矩阵乘法、卷积、注意力等运算的底层函数。写一个高效的 kernel 需要很深的专业知识(内存层次、并行粒度、数据布局),非常耗时。FlashAttention 这样的工作,本质上就是一个写得极好的 kernel。如果 LLM 能自动写出高效的 kernel,收益是直接的:模型训练和推理都变快。

难点在于:kernel 既要正确,又要快。而且 CUDA 这类底层代码在训练数据里很少——论文统计,在 The Stack v1.2 这个流行的代码语料里,CUDA 只占 0.073%。

3.2 设计

Ouyang et al. 2025(作者包括讲师 Azalia Mirhoseini)的 KernelBench 有 250 个 PyTorch 的计算任务,分三级:

  • 第 1 级(100 个):单个基本运算——卷积、矩阵乘法、损失函数、激活函数、层归一化……
  • 第 2 级(100 个):几个运算的序列(例如卷积 + ReLU + 加偏置),有融合的机会。
  • 第 3 级(50 个):完整的模型结构(来自 GitHub 上流行的仓库)。

模型的任务是写出一个替代 PyTorch 实现的 kernel。评估:

  • 正确性:在随机生成的输入上和 PyTorch 的结果比较。
  • 速度:多次计时,算出相对 PyTorch eager 模式的加速比。

3.3 fast_p

KernelBench 提出了一个新的指标:

fastp=1N∑i=1N1[kerneli 正确  ∧  加速比i>p]\text{fast}_p = \frac{1}{N}\sum_{i=1}^{N} \mathbb{1}\big[\text{kernel}_i \text{ 正确} \;\wedge\; \text{加速比}_i > p\big]

即”正确并且比 PyTorch 快 pp 倍以上”的任务所占的比例。fast0\text{fast}_0 就是正确率;fast1\text{fast}_1 是”正确且不比 PyTorch 慢”;pp 越大,要求越高。用一个阈值 pp 把”正确”和”快”合在一个数字里,而且可以调节要求的高低。

3.4 结果

前沿模型一次写出的 kernel,fast_1:

模型第 1 级第 2 级第 3 级
OpenAI o110%24%12%
DeepSeek-R112%36%2%
GPT-4o4%5%0%
Claude 3.5 Sonnet10%7%2%

reasoning model 表现最好,但整体上不到 20% 的情况能达到 PyTorch 的速度。test-time 的方法能明显帮忙:

  • 重复采样:DeepSeek-V3 在第 2 级上采样 100 次,fast_1 从 4% 提高到 37%。
  • 迭代修改 + 反馈:把执行反馈(编译错误、正确性错误)和性能分析反馈(profiler 的输出)给模型,让它修改 10 轮,DeepSeek-R1 在第 2 级上的 fast_1 从 36% 提高到 72%。迭代修改比单纯的重复采样更有效。

失败的分析:编译错误、内存访问越界、运行时崩溃这类执行失败很常见;功能上的错误(输出的形状或数值不对)对所有模型都同样困难;即使正确,大部分 kernel 也比 PyTorch 慢。另外,同一个 kernel 在不同的 GPU 上表现差别很大(DeepSeek-R1 第 2 级的 fast_1,在 L40S 上 36%,在 A10G 上 47%)。


4. Agent–System Interface:为优化任务设计接口和反馈

4.1 问题:mapper

Wei et al. 2024(Stanford,Alex Aiken 组)研究的是并行程序的性能。在 Legion 这样的并行编程框架里,mapper 决定”哪个任务放在哪个处理器上、哪块数据放在哪种内存里”。好的 mapper 能带来数量级的加速,但它是几百行复杂的 C++ 代码,专家要调好几天。

能不能让 LLM 来写 mapper?直接让 LLM 写 C++ mapper 几乎完全失败。论文的回答是:不是模型不够强,而是接口不对。

4.2 两个组件

(1) 领域专用语言(DSL):用声明式的语句代替命令式的 C++。例如:

  • 任务语句:这个任务放在 CPU、GPU 还是 OpenMP 上;
  • 区域语句:数据放在 GPU 显存、零拷贝内存还是系统内存里;
  • 布局语句:数据结构是 SOA 还是 AOS、C 顺序还是 Fortran 顺序;
  • 下标映射语句:任务的下标怎样映射到处理器的维度上。

DSL 把代码量平均减少了 14 倍,更重要的是它定义了一个结构化的搜索空间。结果非常鲜明:单次生成时,用 DSL 写的 mapper 80% 能正确运行,用 C++ 写的 0%;加上迭代修改,DSL 100%,C++ 仍然 0%——尽管训练数据里有大量的 C++,而这个 DSL 在训练数据里根本不存在。

(2) AutoGuide:把原始的执行输出翻译成可以行动的反馈:

原始输出AutoGuide 的输出
“Assertion failed: stride does not match expected value”“调整布局约束,或者把任务移到别的处理器类型上”
“Execution time is 0.03s”“把更多的任务移到 GPU 上,以减少执行时间”

然后用一个”生成式优化器”(Trace 框架)根据这些反馈迭代地修改 mapper。

4.3 结果

  • 和 OpenTuner(只用标量的运行时间作为反馈的传统自动调优方法)比较:只用 10 轮迭代,找到的 mapper 就比 OpenTuner 跑 1000 轮的结果快 3.8 倍。
  • 和专家比较:在 9 个基准(3 个科学计算应用、6 种矩阵乘法算法)上,最多比专家写的 mapper 快 1.34 倍。
  • 调优时间:从几天缩短到几分钟。
  • 消融:没有反馈(0-shot / 5-shot)最差;只有执行结果,提升很小;加上”解释”更好;“解释 + 建议”最好。

4.4 toy world:不同的反馈,同样的轮数

02_kernel_optimization.py 演示 1 先看”一次写出来”的 kernel(200 个任务):27.0% 编译失败、31.0% 结果不对,只有 42.0% 正确;fast_1 = 0.320,fast_1.5 = 0.105。模型(被设定为)爱用激进的优化——大 tile + 共享内存、宽向量化、融合——每一种都可能在某些任务上出错。

演示 2 比较不同反馈下的迭代优化(fast_1 / fast_1.5):

反馈5 轮10 轮20 轮50 轮
重复采样(不用反馈)0.72 / 0.270.81 / 0.340.92 / 0.350.97 / 0.46
只有标量反馈0.58 / 0.180.77 / 0.300.87 / 0.390.97 / 0.46
+ 执行反馈(解释错误)0.83 / 0.240.94 / 0.390.98 / 0.450.99 / 0.49
+ 性能分析建议0.86 / 0.260.96 / 0.370.98 / 0.380.99 / 0.40
  • 只有标量反馈时,从一个失败的配置出发随机改一个旋钮,常常还是失败——在少数几轮里,它甚至不如每轮重新写一个(重复采样)。
  • 知道为什么失败,就能直接修好它(例如把向量宽度改成能整除问题规模的值):执行反馈的 fast_1 始终明显高于标量反馈和重复采样。这正是 Agent–System Interface 和 KernelBench 的共同发现。
  • 性能分析的建议在前几轮最有用(10 轮时 fast_1 最高),但它把修改限制在和瓶颈相关的旋钮上,轮数多了以后,在更高的加速要求(fast_1.5)上反而不如”只解释错误”。有用的建议加快了早期的进步,也缩窄了搜索——好的反馈应该是”建议”,而不是”命令”。
  • pp 越大,所有方法都越难;fast_p 随 pp 下降的速度,反映了”优化的深度”。

5. 共同的经验

  1. 验证是骨架:测试、编译器、正确性检查、性能分析,让软件工程成为 test-time compute 和自我改进最有效的领域。但模型自己写的测试也会错,而且和修复错得一样(第 2.6 节演示 2);对 kernel 来说,“正确性检查”必须覆盖足够多样的输入,否则一个只在测试规模上正确的 kernel 会被误判为正确。
  2. 接口和模型一样重要:SWE-agent 的 ACI、Agent–System Interface 的 DSL 和 AutoGuide,都是在为 agent 设计动作空间和反馈。一个好的接口能把”0% 成功”变成”80% 成功”。第 9 讲说”人的角色在上移到设计环境和奖励”,这里就是具体的例子。
  3. 并行、串行和挑选要一起设计:读整个代码库的固定成本可以被并行的样本分摊;串行修改的收益来得快但会饱和;挑选的能力决定了 coverage 能变成多少真实的成绩。
  4. 小心被钻空子:只看”测试通过”,agent 可能学会修改测试本身;只看”快了多少”,一个 kernel 可能跳过了一部分计算。第 9 讲提到的编程任务里的 reward hacking,在 SWE 和 kernel 优化里都是真实的风险。

6. 小结

  1. 软件工程是 agent 最先变得可靠的领域,因为代码可以运行、可以测试。SWE-bench(2294 个真实 issue;Verified 版 500 个)是主要的 benchmark,从不到 2% 进步到 2025 年的 70% 以上。agent 式和流水线式(Agentless)两类做法;ACI 强调为 agent 设计专门的接口。
  2. CodeMonkeys:让小模型读每一个文件找上下文(固定成本,可被分摊);10 条并行的轨迹,每条里测试状态机和编辑状态机最多 8 轮;用模型写的测试投票 + 能写新测试的选择 agent 挑选。coverage 69.8%,最终 57.4%(收回约一半的差距),约 2300 美元;合并多个顶级系统得到 66.2%。toy world 显示:串行修改的收益快但饱和;迭代之后,模型自己的测试和修复错误相关,投票甚至不如随机;合并同一家族的系统没有帮助——合并的价值来自”错得不一样”。
  3. KernelBench:250 个 PyTorch 任务(三级),fast_p = 正确且加速比 > p 的比例。前沿模型一次写出的 kernel 在不到 20% 的情况下达到 PyTorch 的速度;重复采样和”执行 + 性能分析”反馈的迭代修改能大幅提高(DeepSeek-R1 第 2 级:36% → 72%)。
  4. Agent–System Interface:DSL 把 LLM 写 mapper 的成功率从 0% 提高到 80%~100%;AutoGuide 把原始输出翻译成”解释 + 建议”;10 轮胜过 OpenTuner 的 1000 轮(快 3.8 倍),最多比专家快 1.34 倍。toy world 显示:解释错误的反馈最稳定地有效;具体的建议加快早期进步,也可能缩窄搜索。
  5. 共同的经验:验证是骨架,接口和模型一样重要,并行 / 串行 / 挑选要一起设计,小心 agent 钻测试和指标的空子。

7. 练习

1. 固定成本的分摊(第 2.2 节) CodeMonkeys 读文件找上下文的成本约占总成本的 14.6%,生成修改占 59.6%(10 条轨迹)。 (a) 如果只跑 1 条轨迹(其他成本按比例减少,找上下文的成本不变),找上下文的成本占比是多少? (b) 这说明”让 LLM 读每一个文件”这种做法在什么情况下划算?

参考答案

(a) 设总成本 100:找上下文 14.6,其余(测试、修改、挑选、排序)85.4 与轨迹数成正比(近似)。1 条轨迹时其余部分约 8.54,总成本约 23.1,找上下文占约 63%。 (b) 只有当这份上下文被很多样本共用时才划算;并行的样本越多,固定成本越不重要。这也是”并行扩展”在经济上的一个优势。

2. 自己的测试(第 2.6 节) (a) 为什么迭代之后,“模型写的测试投票”反而不如随机挑选?用”候选和测试的错误相关”解释。 (b) CodeMonkeys 的选择状态机可以写新的测试来区分前 3 名候选。为什么这比”再投一次票”更有用? (c) 如果测试由另一个模型来写(和写修复的模型不同),你预计演示 2 的结果会怎样变化?在 01 号文件里试一试。

3. fast_p(第 3.3 节) 5 个任务的结果:正确且加速比 0.8;正确且加速比 1.2;错误;正确且加速比 2.5;正确且加速比 1.6。 (a) 算 fast_0、fast_1、fast_1.5、fast_2。 (b) 为什么 KernelBench 不直接报告”平均加速比”?

参考答案

(a) fast_0 = 4/5 = 0.8;fast_1 = 3/5 = 0.6(1.2、2.5、1.6);fast_1.5 = 2/5 = 0.4(2.5、1.6);fast_2 = 1/5 = 0.2。 (b) 平均加速比会被少数几个巨大的加速(或者错误的 kernel,例如跳过了计算而显得很快)主导,也没法处理”不正确”的 kernel(加速比没有意义)。fast_p 把正确性和速度合在一起,而且对极端值不敏感。

4. DSL 为什么有用(第 4.2 节) 用 C++ 写 mapper 的成功率是 0%,用 DSL 是 80%——即使 DSL 在训练数据里根本不存在。给出至少两个解释。这对你设计 agent 的工具有什么启示?

5. 建议 vs 命令(第 4.4 节) 02 号文件里,“性能分析建议”把修改限制在和瓶颈相关的旋钮上。 (a) 为什么这会在 fast_1.5 上变差? (b) 修改 propose:以 70% 的概率按建议挑旋钮、30% 的概率随机挑。结果会怎样?试一试。

6. 被钻空子(第 5 节) (a) 一个 coding agent 的奖励是”测试全部通过”。列出至少三种它可能”作弊”的方式。 (b) 一个 kernel 优化 agent 的奖励是”比 PyTorch 快多少”。列出至少两种它可能”作弊”的方式,以及你会怎样设计评估来防止它们。

7. 动手改代码 (a) 01 号文件:把挑选时选择者考虑的候选从前 3 名扩大到全部 10 个,L = 4 时的结果会改善吗? (b) 02 号文件:把”一次写出来”的配置改得更保守(例如 vec 和 shared 的概率都降低),一次写出的正确率和 fast_1.5 怎样变化?


8. 延伸阅读

本讲的阅读材料

  • Ehrlich et al. 2025. CodeMonkeys: Scaling Test-Time Compute for Software Engineering.
  • Ouyang et al. 2025. KernelBench: Can LLMs Write Efficient GPU Kernels?
  • Wei et al. 2024. Improving Parallel Program Performance with LLM Optimizers via Agent-System Interfaces.

相关工作

  • Jimenez et al. 2023. SWE-bench: Can Language Models Resolve Real-World GitHub Issues?
  • Yang et al. 2024. SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering.
  • Xia et al. 2024. Agentless: Demystifying LLM-based Software Engineering Agents.
  • Dao et al. 2022. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness.(一个写得极好的 kernel 能带来什么)
  • 同目录 CS224V 第 12 讲(coding agent 的结构与元优化)、CS336 第 6 讲(GPU kernel 与 Triton)。

9. 下一讲预告

第 11 讲:给 Agent 加上记忆(客座:Junchen Jiang,LMCache / UChicago)

CodeMonkeys 要把 7.5 万个 token 的代码放进上下文——每一次调用都要重新处理一遍。agent 越来越多地需要处理长的上下文:长对话、大代码库、一整本书。第 11 讲讨论:

  • MemGPT:把 LLM 当作操作系统,在”主上下文”和”外部存储”之间分页。
  • CacheBlend:检索到的文档的 KV cache 能不能复用?不在开头的文档怎样复用?
  • Cartridges:为一个语料库离线训练一个小的 KV cache,用”自学”(self-study)代替把整个语料塞进上下文。
← 返回课程目录