Claude Code Agent Teams की रिवर्स इंजीनियरिंग: आर्किटेक्चर और प्रोटोकॉल

मशीनी अनुवाद मूल लेख.

Banner for Claude Code Agent Teams की रिवर्स इंजीनियरिंग: आर्किटेक्चर और प्रोटोकॉल

सामग्री

परिचय

Claude Code (v2.1.47) में Agent Teams नाम की एक प्रयोगात्मक सुविधा है: कई Claude Code सत्र, एक लीड और उसके साथियों वाली संरचना के ज़रिए साझा काम में समन्वय करते हैं। मैं Hive बना रहा हूँ, जो कई कोडिंग एजेंटों का एक ऑर्केस्ट्रेटर है। इसके लक्ष्य मिलते-जुलते हैं, लेकिन आर्किटेक्चर बहुत अलग है, इसलिए मैं समझना चाहता था कि Anthropic का तरीका अंदर से कैसे काम करता है।

इस लेख में मैंने उन बातों को दर्ज किया है जो मुझे इन तरीकों से पता चलीं:

  1. आधिकारिक दस्तावेज़ पढ़कर
  2. पिछले टीम सत्रों से डिस्क पर बचे वास्तविक आर्टिफ़ैक्ट की जाँच करके
  3. कार्यान्वयन की बारीकियाँ जानने के लिए Claude से Claude Code की बाइनरी (v2.1.47) का विश्लेषण करवाकर (हा!)

विषय सूची

1. आर्किटेक्चर का अवलोकन

एक एजेंट टीम के चार घटक होते हैं:

घटक भूमिका
टीम लीड मुख्य Claude Code सत्र, जो टीम बनाता है और साथियों को शुरू करता है
टीम के साथी अलग Claude Code इंस्टेंस, जिनमें से हर एक की अपनी कॉन्टेक्स्ट विंडो होती है
कार्य सूची काम की साझा प्रविष्टियाँ, जो डिस्क पर अलग-अलग JSON फ़ाइलों में रखी जाती हैं
मेलबॉक्स संदेश पहुँचाने के लिए हर एजेंट की अलग इनबॉक्स फ़ाइलें

समन्वय की पूरी परत फ़ाइलों पर आधारित है। ~/.claude/ पर मौजूद फ़ाइलसिस्टम ही समन्वय का एकमात्र आधार है:

~/.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
    └── ...

यह मूलतः विकेंद्रीकृत डिज़ाइन है। लीड भी बस एक अन्य Claude सत्र है, जिसके पास कुछ अतिरिक्त टूल हैं (TeamCreate, TeamDelete, SendMessage)। कोई बैकग्राउंड प्रोसेस नहीं है। साझा फ़ाइलों तक पहुँच से समन्वय होता है।

किसी सक्रिय सत्र में, अगर आप Claude से कोई काम करने के लिए एक टीम शुरू करने को कहें और फिर दूसरी विंडो में नीचे दिया गया कमांड चलाएँ, तो आप फ़ाइलसिस्टम में होने वाले बदलावों को उसी समय देख सकते हैं।

watch -n 0.5 'tree ~/.claude/teams/ 2>/dev/null; echo "---"; tree ~/.claude/tasks/ 2>/dev/null'

उदाहरण के लिए, इस प्रॉम्प्ट के साथ:

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

मुझे यह देखने को मिला:

teams
└── code-review
    ├── config.json
    └── inboxes
        ├── bug-hunter.json
        ├── complexity-analyst.json
        ├── devils-advocate.json
        └── team-lead.json

टीम कॉन्फ़िगरेशन

~/.claude/teams/{team-name}/config.json पर मौजूद टीम कॉन्फ़िगरेशन में एक members ऐरे होता है, जिसे पढ़कर टीम के साथियों को एक-दूसरे का पता चलता है:

{
  "members": [
    { "name": "team-lead", "agentId": "abc-123", "agentType": "leader" },
    {
      "name": "researcher",
      "agentId": "def-456",
      "agentType": "general-purpose"
    }
  ]
}

