Sebuah "outcome" (hasil akhir) memberi tahu sesi seperti apa hasil akhir yang seharusnya dan bagaimana mengukur kualitasnya. Agen bekerja menuju target tersebut, mengevaluasi diri dan beriterasi hingga outcome terpenuhi.
Saat Anda mendefinisikan outcome, harness secara otomatis menyediakan sebuah grader (penilai) untuk mengevaluasi artefak terhadap sebuah rubrik. Grader menggunakan "context window" (jendela konteks) terpisah agar tidak terpengaruh oleh pilihan implementasi agen utama.
Grader mengembalikan penjelasan yang merangkum kriteria mana yang lolos atau gagal, atau mengonfirmasi bahwa artefak memenuhi rubrik. Umpan balik tersebut diserahkan kembali kepada agen untuk iterasi berikutnya.
Rubrik adalah dokumen markdown yang menjelaskan penilaian per kriteria. Rubrik wajib disertakan.
Contoh 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 includedTeruskan rubrik sebagai teks inline pada user.define_outcome (lihat Membuat sesi dengan outcome), atau unggah melalui Files API agar dapat digunakan kembali di berbagai sesi.
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}")Contoh berikut membuat sebuah sesi untuk agen dan environment yang sudah ada (keduanya dibuat secara terpisah), lalu mengirim event user.define_outcome. Agen segera mulai bekerja. Tidak diperlukan event pesan pengguna tambahan.
# Buat sesi
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
title="Financial analysis on Costco",
)
# Definisikan hasil — agen mulai bekerja saat menerimanya
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},
# atau: "rubric": {"type": "file", "file_id": rubric.id},
"max_iterations": 5, # optional; default 3, max 20
}
],
)Kemajuan pada sesi berorientasi outcome ditampilkan pada stream event.
agent.* (seperti pesan dan penggunaan alat) menunjukkan kemajuan menuju outcome.span.outcome_evaluation_* hanya dipancarkan untuk sesi berorientasi outcome dan menunjukkan jumlah loop iterasi serta proses umpan balik grader.user.message ke sesi berorientasi outcome untuk mengarahkan pekerjaan agen seiring kemajuannya, tetapi ini tidak wajib: agen bekerja menuju outcome secara mandiri, beriterasi hingga berhasil atau kehabisan iterasi.user.interrupt menjeda pekerjaan pada outcome saat ini dan menandai span.outcome_evaluation_end.result sebagai interrupted, sehingga Anda dapat memulai outcome baru.Ini adalah event yang Anda kirim untuk memulai sebuah outcome. Event ini dipantulkan kembali saat diterima, termasuk timestamp processed_at dan 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
}Dipancarkan ketika grader memulai evaluasi atas satu loop iterasi. Field iteration adalah penghitung revisi berindeks 0: 0 adalah evaluasi pertama, 1 adalah evaluasi ulang setelah revisi pertama, dan seterusnya.
{
"type": "span.outcome_evaluation_start",
"id": "sevt_01def...",
"outcome_id": "outc_01a...",
"iteration": 0,
"processed_at": "2026-03-25T14:01:45Z"
}Heartbeat yang dipancarkan selama grader berjalan. Penalaran internal grader bersifat tertutup: Anda melihat bahwa grader sedang bekerja, bukan apa yang dipikirkannya.
{
"type": "span.outcome_evaluation_ongoing",
"id": "sevt_01ghi...",
"outcome_id": "outc_01a...",
"iteration": 0,
"processed_at": "2026-03-25T14:02:10Z"
}Dipancarkan ketika siklus evaluasi outcome berakhir: setelah grader selesai mengevaluasi satu iterasi, atau ketika sesi diinterupsi saat sebuah outcome sedang aktif. Field result menunjukkan apa yang terjadi selanjutnya.
| Result | Selanjutnya |
|---|---|
satisfied | Sesi beralih ke idle. |
needs_revision | Agen memulai siklus iterasi baru. |
max_iterations_reached | Satu giliran pengakuan terakhir menyusul sebelum sesi beralih ke idle. Tidak ada evaluasi lebih lanjut yang dijalankan. |
failed | Sesi beralih ke idle. Dikembalikan ketika rubrik tidak berlaku untuk deliverable, misalnya jika deskripsi dan rubrik saling bertentangan. |
interrupted | Dipancarkan ketika sesi diinterupsi saat sebuah outcome sedang aktif, bahkan jika evaluasi belum dimulai. Jika tidak ada outcome_evaluation_start yang terpicu sebelum interupsi, outcome_evaluation_start_id berupa string kosong. |
{
"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"
}Anda dapat mendengarkan stream event untuk span.outcome_evaluation_end, atau melakukan polling GET /v1/sessions/{session_id} dan membaca outcome_evaluations[].result. Hingga evaluasi selesai, result melaporkan pending, running, atau evaluating:
session = client.beta.sessions.retrieve(session.id)
for outcome in session.outcome_evaluations:
print(f"{outcome.outcome_id}: {outcome.result}")
# outc_01a...: satisfiedAgen menulis file output ke /mnt/session/outputs/ di dalam sandbox. Setelah sesi idle, ambil file tersebut melalui Files API yang dicakupkan ke sesi.
# Daftar file yang dihasilkan oleh sesi ini
# Pemfilteran scope_id memerlukan beta managed-agents pada permintaan 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)
# Unduh file
if files.data:
content = client.files.download(files.data[0].id)
content.write_to_file("/tmp/output.txt")Daftarkan kredensial per pengguna saat membuat sesi.
Kirim event, stream respons, dan interupsi atau arahkan ulang sesi Anda di tengah eksekusi.
Unggah file dan mount ke dalam sandbox Anda untuk dibaca dan diproses.
Was this page helpful?