五、第五阶段

5.1 S15 Agent团队

       有身份、能长期存在、能反复协作的队友。

       5.1.1 子 Agent vs 队友

子Agent 队友
生命周期 一次性,用完销毁 多轮
通信 只回传结论 异步收件箱,随时通信
上下文 完全隔离 通过消息共享信息
数量 一个主 Agent + 偶尔子 Agent 一个 Lead + 多个队友

       5.1.2 调用 spawn_teammate 工具启动一个队友 --> 每个 Agent(包括 Lead 和队友)有一个 .jsonl 邮箱。发消息 = 往对方的文件里 append 一行 JSON。读消息 = 读文件 + 删除(消费式)--> 队友每轮先看邮箱,再继续工作

       5.1.3 CC源码

1

没有中央消息总线,是文件系统

1.每个 Agent 直接写其他 Agent 的收件箱文件。

2. 收件箱路径:~/.claude/teams/{teamName}/inboxes/{agentName}.json

3.写入时用 proper-lockfile 文件锁保证并发安全(最多重试 10 次)。

2

15 种消息类型

1.plain text:普通队友间通信

2.idle_notification:队友完成一轮工作,进入空闲

3. permission_request:队友需要操作审批

4.permission_response:Lead 审批结果

5.plan_approval_request:队友提交计划待审

6.plan_approval_response:Lead 审批计划

7.shutdown_request:请求体面关机

8.shutdown_approved:确认关机

9.shutdown_rejected:拒绝关机(附原因)

10.task_assignment:分配任务

11.team_permission_update:广播权限变更

12.mode_set_request:修改队友的权限模式

13.sandbox_permission_*:网络权限请求/回复

14.teammate_terminated:队友被移除通知

15.文本消息被包装在 <teammate-message> XML 标签中交付给模型。

3

权限冒泡:双向轮询

1.队友遇到需要审批的操作(permission_request)

2.Lead 的 useInboxPoller(每 1 秒轮询)检测到请求 

3.Lead 的 UI 显示审批对话框

4.用户审批->Lead (permission_response) 回队友

5.队友的 useSwarmPermissionPoller(每 500ms 轮询)收到回复

4

队友生命周期

1.Spawn

2.Work

3.Idle

4.Shutdown

5

Team Config

1.团队注册表在 ~/.claude/teams/{teamName}/config.json

2.队友之间不能嵌套

       5.1.4 测试prompt

        a. Spawn alice as a backend developer. Ask her to create a file called schema.sql with a users table.
         b. Check your inbox for alice's result.
         c. Spawn bob as a tester. Ask him to check if schema.sql exists and list its contents.

5.2 S16团队协议

       5.2.1 ProtocolState: 请求状态

@dataclass
class ProtocolState:
    request_id: str # 唯一ID
    type: str       # 协议类型:"shutdown" | "plan_approval"
    sender: str     # 发起方
    target: str     # 接受方
    status: str     # pending | approved | rejected
    payload: str    # 计划文本或关机原因
    created_at: float = field(default_factory=time.time) #时间戳

       request_id 区分每个请求;status记录请求状态。

       5.2.2 CC源码

1 关机协议 shutdown 是三向通信。Lead 发 shutdown_request,队友回复 shutdown_approved(或 shutdown_rejected 附原因),系统发送 teammate_terminated 通知所有相关方。关机确认后系统自动清理 pane、unassign 任务、从 team config 移除成员。
2 计划审批 plan approval request 在 plan-mode-required 队友退出 plan mode 时产生。自动回写 approval,并把请求交给 Lead 作为上下文(regular message)。
3 消息格式 协议消息是结构化的 JSON(有 Zod schema 验证)。
4 执行门控 队友有完整的 permission gating。未获批准的高风险操作会被拦截,不是可选的。
5 通用性 所有协议消息共用同一个 request id 关联机制。

       5.2.3 测试prompt

        a. Spawn alice as a backend dev. Ask her to create a file. Then request her shutdown.
        b. Spawn bob with a refactoring task. Have him submit a plan first. Then review and approve it.

5.3 S17 自治,主动认领任务

       让空闲队友自己扫描任务板,找到可做的任务并认领。减轻lead的负担。

       5.3.1 idle_poll: 队友完成当前任务后不退出,进入 IDLE 阶段,每 5 秒检查一次有没有新工作

IDLE_POLL_INTERVAL = 5   # seconds
IDLE_TIMEOUT = 60         # seconds

