Un "outcome" (risultato atteso) indica alla sessione come dovrebbe apparire il risultato finale e come misurarne la qualità. L'agente lavora verso quell'obiettivo, autovalutandosi e iterando finché l'outcome non è soddisfatto.
Quando definisci un outcome, l'harness predispone automaticamente un grader (valutatore) per valutare l'artefatto rispetto a una rubrica. Il grader usa una "context window" (finestra di contesto) separata per evitare di essere influenzato dalle scelte implementative dell'agente principale.
Il grader restituisce una spiegazione che riassume quali criteri sono stati superati o meno, oppure conferma che l'artefatto soddisfa la rubrica. Quel feedback viene restituito all'agente per l'iterazione successiva.
Una rubrica è un documento markdown che descrive il punteggio per ciascun criterio. La rubrica è obbligatoria.
Rubrica di esempio:
# DCF Model Rubric
## Revenue Projections
- Uses historical revenue data from the last 5 fiscal years
- Projects revenue for at least 5 years forward
- Growth rate assumptions are explicitly stated and reasonable
## Cost Structure
- COGS and operating expenses are modeled separately
- Margins are consistent with historical trends or deviations are justified
## Discount Rate
- WACC is calculated with stated assumptions for cost of equity and cost of debt
- Beta, risk-free rate, and equity risk premium are sourced or justified
## Terminal Value
- Uses either perpetuity growth or exit multiple method (stated which)
- Terminal growth rate does not exceed long-term GDP growth
## Output Quality
- All figures are in a single .xlsx file with clearly labeled sheets
- Key assumptions are on a separate "Assumptions" sheet
- Sensitivity analysis on WACC and terminal growth rate is includedPassa la rubrica come testo inline in user.define_outcome (vedi Creare una sessione con un outcome), oppure caricala tramite la Files API per riutilizzarla tra le sessioni.
import time
from pathlib import Path
from anthropic import Anthropic
client = Anthropic()
RUBRIC = """# DCF Model Rubric
## Revenue Projections
- Uses historical revenue data from the last 5 fiscal years
- Projects revenue for at least 5 years forward
## Output Quality
- All figures are in a single .xlsx file with clearly labeled sheets
"""
Path("/tmp/rubric.md").write_text(RUBRIC)
rubric = client.files.upload(file=Path("/tmp/rubric.md"))
print(f"Uploaded rubric: {rubric.id}")Gli esempi seguenti creano una sessione per un agente e un ambiente esistenti (entrambi creati separatamente), quindi inviano un evento user.define_outcome. L'agente inizia a lavorare immediatamente. Non è richiesto alcun evento di messaggio utente aggiuntivo.
# Crea una sessione
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
title="Financial analysis on Costco",
)
# Definisci l'esito — l'agente inizia a lavorare alla ricezione
client.beta.sessions.events.send(
session_id=session.id,
events=[
{
"type": "user.define_outcome",
"description": "Build a DCF model for Costco in .xlsx",
"rubric": {"type": "text", "content": RUBRIC},
# oppure: "rubric": {"type": "file", "file_id": rubric.id},
"max_iterations": 5, # optional; default 3, max 20
}
],
)L'avanzamento di una sessione orientata all'outcome viene esposto sullo stream degli eventi.
agent.* (come messaggi e uso degli strumenti) mostrano l'avanzamento verso l'outcome.span.outcome_evaluation_* vengono emessi solo per le sessioni orientate all'outcome e mostrano il numero di cicli di iterazione e il processo di feedback del grader.user.message a una sessione orientata all'outcome per indirizzare il lavoro dell'agente man mano che procede, ma non è obbligatorio: l'agente lavora verso l'outcome autonomamente, iterando finché non riesce o esaurisce le iterazioni.user.interrupt mette in pausa il lavoro sull'outcome corrente e contrassegna span.outcome_evaluation_end.result come interrupted, permettendoti di avviare un nuovo outcome.Questo è l'evento che invii per avviare un outcome. Viene restituito in eco alla ricezione, includendo un timestamp processed_at e un outcome_id.
{
"type": "user.define_outcome",
"description": "Build a DCF model for Costco in .xlsx",
"rubric": { "type": "file", "file_id": "file_01..." },
"max_iterations": 5
}Emesso quando il grader avvia una valutazione su un ciclo di iterazione. Il campo iteration è un contatore di revisioni con indice a partire da 0: 0 è la prima valutazione, 1 è la rivalutazione dopo la prima revisione, e così via.
{
"type": "span.outcome_evaluation_start",
"id": "sevt_01def...",
"outcome_id": "outc_01a...",
"iteration": 0,
"processed_at": "2026-03-25T14:01:45Z"
}Heartbeat emesso mentre il grader è in esecuzione. Il ragionamento interno del grader è opaco: vedi che sta lavorando, non cosa sta pensando.
{
"type": "span.outcome_evaluation_ongoing",
"id": "sevt_01ghi...",
"outcome_id": "outc_01a...",
"iteration": 0,
"processed_at": "2026-03-25T14:02:10Z"
}Emesso quando termina un ciclo di valutazione dell'outcome: dopo che il grader ha finito di valutare un'iterazione, oppure quando la sessione viene interrotta mentre un outcome è attivo. Il campo result indica cosa succede dopo.
| Risultato | Successivo |
|---|---|
satisfied | La sessione passa a idle. |
needs_revision | L'agente avvia un nuovo ciclo di iterazione. |
max_iterations_reached | Segue un ultimo turno di conferma prima che la sessione passi a idle. Non viene eseguita alcuna ulteriore valutazione. |
failed | La sessione passa a idle. Restituito quando la rubrica non si applica ai deliverable, ad esempio se la descrizione e la rubrica si contraddicono a vicenda. |
interrupted | Emesso quando la sessione viene interrotta mentre un outcome è attivo, anche se la valutazione non era ancora iniziata. Se nessun outcome_evaluation_start è stato emesso prima dell'interruzione, outcome_evaluation_start_id è una stringa vuota. |
{
"type": "span.outcome_evaluation_end",
"id": "sevt_01jkl...",
"outcome_evaluation_start_id": "sevt_01def...",
"outcome_id": "outc_01a...",
"result": "satisfied",
"explanation": "All 12 criteria met: revenue projections use 5 years of historical data, WACC assumptions are stated, sensitivity table is included...",
"iteration": 0,
"usage": {
"input_tokens": 2400,
"output_tokens": 350,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 1800
},
"processed_at": "2026-03-25T14:03:00Z"
}Puoi ascoltare lo stream degli eventi in attesa di span.outcome_evaluation_end, oppure interrogare periodicamente GET /v1/sessions/{session_id} e leggere outcome_evaluations[].result. Finché una valutazione non è completata, result riporta pending, running o evaluating:
session = client.beta.sessions.retrieve(session.id)
for outcome in session.outcome_evaluations:
print(f"{outcome.outcome_id}: {outcome.result}")
# outc_01a...: satisfiedL'agente scrive i file di output in /mnt/session/outputs/ all'interno della sandbox. Una volta che la sessione è idle, recuperali tramite la Files API con ambito limitato alla sessione.
# Elenca i file prodotti da questa sessione
# il filtro scope_id richiede la beta managed-agents nella richiesta files
files = client.beta.files.list(scope_id=session.id, betas=["managed-agents-2026-04-01"])
for file in files:
print(file.id, file.filename)
# Scarica un file
if files.data:
content = client.files.download(files.data[0].id)
content.write_to_file("/tmp/output.txt")Registra credenziali per utente durante la creazione delle sessioni.
Invia eventi, ricevi risposte in streaming e interrompi o reindirizza la tua sessione durante l'esecuzione.
Carica file e montali nella tua sandbox per la lettura e l'elaborazione.
Was this page helpful?