对应:Stanford CS329A Autumn 2025 Lecture 13(Mon 11/3,Agentic Frameworks for Software Engineering;10/24
10/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 的实验室。幻灯片没有公开,本讲依据这三篇论文编写。 配套代码:3 小时(含运行代码)code/lecture10/(只用 Python 标准库,每个文件 1 秒以内) 预计阅读时间:2.5
0. 本讲导航
0.1 学完本讲,你应该能够
- 说出为什么软件工程是 agent 最先变得可靠的领域,以及 SWE-bench 是什么、怎样评估。
- 说出 CodeMonkeys 怎样组合三种 test-time compute:读整个代码库找上下文(可以被多个样本分摊的固定成本)、并行的轨迹、每条轨迹里串行的”写测试 → 修改 → 跑测试”;以及怎样用模型写的测试投票 + 选择 agent 挑选。
- 说出 CodeMonkeys 的主要数字(coverage 69.8%、最终 57.4%、约 2300 美元、合并多个系统得到 66.2%)和”挑选收回了约一半的差距”。
- 说出 KernelBench 的设计(250 个任务、三个级别)和 fast_p 指标的定义;说出前沿模型的表现和”执行 + 性能分析反馈”带来的提升。
- 说出 Agent–System Interface 的两个组件:领域专用语言(缩小、规整搜索空间)和 AutoGuide(把原始的执行输出翻译成”解释 + 建议”);以及”10 轮胜过 OpenTuner 1000 轮”的结果。
- 总结一条贯穿本讲的经验:给 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 的做法简单粗暴:
- 用一个本地运行的小模型(Qwen2.5-Coder-32B-Instruct)读代码库里的每一个文件,判断它和 issue 是否相关。平均每个问题要读 294 万个 token。
- 用 Claude 3.5 Sonnet 给相关的文件排序。
- 按排名把文件的完整内容放进上下文,直到 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 个候选修改,怎样挑一个?
- 用模型写的测试投票:把每条轨迹生成的测试,都在所有候选上跑一遍,选通过最多的。这和第 8 讲 AlphaCode 的”按行为聚类”思想相通:不只看候选自己的测试,而是看它和其他轨迹对”正确行为”的理解是否一致。
- 选择状态机:投票的前 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)
| 轨迹数 \ 每条轨迹的轮数 | 1 | 2 | 4 | 8 |
|---|---|---|---|---|
| 1 | 0.380 | 0.580 | 0.633 | 0.647 |
| 2 | 0.620 | 0.747 | 0.687 | 0.727 |
| 5 | 0.760 | 0.860 | 0.847 | 0.853 |
| 10 | 0.867 | 0.907 | 0.900 | 0.900 |
(相邻格子之间 0.03~0.05 的差别可能只是随机波动。)
- 并行和串行都能提高 coverage。串行的收益来得快、但很快饱和:第一次修改的收益最大,之后几乎不再提高——修改是朝着模型自己写的测试去改的,测试写错了,越改越偏。并行的收益更持久:不同的轨迹写出不同的测试、不同的修复。
演示 2:挑选( = 10)
| 挑选方法 | 不迭代( = 1) | 迭代 4 轮( = 4) |
|---|---|---|
| 随机挑一个 | 0.453 | 0.673 |
| 模型写的测试投票 | 0.673 | 0.627 |
| 投票 + 选择状态机(100B) | 0.753 | 0.680 |
| oracle(coverage) | 0.873 | 0.887 |
| 收回的差距 | 71% | 3% |
- 不迭代时,测试投票和选择 agent 很有价值:从随机的 0.453 提高到 0.753,收回了 71% 的差距。
- 迭代 4 轮之后,投票反而比随机还差。每条轨迹都已经朝着自己的测试修改过,候选和测试高度一致;模型最常犯的那个错误,同时占据了很多候选和很多测试,投票就会偏向它。这又是第 1 讲”self-check 是一种软的 majority vote”的问题:测试和修复出自同一个模型,错误是相关的。
- CodeMonkeys 的选择状态机能写新的测试来区分候选,比 toy 里”自己算一遍”的选择者强得多;这是它能收回一半差距的关键。
演示 3:合并几个系统的候选
| 单独挑选 | |
|---|---|
| 系统 A:30B,温度 0.7 | 0.867 |
| 系统 B:30B,温度 1.0 | 0.907 |
| 系统 C:20B,温度 0.7 | 0.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 提出了一个新的指标:
即”正确并且比 PyTorch 快 倍以上”的任务所占的比例。 就是正确率; 是”正确且不比 PyTorch 慢”; 越大,要求越高。用一个阈值 把”正确”和”快”合在一个数字里,而且可以调节要求的高低。
3.4 结果
前沿模型一次写出的 kernel,fast_1:
| 模型 | 第 1 级 | 第 2 级 | 第 3 级 |
|---|---|---|---|
| OpenAI o1 | 10% | 24% | 12% |
| DeepSeek-R1 | 12% | 36% | 2% |
| GPT-4o | 4% | 5% | 0% |
| Claude 3.5 Sonnet | 10% | 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.27 | 0.81 / 0.34 | 0.92 / 0.35 | 0.97 / 0.46 |
| 只有标量反馈 | 0.58 / 0.18 | 0.77 / 0.30 | 0.87 / 0.39 | 0.97 / 0.46 |
| + 执行反馈(解释错误) | 0.83 / 0.24 | 0.94 / 0.39 | 0.98 / 0.45 | 0.99 / 0.49 |
| + 性能分析建议 | 0.86 / 0.26 | 0.96 / 0.37 | 0.98 / 0.38 | 0.99 / 0.40 |
- 只有标量反馈时,从一个失败的配置出发随机改一个旋钮,常常还是失败——在少数几轮里,它甚至不如每轮重新写一个(重复采样)。
- 知道为什么失败,就能直接修好它(例如把向量宽度改成能整除问题规模的值):执行反馈的 fast_1 始终明显高于标量反馈和重复采样。这正是 Agent–System Interface 和 KernelBench 的共同发现。
- 性能分析的建议在前几轮最有用(10 轮时 fast_1 最高),但它把修改限制在和瓶颈相关的旋钮上,轮数多了以后,在更高的加速要求(fast_1.5)上反而不如”只解释错误”。有用的建议加快了早期的进步,也缩窄了搜索——好的反馈应该是”建议”,而不是”命令”。
- 越大,所有方法都越难;fast_p 随 下降的速度,反映了”优化的深度”。
5. 共同的经验
- 验证是骨架:测试、编译器、正确性检查、性能分析,让软件工程成为 test-time compute 和自我改进最有效的领域。但模型自己写的测试也会错,而且和修复错得一样(第 2.6 节演示 2);对 kernel 来说,“正确性检查”必须覆盖足够多样的输入,否则一个只在测试规模上正确的 kernel 会被误判为正确。
- 接口和模型一样重要:SWE-agent 的 ACI、Agent–System Interface 的 DSL 和 AutoGuide,都是在为 agent 设计动作空间和反馈。一个好的接口能把”0% 成功”变成”80% 成功”。第 9 讲说”人的角色在上移到设计环境和奖励”,这里就是具体的例子。
- 并行、串行和挑选要一起设计:读整个代码库的固定成本可以被并行的样本分摊;串行修改的收益来得快但会饱和;挑选的能力决定了 coverage 能变成多少真实的成绩。
- 小心被钻空子:只看”测试通过”,agent 可能学会修改测试本身;只看”快了多少”,一个 kernel 可能跳过了一部分计算。第 9 讲提到的编程任务里的 reward hacking,在 SWE 和 kernel 优化里都是真实的风险。
6. 小结
- 软件工程是 agent 最先变得可靠的领域,因为代码可以运行、可以测试。SWE-bench(2294 个真实 issue;Verified 版 500 个)是主要的 benchmark,从不到 2% 进步到 2025 年的 70% 以上。agent 式和流水线式(Agentless)两类做法;ACI 强调为 agent 设计专门的接口。
- CodeMonkeys:让小模型读每一个文件找上下文(固定成本,可被分摊);10 条并行的轨迹,每条里测试状态机和编辑状态机最多 8 轮;用模型写的测试投票 + 能写新测试的选择 agent 挑选。coverage 69.8%,最终 57.4%(收回约一半的差距),约 2300 美元;合并多个顶级系统得到 66.2%。toy world 显示:串行修改的收益快但饱和;迭代之后,模型自己的测试和修复错误相关,投票甚至不如随机;合并同一家族的系统没有帮助——合并的价值来自”错得不一样”。
- KernelBench:250 个 PyTorch 任务(三级),fast_p = 正确且加速比 > p 的比例。前沿模型一次写出的 kernel 在不到 20% 的情况下达到 PyTorch 的速度;重复采样和”执行 + 性能分析”反馈的迭代修改能大幅提高(DeepSeek-R1 第 2 级:36% → 72%)。
- Agent–System Interface:DSL 把 LLM 写 mapper 的成功率从 0% 提高到 80%~100%;AutoGuide 把原始输出翻译成”解释 + 建议”;10 轮胜过 OpenTuner 的 1000 轮(快 3.8 倍),最多比专家快 1.34 倍。toy world 显示:解释错误的反馈最稳定地有效;具体的建议加快早期进步,也可能缩窄搜索。
- 共同的经验:验证是骨架,接口和模型一样重要,并行 / 串行 / 挑选要一起设计,小心 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)代替把整个语料塞进上下文。