Skip to content
Guides10 min read

Valutare gli Agenti AI: Una Guida Completa all'Annotazione Umana delle Tracce degli Agenti

Scopri come configurare la valutazione umana degli output di agenti AI utilizzando le funzionalità di annotazione agentica di Potato, dall'importazione delle tracce alla progettazione degli schemi di annotazione.

Potato Team·
هذه الصفحة غير متوفرة بلغتك بعد. يتم عرض النسخة الإنجليزية.

Valutare gli Agenti AI: Una Guida Completa all'Annotazione Umana delle Tracce degli Agenti

Le metriche automatizzate ti dicono con quale frequenza un agente ha successo. La valutazione umana ti dice perché fallisce, dove sbaglia, e come correggerlo. Questa guida illustra la configurazione di una pipeline completa di valutazione umana per agenti AI utilizzando le funzionalità di annotazione agentica di Potato.

Valuteremo un agente in stile ReAct che risponde a domande effettuando ricerche sul web. Al termine di questa guida, avrai:

  • Importato le tracce degli agenti in Potato
  • Configurato la visualizzazione delle tracce degli agenti
  • Impostato schemi di annotazione sia complessivi che per singolo passo
  • Eseguito il task di annotazione
  • Esportato i risultati strutturati della valutazione

Prerequisiti

Installa Potato 2.3.0 o versione successiva:

bash
pip install --upgrade potato-annotation

Avrai anche bisogno di tracce di agenti da valutare. Questa guida utilizza tracce ReAct, ma lo stesso approccio funziona per tutti i 12 formati supportati.


Passo 1: Prepara le Tracce degli Agenti

Una traccia ReAct è una sequenza di passi Thought (pensiero), Action (azione) e Observation (osservazione). Ecco un esempio minimale. Crea un file in data/traces.jsonl:

json
{
  "trace_id": "trace_001",
  "task": "What is the capital of Australia and what is its population?",
  "trace": [
    {"type": "thought", "content": "I need to find the capital of Australia and its population. Let me search for this."},
    {"type": "action", "content": "search", "action_input": "capital of Australia"},
    {"type": "observation", "content": "Canberra is the capital city of Australia. It was chosen as the capital in 1908 as a compromise between Sydney and Melbourne."},
    {"type": "thought", "content": "The capital is Canberra. Now I need to find its population."},
    {"type": "action", "content": "search", "action_input": "Canberra population 2025"},
    {"type": "observation", "content": "Canberra has a population of approximately 467,000 as of 2025, making it the eighth-largest city in Australia."},
    {"type": "thought", "content": "I now have both pieces of information. The capital of Australia is Canberra with a population of approximately 467,000."},
    {"type": "action", "content": "finish", "action_input": "The capital of Australia is Canberra, with a population of approximately 467,000 as of 2025."}
  ],
  "ground_truth": "Canberra, approximately 467,000"
}

Ogni riga nel file JSONL è una traccia completa dell'agente. Il campo trace contiene il log passo per passo. Il campo task indica cosa era stato chiesto all'agente di fare.

Note sui Formati delle Tracce

Per le tracce di function-calling di OpenAI, il formato è diverso:

json
{
  "trace_id": "oai_001",
  "task": "Find cheap flights from NYC to London",
  "messages": [
    {"role": "user", "content": "Find cheap flights from NYC to London"},
    {"role": "assistant", "content": null, "tool_calls": [{"function": {"name": "search_flights", "arguments": "{\"from\": \"NYC\", \"to\": \"LHR\"}"}}]},
    {"role": "tool", "name": "search_flights", "content": "{\"flights\": [{\"airline\": \"BA\", \"price\": 450}, {\"airline\": \"AA\", \"price\": 520}]}"},
    {"role": "assistant", "content": "I found flights from NYC to London. The cheapest is British Airways at $450."}
  ]
}

Il convertitore di Potato gestisce queste differenze. Basta specificare il nome del convertitore corretto.


Passo 2: Crea la Configurazione del Progetto

Crea config.yaml:

yaml
task_name: "ReAct Agent Evaluation"
task_dir: "."
 
