CodeScene 公布的一项案例显示,编码 Agent 在三周内重构了约 30 万行 C 代码,Token 成本约为 4,000 美元。整个过程通过逐帧回放测试验证,Agent 还在执行过程中积累了一套针对该代码库的重构配方。
这些数字足够醒目,但更值得工程团队关注的不是“Agent 一次能改多少行”,而是:在什么验证条件下,大规模自动修改才值得信任?
30 万行是工作量指标,不是质量指标
代码行数可以描述变更规模,却无法单独证明重构成功。机械格式化、批量重命名、提取函数和重新组织模块,都可能产生很大的 diff;真正关键的是系统行为有没有保持不变,以及代码是否因此更容易继续修改。
评估这类项目时,至少要把几个维度拆开:
- 变更范围:Agent 是遍历了 30 万行代码,还是实质性修改了 30 万行?
- 任务类型:修改主要是规则明确的机械重构,还是涉及架构边界、并发、内存生命周期等高风险问题?
- 验证强度:逐帧回放覆盖了多少输入、平台和异常路径?
- 人工投入:Token 成本之外,测试框架建设、代码审查、失败归因和返工用了多少工程时间?
- 长期收益:重构后复杂度、缺陷率、构建时间和后续变更成本是否下降?
因此,“30 万行、三周、4,000 美元”更像吞吐量数据,而不是完整的投资回报结论。它证明了 Agent 可以在强约束环境中执行大规模修改,但不能仅凭这些数字推导出修改是自主完成的、适用于所有 C 项目,或者总成本只有 Token 账单。
回放测试不是辅助工具,而是这套系统的核心
这个案例最重要的工程细节,是逐帧回放验证。对于图形、视频、游戏、仿真或其他按帧推进的程序,回放框架可以把历史输入重新送入基线版本和候选版本,再比较每一帧的输出。
这相当于为 Agent 建立一条可执行的边界:代码内部可以改变,但可观察行为必须保持一致。Agent 的价值与验证系统的能力是相乘关系,而不是彼此独立:
可接受的自动化变更规模 ≈ Agent 的修改能力 × 验证反馈的速度与覆盖率
不过,逐帧一致也有边界。它通常无法自动证明:
- 未被录制的输入仍然正确;
- 不同编译器、CPU 架构或操作系统上的行为一致;
- 内存安全、数据竞争和未定义行为已经消失;
- 性能、延迟和峰值内存没有退化;
- 新结构确实比旧结构更容易维护。
稳健的流水线应把回放测试与单元测试、模糊测试、Sanitizer、静态分析和性能基准组合起来,而不是把一次视觉或字节级对比当成全部证明。
可以这样实践:给 C 重构建立最小回放闸门
下面是一个可复制的简化示例。它并非案例中的实际测试框架,而是演示如何让基线程序与重构后的程序处理同一组“帧”,并逐字节比较输出。
先创建基线实现 baseline.c:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc != 2) return 2;
int frame = atoi(argv[1]);
printf("P2\n16 16\n255\n");
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
int pixel = (x * 17 + y * 13 + frame * 7) % 256;
printf("%d%c", pixel, x == 15 ? '\n' : ' ');
}
}
return 0;
}
再创建经过函数提取的候选实现 candidate.c:
#include <stdio.h>
#include <stdlib.h>
static int pixel_at(int x, int y, int frame) {
return (x * 17 + y * 13 + frame * 7) % 256;
}
static void render_frame(int frame) {
puts("P2");
puts("16 16");
puts("255");
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
printf("%d%c", pixel_at(x, y, frame), x == 15 ? '\n' : ' ');
}
}
}
int main(int argc, char **argv) {
if (argc != 2) return 2;
render_frame(atoi(argv[1]));
return 0;
}
创建 replay.py,对 120 帧执行确定性回放:
from pathlib import Path
import hashlib
import subprocess
import sys
FRAMES = range(120)
def run(binary: str, frame: int) -> bytes:
return subprocess.check_output([binary, str(frame)], timeout=2)
for frame in FRAMES:
expected = run("./baseline", frame)
actual = run("./candidate", frame)
if expected != actual:
Path("expected.pgm").write_bytes(expected)
Path("actual.pgm").write_bytes(actual)
print(f"Mismatch at frame {frame}", file=sys.stderr)
sys.exit(1)
digest = hashlib.sha256(actual).hexdigest()[:12]
print(f"frame={frame:03d} sha256={digest}")
print("Replay passed: all frames are byte-identical")
编译并运行:
cc -std=c11 -O2 -Wall -Wextra -Werror baseline.c -o baseline
cc -std=c11 -O2 -Wall -Wextra -Werror candidate.c -o candidate
python3 replay.py
# 再补一轮内存与未定义行为检查
cc -std=c11 -O1 -g -fsanitize=address,undefined candidate.c -o candidate-asan
for frame in 0 1 2 30 60 119; do
./candidate-asan "$frame" >/dev/null
done
在真实项目中,可以把帧号替换为录制的输入事件、网络包、文件或随机种子。若输出含时间戳、线程调度结果或浮点抖动,则应先定义规范化规则和容差,避免测试既频繁误报,又悄悄放过真正的行为变化。
Agent 的“配方库”可能比单次重构更有价值
案例中另一个值得关注的产物,是 Agent 逐步形成了代码库专属的操作配方。这类配方可以记录:
- 哪些目录允许修改,哪些模块必须保持 ABI 稳定;
- 某种代码异味应使用什么重构步骤;
- 每类修改完成后必须运行哪些测试;
- 哪些宏、所有权约定或错误处理模式不能机械替换;
- 失败后如何缩小 diff、恢复现场并重新执行。
可以把这些规则放入版本库,例如:
name: extract-render-helper
scope:
include: ["src/render/**/*.c"]
exclude: ["src/render/compat/**"]
constraints:
- "Do not change exported symbols"
- "Preserve integer arithmetic and evaluation order"
- "Keep each patch below 500 changed lines"
validation:
- "make replay-test"
- "make test-asan"
- "make benchmark-render"
rollback_on:
- "any frame mismatch"
- "performance regression above 3 percent"
这段 YAML 只是可采用的项目约定,并非特定 Agent 的标准格式。关键是把提示词、修改边界和验证命令变成可审查、可版本化的工程资产,而不是留在一次性的聊天记录里。
采用前应检查什么
这项案例较有说服力地说明:当任务可以拆成重复、局部且可验证的步骤时,编码 Agent 能把大型遗留代码重构从手工作业转变为受控流水线。但它没有证明验证基础薄弱的项目也能获得同样结果。
开始类似尝试时,建议按以下顺序推进:
- 先选择行为稳定、输入可回放、失败可回滚的模块。
- 建立基线,包括测试通过率、性能、二进制大小和静态分析结果。
- 将每次变更限制为小批次,不要让 Agent 一次生成无法审查的巨型补丁。
- 把 Token、人工审查、测试基础设施和返工时间一起计入成本。
- 保存有效的重构配方,并记录失败配方及其触发条件。
- 用缺陷率、复杂度和后续修改时间衡量长期价值,而不只统计修改行数。
真正可复制的结论不是“Agent 能在三周内改 30 万行代码”,而是“足够强的验证闭环,可以让 Agent 安全地尝试远超人工节奏的大规模变更”。在这类系统里,Agent 是执行器,回放框架和工程约束才是信任的来源。