Skip to content

过程奖励标注

用首错模式和逐步模式收集逐步奖励信号,训练过程奖励模型,并直接导出为 PRM、DPO 和 SWE-bench 训练格式。

v2.4.0 新增

过程奖励模型(PRM)需要的是逐步的正确性标签,而不是单一的结果级评分。要训练出有效的 PRM,就得收集这样的标注:在一条多步骤 trace 中,智能体究竟从哪里开始出错、出的是什么错、之后还有没有可能挽回。这和基于结果的标注不同,后者只判断最终结果。

Potato 提供两种标注模式,对应收集过程奖励数据时不同的速度/细节取舍。首错模式面向快速的二元标注:标注者点击第一个错误步骤,后续所有步骤自动标记为受污染。逐步模式要求标注者独立评价每一步,信号更丰富,代价是标注时间更长。

两种模式都能和编码 trace 显示、智能体 trace 显示以及 web 智能体显示配合使用,因此你可以为任意类型的智能体 trace 收集过程奖励。

首错模式

在首错模式下,标注者按顺序读完 trace,点击智能体第一次出错的那一步。被点击步骤之前的所有步骤自动标为正确。被点击步骤及其之后的所有步骤标为错误(被点击的那一步标为“首个错误”,其余标为“错误的下游”)。

这正好产出训练二元 PRM 所需的标签格式:一串 +1,在出错点变成 -1,之后所有步骤都是 -1。

配置

yaml
annotation_schemes:
  - name: process_reward
    annotation_type: process_reward
    mode: first_error
    description: "Click the first step where the agent made a mistake"
 
    first_error:
      # Visual styling
      correct_color: "#22c55e"     # green for steps before the error
      error_color: "#ef4444"       # red for the first error step
      downstream_color: "#f97316"  # orange for steps after the error
      unmarked_color: "#6b7280"    # gray for steps not yet reviewed
 
      # Behavior
      require_confirmation: true   # ask "Are you sure?" before marking
      allow_no_error: true         # allow annotator to mark all steps correct
      show_step_content: true      # show step content in the annotation panel
 
      # Labels applied automatically
      labels:
        correct: "+1"
        first_error: "-1 (first error)"
        downstream: "-1 (downstream)"
        all_correct: "+1 (all correct)"

标注流程

  1. 标注者从上到下读完 trace
  2. 步骤初始状态是未标记(灰色)
  3. 标注者点击第一个错误步骤
  4. 第 0 步到第 N-1 步变绿(正确)
  5. 第 N 步变红(首个错误)
  6. 第 N+1 步到结尾变橙(下游)
  7. 如果整条 trace 都正确,标注者点击 “All Steps Correct”

输出格式

json
{
  "id": "trace_042",
  "annotations": {
    "process_reward": {
      "mode": "first_error",
      "first_error_step": 4,
      "total_steps": 8,
      "labels": [1, 1, 1, 1, -1, -1, -1, -1]
    }
  }
}

当标注者把所有步骤都标为正确时,first_error_stepnull,labels 数组里全是 1

逐步模式

在逐步模式下,标注者独立评价 trace 中的每一步。这样得到的信号更丰富——一步可以是“部分正确”或“多余”,而不只是对或错。它还能记录智能体从错误中恢复的情况,这是首错模式表达不了的。

配置

yaml
annotation_schemes:
  - name: process_reward
    annotation_type: process_reward
    mode: per_step
    description: "Rate each step independently"
 
    per_step:
      # Rating options
      labels:
        - value: "correct"
          display: "Correct"
          color: "#22c55e"
          score: 1.0
        - value: "partially_correct"
          display: "Partially Correct"
          color: "#eab308"
          score: 0.5
        - value: "incorrect"
          display: "Incorrect"
          color: "#ef4444"
          score: -1.0
        - value: "unnecessary"
          display: "Unnecessary"
          color: "#f97316"
          score: -0.5
        - value: "recovery"
          display: "Recovery from Error"
          color: "#3b82f6"
          score: 0.25
 
      # Optional error categorization for incorrect/partially correct steps
      error_categories:
        enabled: true
        categories:
          - "Wrong tool selected"
          - "Correct tool, wrong arguments"
          - "Hallucinated information"
          - "Repeated previous step"
          - "Logic error"
          - "Syntax error"
          - "Missed edge case"
          - "Unnecessary step"
          - "Other"
 
      # Behavior
      require_all_steps: true     # all steps must be rated before submission
      allow_notes: true           # optional text field per step
      show_running_score: true    # show cumulative reward score

标注流程

  1. trace 中的每一步旁边都有一个评分控件
  2. 标注者为每一步选择一个标签
  3. 如果某一步被评为 “Incorrect” 或 “Partially Correct”,且启用了错误分类,会出现一个下拉框供选择错误类型
  4. 一个可选的备注框允许写自由文本说明
  5. 顶部的连续评分显示累计奖励

输出格式

json
{
  "id": "trace_042",
  "annotations": {
    "process_reward": {
      "mode": "per_step",
      "total_steps": 6,
      "labels": [1.0, 1.0, -1.0, 0.25, 1.0, 1.0],
      "step_details": {
        "0": {"label": "correct"},
        "1": {"label": "correct"},
        "2": {
          "label": "incorrect",
          "error_category": "Wrong tool selected",
          "notes": "Agent used grep when it should have read the file directly"
        },
        "3": {
          "label": "recovery",
          "notes": "Agent recognized the mistake and tried a different approach"
        },
        "4": {"label": "correct"},
        "5": {"label": "correct"}
      },
      "cumulative_score": 2.75
    }
  }
}

