Claude Code Agent Teams'in Tersine Mühendisliği: Mimari ve Protokol

Makine çevirisi Özgün yazı.

Banner for Claude Code Agent Teams'in Tersine Mühendisliği: Mimari ve Protokol

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:

  1. Resmî belgeleri okuyarak
  2. Önceki ekip oturumlarının diskte bıraktığı somut kalıntıları inceleyerek
  3. 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ış

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ıyor
  • CLAUDE_CODE_PLAN_MODE_REQUIRED: plan onayı gerekiyorsa true değ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.md dosyaları
  • 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, teamName
  • parentSessionId, color
  • planModeRequired

Başlıca dahili işlevler:

  • isTeammate() / isTeamLead(): rol tespiti
  • waitForTeammatesToBecomeIdle(): lider için eşzamanlama ilkeli
  • getTeammateContext() / 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ü

  1. Lider bir ekip üyesine shutdown_request gönderiyor
  2. Ekip üyesi onaylayabiliyor (kontrollü biçimde kapanıyor) veya reddedebiliyor (bir açıklamayla çalışmaya devam ediyor)
  3. TeamDelete ile ekip temizliği yapıldığında ~/.claude/teams/{team-name}/ ve ~/.claude/tasks/{team-name}/ siliniyor
  4. 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

Diskteki Kalıntılar (Claude Code v2.1.47)

/Users/tau/.claude/ konumunda gözlemlenenler:

  • config.json ve inboxes/{agent-name}.json dosyalarını içeren ekip dizinleri
  • .lock, .highwatermark ve ayrı görev JSON dosyalarını içeren görev dizinleri
  • Göndereni team-lead, alıcısı cp-agent olan, 2026-02-18T02:37:16.890Z zaman 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.

Hive Kod Tabanı