面向 agentic RL 后训练的跨语言跨抽象层 bug-fix 任务集 —— 底层 bug,上层症状,延迟显现。
延迟显现(Delayed Manifestation):bug 在底层(C / CUDA / Rust / ASM),症状在上层(Python / SQL / CLI),两者之间跨越多个抽象层和数百个操作。agent 需要从症状反推、穿越语言边界、理解框架内部,才能定位根因。
bug 代码执行(CUDA kernel / C++ / Rust)
↓ 正常返回,没有报错
大量下游操作(autograd / 图像管线 / 查询执行...)
↓ 每一步都"看起来正常"
症状出现(NaN / accuracy 下降 / 结果偏差 / segfault)
↓ 症状远离 bug,stack trace 指向错误位置
| # | 任务 | Bug 层 | 症状 | 延迟机制 | 语言 | 状态 |
|---|---|---|---|---|---|---|
| 1 | PyTorch CUDA index | CUDA | 训练 NaN | 累积误差 | Python+CUDA | ✅ 可交付 |
| 2 | PyTorch autograd sign | C++ | accuracy↓ | 累积误差 | Python+C++ | |
| 3 | NumPy BLAS register | x86 ASM | 结果偏差 | 触发条件 | Python+ASM | |
| 4 | JAX vmap batching | Python 内部 | 梯度错 | 级联传播 | Python+内部 | ✅ 可交付 |
| 5 | CPython refcount | C | segfault | 概率性 | Python+C | |
| 6 | TF shape inference | C++ | shape err | 级联传播 | Python+C++ | |
| 7 | cuDNN conv backward | CUDA | 效果差 | 累积+触发 | Python+CUDA | |
| 8 | Rust FFI lifetime | Rust | segfault | 概率性 | Python+Rust | |
| 9 | PG executor NULL | C | 行数不对 | 触发条件 | SQL+C | |
| 10 | Redis module write | C | 数据乱码 | 级联传播 | Redis+C | |
| 11 | LLVM codegen | C++ | -O2 输出错 | 级联传播 | C+ASM | |
| 12 | Python GIL race | C | 偶发错 | 概率性 | Python+C | |
| 13 | OpenCV CUDA resize | CUDA | 像素偏差 | 级联传播 | Python+CUDA | |
| 14 | NumPy dtype overflow | C | 溢出 | 触发条件 | Python+C | |
| 15 | SQLite optimizer | C | 少行 | 触发条件 | SQL+C |
- ✅ 可交付:镜像、Oracle、
run.sh/calibrate.sh已跑通,可直接用于评测。 ⚠️ 骨架待完善:有 Dockerfile /run.sh/instruction.md骨架,但task/solution/oracle.sh未补齐或测试未验证,暂不能端到端运行。
难度校准(指令框架 + 提示泄露)—— kimi seed42 实测:
| 配置 | 官方 reward | turns | agent 自测分轨迹 |
|---|---|---|---|
| 旧:instruction "≥0.6 即过" | 0.85 | 111 | 到 0.85 即收工(satisficer) |
| 改:instruction "尽力满分" + 教 CPU-vs-CUDA/多warp/竞态 提示 | 1.00 | 235 | 一路爬到 1.0,自己补回 SoftMax 三处 __syncthreads |
| 再改:删掉方法提示,只留"冲满分"动机 | 0.88 | 436 | 卡 0.88(连刷 12 次 grade 上不去),最难那簇啃不下 |
| 同上配置 + 时限 1h→3h(max-history 镜像已生效) | 0.9706 | 500(撞 step 上限) | 久卡 0.88 后突破到 0.91→0.94→0.97,仅剩 SoftMax 2D 多 warp 归约删 sync 那 1 个 kernel |
追加发现(2026-06-28 重建镜像实测):时限是个大杠杆 —— 同样"去提示"配置,1h 卡 0.88,给到 3h / 500 步后 kimi 一路啃到 0.97,只剩 1 个 kernel(softmax:2d_C2048 删 __syncthreads 簇)。说明现难度对充足预算 agent 偏低。oracle 复测 buggy 0.10 / fixed 1.0,history.log 累积正确,max-history 计分已在重建镜像上验证生效。
结论:
- "≥0.6 即过"是 satisficer 陷阱 —— agent 够分就停,白白放掉难 bug。改成"目标满分、不到 1.0 继续"才逼出真实能力。
- instruction 里的"方法提示"会泄答案 —— "逐算子对比 CPU/CUDA""归约用 >1024 维触发多 warp""部分 bug 是竞态需重复跑"等于把最难的删
__syncthreads簇钥匙直接给 agent(1.0);删掉后难度回升到 0.88,区分度恢复。动机与方法要解耦:留动机、删方法。
判分改进:
- run.sh 坏指令修复:追加给 agent 的 prompt 里
bash /task/tests/test.sh(该路径在 protected grading 下不存在)统一改为grade,消除"test.sh 跑不了"的误导。 - max-history 计分:test.sh 每次落分追加到受保护
/logs/verifier/history.log(root:700,agent 不可伪造),run.sh 末取sort -g | tail -1当 reward + 保留一次兜底重跑。agent 中途到过高分、末态被打断/改坏时按最佳验证状态计分。代价:对 flaky 竞态 bug 的 max 可能虚高,靠REP=8压低。(详见skills/generate-task.md"max-history 计分"、skills/anti-hack.md#8) - timeout 默认 1h → 3h(冲满分要多迭代 + 重编译)。
本次改动:
task/tests/test.sh每次判分同时写入/logs/verifier/history.log(受保护 root:700),与 task1 保持一致。run.sh最终 reward 改为取sort -g history.log | tail -1的历史最高分,并保留一次兜底重跑。- 重建
task4镜像,protected grading 与 max-history 同时生效。
Task 4 当前状态:
- Bug 数量:26 真 bug + 11 诱饵
- inject_bug.py 支持
--reverse,solve.sh 直接调用 - 启用 protected grading:非 root agent、
/opt/judgeroot-only、gradesetuid、空目录覆盖/task/solution - Oracle 测试通过:Buggy 0.10, Fixed 1.0
- Per-bug Oracle:26/26 全部通过
Kimi 复测(seed 42,预算 $20,超时 3h):
| 指标 | 结果 |
|---|---|
| Reward | 0.10 |
| Turns | 500(撞 step 上限) |
| Tool calls | 500 |
结论:
- max-history 计分机制已部署,但本次 agent 中途未突破 0.10,最终按兜底 test 的 0.10 计分。
- Kimi 在 500 步内未能有效修复 JAX vmap batching bug,轨迹里主要是 shape/broadcasting 类报错(如
Batching rule for 'iota' not implemented、多处incompatible shapes for broadcasting)。 - task4 当前对 Kimi 明显偏难,后续需校准(加提示 / 减少 bug / 优化 instruction)。
关键发现:
- 删除代码比添加代码更难被 agent 发现
- 陷阱诱饵(修了反而有害)是有效的反 hack 手段
- "霰弹枪策略"(修所有可疑代码)是 agent 的常见行为
- Protected grading 是必须的:agent 会尝试读
bugs.patch、判分脚本、/logs/verifier作弊,必须对 agent 隐藏 solution 和测试逻辑 - 轨迹分析工具很重要:
analyze_trajectory.py能区分“修对真 bug”“改坏代码”“无效编辑”,是难度校准的关键
| 措施 | 说明 |
|---|---|
| 禁止上网搜索 | run.sh 中 deny WebSearch/WebFetch |
删除 .git |
防止 git diff 看到改动 |
| 统一文件修改时间 | Dockerfile 中 touch 所有文件 |
| 陷阱诱饵 | && True、assert,删了就出错 |
| Anti-hack 检查 | test.sh 中检查完整性 |
| Protected grading | solution/测试对 agent 不可读,grade setuid 只回显总分 |
详见 skills/anti-hack.md。
目前只有 task1 和 task4 可完整跑通(镜像、Oracle、run.sh / calibrate.sh 已验证)。其余任务为骨架状态,需补齐 task/solution/oracle.sh 并验证 tests/test.sh 后才能使用。
cd <项目路径>
# task1
DOCKER_BUILDKIT=1 docker build \
--secret id=ssh_key,src=.secrets/id_rsa \
-t task1 -f tasks/task1-pytorch-cuda-index/task/environment/Dockerfile .
# task4
DOCKER_BUILDKIT=1 docker build \
--secret id=ssh_key,src=.secrets/id_rsa \
-t task4 -f tasks/task4-jax-vmap-batch/task/environment/Dockerfile .各任务的 Oracle 脚本在 task/solution/oracle.sh,需在挂载 solution 的容器内运行(详见各任务 README.md 的「测试命令」小节)。
cd tasks/task1-pytorch-cuda-index
./run.sh kimi-code/kimi-for-coding 10 42 10800
cd tasks/task4-jax-vmap-batch
./run.sh kimi-code/kimi-for-coding 10 42 10800参数顺序:模型名 预算(seed) 超时(秒)。注意模型名需写完整 kimi-code/kimi-for-coding,只写 kimi-for-coding 会导致 config 不匹配。
cd tasks/task1-pytorch-cuda-index
./calibrate.sh kimi-code/kimi-for-coding 10 3 10800参数:模型名 单次预算 运行次数 单次超时。
评测管线由四个阶段组成:
生成任务(generate-task) → 构建镜像(build) → Oracle 验证 → Kimi 测试 → 轨迹分析(analyze) → 调整难度
输入: CVE / bug 描述 / 框架
↓
Phase 1: 分析 bug 类型和触发条件
↓
Phase 2: 设计用户接口 (train.py / model.py)
↓
Phase 3: 设计诱饵 (陷阱诱饵 + 普通诱饵)
↓
Phase 4: 编写 inject_bug.py (支持 --reverse)
↓
Phase 5: 编写 solve.sh (调用 inject_bug.py --reverse)
↓
Phase 6: 编写 oracle.sh (验证 buggy 失败 + fixed 通过)
↓
Phase 7: 编写 test.sh (多场景 + anti-hack)
↓
Phase 8: 编写 Dockerfile (注入 bug + touch 统一时间戳)
↓
输出: tasks/taskN-<name>/ 完整目录
# Fat base (一次性, 1-2 小时)
DOCKER_BUILDKIT=1 docker build \
--secret id=ssh_key,src=.secrets/id_rsa \
-t pytorch-2.5.0-fat-base \
-f tasks/task1-pytorch-cuda-index/task/environment/Dockerfile.base .
# Task 镜像 (增量, 5-15 分钟)
docker build --no-cache -t task1 \
-f tasks/task1-pytorch-cuda-index/task/environment/Dockerfile .关键步骤:
COPY inject_bug.py /tmp/— 复制注入脚本RUN python3 /tmp/inject_bug.py— 注入 bug + 诱饵RUN find ... -exec touch {} +— 统一文件修改时间RUN ninja -j32 lib/libtorch_cuda.so— 重编译RUN rm -rf /build/pytorch/.git— 删除 git 历史
以 task1 为例(task4 类似,详见各任务 README.md):
# 启动容器并挂载 solution(开发/验证时用)
docker run --rm --gpus all \
-v "$PWD/tasks/task1-pytorch-cuda-index/task/workspace:/workspace:ro" \
-v "$PWD/tasks/task1-pytorch-cuda-index/task/solution:/task/solution:ro" \
-v "$PWD/tasks/task1-pytorch-cuda-index/task/tests:/task/tests:ro" \
task1 bash /task/solution/oracle.sh流程:
1. 启动 Docker 运行环境 (挂载 workspace/tests/solution)
↓
2. 运行 test.sh (buggy 版本)
↓
3. 检查分数 < 1.0 (确认 bug 有效)
↓
4. 运行 solve.sh (调用 inject_bug.py --reverse)
↓
5. 运行 test.sh (fixed 版本)
↓
6. 检查分数 = 1.0 (确认修复正确)
cd tasks/task1-pytorch-cuda-index
./run.sh流程:
1. 生成 kimi_config.toml (API key + 权限规则)
↓
2. 启动 Docker 运行环境 (挂载 workspace/tests/instruction)
↓
3. 运行 kimi -p "任务 prompt"
↓
4. 保存 trajectory.jsonl (完整轨迹)
↓
5. docker commit (保存修复状态)
↓
6. 在快照镜像中运行 test.sh
↓
7. 输出 result.jsonl (reward/turns/tool_calls)
# 查看结果
cat trajectories/*/result.jsonl
# 分析轨迹
python3 -c "
import json
with open('trajectories/*/trajectory.jsonl') as f:
lines = [json.loads(l) for l in f]
# 分析 agent 的调试路径
"分析要点:
- 定位方式: 系统搜索 / 偶然发现 / 提示引导
- 关键转折: 在哪一步发现了 bug
- 失败原因: 卡在哪里, 为什么
- hack 尝试: 有没有尝试绕过约束
.claude/skills/
├── README.md ← Skills 索引
├── generate-task.md ← 任务生成 (9 个 Phase)
├── calibrate-task.md ← 难度校准
├── select-tasks.md ← 选题
└── anti-hack.md ← 反 hack 措施 (7 种)
| Skill | 用途 | 关键功能 |
|---|---|---|
/generate-task |
生成评测题 | Bug 构造策略、诱饵设计、anti-hack |
/calibrate-task |
校准难度 | 多次运行、轨迹分析、调整策略 |
/select-tasks |
选题 | 按成功率排序、淘汰太难/太简单 |
/anti-hack |
反 hack | 禁止上网、删除 .git、陷阱诱饵 |
| 策略 | 难度 | 说明 |
|---|---|---|
| 删除关键代码 | ⭐⭐⭐⭐⭐ | 删 __syncthreads、删 early return |
| 条件触发 | ⭐⭐⭐⭐ | 只在特定输入下触发 |
| 跨函数依赖 | ⭐⭐⭐⭐ | 需要理解调用链 |
| 陷阱诱饵 | ⭐⭐⭐ | 修了反而有害 (&& True、assert) |
| 数值精度 | ⭐⭐⭐ | 不崩溃, 需数值分析 |
| 符号翻转 | ⭐⭐ | 有迹可循 |
| 普通诱饵 | ⭐ | 最容易排除 |
详见 skills/generate-task.md Phase 4.5。
agentic-xlang-bugfix/
├── README.md ← 本文件
├── .claude/
│ ├── skills/ ← Claude Code Skills
│ │ ├── generate-task.md
│ │ ├── calibrate-task.md
│ │ ├── select-tasks.md
│ │ └── anti-hack.md
│ └── settings.local.json
├── .secrets/ ← API keys (不提交)
│ ├── claude_api_key
│ ├── kimi_api_key
│ └── id_rsa
└── tasks/ ← 15 道任务
├── task1-pytorch-cuda-index/
│ ├── README.md ← 设计思路 + 踩坑记录
│ ├── run.sh ← 单次运行 (含 deny WebSearch)
│ ├── calibrate.sh ← 多模型校准
│ ├── trajectories/ ← 轨迹存储
│ └── task/
│ ├── task.toml ← 任务元数据
│ ├── instruction.md ← 发给 agent 的 prompt
│ ├── environment/
│ │ ├── Dockerfile ← 注入 bug + touch + 编译
│ │ └── Dockerfile.base ← fat base 镜像
│ ├── workspace/ ← 用户代码 (train.py, model.py)
│ ├── solution/
│ │ ├── inject_bug.py ← 注入 bug (支持 --reverse)
│ │ ├── solve.sh ← 调用 inject_bug.py --reverse
│ │ └── oracle.sh ← 验证 buggy 失败 + fixed 通过
│ └── tests/
│ └── test.sh ← 判题脚本 (多场景 + anti-hack)
└── task4-jax-vmap-batch/
├── README.md ← 设计思路 + 踩坑记录
├── run.sh ← 单次运行 (deny WebSearch, protected grading)
├── calibrate.sh ← 多模型校准
├── trajectories/ ← 轨迹存储
└── task/
├── task.toml ← 任务元数据
├── instruction.md ← 发给 agent 的 prompt
├── environment/
│ ├── Dockerfile ← 注入 bug + touch + protected grading
│ ├── Dockerfile.base ← fat base 镜像
│ └── grade.c ← setuid-root 判分入口
├── workspace/ ← 用户代码 (test_vmap.py stub)
├── solution/
│ ├── inject_bug.py ← 注入 bug (支持 --reverse)
│ ├── solve.sh ← 调用 inject_bug.py --reverse
│ ├── oracle.sh ← 验证 buggy 失败 + fixed 通过
│ └── analyze_trajectory.py ← 轨迹分析
└── tests/
└── test.sh ← 判题脚本 (多场景 + anti-hack)
-
构建镜像
docker build --no-cache -t task1 -f tasks/task1-pytorch-cuda-index/task/environment/Dockerfile . docker build --no-cache -t task4 -f tasks/task4-jax-vmap-batch/task/environment/Dockerfile .
-
Oracle 验证
- buggy 版本分数 < 1.0
- fixed 版本分数 = 1.0
-
Kimi 测试
cd tasks/task1-pytorch-cuda-index && ./run.sh cd tasks/task4-jax-vmap-batch && ./run.sh
-
轨迹分析
- 用
analyze_trajectory.py分析 agent 调试路径、关键转折、失败原因
- 用
-
调整难度
- 太简单 → 增加 bug / 删除型 bug / 陷阱诱饵
- 太难 → 减少 bug / 加提示
-
重复 2-5 直到成功率 ~50%
每道题的 tests/test.sh 包含多层反 hack 检查:
| 检查 | 防什么 |
|---|---|
| 多 seed / 多参数测试 | 防"只过一个 case" |
| 性能回归测试 | 防"CPU 回退绕过 CUDA bug" |
| diff 只允许底层文件 | 防"改 Python 不改 C++" |
| 静态分析(isnan / try/catch) | 防"Python 层打补丁掩盖" |
| Mutation testing | 防"测试套件本身弱" |
详见 skills/anti-hack.md。
设计了 15 道题,校准后选成功率最接近 50% 的 10 道:
- 成功率 40-60% → 选入(难度合适)
- 成功率 >60% → 淘汰或加难度
- 成功率 <30% → 淘汰或加提示
本项目包含 Claude Code skills,用于自动化任务生成和校准:
| Skill | 用途 | 用法 |
|---|---|---|
/generate-task |
生成一道跨语言 bug-fix 评测题 | /generate-task --cve CVE-2024-xxxx --framework pytorch |
/calibrate-task |
校准一道题的难度 | /calibrate-task --task-dir tasks/taskN-xxx --runs 3 |
/select-tasks |
从 N 道题里选最优 M 道 | /select-tasks --n 15 --m 10 |
详见 .claude/skills/ 目录。
- ExploitBench — V8 JavaScript 引擎漏洞利用评测基准(本项目的灵感来源)
- harbor — 任务格式框架
本项目使用 Claude Code 作为 AI 编程助手,接入以下模型:
- MiMo-V2.5-Pro