配置参考

过程奖励标注方案的完整配置项:

yaml
annotation_schemes:
  - name: process_reward
    annotation_type: process_reward
    mode: first_error              # "first_error" or "per_step"
    description: "Process reward annotation"
 
    # Required for mode: first_error
    first_error:
      correct_color: "#22c55e"
      error_color: "#ef4444"
      downstream_color: "#f97316"
      unmarked_color: "#6b7280"
      require_confirmation: true
      allow_no_error: true
      show_step_content: true
 
    # Required for mode: per_step
    per_step:
      labels:
        - value: "correct"
          display: "Correct"
          color: "#22c55e"
          score: 1.0
        - value: "incorrect"
          display: "Incorrect"
          color: "#ef4444"
          score: -1.0
      error_categories:
        enabled: false
        categories: []
      require_all_steps: true
      allow_notes: false
      show_running_score: false
 
    # Common options
    target: agentic_steps          # bind to trace steps
    keyboard_shortcuts:
      enabled: true
      correct: "1"
      incorrect: "2"
      partially_correct: "3"
      unnecessary: "4"
      next_step: "j"
      prev_step: "k"

导出到训练格式

Potato 可以把过程奖励标注直接导出为常见 PRM 训练流水线使用的格式。

PRM 训练格式

导出用于 PRM 训练的二元步骤级标签:

bash
python -m potato.export \
  -i output/ \
  -f prm \
  -o results/prm_training_data.jsonl

输出格式:

json
{
  "trace_id": "trace_042",
  "steps": [
    {"content": "Search for Tokyo population", "label": 1},
    {"content": "Parse search results", "label": 1},
    {"content": "Search for NYC population", "label": -1},
    {"content": "Compare populations", "label": -1}
  ]
}

DPO / RLHF 偏好对

当同一个任务有多条已标注的 trace 时,可以导出成对偏好数据用于 DPO 或 RLHF 训练。导出器会把累计奖励更高的 trace 和更低的配成一对:

bash
python -m potato.export \
  -i output/ \
  -f dpo \
  -o results/dpo_pairs.jsonl \
  --min-score-gap 0.5

输出格式:

json
{
  "prompt": "Fix the failing test in test_parser.py",
  "chosen": [
    {"role": "assistant", "content": "Step 1: Read the test file..."},
    {"role": "assistant", "content": "Step 2: Identify the bug..."}
  ],
  "rejected": [
    {"role": "assistant", "content": "Step 1: Run all tests..."},
    {"role": "assistant", "content": "Step 2: Edit a random file..."}
  ]
}

SWE-bench 兼容结果

导出成可用于 SWE-bench 排行榜提交的评估结果格式:

bash
python -m potato.export \
  -i output/ \
  -f swebench \
  -o results/swebench_results.json

这会生成标准的 SWE-bench 评估 JSON,包含实例 ID、模型 patch,以及由标注者判断推导出的解决状态。

分析

Potato 提供了一些分析过程奖励标注的工具函数:

python
from potato.analysis import load_annotations, process_reward_stats
 
# Load annotations
annotations = load_annotations("output/")
 
# Step-level accuracy statistics
stats = process_reward_stats(annotations)
 
print(f"Total traces annotated: {stats['total_traces']}")
print(f"Traces with no errors: {stats['all_correct_count']} ({stats['all_correct_pct']:.1f}%)")
print(f"Average first-error position: step {stats['avg_first_error_step']:.1f}")
print(f"Average steps before error: {stats['avg_correct_prefix_length']:.1f}")
 
# Error distribution by step position
for position, count in stats['error_by_position'].items():
    print(f"  Step {position}: {count} errors")
 
# Error category distribution (per-step mode only)
if 'error_categories' in stats:
    for category, count in stats['error_categories'].items():
        print(f"  {category}: {count}")
 
# Inter-annotator agreement on first-error step
if stats['multi_annotator']:
    print(f"First-error agreement (exact): {stats['first_error_exact_agreement']:.2f}")
    print(f"First-error agreement (within 1): {stats['first_error_near_agreement']:.2f}")

可视化

python
from potato.analysis import plot_error_distribution
 
# Plot error position distribution across all traces
plot_error_distribution(
    annotations,
    output_path="figures/error_distribution.png",
    normalize_by_trace_length=True,
    title="Where Do Agents First Go Wrong?"
)
 
# Plot per-step reward curves
from potato.analysis import plot_reward_curves
 
plot_reward_curves(
    annotations,
    output_path="figures/reward_curves.png",
    group_by="agent_model",
    title="Cumulative Reward by Model"
)

研究背景

Potato 的过程奖励标注是为支持智能体系统奖励模型的训练与评估研究而设计的。近期有几条工作线推动了这个功能:

  • AgentPRM 表明,在搜索过程中引导编码智能体时,用步骤级标签训练的过程奖励模型明显优于结果奖励模型。
  • ToolRMToolRL 表明,专门针对工具使用步骤的奖励模型可以提升智能体在 API 调用和代码生成任务上的表现。
  • DeepSWE 把过程奖励模型用到 SWE-bench 规模的软件工程任务上,用逐步标签训练验证器来引导智能体的树搜索。
  • 步骤级 RLHF 的研究显示,逐步的人类反馈比整段反馈更省样本。

Potato 的首错模式和逐步模式直接对应这些方法所用的标签格式。导出流程产出的数据无需额外预处理即可用于训练。

另请参阅

有关实现详情,请参阅源文档