Thread sesi
Cantumkan, interupsi, dan arsipkan thread dari sesi multiagen, baca event-nya, dan tangani izin alat di seluruh thread tersebut.
Dalam sesi multiagen, setiap agen bekerja di session thread (thread sesi) miliknya sendiri. Halaman ini membahas cara mencantumkan, menginterupsi, dan mengarsipkan thread, event yang dikirimkannya, serta cara kerja izin alat di seluruh thread tersebut. Sebuah eksekusi workflow juga membuat thread sesi.
Thread utama dan thread sesi
Aliran event tingkat sesi (/v1/sessions/{session_id}/events/stream) dianggap sebagai primary thread (thread utama), yang berisi tampilan ringkas dari semua aktivitas di seluruh thread. Anda tidak melihat aktivitas lengkap dari subagen, tetapi Anda melihat awal dan akhir pekerjaan mereka, serta event yang memblokir seperti permintaan izin alat.
Thread sesi adalah tempat Anda menelusuri aktivitas agen tertentu secara mendalam.
status sesi merupakan agregasi dari semua aktivitas agen; jika setidaknya satu thread berstatus running, maka status sesi secara keseluruhan juga running. Sebuah eksekusi workflow yang sedang berjalan juga dapat membuat sesi tetap running, bahkan ketika tidak ada thread-nya yang sedang bekerja. Ketika tidak ada thread yang bekerja dan sebuah thread menunggu klien Anda, sesi berstatus idle; lihat Mengetahui kapan pekerjaan selesai.
Sebuah anggaran sesi adalah satu batas bersama untuk semua thread dalam sebuah sesi. Saat batas tercapai, thread berhenti sementara secara independen, dan biaya setiap thread dihitung berdasarkan model yang melayani thread itu sendiri.
Mencantumkan thread
Cantumkan semua thread yang terkait dengan sebuah sesi sebagai berikut:
for thread in client.beta.sessions.threads.list(session.id):
agent = thread.agent
label = agent.type if agent.type == "advisor" else agent.name
print(f"[{label}] {thread.status}")Daftar lengkap mencakup thread utama. parent_thread_id bernilai null untuk thread utama. Setiap thread lainnya adalah thread anak. workflow_run_id bernilai null kecuali pada thread milik sebuah eksekusi.
Untuk mencantumkan hanya thread yang memiliki status tertentu, tambahkan statuses[] ke permintaan, dan ulangi untuk memberikan lebih dari satu status, seperti pada ?statuses[]=running&statuses[]=idle. Hilangkan parameter ini untuk mengembalikan thread dengan semua status.
Menginterupsi thread sesi
Kirim user.interrupt dengan session_thread_id untuk menghentikan thread tertentu. Menghilangkan session_thread_id akan menginterupsi setiap thread yang tidak diarsipkan dalam sesi, termasuk thread utama. Dalam sesi dengan alur kerja dinamis, interupsi tidak mengakhiri eksekusi apa pun, dan interupsi yang menyebut thread milik sebuah eksekusi tidak menghentikan apa pun. Interupsi menutup panggilan alat yang tertunda pada thread anak lainnya, tetapi jangan mengandalkannya untuk menutup panggilan alat milik thread eksekusi. Lihat Menginterupsi sesi dengan eksekusi yang terbuka.
client.beta.sessions.events.send(
session.id,
events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
)Terhadap thread subagen yang terblokir pada requires_action, interupsi menutup setiap panggilan alat yang tertunda dengan hasil alat berupa error ("Tool execution was interrupted before completion. Please retry.") dan langsung memancarkan ulang session.thread_status_idle dengan stop_reason: end_turn; model tidak di-sampling. Terhadap thread anak yang idle dengan end_turn atau budget_reached, interupsi tidak berpengaruh apa pun. Interupsi yang menyebut thread yang telah dihentikan mengembalikan error 400. Thread anak yang diinterupsi tidak mengirimkan kepada agen thread utama laporan yang biasanya dikirimkannya saat sebuah giliran berakhir. Selama agen tersebut menunggu thread anak, agen tidak memulai giliran lain hingga ada hal lain yang mencapainya, seperti user.message atau laporan dari thread lain.
Mengarsipkan thread sesi
Secara opsional, arsipkan thread sesi ketika thread tersebut telah menyelesaikan pekerjaannya. Mengarsipkan thread membebaskan tempatnya di bawah batas 25 thread anak. Server mengarsipkan sendiri thread milik sebuah eksekusi workflow. Anda tidak perlu mengarsipkannya, dan Anda tidak dapat melakukannya selama eksekusi masih terbuka.
archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
print(archived.status, archived.archived_at)Pengarsipan hanya berhasil jika thread berstatus idle. Thread yang tertahan pada requires_action dihitung sebagai idle dan dapat langsung diarsipkan; hanya thread yang sedang berjalan yang harus diinterupsi terlebih dahulu:
client.beta.sessions.events.send(
session.id,
events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
)
archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
print(archived.status, archived.archived_at)Event thread utama
Event-event ini menampilkan aktivitas multiagen pada thread utama di /v1/sessions/{session_id}/events/stream. Event arah pesan dinamai relatif terhadap thread yang aliran event-nya memuat event tersebut: agent.thread_message_received berarti sebuah pesan tiba di thread ini dari thread lain, dan agent.thread_message_sent berarti thread ini mengirimkan pesan. Tugas yang didelegasikan oleh agen thread utama, misalnya, tiba di aliran milik thread anak sebagai event agent.thread_message_received.
| Tipe | Deskripsi |
|---|---|
session.thread_created | Sebuah thread telah dibuat. Mencakup session_thread_id dan agent_name. |
session.thread_status_running | Sebuah thread memulai aktivitas. |
session.thread_status_idle | Agen yang terkait dengan thread sedang menunggu input. Mencakup stop_reason yang menunjukkan mengapa agen berhenti. |
session.thread_status_terminated | Sebuah thread dihentikan dan tidak menerima input lebih lanjut, misalnya karena diarsipkan atau mengalami error yang tidak dapat dipulihkan. Thread advisor juga dihentikan ketika konsultasinya berakhir. |
agent.thread_message_received | Pada thread utama, sebuah subagen mengirimkan laporan atau pertanyaan kepada agen thread utama. Mencakup from_session_thread_id, from_agent_name, dan content. |
agent.thread_message_sent | Pada thread utama, agen thread utama mengirimkan tugas atau pesan tindak lanjut kepada sebuah subagen. Mencakup to_session_thread_id, to_agent_name, dan content. |
Konsultasi advisor memancarkan event thread yang sama ini dengan nama cadangan anthropic.advisor (sebagai agent_name pada event siklus hidup thread dan from_agent_name pada penyampaian saran); lihat Berikan advisor pada sesi untuk urutannya.
Thread milik sebuah eksekusi workflow ditampilkan pada aliran utama sebagai berikut:
- Event siklus hidup: Setiap thread eksekusi mengirimkan
session.thread_created, denganworkflow_run_idmilik eksekusi tersebut, serta eventsession.thread_status_running,session.thread_status_idle, dansession.thread_status_terminatedmiliknya. - Event pesan: Prompt thread eksekusi, yaitu event
agent.thread_message_received, tetap berada di alirannya sendiri. - Event eksekusi: Event
workflow_run.*juga tiba di aliran ini; lihat Event eksekusi. - Panggilan alat yang menunggu Anda: Panggilan alat thread eksekusi yang memerlukan klien Anda diposting silang ke aliran ini, sama seperti untuk thread anak mana pun. Lihat Izin alat dan alat kustom.
Event thread sesi
Event penting diteruskan ke thread utama. Namun, Anda mungkin tetap ingin menyelidiki penalaran dan panggilan alat dari agen tertentu. Untuk melakukannya, lakukan streaming atau cantumkan event dari thread sesi yang terkait.
Setiap thread sesi memiliki aliran event sendiri di /v1/sessions/{session_id}/threads/{thread_id}/stream, dan aliran ini menerima parameter event_deltas[] yang sama dengan aliran tingkat sesi, sehingga Anda dapat melihat pratinjau teks subagen saat model menghasilkannya. Sebuah koneksi hanya menampilkan pratinjau thread yang sedang dibacanya: pratinjau thread anak tidak pernah muncul di aliran tingkat sesi, jadi untuk memantau subagen secara langsung, buka aliran thread miliknya sendiri. Lihat Pratinjau event thread sesi untuk cara mengaktifkan, mengakumulasi, dan merekonsiliasi pratinjau.
Dalam sebuah eksekusi workflow, server menjalankan workflow: sebuah program yang ditulis oleh agen thread utama. Pada setiap thread milik eksekusi, agent.thread_message_received pertama adalah prompt yang ditulis oleh workflow. from_session_thread_id-nya adalah ID thread utama, dan event tersebut tidak memiliki from_agent_name. API tidak menjamin teks prompt tersebut, jadi jangan mem-parsing-nya. Event session.thread_status_terminated milik thread, pada aliran thread utama, memberi tahu Anda bahwa thread telah selesai. Tidak ada event yang mencatat hasil yang dikembalikannya ke workflow.
Aliran thread tidak memutar ulang event sebelumnya. Tepat setelah session.thread_created, daftar event thread milik eksekusi dapat kosong, karena server menulis event pertama thread setelahnya. Jadi, buka aliran thread terlebih dahulu, lalu cantumkan event thread tersebut, dan lewati setiap event yang di-streaming yang id-nya telah dikembalikan oleh daftar.
with client.beta.sessions.threads.events.stream(
thread.id,
session_id=session.id,
) as stream:
for event in stream:
match event.type:
case "agent.message":
for block in event.content:
if block.type == "text":
print(block.text, end="")
case "session.thread_status_idle":
breakCantumkan semua event thread sesi sebelumnya untuk mengambil riwayat lengkap.
for event in client.beta.sessions.threads.events.list(
thread.id,
session_id=session.id,
):
print(f"[{event.type}] {event.processed_at}")Izin alat dan alat kustom
Jika sebuah subagen memerlukan sesuatu dari klien Anda, seperti izin untuk menjalankan panggilan alat atau hasil dari alat kustom, event tersebut diposting silang ke thread utama dengan session_thread_id yang mengidentifikasi thread sesi asalnya. Sebuah panggilan alat memerlukan izin Anda di bawah always_ask, atau di bawah auto ketika server tidak mencapai keputusan.
{
"type": "session.thread_status_idle",
"id": "sevt_01ABC...",
"session_thread_id": "sthr_01DEF...",
"agent_name": "code-reviewer",
"stop_reason": {
"type": "requires_action",
"event_ids": ["sevt_01XYZ..."]
}
}Kirim user.tool_confirmation (dengan tool_use_id) atau user.custom_tool_result (dengan custom_tool_use_id); server secara otomatis merutekan respons ke thread yang benar. Respons dapat muncul di thread utama dan di thread subagen dengan nilai id yang berbeda. Untuk mencocokkan kedua salinan tersebut, bandingkan type dan tool_use_id (atau custom_tool_use_id), bukan id.
Sesi menjadi idle hanya ketika tidak ada thread yang berstatus running, sehingga session.status_idle dapat tiba lama setelah panggilan subagen. Anda tidak perlu menunggunya: kirim user.custom_tool_result segera setelah event agent.custom_tool_use yang diposting silang tiba.
Di bawah auto, event user.message Anda dapat membuat server mengizinkan panggilan yang seharusnya ditolaknya. Tidak ada apa pun di thread subagen yang dihitung sebagai maksud Anda. Klien Anda tidak memposting pesan apa pun di sana, dan pesan yang dikirimkan agen thread utama kepada subagen tidak dihitung. Ketika server menolak panggilan di bawah auto, tidak ada yang diposting silang: event dan hasil alat berupa error hanya muncul di aliran thread milik subagen itu sendiri, dan subagen tetap berjalan.
Contoh berikut ditempatkan di dalam loop event dari handler konfirmasi alat. Untuk setiap ID dalam stop_reason.event_ids, contoh ini mengirimkan user.tool_confirmation yang mengizinkan panggilan tersebut. Pola yang sama berlaku untuk user.custom_tool_result.
for event_id in stop.event_ids:
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.tool_confirmation",
"tool_use_id": event_id,
"result": "allow",
}
],
)Pola sebelumnya menjawab panggilan yang dicantumkan oleh event idle. Pada aliran utama, event session.thread_status_idle milik subagen dapat tiba sebelum event agent.tool_use atau agent.mcp_tool_use yang dicantumkan oleh stop_reason.event_ids-nya. user.tool_confirmation untuk panggilan yang event-nya belum tiba dapat mengembalikan 400. Untuk menghindarinya, jawab setiap panggilan yang evaluated_permission-nya bernilai ask ketika event miliknya sendiri tiba di aliran utama.
Was this page helpful?