def idle_poll(agent_name, messages, name, role) -> str:
    """Return 'work', 'shutdown', or 'timeout'."""
    for _ in range(IDLE_TIMEOUT // IDLE_POLL_INTERVAL):
        time.sleep(IDLE_POLL_INTERVAL)

        # ① 检查收件箱(优先)
        inbox = BUS.read_inbox(agent_name)
        if inbox:
            # shutdown_request 立即处理
            for msg in inbox:
                if msg.get("type") == "shutdown_request":
                    # ... 回复 shutdown_response
                    return "shutdown"
            # 普通消息注入上下文,回到 WORK
            messages.append(...)
            return "work"

        # ② 扫描任务看板,找pending状态、无owner、所有依赖已完成的任务
        unclaimed = scan_unclaimed_tasks()
        if unclaimed:
            task = unclaimed[0]
            result = claim_task(task["id"], agent_name)
            if "Claimed" in result:
                messages.append(...)
                return "work"
    return "timeout"

       5.3.2 队友生命周期: WORK → IDLE → SHUTDOWN

# Outer loop: WORK → IDLE cycle
while True:
    # WORK phase: 内层循环(最多 10 轮 LLM 调用)
    for _ in range(10):
        # 检查 inbox、处理协议消息、调 LLM、执行工具
        ...
        if response.stop_reason != "tool_use":
            break  # WORK 阶段结束

    # IDLE phase
    idle_result = idle_poll(name, messages, name, role)
    if idle_result == "shutdown":
        break
    if idle_result == "timeout":
        break  # 60s 超时 → SHUTDOWN

# SHUTDOWN: 发 summary 给 Lead
BUS.send(name, "lead", summary, "result")

       5.3.3 CC源码

维度 教学版 CC
空闲机制 idle_poll 统一轮询 组合:idle_notification + 500ms mailbox 轮询 + task watcher
任务发现 scan_unclaimed_tasks(轮询) useTaskListWatcher(文件监听)+ tryClaimNextTask(主动轮询)
依赖判断 can_start(所有 blockedBy 已完成) findAvailableTask(同样语义)
并发安全 owner 检查(无文件锁) proper-lockfile 任务锁 + task-list 锁

shutdown

处理

IDLE 直接分发,WORK 通过 handle_inbox_message 500ms 轮询中优先处理 shutdown_request
超时退出 60s 无新任务 无固定超时,Lead 手动 shutdown
身份保持 message长度检测 context compaction 保留 system prompt

claim

失败处理

检查返回值,失败不注入 文件锁保证原子性

       5.3.4 测试prompt

       a. Create 3 tasks on the board, then spawn alice and bob. Watch them auto-claim and work.

5.4 S18 Worktree 隔离

      每个任务在独立工作目录里执行。把任务和执行目录做显式绑定,让并行工作有清楚的边界。

      5.4.1 Task

@dataclass
class Task:
    id: str
    subject: str
    description: str
    status: str
    owner: str | None
    blockedBy: list[str]
    worktree: str | None = None      # s18:绑定的工作目录

      5.4.2 CC源码

1

EnterWorktree:当前会话切换

当前会话的工作目录直接切换到 worktree——不是 prompt 提醒,而是进程级目录变更。
2

AgentTool isolation:子 agent 隔离

子 agent 的所有操作自动在 worktree 目录下进行。
3

name 校验

校验 slug:拒绝 ./..,允许 [a-zA-Z0-9._-]
4

路径和分支命名

真实路径是 .claude/worktrees/,分支名 worktree-{slug}(斜杠用 + 替代)
5

状态管理

没有 task-worktree 绑定。把 worktree 和 task 作为两个独立系统,通过 Agent 理解上下文来关联。

      5.4.3 测试prompt

      a. Create two tasks, then create worktrees for each (bind with task_id). Spawn alice and bob. Watch them auto-claim and work in isolated directories.

六、第六阶段

6.1 S07 Skill

        不是“多一个工具”,而是“把可选知识从常驻 prompt 里拆出来,改成按需加载”。

        6.1.1 循环:没有变化。增加了load_skill 工具。技能内容不是 system prompt 的一部分,它作为一次工具结果进入当前 messages。后续调用会随历史一起携带,直到上下文压缩、截断或会话结束。

         SYSTEM = ( f"You are a coding agent at {WORKDIR}. "

f"Skills available:\n{catalog}\n"

"Use load_skill to get full details when needed." )

        6.1.2 CC源码

1

技能来源:不是只有一个 skills/ 目录

实际从多个来源加载,分布在多个文件中
2

SKILL.md Frontmatter 常见字段

name / description、when_to_use、allowed-tools、context、model、hooks、paths、user-invocable
3

两级加载的精确实现

1. Catalog(启动时)

2. Load(调用时)

        6.1.3 测试prompt

         a. What skills are available?
         b. Load the code-review skill and follow its instructions
         c. I need to do a code review -- load the relevant skill first

6.2 S19 MCP-外接工具,标准协议

        6.2.1 MCP核心概念

概念 作用
MCPClient Agent 端的客户端,连接 server、发现工具、调用工具
MCP Server 外部服务,实现 tools/list + tools/call
assemble_tool_pool 把内置工具和 MCP 工具组装成一个工具池
mcp__server__tool 命名 避免不同 server 的工具名冲突

        6.2.2 assemble_tool_pool:组装工具池(内置工具+MCP工具)

def assemble_tool_pool() -> tuple[list[dict], dict]:
    tools = list(BUILTIN_TOOLS) # 内置工具
    handlers = dict(BUILTIN_HANDLERS)
    for server_name, mcp_client in mcp_clients.items(): # 循环MCP工具
        safe_server = normalize_mcp_name(server_name)
        for tool_def in mcp_client.tools:
            safe_tool = normalize_mcp_name(tool_def["name"]) # 名称规范化
            prefixed = f"mcp__{safe_server}__{safe_tool}" # 避免不同 server 的工具名冲突
            tools.append(...)
            handlers[prefixed] = (
                lambda *, c=mcp_client, t=tool_def["name"], **kw:
                    c.call_tool(t, kw))
    return tools, handlers

        6.2.3 CC源码

1

6 种 Transport 类型

Transport 通信方式
stdio 子进程 stdin/stdout(跨平台默认)
sse HTTP Server-Sent Events
http Streamable HTTP(POST/SSE 双向)
ws WebSocket
sse-ide IDE 内嵌 SSE 传输
sdk 进程内 SDK 传输

2

工具池组装算法

1.去重时优先保留内置工具(name 相同时内置在前)

2.内置工具和 MCP 工具分开排序

3

命名规则

mcp__server__tool
4

权限检查

MCP 工具可以声明自己的权限需求(readOnly、destructive 等),CC 根据声明决定是否需要用户确认。
5

配置来源与优先级

claude.ai 连接器 < plugin < user settings.json < approved project .mcp.json < local settings.local.json
6

Channel 通知:服务器反向推消息

支持反向通知:MCP Server -> Agent
7

OAuth 认证流程

支持完整的 OAuth 2.0 + PKCE 流程
8

连接生命周期的错误处理

1. 终局性错误(ECONNRESET、ETIMEDOUT、EPIPE 等):连续 3 次 → 关闭 + 重连
2. 工具调用 401:令牌过期 → 抛出 McpAuthError → 触发重认证
3. 工具调用超时:Promise.race 超时(可配置,默认约 28 小时)
4. Stdio 断连:按 SIGINT → SIGTERM → SIGKILL 顺序杀进程

        6.2.4 测试prompt

         a. Connect to the docs MCP server and search for something 
         b. Connect to the deploy server and trigger a deployment
         c. Connect both servers — what tools are now available?

6.3 S20 把所有组件放到循环的合适位置

        6.3.1 组件在循环中的位置

位置 组件 作用
用户输入前后 UserPromptSubmit hooks 记录、注入、审计用户输入
LLM 前 cron queue 把定时触发的 prompt 注入 messages
LLM 前 background notifications 后台任务完成后以 <task_notification> 注入
LLM 前 compaction pipeline 先压大输出,再裁历史,再压旧 tool_result,必要时摘要
LLM 前 memory / skills / MCP state 组装 system prompt,让模型看到当前能力和长期上下文
LLM 调用 error recovery 429/529 重试,max_tokens 升级,prompt too long 触发 reactive compact
工具执行前 PreToolUse hooks + permission 拦截危险命令、写越界、破坏性 MCP 工具
工具分发 assemble_tool_pool 组装内置工具和 MCP 动态工具
工具执行时 background dispatch 慢 bash 操作放 daemon thread,主循环先返回占位结果
工具执行后 PostToolUse hooks 大输出告警、日志等后处理
返回循环 tool_result 每个 tool_use 对应一个 tool_result,再回到下一轮
本轮没有 tool_use / 停止时 Stop hooks 统计、清理、审计

        6.3.2 测试prompt

         a. Create a todo list for inspecting this repo, then list Python files
         b. Connect to the docs MCP server and search for agent loop
         c. Create two tasks, create worktrees for them, then spawn alice and bob. Ask them to submit plans before claiming tasks.
         d. remind me of the meeting in 3 minutes.
         e. Run npm install in the background and continue reading README.md

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