isi
Pendahuluan
Claude Code (v2.1.47) hadir dengan fitur eksperimental bernama Agent Teams: beberapa sesi Claude Code berkoordinasi untuk mengerjakan pekerjaan bersama melalui topologi pemimpin dan anggota tim. Saya sedang mengembangkan Hive, sebuah orkestrator pemrograman multiagen dengan tujuan serupa tetapi arsitektur yang sangat berbeda, jadi saya ingin memahami cara kerja pendekatan Anthropic di balik layar.
Artikel ini mendokumentasikan temuan saya melalui:
- Membaca dokumentasi resmi
- Memeriksa artefak nyata yang ditinggalkan di disk oleh sesi tim sebelumnya
- Meminta Claude menganalisis biner Claude Code (v2.1.47) untuk mengetahui detail implementasinya (hah!)
Daftar Isi
- 1. Gambaran Umum Arsitektur
- 2. Daftar Tugas Bersama
- 3. Komunikasi Antaragen
- 4. Pembuatan dan Siklus Hidup Agen
- 5. Gerbang Kualitas dan Hook
- 6. Ekonomi Token
- 7. Ringkasan Arsitektur
- Sumber
1. Gambaran Umum Arsitektur
Sebuah tim agen terdiri dari empat komponen:
| Komponen | Peran |
|---|---|
| Pemimpin tim | Sesi utama Claude Code yang membuat tim dan menjalankan anggota tim |
| Anggota tim | Instans Claude Code yang terpisah, masing-masing dengan jendela konteks sendiri |
| Daftar tugas | Butir pekerjaan bersama yang disimpan sebagai berkas JSON tersendiri di disk |
| Kotak surat | Berkas kotak masuk untuk setiap agen guna mengirimkan pesan |
Seluruh lapisan koordinasinya berbasis berkas. Sistem berkas di ~/.claude/ menjadi satu-satunya landasan koordinasi:
~/.claude/
├── teams/{team-name}/
│ ├── config.json # team membership registry
│ └── inboxes/{agent-name}.json # per-agent mailbox
└── tasks/{team-name}/
├── .lock # flock() for concurrent task claiming
├── .highwatermark # auto-increment counter
├── 1.json # individual task files
├── 2.json
└── ...
Desain ini pada dasarnya terdesentralisasi. Pemimpin hanyalah sesi Claude lain dengan alat tambahan (TeamCreate, TeamDelete, SendMessage). Tidak ada proses latar belakang. Koordinasi terbentuk melalui akses berkas bersama.
Dalam sesi aktif, jika Anda meminta Claude membentuk tim untuk mengerjakan suatu tugas lalu menjalankan perintah berikut di jendela lain, Anda dapat mengamati perubahan sistem berkas secara langsung.
watch -n 0.5 'tree ~/.claude/teams/ 2>/dev/null; echo "---"; tree ~/.claude/tasks/ 2>/dev/null'
Misalnya, dengan prompt berikut:
can you spawn an agent team to examine this codebase?
- have one look for bugs
- have one look for complexity
- have one look for good things to call out and play devil's advocate against the other two agents
Saya mengamati hal ini:
teams
└── code-review
├── config.json
└── inboxes
├── bug-hunter.json
├── complexity-analyst.json
├── devils-advocate.json
└── team-lead.json
Konfigurasi Tim
Konfigurasi tim di ~/.claude/teams/{team-name}/config.json berisi array members yang dibaca anggota tim untuk menemukan satu sama lain:
{
"members": [
{ "name": "team-lead", "agentId": "abc-123", "agentType": "leader" },
{
"name": "researcher",
"agentId": "def-456",
"agentType": "general-purpose"
}
]
}
Nama menjadi mekanisme pengalamatan utama (UUID ada, tetapi tidak digunakan untuk perutean). Semua pengiriman pesan dan penugasan menggunakan field name.
2. Daftar Tugas Bersama
Format Berkas
Setiap tugas disimpan sebagai berkas JSON tersendiri di ~/.claude/tasks/{team-name}/. Berikut contoh nyata dari sesi sebelumnya:
{
"id": "1",
"subject": "Hunt for bugs across the codebase",
"description": "...",
"activeForm": "Hunting for bugs",
"owner": "bug-hunter",
"status": "completed",
"blocks": [],
"blockedBy": []
}
Skema tugas:
| Field | Tipe | Deskripsi |
|---|---|---|
id |
string | ID numerik, bertambah otomatis melalui .highwatermark |
subject |
string | Judul berbentuk perintah (misalnya, "Jalankan pengujian") |
description |
string | Persyaratan terperinci dan kriteria penerimaan |
activeForm |
string | Bentuk present continuous untuk tampilan spinner ("Sedang menjalankan pengujian") |
status |
string | pending → in_progress → completed (atau deleted) |
blocks |
string[] | ID tugas yang terhalang oleh tugas ini |
blockedBy |
string[] | ID tugas yang harus selesai sebelum tugas ini dapat dimulai |
Kontrol Konkurensi
Dua berkas khusus menyediakan koordinasi:
.lock: Berkas berukuran 0 byte yang digunakan untuk eksklusi mutual pada tingkat sistem berkas (flock()). Ada di seluruh 42 direktori tugas yang saya amati di komputer saya..highwatermark: Berisi satu bilangan bulat (misalnya,"3","13"). Nilainya adalah ID tugas berikutnya yang tersedia untuk penomoran otomatis.
Pengambilan Tugas
Pengambilan tugas menggunakan penguncian berkas untuk mencegah kondisi balapan. Anggota tim mengutamakan urutan dari ID terendah. Tugas dengan array blockedBy yang tidak kosong tidak dapat diambil sampai semua tugas yang menghalanginya berada dalam status akhir.
Pengamatan: Sebagian Besar Direktori Tugas Kosong
Dari 42 direktori tugas di komputer saya, hanya 5 yang benar-benar berisi berkas JSON tugas. Sebanyak 37 sisanya hanya berisi .lock dan .highwatermark. Ini kemungkinan berarti tugas dibersihkan setelah selesai, atau direktori tersebut berasal dari sesi ketika Claude menggunakan daftar tugas internal (tersedia sejak peluncuran fitur daftar tugas) tanpa memecahnya menjadi berkas subtugas.
3. Komunikasi Antaragen
Pola Kotak Surat
Setiap agen memiliki berkas array JSON di ~/.claude/teams/{team-name}/inboxes/{agent-name}.json. Berikut kotak masuk nyata dari sesi sebelumnya ketika pemimpin tim memberikan pekerjaan kepada controlplane-agent:
[
{
"from": "team-lead",
"text": "{\"type\":\"task_assignment\",\"taskId\":\"1\",\"subject\":\"Phase 2: Control-plane - remove participants/presence\",\"description\":\"Remove multiplayer code from the control-plane package...\",\"assignedBy\":\"team-lead\",\"timestamp\":\"2026-02-18T02:37:16.890Z\"}",
"timestamp": "2026-02-18T02:37:16.890Z",
"read": false
}
]
Perhatikan pengodean JSON-di-dalam-JSON: field text merupakan string JSON yang berisi objek pesan yang telah diserialisasi. Amplop luarnya memiliki field from, text, timestamp, dan read.
Jenis Pesan
Field type di dalam payload text mendukung:
| Jenis | Arah | Tujuan |
|---|---|---|
task_assignment |
pemimpin → anggota | Memberikan tugas dengan detail lengkap |
message |
siapa pun → siapa pun | Pesan langsung kepada satu penerima |
broadcast |
pemimpin → semua | Pesan yang sama kepada setiap anggota tim |
shutdown_request |
pemimpin → anggota | Meminta penghentian secara tertib |
shutdown_response |
anggota → pemimpin | Menyetujui atau menolak penghentian |
plan_approval_request |
anggota → pemimpin | Mengajukan rencana untuk ditinjau |
plan_approval_response |
pemimpin → anggota | Menyetujui atau menolak dengan umpan balik |
idle_notification |
anggota → pemimpin | Dikirim otomatis saat giliran anggota tim berakhir |
Mekanisme Pengiriman
Jalur penulisan: Pengirim menambahkan entri baru ke berkas array JSON kotak masuk penerima.
Jalur pembacaan: Penerima memeriksa berkas kotak masuknya sendiri secara berkala. Pesan baru disisipkan sebagai giliran percakapan sintetis (tampil seolah-olah dikirim oleh pengguna).
Siaran: Secara harfiah menulis pesan yang sama ke berkas kotak masuk setiap anggota tim. Biaya token bertambah secara linear seiring ukuran tim.
Komunikasi hanya berupa penambahan isi berkas + pembacaan berkas. Latensi antara pengiriman dan penerimaan bergantung pada interval pemeriksaan penerima.
Visibilitas DM Antaranggota
Ketika seorang anggota tim mengirim DM kepada anggota lain, ringkasan singkatnya disertakan dalam notifikasi idle yang diterima pemimpin. Ini memungkinkan pemimpin mengetahui kolaborasi antaranggota tanpa melihat isi pesan lengkapnya.
4. Pembuatan dan Siklus Hidup Agen
Cara Anggota Tim Dibuat
Setiap anggota tim merupakan proses CLI claude yang terpisah. Pemimpin menjalankannya melalui alat Task dengan parameter team_name dan name. Variabel lingkungan ditetapkan pada proses yang dijalankan:
CLAUDE_CODE_TEAM_NAME: ditetapkan otomatis pada anggota tim yang dijalankanCLAUDE_CODE_PLAN_MODE_REQUIRED: ditetapkan ketruejika persetujuan rencana diperlukan
Inisialisasi Konteks
Anggota tim memuat konteks proyek yang sama seperti sesi baru pada umumnya:
- Berkas
CLAUDE.mddari direktori kerja - Server MCP
- Skill
- Prompt awal dari pemimpin
Riwayat percakapan pemimpin TIDAK ikut dibawa. Setiap anggota tim memulai dari awal dengan hanya prompt awal sebagai konteks.
Implementasi Internal
Dari analisis biner Claude Code v2.1.47, konteks anggota tim dikelola melalui AsyncLocalStorage dengan field berikut:
agentId,agentName,teamNameparentSessionId,colorplanModeRequired
Fungsi internal utama:
isTeammate()/isTeamLead(): deteksi peranwaitForTeammatesToBecomeIdle(): primitif sinkronisasi untuk pemimpingetTeammateContext()/setDynamicTeamContext(): pengelolaan konteks saat eksekusi
Deteksi Idle
Setelah setiap giliran LLM, anggota tim secara otomatis masuk ke status idle dan mengirim idle_notification kepada pemimpin. Ini adalah status istirahat normal, bukan kondisi kesalahan atau tidak adanya aktivitas yang berkepanjangan. Mengirim pesan kepada anggota tim yang idle akan mengaktifkannya kembali (siklus pemeriksaan berikutnya mengambil pesan dari kotak masuk).
Protokol Penghentian
- Pemimpin mengirim
shutdown_requestkepada anggota tim - Anggota tim dapat menyetujui (keluar secara tertib) atau menolak (melanjutkan pekerjaan dengan memberikan penjelasan)
- Pembersihan tim melalui
TeamDeletemenghapus~/.claude/teams/{team-name}/dan~/.claude/tasks/{team-name}/ - Pembersihan gagal jika masih ada anggota tim yang aktif; mereka harus dihentikan terlebih dahulu
Pewarisan Izin
Anggota tim mewarisi mode izin pemimpin saat dijalankan. Jika pemimpin menjalankan --dangerously-skip-permissions, semua anggota tim juga demikian. Mode masing-masing dapat diubah setelah dijalankan, tetapi tidak dapat dikonfigurasi per anggota saat pertama kali dijalankan.
5. Gerbang Kualitas dan Hook
Agent Teams terintegrasi dengan sistem hook Claude Code untuk menegakkan standar kualitas:
Hook TeammateIdle
Dipicu saat anggota tim akan masuk ke status idle. Kode keluar 2 mengirim stderr sebagai umpan balik dan mencegah status idle, sehingga anggota tim terus bekerja.
{
"hook_event_name": "TeammateIdle",
"teammate_name": "researcher",
"team_name": "my-project"
}
Hook TaskCompleted
Dipicu saat tugas sedang ditandai selesai. Kode keluar 2 mencegah penyelesaian dan mengirimkan kembali stderr sebagai umpan balik.
{
"hook_event_name": "TaskCompleted",
"task_id": "task-001",
"task_subject": "Implement user authentication",
"task_description": "Add login and signup endpoints",
"teammate_name": "implementer",
"team_name": "my-project"
}
Hook ini dipicu dalam dua situasi: (1) ketika agen mana pun secara eksplisit menandai tugas sebagai selesai melalui TaskUpdate, atau (2) ketika anggota tim agen mengakhiri gilirannya dengan tugas yang masih berlangsung.
Jenis Penangan Hook
| Jenis | Deskripsi |
|---|---|
command |
Skrip shell. JSON pada stdin, kode keluar untuk keputusan. |
prompt |
Evaluasi LLM satu giliran. Mengembalikan {ok, reason}. |
agent |
Subagen dengan beberapa giliran dan alat baca. Hingga 50 giliran. |
6. Ekonomi Token
Tim agen menggunakan sekitar 7× lebih banyak token daripada sesi standar saat anggota tim berjalan dalam mode perencanaan. Setiap anggota tim mempertahankan jendela konteks lengkapnya sendiri sebagai instans Claude yang terpisah.
Acuan Dasar
- Rata-rata penggunaan Claude Code: ~$6/pengembang/hari
- Tim agen: tambahan di atas penggunaan dasar, kurang lebih sebanding dengan ukuran tim
7. Ringkasan Arsitektur
| Dimensi | Claude Code Agent Teams |
|---|---|
| Landasan koordinasi | Berkas datar (~/.claude/tasks/, ~/.claude/teams/) |
| Format tugas | Satu berkas JSON per tugas + .lock untuk pengambilan |
| Pengiriman pesan | Berkas kotak masuk JSON (penambahan + pemeriksaan berkala) |
| Siklus hidup agen | Proses CLI yang mengelola dirinya sendiri |
| Isolasi pekerjaan | Direktori kerja bersama |
| Strategi penggabungan | Tidak ada (agen menyunting berkas secara langsung) |
| Percobaan ulang/eskalasi | Manual (pemimpin memutuskan, atau pengguna turun tangan) |
| Topologi | Pemimpin + anggota sejajar, pengiriman pesan antaranggota |
| Penjadwalan | Pengambilan mandiri (anggota tim mengambil tugas berikutnya) |
| Persistensi status | Hanya berkas; tidak ada pelanjutan kembali anggota tim dalam proses |
| Gerbang kualitas | Hook shell (TeammateIdle, TaskCompleted) |
| Pelacakan token | Hanya per sesi, tanpa agregasi antaragen |
| Deteksi kemacetan | Manual (pengguna menyadari anggota tim berhenti) |
| Kontrol konkurensi | Implisit (ukuran tim = jumlah anggota tim) |
| Model dependensi | blocks/blockedBy pada berkas tugas |
Sumber
Dokumentasi Resmi
- Tim sesi Claude Code: Arsitektur
- Mode interaktif — Daftar tugas
- Tim agen — Memberikan dan mengambil tugas
- Tim agen — Konteks dan komunikasi
- Tim agen — Menghentikan anggota tim
- Tim agen — Membersihkan tim
- Tim agen — Izin
- Tim agen — Keterbatasan
- Tim agen — Praktik terbaik
- Hook
- Biaya — Biaya token tim agen
- Pengaturan
- Subagen
Artefak di Disk (Claude Code v2.1.47)
Diamati di /Users/tau/.claude/:
- Direktori tim dengan berkas
config.jsondaninboxes/{agent-name}.json - Direktori tugas dengan
.lock,.highwatermark, dan berkas JSON tersendiri untuk setiap tugas - Contoh pesan penugasan dari
team-leadkepadacp-agent, dengan stempel waktu2026-02-18T02:37:16.890Z
Analisis Biner
Biner Claude Code v2.1.47. Fungsi internal yang diidentifikasi melalui analisis string: getTeamName, getAgentName, getAgentId, isTeammate, isTeamLead, waitForTeammatesToBecomeIdle, getTeammateContext, setDynamicTeamContext, createTeammateContext. Field konteks AsyncLocalStorage: agentId, agentName, teamName, parentSessionId, color, planModeRequired.