एजेंटों को संबोधित करने का मुख्य माध्यम उनके नाम हैं (UUID मौजूद हैं, लेकिन रूटिंग के लिए उनका उपयोग नहीं होता)। सभी संदेशों और कार्य आवंटन में name फ़ील्ड का उपयोग होता है।

2. साझा कार्य सूची

फ़ाइल का फ़ॉर्मैट

हर कार्य को ~/.claude/tasks/{team-name}/ में एक अलग JSON फ़ाइल के रूप में रखा जाता है। पिछले सत्र का एक वास्तविक उदाहरण यह है:

{
  "id": "1",
  "subject": "Hunt for bugs across the codebase",
  "description": "...",
  "activeForm": "Hunting for bugs",
  "owner": "bug-hunter",
  "status": "completed",
  "blocks": [],
  "blockedBy": []
}

कार्य का स्कीमा:

फ़ील्ड प्रकार विवरण
id string संख्यात्मक ID, जो .highwatermark के ज़रिए अपने-आप बढ़ता है
subject string आदेशवाचक रूप में शीर्षक (जैसे, "टेस्ट चलाएँ")
description string विस्तृत आवश्यकताएँ और स्वीकृति के मानदंड
activeForm string स्पिनर पर दिखाने के लिए वर्तमान में जारी क्रिया का रूप ("टेस्ट चल रहे हैं")
status string pending → in_progress → completed (या deleted)
blocks string[] उन कार्यों के ID जिन्हें यह कार्य रोकता है
blockedBy string[] उन कार्यों के ID जिन्हें इस कार्य के शुरू होने से पहले पूरा होना चाहिए

समवर्ती निष्पादन का नियंत्रण

दो विशेष फ़ाइलें समन्वय उपलब्ध कराती हैं:

  • .lock: एक 0-बाइट की फ़ाइल, जिसका उपयोग फ़ाइलसिस्टम के स्तर पर म्यूचुअल एक्सक्लूज़न (flock()) के लिए होता है। मेरी मशीन पर देखी गई सभी 42 कार्य डायरेक्टरियों में मौजूद थी।
  • .highwatermark: इसमें एक पूर्णांक होता है (जैसे, "3", "13")। अपने-आप बढ़ते क्रम में आवंटन के लिए अगला उपलब्ध कार्य ID।

कार्य अपने ज़िम्मे लेना

कार्य अपने ज़िम्मे लेने की प्रक्रिया में रेस कंडीशन से बचने के लिए फ़ाइल लॉकिंग का उपयोग होता है। टीम के साथी सबसे छोटे ID वाला कार्य पहले लेने को प्राथमिकता देते हैं। जिस कार्य का blockedBy ऐरे खाली नहीं है, उसे तब तक अपने ज़िम्मे नहीं लिया जा सकता जब तक उसे रोकने वाले सभी कार्य अंतिम अवस्था में न पहुँच जाएँ।

अवलोकन: अधिकांश कार्य डायरेक्टरियाँ खाली हैं

मेरी मशीन पर मौजूद 42 कार्य डायरेक्टरियों में से केवल 5 में कार्यों की वास्तविक JSON फ़ाइलें थीं। बाकी 37 में केवल .lock और .highwatermark थे। इसका संभवतः मतलब है कि पूरा होने के बाद कार्य हटा दिए जाते हैं, या ये ऐसे सत्र थे जिनमें Claude ने आंतरिक कार्य सूची का उपयोग किया था (जो कार्य सूची सुविधा की शुरुआत से उपलब्ध है), लेकिन काम को उपकार्यों की फ़ाइलों में नहीं बाँटा था।

3. एजेंटों के बीच संचार

मेलबॉक्स पैटर्न

हर एजेंट की ~/.claude/teams/{team-name}/inboxes/{agent-name}.json पर एक JSON ऐरे फ़ाइल होती है। यह पिछले सत्र का एक वास्तविक इनबॉक्स है, जिसमें टीम लीड ने एक 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
  }
]