data_files:
  - "data/traces.jsonl"
 
item_properties:
  id_key: trace_id
  text_key: task
 
# --- Agentic annotation settings ---
agentic:
  enabled: true
  trace_converter: react
  display_type: agent_trace
 
  agent_trace_display:
    colors:
      thought: "#6E56CF"
      action: "#3b82f6"
      observation: "#22c55e"
      error: "#ef4444"
    collapse_observations: true
    collapse_threshold: 400
    show_step_numbers: true
    show_timestamps: false
    render_json: true
    syntax_highlight: true

Questo indica a Potato di:

  1. Caricare le tracce da data/traces.jsonl
  2. Usare il convertitore ReAct per analizzare il campo trace
  3. Visualizzare le tracce usando il display delle tracce agentiche con card colorate per passo

Passo 3: Progetta gli Schemi di Annotazione

La valutazione degli agenti richiede tipicamente sia giudizi a livello di traccia (l'agente ha avuto successo?) che giudizi a livello di passo (ogni passo era corretto?). Aggiungiamo entrambi.

Aggiungi quanto segue a config.yaml:

yaml
annotation_schemes:
  # --- Schemi a livello di traccia ---
 
  # 1. Successo del task (la metrica più importante)
  - annotation_type: radio
    name: task_success
    description: "Did the agent successfully complete the task?"
    labels:
      - "Success"
      - "Partial Success"
      - "Failure"
    label_requirement:
      required: true
    sequential_key_binding: true
 
  # 2. Correttezza della risposta (se il task ha un ground truth)
  - annotation_type: radio
    name: answer_correctness
    description: "Is the agent's final answer factually correct?"
    labels:
      - "Correct"
      - "Partially Correct"
      - "Incorrect"
      - "Cannot Determine"
    label_requirement:
      required: true
 
  # 3. Valutazione dell'efficienza
  - annotation_type: likert
    name: efficiency
    description: "Did the agent use an efficient path to the answer?"
    min: 1
    max: 5
    labels:
      1: "Very Inefficient (many unnecessary steps)"
      3: "Average"
      5: "Optimal (no wasted steps)"
 
  # 4. Note in testo libero
  - annotation_type: text
    name: evaluator_notes
    description: "Any additional observations"
    label_requirement:
      required: false
 
  # --- Schemi a livello di passo ---
 
  # 5. Correttezza per passo
  - annotation_type: per_turn_rating
    name: step_correctness
    target: agentic_steps
    description: "Was this step correct and useful?"
    rating_type: radio
    labels:
      - "Correct"
      - "Partially Correct"
      - "Incorrect"
      - "Unnecessary"
 
  # 6. Tipo di errore per passo (mostrato solo quando il passo non è corretto)
  - annotation_type: per_turn_rating
    name: error_type
    target: agentic_steps
    description: "What type of error occurred?"
    rating_type: multiselect
    labels:
      - "Wrong tool/action"
      - "Wrong arguments"
      - "Hallucinated information"
      - "Reasoning error"
      - "Redundant step"
      - "Premature termination"
      - "Other"
    conditional:
      show_when:
        step_correctness: ["Partially Correct", "Incorrect", "Unnecessary"]

Questo design dello schema fornisce:

  • Una metrica binaria successo/fallimento per l'analisi di alto livello
  • Una valutazione della correttezza per la risposta finale
  • Un punteggio di efficienza per confrontare le strategie degli agenti
  • Valutazioni per passo per identificare esattamente dove gli agenti sbagliano
  • Una tassonomia condizionale degli errori che appare solo quando un passo ha un problema

Passo 4: Configura l'Output e Avvia il Server

Aggiungi le impostazioni di output a config.yaml:

yaml
output_annotation_dir: "output/"
output_annotation_format: "jsonl"
 
# Opzionale: esporta anche in Parquet per l'analisi
parquet_export:
  enabled: true
  output_dir: "output/parquet/"
  compression: zstd

config.yaml completo di riferimento:

yaml
task_name: "ReAct Agent Evaluation"
task_dir: "."
 
data_files:
  - "data/traces.jsonl"
 
item_properties:
  id_key: trace_id
  text_key: task
 
agentic:
  enabled: true
  trace_converter: react
  display_type: agent_trace
  agent_trace_display:
    colors:
      thought: "#6E56CF"
      action: "#3b82f6"
      observation: "#22c55e"
      error: "#ef4444"
    collapse_observations: true
    collapse_threshold: 400
    show_step_numbers: true
    render_json: true
    syntax_highlight: true
 
annotation_schemes:
  - annotation_type: radio
    name: task_success
    description: "Did the agent successfully complete the task?"
    labels: ["Success", "Partial Success", "Failure"]
    label_requirement:
      required: true
    sequential_key_binding: true
 
  - annotation_type: radio
    name: answer_correctness
    description: "Is the agent's final answer factually correct?"
    labels: ["Correct", "Partially Correct", "Incorrect", "Cannot Determine"]
    label_requirement:
      required: true
 
  - annotation_type: likert
    name: efficiency
    description: "Did the agent use an efficient path?"
    min: 1
    max: 5
    labels:
      1: "Very Inefficient"
      3: "Average"
      5: "Optimal"
 
  - annotation_type: text
    name: evaluator_notes
    description: "Any additional observations"
    label_requirement:
      required: false
 
  - annotation_type: per_turn_rating
    name: step_correctness
    target: agentic_steps
    description: "Was this step correct?"
    rating_type: radio
    labels: ["Correct", "Partially Correct", "Incorrect", "Unnecessary"]
 
  - annotation_type: per_turn_rating
    name: error_type
    target: agentic_steps
    description: "Error type"
    rating_type: multiselect
    labels:
      - "Wrong tool/action"
      - "Wrong arguments"
      - "Hallucinated information"
      - "Reasoning error"
      - "Redundant step"
      - "Premature termination"
      - "Other"
    conditional:
      show_when:
        step_correctness: ["Partially Correct", "Incorrect", "Unnecessary"]
 
output_annotation_dir: "output/"
output_annotation_format: "jsonl"
 
parquet_export:
  enabled: true
  output_dir: "output/parquet/"
  compression: zstd

Avvia il server:

bash
potato start config.yaml -p 8000

Apri http://localhost:8000 nel browser.


Passo 5: Il Flusso di Lavoro dell'Annotazione

Quando un annotatore apre una traccia, vede:

  1. Descrizione del task in cima (la query originale dell'utente)
  2. Card dei passi che mostrano la traccia completa dell'agente, codificate per colore per tipo:
    • Card viola per i pensieri/ragionamenti
    • Card blu per le azioni/chiamate agli strumenti
    • Card verdi per le osservazioni/risultati
    • Card rosse per gli errori
  3. Controlli di valutazione per passo accanto a ciascuna card
  4. Schemi a livello di traccia sotto la visualizzazione della traccia

Il flusso di lavoro tipico:

  1. Leggi la descrizione del task per capire cosa l'agente doveva fare
  2. Scorri i passi della traccia, valutando ciascuno
  3. Per qualsiasi passo valutato come "Partially Correct" o "Incorrect", seleziona il/i tipo/i di errore
  4. Valuta la traccia complessiva (successo, correttezza, efficienza)
  5. Aggiungi note se necessario
  6. Invia e passa alla traccia successiva

Suggerimenti per gli Annotatori

  • Espandi le osservazioni compresse per verificare che l'agente abbia elaborato le informazioni correttamente
  • Confronta la risposta finale con il ground truth (se disponibile) prima di valutare il successo del task
  • Valuta i passi "Unnecessary" separatamente da quelli "Incorrect" -- un passo inutile spreca sforzo ma non introduce errori
  • Usa la timeline dei passi nella barra laterale per saltare a passi specifici in tracce lunghe

Passo 6: Analisi dei Risultati

Dopo l'annotazione, analizza i risultati in modo programmatico.

Analisi di Base con pandas

python
import pandas as pd
import json
 
# Carica le annotazioni
annotations = []
with open("output/annotations.jsonl") as f:
    for line in f:
        annotations.append(json.loads(line))
 
df = pd.DataFrame(annotations)
 
# Tasso di successo del task
success_counts = df.groupby("annotations").apply(
    lambda x: x.iloc[0]["annotations"]["task_success"]
).value_counts()
print("Task Success Distribution:")
print(success_counts)
 
# Valutazione media dell'efficienza
efficiency_scores = [
    a["annotations"]["efficiency"]
    for a in annotations
    if "efficiency" in a["annotations"]
]
print(f"\nAverage Efficiency: {sum(efficiency_scores) / len(efficiency_scores):.2f}")

Analisi degli Errori a Livello di Passo

python
# Raccogli tutti gli errori a livello di passo
error_counts = {}
for ann in annotations:
    step_errors = ann["annotations"].get("error_type", {})
    for step_idx, errors in step_errors.items():
        for error in errors:
            error_counts[error] = error_counts.get(error, 0) + 1
 
print("Error Type Distribution:")
for error, count in sorted(error_counts.items(), key=lambda x: -x[1]):
    print(f"  {error}: {count}")

Analisi con DuckDB (tramite Parquet)

python
import duckdb
 
# Tasso di successo complessivo
result = duckdb.sql("""
    SELECT value, COUNT(*) as count
    FROM 'output/parquet/annotations.parquet'
    WHERE schema_name = 'task_success'
    GROUP BY value
    ORDER BY count DESC
""")
print(result)

Passo 7: Scalare il Progetto

Per progetti di valutazione più grandi (centinaia o migliaia di tracce), considera queste configurazioni:

Più Annotatori

Assegna più annotatori per traccia per l'accordo inter-annotatore:

yaml
annotation_task_config:
  total_annotations_per_instance: 3
  assignment_strategy: random

Utilizzo di Schemi Preconfigurati

Per una configurazione rapida, usa gli schemi di valutazione agente preconfigurati di Potato:

yaml
annotation_schemes:
  - preset: agent_task_success
  - preset: agent_step_correctness
  - preset: agent_error_taxonomy
  - preset: agent_efficiency

Controllo della Qualità

Abilita istanze gold-standard per il monitoraggio della qualità:

yaml
phases:
  training:
    enabled: true
    data_file: "data/training_traces.jsonl"
    passing_criteria:
      min_correct: 4
      total_questions: 5

Adattamento ad Altri Tipi di Agenti

OpenAI Function Calling

yaml
agentic:
  enabled: true
  trace_converter: openai
  display_type: agent_trace

Anthropic Tool Use

yaml
agentic:
  enabled: true
  trace_converter: anthropic
  display_type: agent_trace

Sistemi Multi-Agente (CrewAI/AutoGen)

yaml
agentic:
  enabled: true
  trace_converter: multi_agent
  display_type: agent_trace
  multi_agent:
    agent_converters:
      researcher: react
      writer: anthropic
      reviewer: openai

Agenti di Navigazione Web

Per gli agenti web, passa al display dell'agente web:

yaml
agentic:
  enabled: true
  trace_converter: webarena
  display_type: web_agent
  web_agent_display:
    screenshot_max_width: 900
    overlay:
      enabled: true
    filmstrip:
      enabled: true

Vedi Annotare gli Agenti di Navigazione Web per una guida dedicata.


La valutazione umana degli agenti AI richiede strumenti specializzati. Il sistema di annotazione agentica di Potato fornisce:

  • 12 convertitori per normalizzare le tracce da qualsiasi framework
  • 3 tipi di display ottimizzati per agenti che usano strumenti, navigano il web o hanno conversazioni
  • Valutazioni per turno per la valutazione a livello di passo
  • 9 schemi preconfigurati che coprono le dimensioni di valutazione più comuni
  • Esportazione Parquet per un'analisi efficiente a valle

L'intuizione chiave è che la valutazione degli agenti non riguarda solo "l'agente ha ottenuto la risposta giusta?" -- riguarda "l'agente ha ragionato correttamente a ogni passo?" L'annotazione passo per passo rivela schemi di errore che le metriche aggregate non colgono.


Ulteriori Letture