içerik
Giriş
Claude Code (v2.1.47), Agent Teams adlı deneysel bir özellikle geliyor: birden çok Claude Code oturumu, lider ve ekip üyelerinden oluşan bir topoloji üzerinden ortak çalışmaları koordine ediyor. Hive adlı, benzer hedeflere sahip ancak çok farklı bir mimarisi olan çok ajanlı bir kodlama orkestratörü geliştiriyorum; bu yüzden Anthropic'in yaklaşımının perde arkasında nasıl işlediğini anlamak istedim.
Bu yazıda şu yollarla elde ettiğim bulguları aktarıyorum:
- Resmî belgeleri okuyarak
- Önceki ekip oturumlarının diskte bıraktığı somut kalıntıları inceleyerek
- Uygulama ayrıntılarını öğrenmek için Claude'a Claude Code'un ikili dosyasını (v2.1.47) analiz ettirerek (hah!)
İçindekiler
- 1. Mimariye Genel Bakış
- 2. Paylaşılan Görev Listesi
- 3. Ajanlar Arası İletişim
- 4. Ajanların Başlatılması ve Yaşam Döngüsü
- 5. Kalite Kontrolleri ve Hook'lar
- 6. Token Ekonomisi
- 7. Mimari Özeti
- Kaynaklar
1. Mimariye Genel Bakış
Bir ajan ekibi dört bileşenden oluşur:
| Bileşen | Rol |
|---|---|
| Ekip lideri | Ekibi oluşturan ve ekip üyelerini başlatan ana Claude Code oturumu |
| Ekip üyeleri | Her biri kendi bağlam penceresine sahip ayrı Claude Code örnekleri |
| Görev listesi | Diskte ayrı JSON dosyaları olarak saklanan ortak iş öğeleri |
| Posta kutusu | Mesajların iletilmesi için her ajana ait gelen kutusu dosyaları |
Koordinasyon katmanının tamamı dosya tabanlı. ~/.claude/ konumundaki dosya sistemi, koordinasyonun tek altyapısı:
~/.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
└── ...
Bu, temelde merkezi olmayan bir tasarım. Lider, ek araçları (TeamCreate, TeamDelete, SendMessage) olan bir başka Claude oturumundan ibaret. Arka planda çalışan bir süreç yok. Koordinasyon, ortak dosya erişimiyle sağlanıyor.
Etkin bir oturumda Claude'dan bir işi yapmak üzere bir ekip oluşturmasını isteyip ardından başka bir pencerede aşağıdakini çalıştırırsanız, dosya sistemindeki güncellemeleri gerçek zamanlı olarak gözlemleyebilirsiniz.
watch -n 0.5 'tree ~/.claude/teams/ 2>/dev/null; echo "---"; tree ~/.claude/tasks/ 2>/dev/null'
Örneğin, şu istemle:
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
Şunu gözlemledim:
teams
└── code-review
├── config.json
└── inboxes
├── bug-hunter.json
├── complexity-analyst.json
├── devils-advocate.json
└── team-lead.json
Ekip Yapılandırması
~/.claude/teams/{team-name}/config.json konumundaki ekip yapılandırması, ekip üyelerinin birbirlerini keşfetmek için okuduğu bir members dizisi içeriyor:
{
"members": [
{ "name": "team-lead", "agentId": "abc-123", "agentType": "leader" },
{
"name": "researcher",
"agentId": "def-456",
"agentType": "general-purpose"
}
]
}
Adlar, birincil adresleme mekanizması (UUID'ler var ancak yönlendirme için kullanılmıyor). Tüm mesajlaşmalar ve görev atamaları name alanını kullanıyor.
2. Paylaşılan Görev Listesi
Dosya Biçimi
Her görev, ~/.claude/tasks/{team-name}/ konumunda ayrı bir JSON dosyası olarak saklanıyor. İşte önceki bir oturumdan gerçek bir örnek:
{
"id": "1",
"subject": "Hunt for bugs across the codebase",
"description": "...",
"activeForm": "Hunting for bugs",
"owner": "bug-hunter",
"status": "completed",
"blocks": [],
"blockedBy": []
}
Görev şeması:
| Alan | Tür | Açıklama |
|---|---|---|
id |
string | Sayısal kimlik; .highwatermark aracılığıyla otomatik artırılır |
subject |
string | Emir kipinde başlık (ör. "Testleri çalıştır") |
description |
string | Ayrıntılı gereksinimler ve kabul ölçütleri |
activeForm |
string | Dönen ilerleme göstergesi için şimdiki zaman biçimi ("Testler çalıştırılıyor") |
status |
string | pending → in_progress → completed (veya deleted) |
blocks |
string[] | Bu görevin engellediği görevlerin kimlikleri |
blockedBy |
string[] | Bu görev başlamadan önce tamamlanması gereken görevlerin kimlikleri |
Eşzamanlılık Denetimi
İki özel dosya koordinasyonu sağlıyor:
.lock: Dosya sistemi düzeyinde karşılıklı dışlama (flock()) için kullanılan 0 baytlık bir dosya. Makinemde gözlemlediğim 42 görev dizininin tamamında mevcut..highwatermark: Tek bir tam sayı içeriyor (ör."3","13"). Otomatik artırma için kullanılabilir sıradaki görev kimliği.
Görev Üstlenme
Görev üstlenme işlemi, yarış koşullarını önlemek için dosya kilitleme kullanıyor. Ekip üyeleri, en düşük kimlikli görevden başlamayı tercih ediyor. blockedBy dizisi boş olmayan bir görev, kendisini engelleyen tüm görevler bir sonlanma durumuna ulaşana kadar üstlenilemiyor.
Gözlem: Görev Dizinlerinin Çoğu Boş
Makinemdeki 42 görev dizininden yalnızca 5'inde gerçek görev JSON dosyaları vardı. Kalan 37'sinde yalnızca .lock ve .highwatermark bulunuyordu. Bu, büyük olasılıkla görevlerin tamamlandıktan sonra temizlendiği ya da bu dizinlerin, Claude'un işi alt görev dosyalarına bölmeden dahili görev listesini (görev listesi özelliği kullanıma sunulduğundan beri mevcut) kullandığı oturumlara ait olduğu anlamına geliyor.
3. Ajanlar Arası İletişim
Posta Kutusu Deseni
Her ajanın ~/.claude/teams/{team-name}/inboxes/{agent-name}.json konumunda JSON dizisi içeren bir dosyası var. İşte bir ekip liderinin bir controlplane-agent ajanına iş atadığı önceki bir oturumdan gerçek bir gelen kutusu:
[
{
"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
}
]
JSON içinde JSON kodlamasına dikkat edin: text alanı, serileştirilmiş bir mesaj nesnesi içeren bir JSON dizesi. Dış zarfta from, text, timestamp ve read alanları bulunuyor.
Mesaj Türleri
type alanı, text mesaj yükünün içinde yer alıyor ve şu türleri destekliyor:
| Tür | Yön | Amaç |
|---|---|---|
task_assignment |
lider → ekip üyesi | Tüm ayrıntılarıyla bir görev atama |
message |
herhangi biri → herhangi biri | Tek bir alıcıya doğrudan mesaj gönderme |
broadcast |
lider → herkes | Her ekip üyesine aynı mesajı gönderme |
shutdown_request |
lider → ekip üyesi | Kontrollü kapanma isteme |
shutdown_response |
ekip üyesi → lider | Kapanmayı onaylama veya reddetme |
plan_approval_request |
ekip üyesi → lider | Planı incelemeye sunma |
plan_approval_response |
lider → ekip üyesi | Geri bildirimle onaylama veya reddetme |
idle_notification |
ekip üyesi → lider | Ekip üyesinin turu bittiğinde otomatik gönderilir |
İletim Mekanizması
Yazma yolu: Gönderen, alıcının gelen kutusu dosyasındaki JSON dizisinin sonuna yeni bir kayıt ekliyor.
Okuma yolu: Alıcı kendi gelen kutusu dosyasını yokluyor. Yeni mesajlar, yapay konuşma turları olarak ekleniyor (bir kullanıcı göndermiş gibi görünüyorlar).
Toplu gönderim: Gerçekten de aynı mesajı her ekip üyesinin gelen kutusu dosyasına yazıyor. Token maliyeti, ekip büyüklüğüyle doğrusal olarak artıyor.
İletişim, dosyanın sonuna ekleme + dosya okumadan ibaret. Gönderim ile alım arasındaki gecikme, alıcının yoklama aralığına bağlı.
Ekip Üyeleri Arasındaki Doğrudan Mesajların Görünürlüğü
Bir ekip üyesi başka bir ekip üyesine DM gönderdiğinde, lidere giden boşta kalma bildirimine kısa bir özet ekleniyor. Böylece lider, mesajın tüm içeriğini görmeden üyeler arasındaki iş birliğini takip edebiliyor.
4. Ajanların Başlatılması ve Yaşam Döngüsü
Ekip Üyelerinin Oluşturulması
Her ekip üyesi ayrı bir claude CLI süreci. Lider, onları Task aracı üzerinden, team_name ve name parametreleriyle başlatıyor. Başlatılan süreçte şu ortam değişkenleri ayarlanıyor:
CLAUDE_CODE_TEAM_NAME: başlatılan ekip üyelerinde otomatik olarak ayarlanıyorCLAUDE_CODE_PLAN_MODE_REQUIRED: plan onayı gerekiyorsatruedeğerine ayarlanıyor
Bağlamın Hazırlanması
Ekip üyeleri, her yeni oturum gibi aynı proje bağlamını yüklüyor:
- Çalışma dizinindeki
CLAUDE.mddosyaları - MCP sunucuları
- Beceriler
- Liderin verdiği başlatma istemi
Liderin konuşma geçmişi AKTARILMAZ. Her ekip üyesi, yalnızca başlatma istemini bağlam olarak alıp sıfırdan başlıyor.
Dahili Uygulama
Claude Code v2.1.47'nin ikili dosyasının analizine göre, ekip üyesi bağlamı AsyncLocalStorage üzerinden şu alanlarla yönetiliyor:
agentId,agentName,teamNameparentSessionId,colorplanModeRequired
Başlıca dahili işlevler:
isTeammate()/isTeamLead(): rol tespitiwaitForTeammatesToBecomeIdle(): lider için eşzamanlama ilkeligetTeammateContext()/setDynamicTeamContext(): çalışma zamanı bağlamının yönetimi
Boşta Durumunun Tespiti
Her LLM turundan sonra ekip üyesi otomatik olarak boşta durumuna geçiyor ve lidere bir idle_notification gönderiyor. Bu, bir hata veya güncelliğini yitirme belirtisi değil, normal bekleme durumu. Boştaki bir ekip üyesine mesaj göndermek onu uyandırıyor (bir sonraki yoklama döngüsünde gelen kutusundaki mesaj alınıyor).
Kapatma Protokolü
- Lider bir ekip üyesine
shutdown_requestgönderiyor - Ekip üyesi onaylayabiliyor (kontrollü biçimde kapanıyor) veya reddedebiliyor (bir açıklamayla çalışmaya devam ediyor)
TeamDeleteile ekip temizliği yapıldığında~/.claude/teams/{team-name}/ve~/.claude/tasks/{team-name}/siliniyor- Herhangi bir ekip üyesi hâlâ etkinse temizlik başarısız oluyor; önce bu üyelerin kapatılması gerekiyor
İzinlerin Devralınması
Ekip üyeleri, başlatıldıkları anda liderin izin modunu devralıyor. Lider --dangerously-skip-permissions kullanıyorsa tüm ekip üyeleri de aynı şekilde çalışıyor. Bireysel modlar başlatma sonrasında değiştirilebiliyor, ancak başlatma sırasında her ekip üyesi için ayrı ayrı yapılandırılamıyor.
5. Kalite Kontrolleri ve Hook'lar
Agent Teams, kalite koşullarını uygulamak için Claude Code'un hook sistemiyle bütünleşiyor:
TeammateIdle Hook'u
Bir ekip üyesi boşta durumuna geçmek üzereyken tetikleniyor. 2 çıkış kodu, stderr'i geri bildirim olarak gönderiyor ve boşta durumuna geçişi engelleyerek ekip üyesinin çalışmaya devam etmesini sağlıyor.
{
"hook_event_name": "TeammateIdle",
"teammate_name": "researcher",
"team_name": "my-project"
}
TaskCompleted Hook'u
Bir görev tamamlandı olarak işaretlenirken tetikleniyor. 2 çıkış kodu, tamamlamayı engelliyor ve stderr'i geri bildirim olarak iletir.
{
"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"
}
Bu, iki durumda tetikleniyor: (1) herhangi bir ajan bir görevi TaskUpdate aracılığıyla açıkça tamamlandı olarak işaretlediğinde veya (2) bir ajan ekibindeki ekip üyesi, devam eden görevleri varken turunu bitirdiğinde.
Hook İşleyicisi Türleri
| Tür | Açıklama |
|---|---|
command |
Kabuk betiği. stdin üzerinden JSON alır, kararlar için çıkış kodları kullanır. |
prompt |
Tek turluk LLM değerlendirmesi. {ok, reason} döndürür. |
agent |
Okuma araçlarına sahip çok turlu alt ajan. En fazla 50 tur. |
6. Token Ekonomisi
Ajan ekipleri, ekip üyeleri plan modunda çalışırken standart oturumlara göre yaklaşık 7 kat daha fazla token kullanıyor. Her ekip üyesi, ayrı bir Claude örneği olarak kendi tam bağlam penceresini koruyor.
Temel Kullanım Referansı
- Ortalama Claude Code kullanımı: geliştirici başına günde ~6 $
- Ajan ekipleri: temel kullanıma ek maliyet kabaca ekip büyüklüğüyle orantılı
7. Mimari Özeti
| Boyut | Claude Code Agent Teams |
|---|---|
| Koordinasyon altyapısı | Düz dosyalar (~/.claude/tasks/, ~/.claude/teams/) |
| Görev biçimi | Her görev için bir JSON dosyası + üstlenme için .lock |
| Mesajlaşma | JSON gelen kutusu dosyaları (sona ekleme + yoklama) |
| Ajan yaşam döngüsü | Kendini yöneten CLI süreçleri |
| İşlerin yalıtılması | Paylaşılan çalışma dizini |
| Birleştirme stratejisi | Yok (ajanlar dosyaları doğrudan düzenliyor) |
| Yeniden deneme/üst düzeye aktarma | Manuel (lider karar veriyor veya kullanıcı müdahale ediyor) |
| Topoloji | Lider + aynı düzeyde üyeler, üyeler arası mesajlaşma |
| Zamanlama | Kendi kendine görev üstlenme (ekip üyeleri sıradaki görevi alıyor) |
| Durumun kalıcılığı | Yalnızca dosyalar; ekip üyesi süreç içinde kaldığı yerden devam ettirilemiyor |
| Kalite kontrolleri | Kabuk hook'ları (TeammateIdle, TaskCompleted) |
| Token takibi | Yalnızca oturum bazında, ajanlar arası toplama yok |
| İlerlemenin durduğunu tespit etme | Manuel (kullanıcı ekip üyesinin durduğunu fark ediyor) |
| Eşzamanlılık denetimi | Örtük (ekip büyüklüğü = ekip üyesi sayısı) |
| Bağımlılık modeli | Görev dosyalarındaki blocks/blockedBy alanları |
Kaynaklar
Resmî Belgeler
- Claude Code oturumlarından oluşan ekipler: Mimari
- Etkileşimli mod — Görev listesi
- Ajan ekipleri — Görev atama ve üstlenme
- Ajan ekipleri — Bağlam ve iletişim
- Ajan ekipleri — Ekip üyelerini kapatma
- Ajan ekipleri — Ekibi temizleme
- Ajan ekipleri — İzinler
- Ajan ekipleri — Sınırlamalar
- Ajan ekipleri — En iyi uygulamalar
- Hook'lar
- Maliyetler — Ajan ekibinin token maliyetleri
- Ayarlar
- Alt ajanlar
Diskteki Kalıntılar (Claude Code v2.1.47)
/Users/tau/.claude/ konumunda gözlemlenenler:
config.jsonveinboxes/{agent-name}.jsondosyalarını içeren ekip dizinleri.lock,.highwatermarkve ayrı görev JSON dosyalarını içeren görev dizinleri- Göndereni
team-lead, alıcısıcp-agentolan,2026-02-18T02:37:16.890Zzaman damgalı örnek görev atama mesajı
İkili Dosya Analizi
Claude Code ikili dosyası v2.1.47. Dize analiziyle belirlenen dahili işlevler: getTeamName, getAgentName, getAgentId, isTeammate, isTeamLead, waitForTeammatesToBecomeIdle, getTeammateContext, setDynamicTeamContext, createTeammateContext. AsyncLocalStorage bağlam alanları: agentId, agentName, teamName, parentSessionId, color, planModeRequired.