JSON-in-JSON एन्कोडिंग पर ध्यान दें: text फ़ील्ड एक JSON स्ट्रिंग है, जिसमें सीरियलाइज़ किया गया संदेश ऑब्जेक्ट होता है। बाहरी आवरण में from, text, timestamp और read फ़ील्ड होते हैं।

संदेशों के प्रकार

type फ़ील्ड, जो text पेलोड के अंदर होता है, इन प्रकारों का समर्थन करता है:

प्रकार दिशा उद्देश्य
task_assignment लीड → साथी पूरे विवरण के साथ कार्य सौंपना
message कोई भी → कोई भी एक प्राप्तकर्ता को सीधा संदेश
broadcast लीड → सभी हर साथी को एक ही संदेश
shutdown_request लीड → साथी व्यवस्थित रूप से बंद होने का अनुरोध
shutdown_response साथी → लीड बंद होने की मंज़ूरी देना या उसे अस्वीकार करना
plan_approval_request साथी → लीड समीक्षा के लिए प्लान भेजना
plan_approval_response लीड → साथी फ़ीडबैक के साथ मंज़ूर या अस्वीकार करना
idle_notification साथी → लीड साथी का टर्न समाप्त होने पर अपने-आप भेजा जाता है

संदेश पहुँचाने का तरीका

लिखने की प्रक्रिया: भेजने वाला प्राप्तकर्ता की इनबॉक्स JSON ऐरे फ़ाइल के अंत में एक नई प्रविष्टि जोड़ता है।

पढ़ने की प्रक्रिया: प्राप्तकर्ता अपनी इनबॉक्स फ़ाइल को पोल करता है। नए संदेश बातचीत में कृत्रिम टर्न के रूप में जोड़े जाते हैं (वे ऐसे दिखते हैं मानो किसी उपयोगकर्ता ने भेजे हों)।

ब्रॉडकास्ट: सचमुच वही संदेश हर साथी की इनबॉक्स फ़ाइल में लिखा जाता है। टोकन लागत टीम के आकार के साथ रैखिक रूप से बढ़ती है।

संचार बस फ़ाइल में जोड़ना + फ़ाइल पढ़ना है। भेजने और मिलने के बीच का विलंब प्राप्तकर्ता के पोलिंग अंतराल पर निर्भर करता है।

साथियों के DM की दृश्यता

जब टीम का कोई साथी दूसरे साथी को DM भेजता है, तो लीड को मिलने वाली निष्क्रियता की सूचना में उसका एक संक्षिप्त सार शामिल होता है। इससे लीड को संदेश की पूरी सामग्री के बिना भी साथियों के आपसी सहयोग की जानकारी मिलती है।

4. एजेंट शुरू करना और जीवनचक्र

टीम के साथी कैसे बनाए जाते हैं

टीम का हर साथी एक अलग claude CLI प्रोसेस होता है। लीड उन्हें Task टूल के ज़रिए team_name और name पैरामीटर के साथ शुरू करता है। शुरू किए गए प्रोसेस के लिए ये एनवायरनमेंट वेरिएबल सेट किए जाते हैं:

  • CLAUDE_CODE_TEAM_NAME: शुरू किए गए साथियों के लिए अपने-आप सेट होता है
  • CLAUDE_CODE_PLAN_MODE_REQUIRED: यदि प्लान की मंज़ूरी ज़रूरी हो तो इसे true पर सेट किया जाता है

संदर्भ का आरंभीकरण

टीम के साथी प्रोजेक्ट का वही संदर्भ लोड करते हैं जो किसी भी नए सत्र में लोड होता है:

  • कार्य डायरेक्टरी की CLAUDE.md फ़ाइलें
  • MCP सर्वर
  • स्किल
  • लीड से मिला शुरू करने का प्रॉम्प्ट

लीड की बातचीत का इतिहास साथ नहीं आता। हर साथी केवल शुरू करने के प्रॉम्प्ट को संदर्भ के रूप में लेकर नए सिरे से शुरू करता है।

