Un outcome 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 viene soddisfatto.
Quando definisci un outcome, l'harness fornisce automaticamente un grader (valutatore) per valutare l'artefatto rispetto a una rubrica. Il grader utilizza una "context window" (finestra di contesto) separata per evitare di essere influenzato dalle scelte di implementazione dell'agente principale.
Il grader restituisce una spiegazione che riassume quali criteri sono stati superati o falliti, 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.
Esempio di rubrica:
# 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 su user.define_outcome (vedi Crea una sessione con un outcome), oppure caricala tramite la Files API per riutilizzarla in più 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.
# Create a session
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
title="Financial analysis on Costco",
)
# Define the outcome — agent starts working on receipt
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},
# or: "rubric": {"type": "file", "file_id": rubric.id},
"max_iterations": 5, # optional; default 3, max 20
}
],
)I progressi di una sessione orientata all'outcome vengono esposti sullo stream degli eventi.
agent.* (come i messaggi e l'uso degli strumenti) mostrano i progressi 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 mentre procede, ma non è obbligatorio: l'agente lavora verso l'outcome in autonomia, iterando finché non ha successo o esaurisce le iterazioni.user.interrupt mette in pausa il lavoro sull'outcome corrente e contrassegna span.outcome_evaluation_end.result come interrupted, consentendoti 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 indicizzato 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 un ciclo di valutazione dell'outcome termina: 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.
| Result | 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 vengono eseguite ulteriori valutazioni. |
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 di eventi per span.outcome_evaluation_end, oppure eseguire il polling di GET /v1/sessions/{session_id} e leggere outcome_evaluations[].result. Finché una valutazione non viene 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 è inattiva, recuperali tramite la Files API con ambito limitato alla sessione.
# List files produced by this session
# scope_id filtering requires the managed-agents beta on the files request
files = client.beta.files.list(scope_id=session.id, betas=["managed-agents-2026-04-01"])
for file in files:
print(file.id, file.filename)
# Download a file
if files.data:
content = client.files.download(files.data[0].id)
content.write_to_file("/tmp/output.txt")Registra le 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?