Skip to content

Annotazione di process reward

Raccogli segnali di reward per singolo passo per addestrare process reward model, con modalità primo errore e annotazione passo per passo. Esporta direttamente verso i formati di addestramento PRM, DPO e SWE-bench.

Novità della v2.4.0

I process reward model (PRM) hanno bisogno di etichette di correttezza per ogni singolo passo, non di un solo punteggio sull'esito finale. Addestrare un PRM che funzioni vuol dire raccogliere annotazioni che dicano con precisione in quale punto di una traccia multi-passo l'agente ha sbagliato, che tipo di errore ha commesso e se il recupero era possibile. È un'annotazione diversa da quella basata sull'esito, dove si giudica solo il risultato finale.

Potato mette a disposizione due modalità di annotazione, tarate su compromessi diversi tra velocità e dettaglio, per raccogliere dati di process reward. La modalità primo errore è pensata per un'etichettatura binaria rapida: l'annotatore clicca sul primo passo sbagliato e tutti i passi successivi vengono segnati in automatico come contaminati. La modalità passo per passo chiede invece di valutare ogni passo in modo indipendente, e produce segnali più ricchi al costo di più tempo di annotazione.

Entrambe le modalità funzionano con il display delle tracce di coding, con quello delle tracce degli agenti e con quello degli agenti web, quindi puoi raccogliere process reward per qualunque tipo di traccia.

Modalità primo errore

Nella modalità primo errore l'annotatore legge la traccia in sequenza e clicca sul primo passo in cui l'agente ha sbagliato. Tutti i passi precedenti a quello cliccato vengono etichettati automaticamente come corretti. Il passo cliccato e tutti quelli successivi vengono etichettati come sbagliati (il passo cliccato come «primo errore» e i restanti come «a valle dell'errore»).

Ne esce esattamente il formato di etichette che serve per addestrare un PRM binario: una sequenza di +1 seguita da un -1 nel punto dell'errore e da -1 per tutti i passi rimanenti.

Configurazione

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)"

Flusso di annotazione

  1. L'annotatore legge la traccia dall'alto verso il basso
  2. All'inizio i passi non sono contrassegnati (grigi)
  3. L'annotatore clicca sul primo passo sbagliato
  4. I passi da 0 a N-1 diventano verdi (corretti)
  5. Il passo N diventa rosso (primo errore)
  6. I passi da N+1 alla fine diventano arancioni (a valle dell'errore)
  7. Se l'intera traccia è corretta, l'annotatore clicca su «All Steps Correct»

Formato di output

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]
    }
  }
}

Quando l'annotatore segna tutti i passi come corretti, first_error_step vale null e l'array delle etichette contiene solo valori 1.

Modalità passo per passo

Nella modalità passo per passo l'annotatore valuta ogni passo della traccia in modo indipendente. Ne escono segnali più ricchi: un passo può essere «parzialmente corretto» o «superfluo», non solo corretto o sbagliato. Si colgono anche i casi in cui l'agente si riprende da un errore, che la modalità primo errore non è in grado di rappresentare.

Configurazione

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

Flusso di annotazione

  1. Ogni passo della traccia ha accanto a sé un widget di valutazione
  2. L'annotatore sceglie un'etichetta per ciascun passo
  3. Se il passo viene valutato «Incorrect» o «Partially Correct» e le categorie di errore sono attive, compare un menu a tendina per scegliere il tipo di errore
  4. Un campo note facoltativo permette di aggiungere una spiegazione in testo libero
  5. Un punteggio progressivo in cima mostra il reward cumulativo

Formato di output

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
    }
  }
}

Riferimento di configurazione

Tutte le opzioni di configurazione dello schema di annotazione process reward:

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"

Esportazione verso i formati di addestramento

Potato può esportare le annotazioni di process reward direttamente nei formati usati dalle pipeline di addestramento PRM più diffuse.

Formato di addestramento PRM

Esporta le etichette binarie a livello di passo per l'addestramento di un PRM:

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

Formato di output:

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}
  ]
}

Coppie di preferenza DPO/RLHF

Quando hai più tracce annotate per lo stesso task, puoi esportare le preferenze a coppie per l'addestramento DPO o RLHF. L'esportatore accoppia le tracce in cui una ha un reward cumulativo maggiore dell'altra:

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

Formato di output:

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..."}
  ]
}

Risultati compatibili con SWE-bench

Esporta i risultati della valutazione in un formato compatibile con le sottomissioni alla classifica SWE-bench:

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

Genera il JSON di valutazione standard di SWE-bench, con gli ID delle istanze, le patch del modello e lo stato di risoluzione ricavato dai giudizi degli annotatori.

Analisi

Potato offre alcune funzioni di utilità per analizzare le annotazioni di process reward:

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}")

Visualizzazione

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"
)

Contesto di ricerca

L'annotazione di process reward in Potato è pensata per sostenere la ricerca sull'addestramento e la valutazione dei reward model per i sistemi agentici. Diverse linee di lavoro recenti motivano questa funzionalità:

  • AgentPRM mostra che i process reward model addestrati su etichette a livello di passo battono nettamente gli outcome reward model nel guidare i coding agent durante la ricerca.
  • ToolRM e ToolRL mostrano che i reward model specializzati sui passi di uso degli strumenti migliorano le prestazioni degli agenti nei task di chiamata di API e di generazione di codice.
  • DeepSWE applica i process reward model a task di ingegneria del software su scala SWE-bench, usando le etichette per singolo passo per addestrare verificatori che guidano la ricerca ad albero dell'agente.
  • La ricerca sull'RLHF a livello di passo mostra che il feedback umano per singolo passo produce reward model più efficienti in termini di campioni rispetto al feedback a livello di episodio.

Le modalità primo errore e passo per passo di Potato corrispondono direttamente ai formati di etichetta usati da questi approcci. La pipeline di esportazione produce dati pronti per l'addestramento senza altra preelaborazione.

Vedi anche

Per i dettagli implementativi, vedi la documentazione sorgente.