आंतरिक कार्यान्वयन

Claude Code v2.1.47 के बाइनरी विश्लेषण के अनुसार, साथी के संदर्भ का प्रबंधन AsyncLocalStorage के ज़रिए इन फ़ील्ड के साथ होता है:

  • agentId, agentName, teamName
  • parentSessionId, color
  • planModeRequired

प्रमुख आंतरिक फ़ंक्शन:

  • isTeammate() / isTeamLead(): भूमिका की पहचान
  • waitForTeammatesToBecomeIdle(): लीड के लिए सिंक्रोनाइज़ेशन प्रिमिटिव
  • getTeammateContext() / setDynamicTeamContext(): रनटाइम संदर्भ का प्रबंधन

निष्क्रियता की पहचान

हर LLM टर्न के बाद, टीम का साथी अपने-आप निष्क्रिय हो जाता है और लीड को एक idle_notification भेजता है। यह सामान्य विश्राम अवस्था है, न कि कोई त्रुटि या ठहराव की स्थिति। किसी निष्क्रिय साथी को संदेश भेजने से वह फिर सक्रिय हो जाता है (अगले पोलिंग चक्र में इनबॉक्स का संदेश मिल जाता है)।

बंद करने का प्रोटोकॉल

  1. लीड टीम के किसी साथी को shutdown_request भेजता है
  2. साथी मंज़ूरी दे सकता है (व्यवस्थित रूप से बंद हो जाता है) या अस्वीकार कर सकता है (कारण बताते हुए काम जारी रखता है)
  3. TeamDelete के ज़रिए टीम की सफ़ाई करने पर ~/.claude/teams/{team-name}/ और ~/.claude/tasks/{team-name}/ हट जाते हैं
  4. अगर कोई साथी अभी भी सक्रिय है तो सफ़ाई विफल हो जाती है; पहले उन्हें बंद करना होता है

अनुमतियों का इनहेरिटेंस

शुरू होते समय टीम के साथियों को लीड का अनुमति मोड विरासत में मिलता है। अगर लीड --dangerously-skip-permissions का उपयोग करता है, तो सभी साथी भी करते हैं। शुरू होने के बाद अलग-अलग साथियों के मोड बदले जा सकते हैं, लेकिन उन्हें शुरू करते समय हर साथी के लिए अलग मोड कॉन्फ़िगर नहीं किया जा सकता।

5. गुणवत्ता जाँच और हुक

गुणवत्ता सुनिश्चित करने के लिए Agent Teams, Claude Code के हुक सिस्टम के साथ जुड़ता है:

TeammateIdle हुक

यह तब सक्रिय होता है जब टीम का कोई साथी निष्क्रिय होने वाला हो। एग्ज़िट कोड 2, stderr को फ़ीडबैक के रूप में भेजता है और निष्क्रिय होने से रोकता है, जिससे साथी काम करता रहता है।

{
  "hook_event_name": "TeammateIdle",
  "teammate_name": "researcher",
  "team_name": "my-project"
}

TaskCompleted हुक

यह तब सक्रिय होता है जब किसी कार्य को पूरा चिह्नित किया जा रहा हो। एग्ज़िट कोड 2, कार्य को पूरा चिह्नित होने से रोकता है और stderr को फ़ीडबैक के रूप में वापस भेजता है।

{
  "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"
}

यह दो स्थितियों में सक्रिय होता है: (1) जब कोई भी एजेंट TaskUpdate के ज़रिए स्पष्ट रूप से किसी कार्य को पूरा चिह्नित करता है, या (2) जब एजेंट टीम का कोई साथी ऐसे कार्यों के साथ अपना टर्न समाप्त करता है जो अभी प्रगति पर हैं।

हुक हैंडलर के प्रकार

