HarnessForge:多 Agent 驱动的 Repo 历史反向任务工厂
从精选 GitHub Repo 的演进历史中,通过五角色 Agent 协作,合成长程复合开发任务、重建真实开发者的丢失探索过程、自动标注真实难度。目标产出 3,000-5,000 个经验证的中高难度 RL 训练任务。
HarnessForge:多 Agent 驱动的 Repo 历史反向任务工厂
核心主张:当前 Agent RL 训练数据有两个结构性缺陷——(1) 任务太原子化(单 PR 粒度),缺乏需要长程规划的复合任务;(2) 只有最终 patch,丢失了真实开发者在提交 PR 前的全部探索过程(试错、回退、方向调整)。HarnessForge 用五角色 Agent 协作从 repo 演进历史中合成跨 PR 的复合任务,并重建完整探索轨迹——特别是”卡住 → 收到提示 → 调整方向 → 突破”这一目前完全没有公开训练数据覆盖的交互模式。
一、定位与动机
1.0 起点:“The Harness is the Dataset”
2026 年 1 月,Google DeepMind Staff Engineer Philipp Schmid 在 The importance of Agent Harness in 2026 中提出了一个影响深远的论断:
“Competitive advantage is now the trajectories your harness captures.” (竞争优势现在取决于你的 Harness 所捕获的轨迹数据。)
他的完整论证链条是:
-
模型能力正在趋同。顶尖模型在静态 benchmark 上的差距越来越小,但这是假象——真正的差距体现在长程任务中的指令遵循持久性(模型在第 50 步、第 100 步之后是否还能准确执行)。
-
Harness 是唯一能捕获这种信号的系统。它将模糊的多步工作流转化为可记录、可评分的结构化数据——精确到模型在第几步开始偏离指令、在哪个工具调用上出了错。
-
这些数据直接反馈到训练流程。每一次 Agent 在长流程后期的失败案例,都可以被用于训练下一代模型。训练环境和推理环境正在融合。
-
数据飞轮效应:Harness 运行 → 捕获轨迹 → 反馈训练 → 模型改进 → Harness 再运行。谁先跑通这个闭环、谁积累的轨迹数据越多越好,谁就拥有结构性竞争优势。
这个论断揭示了一个关键事实:高质量的 Agent 训练数据不是可以一次性采购的商品,而是需要通过 Harness 持续积累的资产。 数据的价值随时间复利增长,竞争对手无法复制。
但问题是:这个飞轮的冷启动极其困难。 你需要先有一个足够好的 Harness 在真实场景中运行,才能开始积累轨迹。对于还没有大规模 Agent 产品的团队来说,存在一个鸡生蛋的困境。
HarnessForge 要做的,就是用开源 repo 历史作为原材料,批量模拟 Harness 的数据积累过程——快速冷启动这个飞轮。 不需要等用户在你的产品中产生数据,直接从 GitHub 上数百个高质量项目的演进历史中”锻造”出等价的长程任务轨迹。
1.1 三个被忽视的问题
问题 1:现有训练数据只有结果,没有过程。
一个真实开发者解决一个仓库级 bug,过程可能是这样的:
→ 读 issue → 猜测原因 → grep 相关代码 → 读 3 个文件 → 发现可能是 A 模块
→ 改了 A 模块 → 跑测试 → 失败 → 发现是 B 模块的问题
→ 回退 A 的修改 → 读 B 模块 → 改了 B → 跑测试 → 部分通过
→ 发现 B 和 C 有耦合 → 同时改 B+C → 跑测试 → 全部通过
→ 清理代码 → git commit → push PR
但 git 记录的只有最后一步:一个干净的 diff。中间所有的探索、试错、回退、方向调整——全部丢失。现有的 SWE-bench 系列训练数据也只有 (task_description, final_patch) 对,没有过程。
问题 2:现有任务太原子化,缺乏长程复合任务。
SWE-bench 的任务粒度是”一个 issue 对应一个 PR”。但真实开发中,PM 给你的需求通常是:“重构 QuerySet 的聚合机制,支持 union/intersection 嵌套 annotate,同时保持向后兼容”——这可能对应 repo 历史中的 5-8 个相关 PR。
没有人在做这种跨 PR 的复合任务合成。
问题 3:高质量轨迹数据需要持续积累,冷启动极难。
Schmid 指出数据飞轮的核心逻辑是”Harness 运行 → 捕获轨迹 → 训练 → 改进”。但这个飞轮有一个残酷的前提:你得先有一个在真实场景中大规模运行的 Agent 产品。 OpenAI 有 Codex 的百万用户轨迹,Anthropic 有 Claude Code 的使用数据——这些是他们无法被复制的数据资产。
对于还没有大规模 Agent 产品的团队(大多数团队),这是一个鸡生蛋困境:没有好数据 → 训不出好模型 → 没有好产品 → 没有用户产出数据。
HarnessForge 的答案:用开源 repo 历史作为”替代用户”,用多 Agent 协作批量模拟真实开发过程,直接产出等价于数万次 Agent 产品使用的轨迹数据——跳过”等用户来”这一步。
1.2 HarnessForge 的核心差异化
| 维度 | SWE-bench 系列 | SWE-smith | HarnessForge |
|---|---|---|---|
| 任务来源 | 单 Issue → 单 PR | Bug 注入 | Release 特性分析 → 复合任务合成(单 release 特性或跨 release 合并) |
| 任务粒度 | 单点修复 | 单点修复 | 长程跨模块开发(feature 级别) |
| 需求生成 | 依赖 Issue 质量 | 合成模板 | PM 结合 release 演进历史自由发挥 |
| 难度信号 | 无/人工 | 无 | Dev 需要 PM 提示才能突破 = genuine hard |
| 训练数据 | (task, patch) 对 | (task, patch) 对 | 完整探索轨迹(含失败、回退、提示、调整) |
| DPO 数据 | 需额外构造 | 无 | 自然产出(同任务不同提示级别的轨迹对) |
| 规模 | 500-21K | 50K | 3K-5K(以质量换数量) |
| 覆盖范围 | 仅 Python | 仅 Python | Python/TS/Go/Rust |
诚实的劣势:
- 规模不及 SWE-smith/SWE-rebench:HarnessForge 产出 3K-5K 条,SWE-smith 有 50K。但每条数据包含完整轨迹(平均 25-40 轮交互),信息密度远高于单 (task, patch) 对
- 管线复杂度更高:五角色协作比单 Agent 的 Bug 注入复杂得多。这是”以工程换数据质量”的取舍
- 依赖 repo 测试质量:如果 repo 测试覆盖不足,复合任务的验收标准可能不完整。Test Crafter 部分缓解但不能完全消除
核心论点:在 Agent RL 训练进入”数据质量 > 数据数量”的阶段,3K 条带完整探索过程的复合任务轨迹,训练价值可能高于 50K 条单点 (task, patch) 对。这需要 Phase 3 的消融实验来验证。
1.3 对 frontier 模型(GLM-5 级别)的精准价值
不是通用提升,而是定向突破能力瓶颈。
GLM-5/Opus 4.6/GPT-5.3 这种 frontier 模型在 SWE-bench Verified 上约 70-80%。剩余 20% 几乎全是需要跨模块理解、多步试错的复杂任务。模型的短程编码能力已经很强,真正缺的是三种长程能力:
- 长程规划:拿到一个大需求,怎么拆解成子任务、按什么顺序执行
- 探索-利用平衡:什么时候该继续深挖当前方向,什么时候该换思路
- 从反馈中调整:收到模糊的方向性提示(“考虑并发场景”),怎么调整策略
HarnessForge 产出的数据恰好训练这三种能力:
- PM 的复合任务 → 训练规划能力
- Dev 的完整探索轨迹(含失败路径和回退)→ 训练探索-利用平衡
- PM hint → Dev 方向调整 → 成功的序列 → 训练从反馈中学习
第三点目前几乎没有公开训练数据覆盖。
价值定位:HarnessForge 的数据不是给 frontier 模型”加量”的通用训练数据,而是精准填补”从 80% 到 95%“的能力盲区——长程规划、探索回退、从反馈中调整。3K-5K 条高质量复合任务轨迹,如果包含有效的”卡住→提示→突破”模式,对 SWE-bench 最后 20% 的复杂任务可能有 3-5 个点的提升。在 frontier 竞争中,这是有实际意义的差距。
同时,这些数据对开源模型(Qwen-32B、Llama-70B)的提升会更显著——它们在仓库级任务上和 frontier 差距更大,3K-5K 条高质量 RL 数据可能把 SWE-bench 分数从 30% 推到 45-50%。
二、五角色 Agent 系统
┌──────────────────────────────────────────────────────────────────────────┐
│ HarnessForge 五角色协作 │
│ │
│ ┌──────────┐ 分析 repo 历史 ┌──────────┐ │
│ │ Architect │ ──────────────────→ │ PM │ │
│ │ Agent │ PR 聚类 + 演进图谱 │ Agent │ │
│ └──────────┘ └────┬─────┘ │
│ │ 复合任务 + 渐进提示 │
│ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Test │ ←── │ Dev │ │
│ │ Crafter │ 验收 │ Agent │ 在沙箱中执行 │
│ └──────────┘ 测试 └────┬─────┘ │
│ │ 完整轨迹 │
│ ▼ │
│ ┌──────────┐ │
│ │ Reviewer │ │
│ │ Agent │ 筛选 + 提炼 │
│ └──────────┘ │
│ │ │
│ ▼ │
│ verified_tasks/ │
└──────────────────────────────────────────────────────────────────────────┘
角色 1:Architect Agent(仓库架构师)
职责:分析 repo 的 release 历史,从版本特性中提取复合任务素材——既包括单个 release 中的独立特性,也包括跨多个 release 的相关特性合并。
为什么用 Release 而不是 PR 聚类:
- Release 有官方的 changelog/release notes,特性描述质量远高于随机 PR
- Release 之间有天然的版本递进关系,base_commit 和 ground_truth 都是明确的 tag
- Release 特性天然连贯,不需要人工聚类算法来猜测”哪些 PR 相关”
- 但单个 release 的某些特性可能太小,跨 release 合并可以产出更有挑战的复合任务
name: "Architect Agent"
model: "claude-sonnet-4.5"
phase: "离线预处理(每个 repo 执行一次)"
input:
- repo 的所有 release tags 和对应的 changelog / release notes
- 相邻版本之间的 diff stat(文件变更、行数)
- 目录结构和核心模块划分
- CI 和测试框架配置
tasks:
1. "Release 特性分解":
- 对每个 release(近 2-3 个大版本),提取独立的特性条目
- 每个特性包含:描述、涉及模块、变更规模(文件数/行数)
- 区分:新功能 / 重构 / Bug 修复 / 性能优化
- 只保留"新功能"和"重构"类型(Bug 修复留给 SWE-bench 系列)
2. "特性难度评估":
- 对每个特性,评估独立完成的难度(1-5)
- 考虑因素:跨模块程度、变更规模、是否需要新增 API
- 难度 1-2 的特性标记为"可合并候选"
3. "跨 Release 合并":
- 识别跨版本的相关特性(同一模块在 v5.0 和 v5.1 中持续演进)
- 将 2-4 个相关特性合并为一个复合任务
- 合并原则:
a. 同一模块或紧密耦合模块的演进链
b. 合并后 diff 在 200-1500 行之间(太小没挑战,太大不可控)
c. base_commit = 最早涉及版本的前一个 tag
d. ground_truth = 合并后所有版本的累积 diff
4. "环境验证":
- 对每个 base_commit,确认可以构建和运行测试
- 记录 Dockerfile / 依赖安装命令 / 测试命令
- 如果 base_commit 环境不可用,尝试最近的可用 tag
output:
features.jsonl: # 每个 repo 约 20-60 个特性
# ── 单 release 特性 ──
- feature_id: "django-5.1-async-queryset"
type: "single" # 单 release 特性
source_release: "5.1"
base_tag: "5.0"
ground_truth_tag: "5.1"
description: "QuerySet 支持 async 迭代器和 async 聚合"
modules: ["django/db/models/query.py", "django/db/models/sql/"]
diff_stats: { files: 8, additions: 340, deletions: 45 }
difficulty: 4
test_files: ["tests/async/test_queryset.py"]
environment:
dockerfile: "..."
setup_cmd: "pip install -e '.[dev]'"
test_cmd: "python -m pytest tests/async/ -x -q"
# ── 跨 release 合并特性 ──
- feature_id: "django-5.0-5.1-orm-refactor-compound"
type: "compound" # 跨 release 合并
source_releases: ["5.0", "5.1"]
merged_features:
- "5.0: QuerySet.union/intersection 重构"
- "5.1: async QuerySet + 聚合操作增强"
base_tag: "4.2" # 两个特性最早涉及版本的前一个
ground_truth_tags: ["5.0", "5.1"] # 两个版本的累积变更
description: "QuerySet 集合操作重构 + async 化"
modules: ["django/db/models/query.py", "django/db/models/sql/", "django/db/models/manager.py"]
diff_stats: { files: 14, additions: 730, deletions: 180 }
difficulty: 5
merge_rationale: "5.0 重构了 QuerySet 内部结构,5.1 在此基础上加 async,两者有强依赖"
单 release vs 跨 release 合并的选择标准:
| 情况 | 处理方式 | 示例 |
|---|---|---|
| 单个 release 特性 ≥200 行、涉及 3+ 文件 | 保留为 single task | FastAPI 0.110 的 Lifespan 重构 |
| 单个 release 特性 <200 行但有价值 | 与同模块的其他版本特性合并 | Django 5.0 的小 ORM 改进 + 5.1 的相关增强 |
| 同一模块跨 2-3 个版本持续演进 | 合并为 compound task | TypeScript 5.3→5.4→5.5 的类型推导增强链 |
| 独立模块的不相关特性 | 不合并(强行合并会不自然) | — |
角色 2:PM Agent(产品经理 / 上帝视角)
职责:基于 Architect 的聚类素材,合成复合开发任务;在 Dev 卡住时提供渐进式提示。
核心升级:PM 不是简单地把一个 commit 翻译成需求描述。它看到的是 release 级别的特性演进(可能跨多个版本),然后把这些特性重新编排为一个连贯的开发任务——可以合并、可以重组、可以自由发挥。
name: "PM Agent"
model: "claude-opus-4.6" # 需要最强理解力和创造力
phase: "任务合成 + 实时提示"
# ── 阶段一:任务合成(离线)──
input_for_synthesis:
- Architect 的 release feature 素材包(single 或 compound)
- repo README 和架构文档
- feature 涉及的 release notes 和对应 diff
synthesis_rules:
1. "结合 release 演进历史,自由发挥":
- 对于 single feature:基于该版本特性合成需求,可适度扩展
- 对于 compound feature:把跨版本的 2-4 个相关特性合成一个**有逻辑连贯性的大需求**
- 可以合并:不同版本中同一模块的改进合成一个功能点
- 可以重排:先做某个版本的部分,再做另一版本的部分(如果这样更合理)
- 可以扩展:在真实 PR 基础上增加合理的额外要求
- 但不能无中生有:所有要求必须有 ground truth(对应 release 的实际变更)支撑
2. "任务描述像真实 PM 提需求":
- 描述期望行为,不暴露实现细节
- 包含验收标准(用户可感知的行为,不是代码层面的)
- 可以包含背景信息("我们最近收到用户反馈...")
- 不给文件路径、不给代码片段
3. "一个任务三个难度":
- 同一个 description
- hard:零提示
- medium:给方向性提示(涉及哪个模块、用什么思路)
- easy:给具体提示(涉及哪些文件、核心问题是什么)
output_for_synthesis:
task_id: "django-querysets-union-2026Q1"
scope: "compound" # compound(复合) / single(单一)
estimated_dev_days: 2 # 人类开发者预估工时
description: |
## 需求背景
近期多个用户报告了 QuerySet 聚合操作的问题:union() 与 annotate()
配合使用时结果不正确;intersection() 在子查询嵌套时 SQL 生成有误;
聚合操作链式调用 (.union().filter().annotate()) 的行为不一致。
## 需求描述
重构 QuerySet 的集合操作(union / intersection / difference),
使其正确支持:
1. 嵌套 annotate —— union 后的结果集保留所有 annotate 字段
2. 链式 filter —— 集合操作后可以继续 filter,SQL 正确包裹子查询
3. 向后兼容 —— 不影响现有不带 annotate 的集合操作
## 验收标准
- `qs1.annotate(...).union(qs2.annotate(...))` 返回正确的聚合值
- `qs1.union(qs2).filter(...)` 生成正确的 WHERE 子句
- 所有现有聚合测试继续通过
- 新增测试覆盖上述场景
hints_by_level:
L0: [] # hard:零提示
L1: # medium:方向级
- "问题的根源在 SQL 生成阶段,集合操作需要正确处理子查询的列投影"
- "链式 filter 需要用子查询包裹 UNION 结果"
L2: # easy:模块级
- "核心代码在 django/db/models/sql/query.py 和 compiler.py"
- "Query.combine() 方法需要正确传递 annotation_mask"
- "SQLCompiler.as_sql() 需要在 UNION 外层包裹 SELECT ... FROM (...) 用于后续 WHERE"
L3: # 紧急救援:代码级(只在 Dev 连续 3 次失败后释放)
- "Query.combine() 第 542 行的 annotation_select_mask 赋值有误,它用了 intersection 但应该用 union"
- "参考 PR #18523 的测试用例来验证你的修复"
ground_truth:
commits: ["def456", "ghi789", "jkl012"] # 对应的真实 commit
combined_diff_file: "diffs/django-querysets-union-2026Q1.patch"
test_cmd: "python -m pytest tests/queries/ tests/aggregation/ -x -q"
# ── 阶段二:实时提示(在线,Dev 执行过程中)──
hint_release_protocol:
trigger: "Dev Agent 连续失败(测试未通过 + 再次修改仍未通过),或明确请求帮助"
sequence:
- attempt 1-2: 无提示(hard 模式)
- attempt 3: 释放 L1 hints(方向级)
- attempt 4-5: 观察 Dev 是否利用 L1 调整方向
- attempt 6: 释放 L2 hints(模块级)
- attempt 8+: 释放 L3 hints(代码级紧急救援)
- attempt 10+: 如果仍未解决,标记为"超出当前模型能力"
hint_delivery_format: |
[PM 反馈] 你的方向不太对。这里有一些额外信息:
{hint_content}
请根据这个提示重新考虑你的方案。
recording:
# 记录每次提示释放的精确时间点和 Dev 的反应
- { turn: 12, hint_level: "L1", dev_reaction: "changed_search_direction" }
- { turn: 18, hint_level: "L2", dev_reaction: "found_correct_file" }
PM 的关键设计决策:
- 复合任务是核心:不是”一个 bug 一个 task”,而是”一个方向上的多个 PR 合成一个大任务”
- 提示释放不是可选功能,是数据的核心价值来源
- L3 提示是最后手段:只有连续多次失败才释放,保证这些数据确实标记了”genuine hard”
角色 3:Test Crafter Agent(测试工匠)
职责:为 PM 合成的复合任务生成验收测试。
这个角色为什么必要:复合任务合并了多个 PR 的内容,原始 repo 的测试可能不完全覆盖合成任务的所有验收标准。Test Crafter 需要:
- 整合多个 PR 涉及的测试到一个统一的测试套件
- 为 PM 额外添加的要求编写新测试
- 确保测试在 base_commit 上失败、在 ground truth 上通过
name: "Test Crafter Agent"
model: "claude-sonnet-4.5"
phase: "任务合成后,Dev 执行前"
input:
- PM 的任务描述和验收标准
- cluster 内所有 PR 的测试变更
- repo 的测试框架和约定(pytest / jest / go test)
- base_commit 的完整代码
tasks:
1. "测试整合":
- 从 cluster 内各 PR 提取新增/修改的测试
- 合并为一个统一的测试文件(或最少的文件集)
- 解决可能的命名冲突、fixture 冲突
2. "测试补全":
- 对照 PM 的验收标准,检查是否每条标准都有对应测试
- 如果有未覆盖的标准,编写新测试
- 新测试必须遵循 repo 的测试风格
3. "测试验证":
- 在 base_commit 上运行:新测试应该 FAIL(否则任务无效)
- 在 ground truth 上运行:新测试应该 PASS(否则测试有误)
- 确保测试运行时间 < 2 分钟(避免 Dev 等待太久)
output:
test_suite:
files:
- path: "tests/queries/test_union_compound.py"
content: "..."
run_cmd: "python -m pytest tests/queries/test_union_compound.py -x -q"
expected_at_base: "FAIL (3 failures)"
expected_at_target: "PASS (all 8 tests)"
validation:
base_result: "3 failed, 5 passed" # 确认不是全 fail(说明 repo 基础正常)
target_result: "8 passed"
new_tests_added: 3
existing_tests_integrated: 5
角色 4:Dev Agent(开发者)
职责:在 Docker 沙箱中执行任务,记录完整探索过程。
核心改变:Dev 不只是”干活”,它的每一步探索——包括走错路、回退、被 PM 提示后调整方向——都是训练数据的一部分。
name: "Dev Agent"
model:
primary: "claude-sonnet-4.5" # 主力执行模型
calibration: ["qwen3-32b", "glm-5-chat"] # 用于难度校准
sandbox:
runtime: "OpenHarness Docker"
image: "{repo}-base:latest"
network: "none"
resources: { cpu: 2, memory: "4g", timeout: "30m" }
tools:
- read_file / list_dir # 代码浏览
- edit_file / write_file # 代码修改
- bash # Shell 执行(包括运行测试)
- grep / ripgrep # 代码搜索
- git diff / git log # 查看本地修改和历史
# 禁止:web_search, web_fetch(纯离线)
constraints:
max_turns: 50 # 复合任务需要更多轮次
max_edit_attempts: 15 # 复合任务允许更多修改
must_run_test_before_done: true # 提交前必须跑测试
# ── 执行流程 ──
execution_protocol:
1. "初始探索":
- 读取任务描述
- 浏览项目结构(tree / ls)
- 阅读相关代码和现有测试
- 形成初始方案
2. "迭代开发":
- 修改代码 → 跑测试 → 检查结果
- 如果失败 → 分析错误 → 调整方案 → 重试
- 如果多次失败 → PM 会释放提示
- 收到提示后 → 重新评估方向 → 继续迭代
3. "完成验证":
- 所有测试通过
- 自查:修改是否完整覆盖所有验收标准
- 运行完整测试套件确认无回归
# ── 轨迹记录(核心输出)──
trajectory_format: "TAO-extended"
trajectory_fields:
- turn_id: int
- timestamp: float
- action_type: "think" | "read" | "search" | "edit" | "bash" | "test"
- action_detail: { ... } # 具体操作内容
- observation: string # 操作返回结果
- hint_received: null | { level: "L1", content: "..." } # 本轮是否收到 PM 提示
- direction_change: bool # 本轮是否改变了整体方向(关键标记)
- files_touched: [string] # 本轮涉及的文件
# ── 特殊标记(高价值信号)──
high_value_signals:
- "dead_end_detected": Dev 尝试某个方向 → 多次失败 → 主动放弃 → 换方向
- "hint_breakthrough": 收到 PM 提示 → 在 2 轮内找到正确方向
- "incremental_success": 测试从 "5 fail" → "3 fail" → "1 fail" → "all pass"
- "backtrack": git checkout -- file(主动回退修改)
角色 5:Reviewer Agent(审稿人 / 质检师)
职责:从 Dev 的轨迹中筛选有训练价值的任务,丢弃噪声。
核心改变:Reviewer 不只看结果(pass/fail),更看过程——特别是”需要提示才突破”的模式。
name: "Reviewer Agent"
model: "claude-opus-4.6"
phase: "Dev 执行完毕后"
input:
- PM 的任务描述和验收标准
- Dev 的完整轨迹
- ground truth diff
- 测试结果
- PM 提示释放记录
judgment_dimensions:
1. "难度真实性"(最重要):
rating: 1-5
criteria:
5: "Dev 在 hard 模式下需要 L2+ 提示才突破,提示后明显调整方向"
4: "Dev 在 hard 模式下需要 L1 提示,或多次回退换方向后成功"
3: "Dev 需要 3+ 次编辑迭代但无需提示"
2: "Dev 2 次编辑内完成"
1: "Dev 一次通过"
2. "过程质量":
- Dev 的探索是否有逻辑(不是在随机瞎试)
- 失败后的调整是否合理
- 提示后的方向调整是否快速有效
3. "任务描述清晰度":
- PM 的描述是否足以让人类开发者理解
- 验收标准是否可验证
4. "失败原因分类"(如果 Dev 最终失败):
- genuine_difficulty: 任务确实难,有训练价值
- env_issue: 环境问题(依赖缺失、构建失败)→ 丢弃
- ambiguous_spec: PM 描述模糊导致方向偏 → 退回 PM 重写
- agent_loop: Dev 在简单问题上打转 → 丢弃
5. "RL 训练价值":
high: 难度 4-5,过程有完整的探索-提示-突破链路
medium: 难度 3,有有意义的迭代
low: 难度 1-2,太简单但可作为 curriculum 起点
reject: env_issue / ambiguous_spec / agent_loop
# ── Reward 设计(用于 RL 训练)──
reward_schema:
# 基础 reward:任务是否完成
- task_pass: +1.0 # 所有测试通过
- task_fail: -0.2 # 最终未完成(不是 -1,失败轨迹也有过程价值)
# 提示惩罚:需要越多提示,reward 越低(但仍为正)
- no_hint_success: +1.0 # hard 模式直接搞定 → 满分
- L1_hint_success: +0.7 # 需要方向提示
- L2_hint_success: +0.4 # 需要模块提示
- L3_hint_success: +0.2 # 需要代码级提示(仍为正——因为最终搞定了)
# 过程 bonus:好的探索行为
- efficient_search: +0.1 # 快速定位到正确文件(< 5 轮)
- effective_backtrack: +0.1 # 主动放弃错误方向并换思路
- test_driven: +0.05 # 修改代码前先跑测试了解现状
# 惩罚:坏的探索行为
- repeated_same_edit: -0.1 # 重复修改同一行没有变化
- ignore_test_output: -0.05 # 测试报了错但没有阅读错误信息
三、数据流与产出格式
3.1 端到端数据流
Architect PM Test Crafter Dev Reviewer
│ │ │ │ │
│ ──→ clusters.jsonl │ │ │ │
│ │ │ │ │
│ ← 读取聚类 ──┤ │ │ │
│ │ │ │ │
│ │ ──→ task.yaml │ │ │
│ │ (描述+hints) │ │ │
│ │ │ │ │
│ │ ← 读取 ──┤ │ │
│ │ │ │ │
│ │ │ ──→ test_suite │ │
│ │ │ │ │
│ │ │ ← 注入 ──┤ │
│ │ │ │ │
│ │ ←── 卡住,请求 hint ──────────────── │ │
│ │ │ │ │
│ │ ──→ hint_L1 ─────────────────────→ │ │
│ │ │ │ │
│ │ │ │ ──→ trajectory │
│ │ │ │ │
│ │ │ │ ← 审核 ──┤
│ │ │ │ │
│ │ │ │ verdict │
3.2 最终任务卡片格式
# verified_tasks/django-querysets-union-2026Q1.yaml
task_id: "django-querysets-union-2026Q1"
task_type: "compound" # compound / single
repo: "django/django"
language: "python"
base_commit: "abc123def"
# ── 任务描述 ──
description: |
重构 QuerySet 的集合操作,支持嵌套 annotate、链式 filter、向后兼容...
acceptance_criteria:
- "union 后保留 annotate 字段"
- "集合操作后可以 filter"
- "现有测试不回归"
# ── 测试 ──
test_suite:
cmd: "python -m pytest tests/queries/test_union_compound.py -x -q"
files: ["tests/queries/test_union_compound.py"]
total_tests: 8
# ── 渐进提示 ──
hints:
L0: []
L1: ["问题根源在 SQL 生成阶段..."]
L2: ["核心代码在 query.py 和 compiler.py...", "Query.combine() 需要..."]
L3: ["第 542 行的 annotation_select_mask..."]
# ── Ground Truth ──
ground_truth:
source_prs: ["#18432", "#18501", "#18523"]
combined_diff_file: "diffs/django-querysets-union-2026Q1.patch"
# ── 执行结果与难度 ──
executions:
- model: "claude-sonnet-4.5"
variant: "hard"
status: "SUCCESS_WITH_HINTS"
hints_needed: ["L1"] # 需要 L1 提示才突破
total_turns: 28
edit_attempts: 6
trajectory: "trajectories/django-...-sonnet-hard.jsonl"
key_moments:
- { turn: 8, event: "dead_end", detail: "尝试修改 compiler.py 无效" }
- { turn: 12, event: "hint_received", level: "L1" }
- { turn: 14, event: "direction_change", detail: "转向 query.py 的 combine()" }
- { turn: 22, event: "incremental_success", detail: "6/8 tests pass" }
- { turn: 28, event: "all_pass" }
- model: "qwen3-32b"
variant: "hard"
status: "SUCCESS_WITH_HINTS"
hints_needed: ["L1", "L2"]
total_turns: 38
trajectory: "trajectories/django-...-qwen32b-hard.jsonl"
- model: "qwen3-32b"
variant: "easy"
status: "SUCCESS"
hints_needed: [] # easy 模式预置了 L2 hints,不需要额外提示
total_turns: 15
trajectory: "trajectories/django-...-qwen32b-easy.jsonl"
# ── RL 元数据 ──
difficulty: 4 # 基于执行结果综合判定
rl_value: "high"
reward_profile:
sonnet_hard: 0.7 # L1 hint → 0.7
qwen32b_hard: 0.4 # L1+L2 hint → 0.4
qwen32b_easy: 1.0 # 预置 hints 下无需额外提示 → 1.0
# ── DPO 对(自动产出)──
dpo_pairs:
- chosen: "trajectories/django-...-sonnet-hard.jsonl" # 需要 L1 就搞定
rejected: "trajectories/django-...-qwen32b-hard.jsonl" # 需要 L1+L2
- chosen: "trajectories/django-...-qwen32b-easy.jsonl" # 15 轮完成
rejected: "trajectories/django-...-qwen32b-hard.jsonl" # 38 轮完成
tags: ["orm", "sql-generation", "cross-file", "refactor", "compound"]
四、框架与工具栈
| 组件 | 选型 | 理由 |
|---|---|---|
| Agent 框架 | OpenHarness(HKUDS,MIT,8.9K star)或 Claude Code CLI | Docker 沙箱内置、工具集完整;Claude Code CLI 更轻量 |
| 沙箱 | OpenHarness Docker 后端 | 免费、够用;大规模时可升级 E2B Firecracker |
| 环境构建 | SWE-rebench V2 管线 | 已解决跨 commit 依赖锁定 |
| Release 分析 | Git tag + GitHub Releases API + LLM 分析 | Release notes 质量高于 PR,无需聚类算法 |
| RL 训练 | GRPO(verl-agent / ms-swift) | 免 Reward Model,支持稀疏奖励 |
| DPO 训练 | TRL(HuggingFace) | 成熟、社区支持好 |
| 轨迹格式 | TAO-extended(增加 hint/direction_change 字段) | 兼容主流训练框架 |
| LLM 调用 | Anthropic API(PM/Reviewer)+ 本地 vLLM(Dev calibration) | — |
五、Repo 精选(首批 30 个)
选择标准
| 维度 | 要求 | 原因 |
|---|---|---|
| 测试覆盖 | CI 完善,测试通过率 >90% | 测试是 reward signal |
| Release 历史 | ≥3 个 release tag,有 changelog/release notes | Release 特性是任务来源 |
| 代码规模 | 10K-500K 行 | 太小没挑战,太大环境不可控 |
| Release 质量 | changelog 描述规范、特性明确 | Architect 分析的输入质量 |
| 依赖管理 | 有 lock 文件 | 环境可复现 |
Repo 列表
Python(12):django · flask · fastapi · requests · pandas · scikit-learn · pydantic · celery · httpx · sqlalchemy · pytest · poetry
TypeScript(10):TypeScript(编译器)· next.js · prisma · tRPC · vite · vitest · react-router · drizzle-orm · zod · date-fns
Go(5):gin · chi · testify · cobra · terraform
Rust(3):tokio · serde · clap
六、规模估算
| 阶段 | 输入 | 产出 | 通过率 |
|---|---|---|---|
| Architect Release 分析 | 30 repos × 2-3 大版本 | ~600 single features + ~200 compound features | — |
| PM 合成 | 800 features(筛去过小/过简单的) | ~500 compound tasks + ~1,500 single tasks | ~60% 可用 |
| Test Crafter | 2,000 tasks | ~1,800 validated tasks | ~90% 测试可用 |
| Dev 执行 | 1,800 tasks × 3 难度 × 2 模型 | ~10,800 trajectories | — |
| Reviewer 筛选 | 10,800 trajectories | 3,000-5,000 verified tasks | ~35% |
成本
| 环节 | 单价 | 数量 | 小计 |
|---|---|---|---|
| Architect (Sonnet) | ~$0.08 | 800 features | $64 |
| PM (Opus) | ~$0.15 | 2,000 tasks | $300 |
| Test Crafter (Sonnet) | ~$0.10 | 1,800 tasks | $180 |
| Dev (Sonnet, ~30K tokens/run) | ~$0.50 | 5,400 runs | $2,700 |
| Dev (Qwen-32B 本地 vLLM) | ~$0 | 5,400 runs | $0 |
| Reviewer (Opus) | ~$0.25 | 5,400 | $1,350 |
| Docker 运行 | ~$0.02/run | 10,800 | $216 |
| 总计 | ~$4,810 |
七、实施路线
Phase 1:最小验证(1 周)
- 选 3 个 repo(Django、FastAPI、Next.js)
- Architect 各分析 2-3 个 release → 每个 repo 约 15-20 个 feature
- PM 合成 ~50 个 task(含 single 和 compound)
- Test Crafter 验证测试
- Dev (Sonnet) 跑 hard 模式,PM 实时提示
- 验证指标:60 个任务中能产出多少个 difficulty ≥ 3 的 verified task?
成功标准:≥ 12 个高价值 task(通过率 ≥ 20%),其中 ≥ 5 个是 compound task
Phase 2:全量执行(2 周)
- 全部 30 个 repo
- 多模型 Dev 执行
- 全量 Reviewer 筛选
- 输出 verified_tasks/ 和 trajectories/
Phase 3:RL 训练验证(2 周)
- GRPO 训练 Qwen3-32B / GLM-5-chat
- 在 SWE-bench Verified + SWE-Rebench 上评测
- 关键消融实验(证明每个创新点的价值):
- compound vs single:只用复合任务训练 vs 只用单任务训练 → 证明复合任务的价值
- 带轨迹 vs 只有 patch:用完整探索轨迹训练 vs 只用 (task, final_patch) 训练 → 证明过程数据的价值
- 带 hint 对 vs 无 hint:用 PM 提示产出的 DPO 对训练 vs 不用 → 证明提示机制的价值
- HarnessForge vs SWE-smith:同等量级下(各取 3K 条),哪个训练效果更好 → 头对头比较
- 成功标准:Qwen3-32B 在 SWE-bench Verified 上提升 ≥3 个点,且 compound tasks 的消融贡献 ≥1.5 个点
八、核心创新总结
- Release 特性驱动的任务合成(vs 单 PR 映射 / PR 聚类):Architect 从 release changelog 中提取特性,支持单 release 独立特性和跨 release 合并,产出跨模块长程任务
- 丢失过程重建(vs 只有最终 patch):完整的探索-试错-回退-提示-突破轨迹
- PM 提示作为难度信号(vs 迭代轮次):Dev 需要提示才突破 = genuine hard
- 渐进提示产出 DPO 对:同一任务的 (hard_fail, medium_success) 轨迹 → 自然的 chosen/rejected
- 五角色分工:Architect 做 release 分析、PM 做合成、Test Crafter 做验证、Dev 做执行、Reviewer 做筛选——每个角色用最适合的模型
参考
- Philipp Schmid (Google DeepMind), The importance of Agent Harness in 2026 — “The Harness is the Dataset” 原始论述
- Epsilla, The Harness is the Dataset: Why Agent Trajectories are the New Enterprise Moat — 轨迹数据的飞轮效应与战略价值
- SWE-bench: arXiv:2310.06770 — PR-based 任务标准
- SWE-rebench V2: arXiv:2602.23866 — 自动化环境构建管线
- SWE-smith: NeurIPS 2025 — Bug 注入合成
- Hybrid-Gym: CMU + All Hands AI, 2026 — 基础技能分解训练
- OpenHarness: github.com/HKUDS/OpenHarness — Agent Harness 框架
- DeepSWE: together.ai/blog/deepswe — 纯 RL 训练 Coding Agent
- Harness Engineering — Harness 工程化范式
- The Harness is the Dataset — 轨迹数据构建
- 超越 PR Diff — 任务设计方法论