Yang Artikel sebelumnya Adalah tentang membuat satu agen dapat diandalkan: menjalankan loop, perutean alat, pemadatan konteks, sesi aman-tabrakan. Lapisan itu menjawab "bagaimana seorang agen tunggal bisa menyelesaikan tugas tanpa jatuh?" Artikel ini adalah tentang lapisan di atasnya — apa yang terjadi ketika satu agen tidak cukup, dan pekerjaan harus dibagi menjadi Tim.
Ini adalah apa yang orang-orang biasanya maksud dengan Orkestrasi multi-agen: seorang agen utama yang memiliki percakapan memecah permintaan menjadi beberapa bagian, menyerahkan setiap bagian ke sub-agen khusus, menunggu yang benar selesai sebelum memulai yang berikutnya, meneruskan hasil ke depan, dan menjaga semuanya di rel ketika satu langkah gagal. Orkas menjalankan ini sepenuhnya pada mesin pengguna sendiri. Di bawah ini adalah bagaimana lapisan orkestrasi itu dibangun — kode digosok dan digeneralisasikan, tetapi strukturnya nyata.
Agen utama dan sub-agen
Model mental adalah tim kecil dengan rantai komando yang jelas. Sebuah Agen utama (Kami menyebutnya komandan) memiliki percakapan dan konteks keseluruhan. Itu tidak melakukan semua pekerjaan itu sendiri; tugasnya adalah untuk memutuskan Apa yang perlu dilakukan, dalam urutan apa, dan oleh siapa. Yang Sub-agen Adalah spesialis — masing-masing dikonfigurasi dengan prompt sistemnya sendiri, alat yang diizinkan sendiri, dan seperangkat keterampilannya sendiri. Sub-agen bagus pada satu bagian dari pekerjaan dan dipanggil ketika bagian itu muncul.
Dua hal membuat ini lebih dari sekadar kata kunci. Pertama, sub-agen dan keterampilan adalah Unit kelas satu, bukan trik cepat: sub-agen adalah agen yang nyata, dikonfigurasi secara terpisah, dan mengirim ke salah satu adalah serah terima nyata dengan konteksnya sendiri. Kedua, koordinasi tidak diserahkan kepada niat baik model - itu didorong oleh artefak eksplisit bahwa sistem, bukan model, tetap jujur. Artefak itu adalah rencananya.
Rencana adalah grafik, bukan skrip
Ketika agen utama memutuskan permintaan membutuhkan lebih dari satu langkah, itu menulis sebuah Rencana. Rencananya bukan prosa bentuk bebas dan bukan daftar periksa linier — ini adalah grafik ketergantungan kecil (DAG). Setiap simpul adalah sebuah langkah, dan sebuah langkah membawa semua yang dibutuhkan orkestrator untuk mengirimkannya:
interface PlanStep {
index: number; // 1-based, stable, never renumbered
title: string; // human-readable, shown in the UI
assignee: string; // who runs it: "user" | "commander" | a sub-agent
input?: string; // the dispatch payload — a template (see below)
wait_for?: number[]; // upstream step indexes; defaults to [index - 1]
on_failure?: "abort_plan" | "continue" | "ask_commander";
// --- runtime state, owned by the orchestrator, NOT written by the model ---
status: "pending" | "in_progress" | "done" | "failed" | "skipped" | "blocked";
output_summary?: string; // short summary of what the step produced
output_files?: string[]; // files the step produced
failure_reason?: string;
}Yang wait_for Bidang adalah apa yang mengubah daftar menjadi grafik. Secara default sebuah langkah menunggu yang sebelumnya (rantai sederhana), tetapi sebuah langkah dapat menyatakannya tergantung pada beberapa langkah sebelumnya - "ringkas" mungkin menunggu "penelitian pasar" dan "survei pesaing." Itu adalah berlian, bukan garis, dan orkestrator memperlakukannya sebagai satu.
Siapa yang memiliki kebenaran: orkestrator, bukan model
Lihatlah lagi perpecahan dalam struktur itu. Model tersebut mengisi Niat — judul, penerima tugas, masukan, ketergantungan — ketika pertama kali menulis rencana. Tapi semua tentang Keadaan eksekusi — status, output_summary, failure_reason — dimiliki secara eksklusif oleh orkestrator. Model ini mengusulkan rencananya sekali; tidak pernah menandai langkahnya sendiri "selesai."
Pemisahan ini disengaja, dan itu adalah satu-satunya keputusan terpenting dalam keseluruhan desain. Model bahasa sangat mampu dengan riang mengumumkan "langkah 3 selesai" ketika langkah 3 salah, atau kehilangan jejak langkah mana yang masih luar biasa di tengah percakapan yang panjang. Jika negara hidup di kepala model, rencananya akan melayang dari kenyataan. Dengan menjadikan negara sebagai artefak terstruktur yang hanya ditulis oleh pelaksana - dan ditulis hanya sebagai tanggapan terhadap langkah yang benar-benar selesai - rencana tersebut tetap menjadi cermin akurat dari apa yang sebenarnya terjadi. Model menentukan bentuk pekerjaan; runtime menentukan apa yang benar tentang kemajuannya.
Mengirimkan langkah-langkah yang sudah siap
Setelah rencana ada, sebuah mesin kecil - pelaksana - mendorongnya ke depan. Operasi intinya adalah "menemukan langkah-langkah yang siap dan mengirimkannya." Sebuah langkah adalah Siap Ketika itu masih pending Dan setiap langkah yang ditunggunya telah mencapai terminal, keadaan cukup sukses:
function findReadySteps(plan): PlanStep[] {
return plan.steps.filter((s) => {
if (s.status !== "pending") return false;
const deps = s.wait_for ?? (s.index > 1 ? [s.index - 1] : []);
return deps.every((d) => isTerminal(plan.step(d).status)); // done or skipped
});
}Ini berjalan bukan pada pengatur waktu tetapi sebagai respons terhadap peristiwa. Setiap kali sebuah langkah selesai - seorang sub-agen kembali, komandan menyelesaikan giliran sintesis - pelaksana berdamai: itu mencatat hasil dari langkah yang baru saja selesai, kemudian memindai ulang untuk apa pun yang menjadi siap sebagai hasilnya, dan mengirimkannya. Orkestrasi adalah lingkaran rekonsiliasi ini, berputar berulang-ulang sampai tidak ada langkah yang tersisa.
Pengiriman melalui obrolan yang sama, bukan saluran samping
Berikut adalah pilihan yang membuat sistem tetap jujur: mengirimkan langkah tidak menggunakan saluran RPC tersembunyi. Itu memposting pesan ke dalam percakapan grup yang sama dengan yang sedang ditonton pengguna, Dari agen utama, @-menyebutkan sub-agen. Untuk sub-agen, dikirim tidak dapat dibedakan dari ditangani dalam obrolan — itu hanya berjalan seperti biasa. Tidak ada jalur eksekusi kedua untuk tetap sinkron dengan yang pertama.
Penerima tugas dapat menjadi salah satu dari tiga jenis, dan masing-masing pengiriman sedikit berbeda:
- Seorang sub-agen — kasus yang umum. Pelaksana menyelesaikan nama agen ke id dan postingannya
@<agent> <rendered input>Dari komandan. Sub-agen mengambilnya dan menjalankan giliran agen penuh. - Pengguna — ketika sebuah langkah benar-benar membutuhkan masukan manusia, langkah tersebut berubah menjadi bentuk dan menghentikan rencana (lebih lanjut tentang ini di bawah). Tidak ada hilir yang berlanjut sampai pengguna menjawab.
- Komandan itu sendiri — untuk langkah-langkah sintesis atau keputusan ("baca semua yang di atas dan tulis ringkasannya"). Ini adalah bangun pribadi yang tidak memposting pesan yang terlihat oleh pengguna yang berlebihan; agen utama hanya mengambil giliran dengan konteks yang dikumpulkan di tangan.
Melewati konteks dari satu langkah ke langkah berikutnya
Sebuah tim hanya berguna jika pekerjaan mengalir di antara anggotanya. Mekanismenya adalah input Templat. Ketika agen utama menulis langkah, inputnya bukan string yang dibekukan — itu dapat merujuk hasil sebelumnya, dan pelaksana merender referensi tersebut pada waktu pengiriman:
// step 3.input, as written by the lead agent
"Using the findings below, draft the launch note.\n\n{{step_1.output_summary}}"
// what the sub-agent actually receives at dispatch time
"Using the findings below, draft the launch note.\n\n- Market is growing ~20% YoY; two incumbents…"Perhatikan apa yang diteruskan ke depan: output_summary, sebuah Pendek Ringkasan dari setiap langkah yang sudah selesai — bukan seluruh transkripnya. Ini adalah keputusan anggaran, dan itu adalah naluri yang sama dengan pemadatan konteks harness. Jika setiap langkah hilir mewarisi riwayat penuh token-demi-token dari segala sesuatu sebelumnya, konteks akan menggelembung dan biaya akan meledak setelah hanya beberapa lompatan. Ringkasan menjaga setiap serah terima murah dan menjaga setiap sub-agen tetap fokus pada apa yang sebenarnya dibutuhkan dari hulu, daripada mengarungi bagaimana hulu sampai di sana. Pesan pengguna awal dan lampiran apa pun juga dibawa, jadi langkah tiga melompat ke bawah rantai masih tahu pertanyaan asli.
Serial secara default — dan mengapa
Anda mungkin berharap bahwa ketika beberapa langkah kembali siap sekaligus — dua cabang berlian, katakanlah — orkestrator menembakkan semuanya secara paralel. Itu bisa; sebaliknya, hari ini itu dikirim Satu langkah siap pada satu waktu, yang paling awal berdasarkan indeks, dan biarkan sisanya menunggu rekonsiliasi berikutnya. Menjalankan seluruh tim secara ketat satu per satu adalah pilihan yang disengaja dan konservatif, dan layak untuk jujur tentang alasannya.
Alasannya adalah kebenaran di bawah konkurensi. Gambarkan dua sub-agen selesai pada saat yang hampir sama. Kedua penyelesaian memicu rekonsiliasi; kedua rekonsiliasi membaca rencana; keduanya melihat langkah hilir yang sama masih duduk di pending — dan keduanya mengirimkannya. Sekarang langkah yang sama berjalan dua kali. Untuk membuat itu tidak mungkin, setiap siklus baca-ubah-kirim pada percakapan tertentu diserialisasi di balik kunci per-percakapan:
// all state-changing paths for one conversation run under one mutex
planLock(uid, cid).runExclusive(async () => {
const plan = await readPlan(uid, cid);
applyOutcomeOfFinishedStep(plan); // mark done / failed / skipped
await dispatchReady(plan); // dispatch the next ready step
});Kunci menjamin bahwa "catat apa yang selesai" dan "putuskan apa yang akan terjadi selanjutnya" terjadi sebagai satu unit yang tidak dapat dibagi, sehingga langkah hilir tidak pernah dapat dikirim dua kali. Dengan kunci itu di tempat, langkah-langkah pengiriman satu per satu adalah hal paling sederhana yang jelas benar. Fan-out paralel asli adalah ekstensi yang mudah ditangani di atas fondasi ini - tetapi fondasinya adalah eksekutor yang diserialisasi, bebas ras, dan urutan prioritas (benar dulu, cepat nanti) adalah intinya.
Ketika sebuah langkah salah
Berjalan di mesin nyata terhadap API model eksternal, kegagalan adalah rutin, dan orkestrator memilahnya menjadi beberapa kasus alih-alih memperlakukan setiap kesalahan yang sama.
Pertama itu menanyakan apakah kegagalan itu hanya Sementara — koneksi terputus, batas kecepatan, blip. Jika demikian, dan langkah tersebut belum membakar anggaran percobaan ulang yang kecil, langkah tersebut diam-diam digulirkan kembali ke pending Jadi rekonsiliasi berikutnya mengirimkannya kembali. (Ini duduk Di atas Percobaan ulang harness sendiri; rencana hanya dikirim ulang setelah upaya agen sendiri habis, dengan topi keras sehingga langkah yang benar-benar rusak tidak dapat berulang selamanya.)
Jika kegagalan itu nyata, langkahnya dinyatakan on_failure Kebijakan menentukan apa yang tim lakukan selanjutnya:
abort_plan— langkah ini cukup penting sehingga tidak ada hilir yang masuk akal tanpanya. Tandai itu gagal, dan kaskade: setiap langkah yang masih tertunda ditandaiskipped. Rencananya berhenti dengan bersih daripada membangun fondasi yang hilang.continue— langkah ini bersifat opsional. Tandai ituskippedDan biarkan langkah-langkah hilir berlanjut seolah-olah itu tidak menghasilkan apa-apa.ask_commander(Default) — tidak secara membabi buta membatalkan atau secara membabi buta melanjutkan. Tandai itu gagal dan bangunkan agen utama untuk melihat apa yang terjadi dan memutuskan — coba lagi secara berbeda, rute di sekitarnya, atau berhenti dan tanyakan kepada pengguna.
Ada status keenam yang layak untuk dipanggil: blocked. Seorang sub-agen yang sebagian melalui langkahnya mungkin menyadari bahwa ia membutuhkan sesuatu yang hanya dapat disediakan oleh pengguna, dan memunculkan formulir atau pertanyaan. Langkahnya tidak gagal — itu menuju ke blocked, dan seluruh rencana berhenti. Saat pengguna menjawab, pelaksana merekonsiliasi dan tim melanjutkan tepat di tempat yang ditinggalkan. Rencana yang diblokir adalah rencana yang dijeda, bukan yang rusak.
Setiap langkah adalah menjalankan agen penuh
Layak untuk menutup lingkaran kembali ke artikel sebelumnya. Ketika orkestrator mengirimkan langkah ke sub-agen, sub-agen itu tidak menjalankan beberapa rutinitas yang dilucuti - itu menjalankan Loop harness penuh: loop lari streamingnya sendiri, panggilan alatnya sendiri, jendela konteksnya sendiri dengan pemadatan, sesi crash-safe-nya sendiri. Orkestrasi duduk dengan bersih Di atas Runtime agen tunggal; itu tidak pernah mencapai di dalamnya. Agen utama menentukan bentuk pekerjaan dan urutan serah terima; setiap sub-agen, setelah menyerahkan irisannya, adalah agen yang lengkap dengan haknya sendiri.
Lapisan itu adalah alasan mengapa dua artikel menyusun. Harness membuat satu agen dapat dipercaya untuk satu tugas. Orkestrator menyusun beberapa agen yang dapat dipercaya ke dalam tim yang dapat mengambil tugas yang terlalu besar, atau terlalu bervariasi, untuk salah satu dari mereka.
Beberapa keputusan yang penting
Orchestrator memiliki keadaan eksekusi, model memiliki niat. Model ini mengusulkan rencana; hanya runtime yang menandai langkah-langkah yang dilakukan, gagal, atau dilewati, dan hanya sebagai tanggapan terhadap sesuatu yang benar-benar terjadi. Satu batas ini adalah apa yang membuat rencana menjadi cermin realitas yang jujur daripada tebakan optimis model.
Kirim melalui percakapan yang sama, bukan saluran sampingan. Langkah yang dikirim hanyalah pesan dari agen utama ke sub-agen. Satu jalur eksekusi, tidak ada yang tersembunyi untuk tidak sinkron, dan pengguna dapat menonton tim bekerja di utas yang sama yang sudah mereka baca.
Ringkasan, bukan transkrip, di antara langkah-langkah. Setiap serah terima membawa ringkasan singkat dari output hulu. Itu menjaga anggaran konteks tetap waras di seluruh rantai panjang dan menjaga setiap sub-agen tetap fokus pada apa yang dibutuhkannya, bukan pada bagaimana yang sebelumnya sampai di sana.
Benar sebelum paralel. Kunci per-percakapan membuat serial setiap siklus baca-modifikasi-pengiriman, dan langkah-langkah pengiriman satu per satu. Strictly serial adalah versi yang jelas bebas dari ras pengiriman ganda; fan-out paralel adalah pengoptimalan untuk melapisi fondasi yang sudah benar.
Membungkus
Lapisan orkestrasi Orkas tidak memiliki algoritma eksotis pada intinya. Nilainya ada dalam beberapa batasan yang dipegang teguh: rencana yang merupakan grafik ketergantungan daripada skrip; status eksekusi yang dimiliki oleh runtime daripada model; pengiriman yang mengalir melalui obrolan yang sama yang ditonton pengguna; konteks yang bergerak di antara langkah-langkah sebagai ringkasan; dan eksekutor yang menempatkan kebenaran di atas konkurensi. Masing-masing sederhana dengan sendirinya. Bersama-sama mereka mengubah satu agen yang dapat diandalkan menjadi tim yang membagi tenaga kerja, meneruskan pekerjaan ke depan, dan pulih ketika salah satu bagiannya salah.
Jika Anda menginginkan lapisan di bawah yang ini, baca Bagaimana satu agen direkayasa untuk berjalan dengan andal. Jika Anda menginginkan lapisan yang membuat setiap agen menjadi lebih baik dengan penggunaan, baca Bagaimana agen Orkas belajar dari pekerjaan mereka sendiri. Dan jika Anda lebih suka mengarahkan lapisan ini daripada membangunnya, Orkas mengirimkannya sebagai Orkestrasi agen AI sumber terbuka Yang berjalan di mesin Anda sendiri.