प्रकार विवरण
command शेल स्क्रिप्ट। stdin पर JSON, फ़ैसलों के लिए एग्ज़िट कोड।
prompt एक टर्न में LLM मूल्यांकन। {ok, reason} लौटाता है।
agent पढ़ने के टूल के साथ कई टर्न वाला सबएजेंट। अधिकतम 50 टर्न।

6. टोकन का अर्थशास्त्र

जब टीम के साथी प्लान मोड में चलते हैं, तब एजेंट टीमें सामान्य सत्रों के मुकाबले लगभग 7× अधिक टोकन इस्तेमाल करती हैं। हर साथी एक अलग Claude इंस्टेंस के रूप में अपनी पूरी कॉन्टेक्स्ट विंडो बनाए रखता है।

आधारभूत संदर्भ

  • औसत Claude Code उपयोग: ~$6/डेवलपर/दिन
  • एजेंट टीमें: आधार लागत के ऊपर अतिरिक्त खर्च, जो मोटे तौर पर टीम के आकार के अनुपात में होता है

7. आर्किटेक्चर का सार

पहलू Claude Code Agent Teams
समन्वय का आधार फ़्लैट फ़ाइलें (~/.claude/tasks/, ~/.claude/teams/)
कार्य का फ़ॉर्मैट प्रति कार्य एक JSON फ़ाइल + कार्य अपने ज़िम्मे लेने के लिए .lock
संदेश संचार JSON इनबॉक्स फ़ाइलें (जोड़ना + पोल करना)
एजेंट का जीवनचक्र खुद अपना प्रबंधन करने वाले CLI प्रोसेस
काम का अलगाव साझा कार्य डायरेक्टरी
मर्ज रणनीति कोई नहीं (एजेंट सीधे फ़ाइलें संपादित करते हैं)
पुनः प्रयास/एस्केलेशन मैन्युअल (लीड फ़ैसला करता है, या उपयोगकर्ता हस्तक्षेप करता है)
टोपोलॉजी लीड + समान स्तर के साथी, साथियों के बीच सीधे संदेश
शेड्यूलिंग खुद ज़िम्मेदारी लेना (साथी अगला कार्य अपने ज़िम्मे लेते हैं)
स्थिति का स्थायित्व केवल फ़ाइलें; प्रोसेस के भीतर साथी का काम फिर से शुरू करने की सुविधा नहीं
गुणवत्ता जाँच शेल हुक (TeammateIdle, TaskCompleted)
टोकन की ट्रैकिंग केवल प्रति सत्र, सभी एजेंटों का संयुक्त हिसाब नहीं
काम रुकने की पहचान मैन्युअल (उपयोगकर्ता देखता है कि साथी रुक गया है)
समवर्ती निष्पादन का नियंत्रण निहित (टीम का आकार = साथियों की संख्या)
निर्भरता मॉडल कार्य फ़ाइलों में blocks/blockedBy

स्रोत

आधिकारिक दस्तावेज़

डिस्क पर मौजूद आर्टिफ़ैक्ट (Claude Code v2.1.47)

/Users/tau/.claude/ पर देखे गए:

  • टीम डायरेक्टरियाँ, जिनमें config.json और inboxes/{agent-name}.json फ़ाइलें थीं
  • कार्य डायरेक्टरियाँ, जिनमें .lock, .highwatermark और अलग-अलग कार्यों की JSON फ़ाइलें थीं
  • team-lead से cp-agent को भेजा गया कार्य आवंटन का एक नमूना संदेश, जिस पर 2026-02-18T02:37:16.890Z का टाइमस्टैम्प था

बाइनरी विश्लेषण

Claude Code बाइनरी v2.1.47। स्ट्रिंग विश्लेषण से पहचाने गए आंतरिक फ़ंक्शन: getTeamName, getAgentName, getAgentId, isTeammate, isTeamLead, waitForTeammatesToBecomeIdle, getTeammateContext, setDynamicTeamContext, createTeammateContext। AsyncLocalStorage संदर्भ फ़ील्ड: agentId, agentName, teamName, parentSessionId, color, planModeRequired।

Hive कोडबेस