Ein „outcome" (Ergebnis) teilt der Session mit, wie das Endresultat aussehen soll und wie dessen Qualität gemessen wird. Der Agent arbeitet auf dieses Ziel hin, bewertet sich selbst und iteriert, bis das Ergebnis erreicht ist.
Wenn du ein Ergebnis definierst, stellt der Harness automatisch einen Grader (Bewerter) bereit, der das Artefakt anhand einer Rubrik bewertet. Der Grader verwendet ein separates Kontextfenster, um nicht von den Implementierungsentscheidungen des Hauptagenten beeinflusst zu werden.
Der Grader gibt eine Erklärung zurück, die zusammenfasst, welche Kriterien bestanden oder nicht bestanden wurden, oder bestätigt, dass das Artefakt die Rubrik erfüllt. Dieses Feedback wird für die nächste Iteration an den Agenten zurückgegeben.
Eine „rubric" (Rubrik) ist ein Markdown-Dokument, das die Bewertung pro Kriterium beschreibt. Die Rubrik ist erforderlich.
Beispiel-Rubrik:
# 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 includedÜbergib die Rubrik als Inline-Text in user.define_outcome (siehe Eine Session mit einem Ergebnis erstellen) oder lade sie über die Files API hoch, um sie sessionübergreifend wiederzuverwenden.
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}")Die folgenden Beispiele erstellen eine Session für einen bestehenden Agenten und eine bestehende Umgebung (beide separat erstellt) und senden dann ein user.define_outcome-Event. Der Agent beginnt sofort mit der Arbeit. Es ist kein zusätzliches User-Message-Event erforderlich.
# Erstelle eine Session
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
title="Financial analysis on Costco",
)
# Definiere das Ergebnis — der Agent beginnt bei Erhalt mit der Arbeit
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},
# oder: "rubric": {"type": "file", "file_id": rubric.id},
"max_iterations": 5, # optional; default 3, max 20
}
],
)Der Fortschritt einer ergebnisorientierten Session wird im Event-Stream sichtbar gemacht.
agent.*-Events (wie Nachrichten und Tool-Nutzung) zeigen den Fortschritt in Richtung des Ergebnisses.span.outcome_evaluation_*-Events werden nur für ergebnisorientierte Sessions ausgegeben und zeigen die Anzahl der Iterationsschleifen sowie den Feedback-Prozess des Graders.user.message-Events an eine ergebnisorientierte Session senden, um die Arbeit des Agenten im Verlauf zu steuern, aber das ist nicht erforderlich: Der Agent arbeitet selbstständig auf das Ergebnis hin und iteriert, bis er erfolgreich ist oder keine Iterationen mehr übrig sind.user.interrupt-Event pausiert die Arbeit am aktuellen Ergebnis und markiert span.outcome_evaluation_end.result als interrupted, sodass du ein neues Ergebnis starten kannst.Dies ist das Event, das du sendest, um ein Ergebnis zu initiieren. Es wird beim Empfang zurückgespiegelt, einschließlich eines processed_at-Zeitstempels und einer 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
}Wird ausgegeben, sobald der Grader eine Bewertung über eine Iterationsschleife startet. Das Feld iteration ist ein 0-indizierter Revisionszähler: 0 ist die erste Bewertung, 1 ist die erneute Bewertung nach der ersten Revision und so weiter.
{
"type": "span.outcome_evaluation_start",
"id": "sevt_01def...",
"outcome_id": "outc_01a...",
"iteration": 0,
"processed_at": "2026-03-25T14:01:45Z"
}Heartbeat, der ausgegeben wird, während der Grader läuft. Die interne Argumentation des Graders ist undurchsichtig: Du siehst, dass er arbeitet, nicht, was er denkt.
{
"type": "span.outcome_evaluation_ongoing",
"id": "sevt_01ghi...",
"outcome_id": "outc_01a...",
"iteration": 0,
"processed_at": "2026-03-25T14:02:10Z"
}Wird ausgegeben, wenn ein Ergebnisbewertungszyklus endet: nachdem der Grader die Bewertung einer Iteration abgeschlossen hat oder wenn die Session unterbrochen wird, während ein Ergebnis aktiv ist. Das Feld result gibt an, was als Nächstes passiert.
| Resultat | Als Nächstes |
|---|---|
satisfied | Die Session wechselt zu idle. |
needs_revision | Der Agent startet einen neuen Iterationszyklus. |
max_iterations_reached | Es folgt ein letzter Bestätigungs-Turn, bevor die Session zu idle wechselt. Es wird keine weitere Bewertung ausgeführt. |
failed | Die Session wechselt zu idle. Wird zurückgegeben, wenn die Rubrik nicht auf die Liefergegenstände anwendbar ist, zum Beispiel wenn sich Beschreibung und Rubrik widersprechen. |
interrupted | Wird ausgegeben, wenn die Session unterbrochen wird, während ein Ergebnis aktiv ist, selbst wenn die Bewertung noch nicht begonnen hatte. Wenn vor der Unterbrechung kein outcome_evaluation_start ausgelöst wurde, ist outcome_evaluation_start_id ein leerer String. |
{
"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"
}Du kannst entweder im Event-Stream auf span.outcome_evaluation_end lauschen oder GET /v1/sessions/{session_id} pollen und outcome_evaluations[].result auslesen. Bis eine Bewertung abgeschlossen ist, meldet result den Wert pending, running oder evaluating:
session = client.beta.sessions.retrieve(session.id)
for outcome in session.outcome_evaluations:
print(f"{outcome.outcome_id}: {outcome.result}")
# outc_01a...: satisfiedDer Agent schreibt Ausgabedateien nach /mnt/session/outputs/ innerhalb der Sandbox. Sobald die Session im Zustand idle ist, rufe sie über die auf die Session beschränkte Files API ab.
# Liste die von dieser Session erzeugten Dateien auf
# scope_id-Filterung erfordert die managed-agents-Beta bei der Files-Anfrage
files = client.beta.files.list(scope_id=session.id, betas=["managed-agents-2026-04-01"])
for file in files:
print(file.id, file.filename)
# Lade eine Datei herunter
if files.data:
content = client.files.download(files.data[0].id)
content.write_to_file("/tmp/output.txt")Registriere benutzerspezifische Anmeldedaten beim Erstellen von Sessions.
Sende Events, streame Antworten und unterbrich oder lenke deine Session während der Ausführung um.
Lade Dateien hoch und binde sie in deiner Sandbox zum Lesen und Verarbeiten ein.
Was this page helpful?