深入浅出 Claude Code(三):从源码理解 Agent 系统,一个人指挥一支队伍

2026-06-09 18:12:20 629阅读 0评论 SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

今天来带各位佬友讲讲 agent,本文参考官方教学文档和 claudecode 源码而来
各位佬友抓紧把手,咱们直接发车


1. Agent 是什么:独立 context 的工作单元

一个 agent 就是一个独立的 Claude 会话——有自己的 context window、自己的对话历史、自己的工具集。

你平时跟 Claude Code 对话的那个就是"主 agent"。当你(或模型)调用 Agent 工具时,会创建一个子 agent。子 agent 在自己的 context window 里干活,完成后把结果返回给主 agent。

深入浅出 Claude Code(三):从源码理解 Agent 系统,一个人指挥一支队伍

这里有一个关键区别:普通 subagent 从零开始,只有你传入的 prompt 字符串——你不写进去的信息,它看不到。而 Fork 模式继承父 agent 的完整对话历史——之前聊过什么它都知道,不需要你重复。

源码中子 agent 的 context 创建逻辑(utils/forkedAgent.ts):

深入浅出 Claude Code(三):从源码理解 Agent 系统,一个人指挥一支队伍

function createSubagentContext(parentContext, overrides) { return { readFileState: cloneFileStateCache(...) // 独立的文件缓存 messages: override?.messages || [] // 普通 subagent:空;Fork:父 agent 的历史 agentId: override?.agentId || createAgentId() // 新 ID queryTracking: { chainId, depth: parentDepth + 1 } // 深度 +1 } }

不管哪种模式,每个子 agent 都有独立的文件缓存和 context window。这就是为什么用 agent 能解决长对话"忘事"——子 agent 不会被主 agent 之前对话的内容塞满。


2. 创建 Agent 时发生了什么

当模型调用 Agent 工具时,路径取决于有没有指定 subagent_typetools/AgentTool/AgentTool.tsx):

Agent tool 调用 ├─ 指定了 subagent_type(如 Explore、Plan)→ 用该类型的定义从零开始 ├─ 没指定 + Fork 功能开启 → Fork(继承父 agent 的完整对话历史) └─ 没指定 + Fork 未开启 → General Purpose Agent

日常使用中你接触到的主要是第一种。大部分时候是模型自动调用的——你说"帮我调研一下 auth 模块",Claude 自己判断该用 Explore agent,自动写 prompt、自动派遣,你不需要手动操作。

但不管是自动还是手动触发,子 agent 都是从空白开始工作。主 agent 传给它的 prompt 是它唯一的上下文——主 agent 之前跟你的对话历史、已经读过的文件,子 agent 统统看不到。

这也是为什么你有时候觉得 subagent 的结果不够好——主 agent 写给子 agent 的 prompt 可能没带足够的背景信息。你可以在对话中显式补充:“帮我调研 auth 模块,我们用的是 JWT + Redis session,入口在 src/auth/middleware.ts”,这样主 agent 传给子 agent 的 prompt 会包含这些关键信息。

Fork 模式(feature flag 控制,可能未对外开放)

Fork 是"复制一个分身"——子 agent 继承父 agent 的完整对话历史和 system prompt。你不需要重复背景信息。

源码中 fork 的启用条件(forkSubagent.ts):

function isForkSubagentEnabled(): boolean { if (feature('FORK_SUBAGENT')) { // 编译时 feature flag if (isCoordinatorMode()) return false if (getIsNonInteractiveSession()) return false return true } return false }

feature('FORK_SUBAGENT') 是编译时常量。如果你从来没感知过 fork,大概率是这个 flag 在当前版本中未开启——整个 fork 路径会被 dead code elimination 删掉。

Fork 还有一个成本优势:复用父 agent 的 system prompt(byte-exact 相同),prompt cache 直接命中,50K tokens 的上下文走 cache read 成本约 1/10。但因为功能可能未开放,这里不展开。


3. 三种内置 Agent

Agent 模型 工具 用途
Explore 普通用户: Haiku / Anthropic 员工: 继承主模型 只读(Read, Grep, Glob) 搜代码、找文件、回答 codebase 问题
Plan 继承主模型 只读 架构设计、实现方案规划
General Purpose 继承主模型 全部 复杂多步骤任务

官方文档说 Explore 在需要搜索或理解代码库时被自动委派,调用时分三个 thoroughness 级别:quick(定向查找)、medium(平衡探索)、very thorough(全面分析)。

两个源码级的细节官方没提:

你用的 Explore 默认跑 Haiku,Anthropic 员工跑的是主模型。 源码(built-in/exploreAgent.ts):

model: process.env.USER_TYPE === 'ant' ? 'inherit' : 'haiku'

USER_TYPE === 'ant' 是 Anthropic 内部员工标识。也就是说同样的 Explore agent,他们跑 Opus/Sonnet,你跑 Haiku。Haiku 更快更便宜,但推理能力弱一些。如果你觉得 Explore 给的结果太浅,可以用自定义 agent 覆盖它(后面第 4 节讲怎么做)。

Explore 跳过 CLAUDE.md。 设置了 omitClaudeMd: true——探索型 agent 不需要你的 commit 规范和代码风格规则,省掉这些 token,把空间留给代码内容。


4. 自定义 Agent

两种方式创建:

交互式——输入 /agents,选 Create new agent,可以让 Claude 根据你的描述自动生成定义。选工具、选模型、选颜色,保存就生效。

手动建文件——在 .claude/agents/ 下创建 .md 文件。frontmatter 是配置,正文是 system prompt:

--- name: code-reviewer description: 审查代码变更,关注安全和性能 tools: Read, Grep, Glob, Bash(git diff:*) model: sonnet maxTurns: 15 --- 你是一个代码审查专家。收到审查请求后: 1. 用 git diff 查看所有变更 2. 逐文件检查安全漏洞、性能问题、错误处理 3. 给出结构化审查意见

几个关键字段:

description — 不只是文档。Claude 会根据这个描述自动判断何时委派任务给这个 agent。写得模糊就不会被自动调用。

tools — 硬限制,不是建议。源码中 tools 字段被解析为严格白名单(agentToolUtils.ts:resolveAgentTools)——不在列表里的工具对 agent 来说不存在。而且支持内联权限规则:

tools: "Read, Grep, Bash(git diff:*), Agent(Explore)"

Bash(git diff:*) = 只能执行 git diff 开头的命令。Agent(Explore) = 只能派遣 Explore 类型的子 agent。

modelinherit 继承主模型,或指定 sonnet/opus/haiku

isolation: worktree — 在独立的 git worktree 中运行。完成后无变更自动清理,有变更保留 worktree 和分支。

background: true — 始终后台运行,不阻塞主对话。

memory: project — 给 agent 独立的记忆空间,存在 .claude/agent-memory/{agent-type}/。code-reviewer 的记忆不会和 code-writer 的混在一起。

覆盖内置 Agent

同名 agent 高优先级覆盖低优先级:

企业策略 > 项目 .claude/agents/ > 用户 ~/.claude/agents/ > 插件 > 内置

想让 Explore 用 Sonnet 而不是 Haiku?创建 .claude/agents/Explore.md

--- name: Explore description: 快速探索代码库,搜索文件和代码模式 model: sonnet ---


5. 子 Agent 能用什么工具、不能用什么

源码中有三个工具集控制子 agent 的能力边界:

子 agent 禁止使用的工具constants/tools.ts):

const ALL_AGENT_DISALLOWED_TOOLS = new Set([ TASK_OUTPUT_TOOL_NAME, // 防止递归 EXIT_PLAN_MODE_V2_TOOL_NAME, // 计划模式是主线程的抽象 ENTER_PLAN_MODE_TOOL_NAME, // 同上 ASK_USER_QUESTION_TOOL_NAME, // 需要主线程的用户交互 TASK_STOP_TOOL_NAME, // 需要主线程的状态访问 // 外部用户禁止嵌套 agent: ...(process.env.USER_TYPE === 'ant' ? [] : [AGENT_TOOL_NAME]), ])

最后一行:外部用户的 AGENT_TOOL_NAME 被加入禁止列表。外部用户的子 agent 不能再创建子 agent,架构只能是一层。Anthropic 内部用户(ant)不受此限制。

后台 agent 允许的工具constants/tools.ts)——范围更窄:

const ASYNC_AGENT_ALLOWED_TOOLS = new Set([ FILE_READ_TOOL_NAME, GREP_TOOL_NAME, GLOB_TOOL_NAME, WEB_SEARCH_TOOL_NAME, WEB_FETCH_TOOL_NAME, ...SHELL_TOOL_NAMES, // Bash, PowerShell FILE_EDIT_TOOL_NAME, FILE_WRITE_TOOL_NAME, NOTEBOOK_EDIT_TOOL_NAME, SKILL_TOOL_NAME, TOOL_SEARCH_TOOL_NAME, ENTER_WORKTREE_TOOL_NAME, EXIT_WORKTREE_TOOL_NAME, ])

注意 ASK_USER_QUESTION 不在列表里——后台 agent 不能问你问题,因为它在后台跑,你看不到他。


6. 权限怎么处理

子 agent 需要执行删除文件、运行危险命令等操作时,权限提示怎么办?

取决于 permissionMode 设置:

模式 行为
bubble(Fork 默认) 权限提示冒泡到主终端,你在主终端批准
acceptEdits 自动允许文件操作
plan 只能规划不能执行,等你确认
bypassPermissions 全部自动批准
dontAsk 全部自动拒绝

bubble 是 Fork 的默认模式——子 agent 想做危险操作时,你的主终端会弹出权限请求。

源码中的决策逻辑(runAgent.ts):

const shouldAvoidPrompts = agentPermissionMode === 'bubble' ? false // bubble 模式:始终显示权限提示 : isAsync // 其他模式:后台 agent 自动避免提示

后台 agent 如果遇到需要审批的操作,会自动拒绝(因为你看不到)。想让后台 agent 自由操作,设置 permissionMode: acceptEditsbypassPermissions


7. 并行执行和实际上限

在一条消息中同时发起多个 Agent 调用,它们会并行执行

"帮我同时做三件事: 1. 用 Explore agent 调研 auth 模块 2. 用 Explore agent 调研 payment 模块 3. 用 Explore agent 调研 notification 模块"

模型会在一次回复中生成三个 Agent tool_use,三个子 agent 同时启动。

源码中没有硬编码的 MAX_WORKERS 限制。但实际约束:

  • API 并发请求数(取决于你的订阅/API key)
  • 本地内存和 CPU——每个 agent 是一个独立的查询循环
  • 远程 bridge 模式默认 32 个并发(SPAWN_SESSIONS_DEFAULT = 32

Anthropic 官方博客的实战建议:5-8 个并行 agent,每个负责 5-8 个文件

一个 agent 有约 167K tokens 的工作空间。5 个并行 agent = 835K tokens 的总工作空间。对于大规模重构,这是从"线性处理"到"并行处理"的质变。


8. Agent Teams:让多个 Agent 互相对话

前面讲的 subagent 都是"主 agent 派活 → 子 agent 干活 → 返回结果"的单向模式。子 agent 之间互相看不到,也不能交流。

Agent Teams 是另一种模式——多个 agent 组成团队,共享任务列表,互相发消息讨论

Subagent Agent Team
通信 只能向主 agent 汇报 队友之间直接消息
协调 主 agent 管理所有工作 共享任务列表,自协调
场景 只需要结果的聚焦任务 需要讨论和协作的复杂工作
Token 成本 较低 较高(每个队友独立 context)

一个实际例子——用竞争假设做调试:

用户反馈 app 在发一条消息后就退出了。 创建 5 个 agent 队友分别调查不同的假设。 让他们互相讨论、尝试推翻对方的理论,像科学辩论一样。 把共识写到 findings.md 里。

5 个 agent 独立调查各自的假设,然后互相质疑——"你说是 WebSocket 断开,但我查了连接日志没有断开记录,你的证据是什么?"这种对抗式调查比单 agent 线性排查更容易找到真正的根因。

目前是实验性功能,默认关闭。开启方式:

// settings.json { "env": { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" } }

架构组件:

  • Team lead——主会话,创建团队、分配任务、综合结果
  • Teammates——独立的 Claude Code 实例,各自有完整 context
  • Task list——共享任务列表,支持 pending/in_progress/completed 和依赖关系
  • Mailbox——agent 间的消息系统

显示模式两种:in-process(同一终端内,Shift+Down 切换队友)或 split panes(需要 tmux/iTerm2,每个队友独立窗格)。

几个限制:

  1. 一个 lead 只能管一个团队
  2. 队友不能再创建子团队
  3. session 恢复不支持 in-process 模式的队友
  4. 建议 3-5 个队友,每人 5-6 个任务

什么时候该用 Team 而不是 Subagent?当你需要队友之间互相讨论、质疑、协调时。如果只是"去干活然后告诉我结果",subagent 就够了,成本更低。

因篇幅限制,本文不在此处展开讲解,如需要,可以在评论区提一下,后面会单独开一篇


9. 实际怎么用

几个从源码设计意图推导出的使用模式:

大规模改动 → 并行 subagent + worktree

每个子 agent 在独立 worktree 里改自己那几个文件,互不干扰。完成后各自 commit,主 agent 汇总结果。这就是内置的 /batch skill 的底层原理。

需要验证 → 独立 subagent 做 review

实现完功能后,启动一个新 subagent 做 code review。为什么不用主 agent 自己 review?因为主 agent 在实现过程中形成了"这样是对的"的上下文偏见。独立 subagent 没有这个包袱,能更客观地审查。

长对话保持质量 → 拆成多个 agent 阶段

不要在一个 agent 里干到 context window 满。把任务拆成阶段:研究阶段用 Explore agent,规划阶段用 Plan agent,实现阶段用 General Purpose agent。每个阶段是独立的 context,不会互相污染。

快速搜索 → Explore agent

找文件、搜代码不需要启动重量级 agent。Explore 跑 Haiku,只读模式,不加载 CLAUDE.md,启动快、成本低。调用时可以指定 thoroughness 级别:quick(定向查找)、medium(平衡探索)、very thorough(全面分析)。

临时测试 → --agents CLI flag

不想创建文件,可以用 JSON 直接传临时 agent 定义,这个会话结束就消失:

claude --agents '{ "quick-reviewer": { "description": "快速代码审查", "prompt": "你是一个代码审查专家,只关注安全问题。", "tools": ["Read", "Grep", "Glob"], "model": "haiku" } }' 网友解答:


--【壹】--:

前排支持


--【贰】--:

前排学习,追更追更


--【叁】--:

干货啊,支持大佬


--【肆】--:

厉害厉害,学习了


--【伍】--:

真能学到东西,但太懒了不知道啥时候能学进去


--【陆】--:

Agent 中无法再生成subagent,这种有什么解么,有时候 skill接入上游的 pipline, 上游已经 spawn 成agent了,skill里的multi agent就被拍平了


--【柒】--:

太强了大佬,来学习一下


--【捌】--:

佬!入站的意义,全部都想起来了!


--【玖】--:

前排支持,学习!


--【拾】--:

学习了,基于源码的讲解,太透彻了


--【拾壹】--:

mark一下


--【拾贰】--:

题主这三篇帖子都认真看了,很有价值。感谢。


--【拾叁】--:

写的真棒,感谢佬的分享对日常使用有很大的帮助


--【拾肆】--:

已严肃学习并点赞佬的三个深入浅出教程 ,学到好多技巧,给上下文管理增加了很多方法学,也感叹A÷的技术和工程积累。
补充:

  • 哈雷佬的指南里提到这个网站可以参考
《 Claude Code 终极版 FAQ 指南 》

鉴于没有推进SubAgent的内容,这里给到一个集合网站给予参考

  • http://subagents.cc
  • 风佬的CCG自带几个agents在~/.claude/agents/ccg
    【补档】CCG v2.1.1 : Claude Code 编排三 CLI 协作 | Codex + Gemini + Claude | 加入多种实用skills

--【拾伍】--:

前排学习


--【拾陆】--:

点赞的人越来越少,充分说明了一件事,大部分人都是知识的搬运工,哈哈哈。

还是要写点自己的感悟供大家分享:

  1. 默认模式下,某些简单工作不用调用 agent,原文也指出了本身 agent 都是从空白开始工作,不如直接调用工具。
  2. 原来模型用量里面总是有 Haiku 是因为 Explore 默认用 Haiku,我还以为是设置问题。后续试试覆盖内置 Agent ,让 Explore 用 Sonnet 而不是 Haiku,不知道能否设置为 opus 4.6。
  3. 什么时候该用 Team 而不是 Subagent,这个其实蛮重要的,我记得我曾经看过 Claude 复刻 Linux 就是用了类似的模式吧,可见复杂任务还是需要这个功能的。
  4. 第九点实在是太重要了,解决了工作流程问题。

--【拾柒】--:

学习了,感谢佬的分享


--【拾捌】--:

支持支持


--【拾玖】--:

前排支持

问题描述:

今天来带各位佬友讲讲 agent,本文参考官方教学文档和 claudecode 源码而来
各位佬友抓紧把手,咱们直接发车


1. Agent 是什么:独立 context 的工作单元

一个 agent 就是一个独立的 Claude 会话——有自己的 context window、自己的对话历史、自己的工具集。

你平时跟 Claude Code 对话的那个就是"主 agent"。当你(或模型)调用 Agent 工具时,会创建一个子 agent。子 agent 在自己的 context window 里干活,完成后把结果返回给主 agent。

深入浅出 Claude Code(三):从源码理解 Agent 系统,一个人指挥一支队伍

这里有一个关键区别:普通 subagent 从零开始,只有你传入的 prompt 字符串——你不写进去的信息,它看不到。而 Fork 模式继承父 agent 的完整对话历史——之前聊过什么它都知道,不需要你重复。

源码中子 agent 的 context 创建逻辑(utils/forkedAgent.ts):

深入浅出 Claude Code(三):从源码理解 Agent 系统,一个人指挥一支队伍

function createSubagentContext(parentContext, overrides) { return { readFileState: cloneFileStateCache(...) // 独立的文件缓存 messages: override?.messages || [] // 普通 subagent:空;Fork:父 agent 的历史 agentId: override?.agentId || createAgentId() // 新 ID queryTracking: { chainId, depth: parentDepth + 1 } // 深度 +1 } }

不管哪种模式,每个子 agent 都有独立的文件缓存和 context window。这就是为什么用 agent 能解决长对话"忘事"——子 agent 不会被主 agent 之前对话的内容塞满。


2. 创建 Agent 时发生了什么

当模型调用 Agent 工具时,路径取决于有没有指定 subagent_typetools/AgentTool/AgentTool.tsx):

Agent tool 调用 ├─ 指定了 subagent_type(如 Explore、Plan)→ 用该类型的定义从零开始 ├─ 没指定 + Fork 功能开启 → Fork(继承父 agent 的完整对话历史) └─ 没指定 + Fork 未开启 → General Purpose Agent

日常使用中你接触到的主要是第一种。大部分时候是模型自动调用的——你说"帮我调研一下 auth 模块",Claude 自己判断该用 Explore agent,自动写 prompt、自动派遣,你不需要手动操作。

但不管是自动还是手动触发,子 agent 都是从空白开始工作。主 agent 传给它的 prompt 是它唯一的上下文——主 agent 之前跟你的对话历史、已经读过的文件,子 agent 统统看不到。

这也是为什么你有时候觉得 subagent 的结果不够好——主 agent 写给子 agent 的 prompt 可能没带足够的背景信息。你可以在对话中显式补充:“帮我调研 auth 模块,我们用的是 JWT + Redis session,入口在 src/auth/middleware.ts”,这样主 agent 传给子 agent 的 prompt 会包含这些关键信息。

Fork 模式(feature flag 控制,可能未对外开放)

Fork 是"复制一个分身"——子 agent 继承父 agent 的完整对话历史和 system prompt。你不需要重复背景信息。

源码中 fork 的启用条件(forkSubagent.ts):

function isForkSubagentEnabled(): boolean { if (feature('FORK_SUBAGENT')) { // 编译时 feature flag if (isCoordinatorMode()) return false if (getIsNonInteractiveSession()) return false return true } return false }

feature('FORK_SUBAGENT') 是编译时常量。如果你从来没感知过 fork,大概率是这个 flag 在当前版本中未开启——整个 fork 路径会被 dead code elimination 删掉。

Fork 还有一个成本优势:复用父 agent 的 system prompt(byte-exact 相同),prompt cache 直接命中,50K tokens 的上下文走 cache read 成本约 1/10。但因为功能可能未开放,这里不展开。


3. 三种内置 Agent

Agent 模型 工具 用途
Explore 普通用户: Haiku / Anthropic 员工: 继承主模型 只读(Read, Grep, Glob) 搜代码、找文件、回答 codebase 问题
Plan 继承主模型 只读 架构设计、实现方案规划
General Purpose 继承主模型 全部 复杂多步骤任务

官方文档说 Explore 在需要搜索或理解代码库时被自动委派,调用时分三个 thoroughness 级别:quick(定向查找)、medium(平衡探索)、very thorough(全面分析)。

两个源码级的细节官方没提:

你用的 Explore 默认跑 Haiku,Anthropic 员工跑的是主模型。 源码(built-in/exploreAgent.ts):

model: process.env.USER_TYPE === 'ant' ? 'inherit' : 'haiku'

USER_TYPE === 'ant' 是 Anthropic 内部员工标识。也就是说同样的 Explore agent,他们跑 Opus/Sonnet,你跑 Haiku。Haiku 更快更便宜,但推理能力弱一些。如果你觉得 Explore 给的结果太浅,可以用自定义 agent 覆盖它(后面第 4 节讲怎么做)。

Explore 跳过 CLAUDE.md。 设置了 omitClaudeMd: true——探索型 agent 不需要你的 commit 规范和代码风格规则,省掉这些 token,把空间留给代码内容。


4. 自定义 Agent

两种方式创建:

交互式——输入 /agents,选 Create new agent,可以让 Claude 根据你的描述自动生成定义。选工具、选模型、选颜色,保存就生效。

手动建文件——在 .claude/agents/ 下创建 .md 文件。frontmatter 是配置,正文是 system prompt:

--- name: code-reviewer description: 审查代码变更,关注安全和性能 tools: Read, Grep, Glob, Bash(git diff:*) model: sonnet maxTurns: 15 --- 你是一个代码审查专家。收到审查请求后: 1. 用 git diff 查看所有变更 2. 逐文件检查安全漏洞、性能问题、错误处理 3. 给出结构化审查意见

几个关键字段:

description — 不只是文档。Claude 会根据这个描述自动判断何时委派任务给这个 agent。写得模糊就不会被自动调用。

tools — 硬限制,不是建议。源码中 tools 字段被解析为严格白名单(agentToolUtils.ts:resolveAgentTools)——不在列表里的工具对 agent 来说不存在。而且支持内联权限规则:

tools: "Read, Grep, Bash(git diff:*), Agent(Explore)"

Bash(git diff:*) = 只能执行 git diff 开头的命令。Agent(Explore) = 只能派遣 Explore 类型的子 agent。

modelinherit 继承主模型,或指定 sonnet/opus/haiku

isolation: worktree — 在独立的 git worktree 中运行。完成后无变更自动清理,有变更保留 worktree 和分支。

background: true — 始终后台运行,不阻塞主对话。

memory: project — 给 agent 独立的记忆空间,存在 .claude/agent-memory/{agent-type}/。code-reviewer 的记忆不会和 code-writer 的混在一起。

覆盖内置 Agent

同名 agent 高优先级覆盖低优先级:

企业策略 > 项目 .claude/agents/ > 用户 ~/.claude/agents/ > 插件 > 内置

想让 Explore 用 Sonnet 而不是 Haiku?创建 .claude/agents/Explore.md

--- name: Explore description: 快速探索代码库,搜索文件和代码模式 model: sonnet ---


5. 子 Agent 能用什么工具、不能用什么

源码中有三个工具集控制子 agent 的能力边界:

子 agent 禁止使用的工具constants/tools.ts):

const ALL_AGENT_DISALLOWED_TOOLS = new Set([ TASK_OUTPUT_TOOL_NAME, // 防止递归 EXIT_PLAN_MODE_V2_TOOL_NAME, // 计划模式是主线程的抽象 ENTER_PLAN_MODE_TOOL_NAME, // 同上 ASK_USER_QUESTION_TOOL_NAME, // 需要主线程的用户交互 TASK_STOP_TOOL_NAME, // 需要主线程的状态访问 // 外部用户禁止嵌套 agent: ...(process.env.USER_TYPE === 'ant' ? [] : [AGENT_TOOL_NAME]), ])

最后一行:外部用户的 AGENT_TOOL_NAME 被加入禁止列表。外部用户的子 agent 不能再创建子 agent,架构只能是一层。Anthropic 内部用户(ant)不受此限制。

后台 agent 允许的工具constants/tools.ts)——范围更窄:

const ASYNC_AGENT_ALLOWED_TOOLS = new Set([ FILE_READ_TOOL_NAME, GREP_TOOL_NAME, GLOB_TOOL_NAME, WEB_SEARCH_TOOL_NAME, WEB_FETCH_TOOL_NAME, ...SHELL_TOOL_NAMES, // Bash, PowerShell FILE_EDIT_TOOL_NAME, FILE_WRITE_TOOL_NAME, NOTEBOOK_EDIT_TOOL_NAME, SKILL_TOOL_NAME, TOOL_SEARCH_TOOL_NAME, ENTER_WORKTREE_TOOL_NAME, EXIT_WORKTREE_TOOL_NAME, ])

注意 ASK_USER_QUESTION 不在列表里——后台 agent 不能问你问题,因为它在后台跑,你看不到他。


6. 权限怎么处理

子 agent 需要执行删除文件、运行危险命令等操作时,权限提示怎么办?

取决于 permissionMode 设置:

模式 行为
bubble(Fork 默认) 权限提示冒泡到主终端,你在主终端批准
acceptEdits 自动允许文件操作
plan 只能规划不能执行,等你确认
bypassPermissions 全部自动批准
dontAsk 全部自动拒绝

bubble 是 Fork 的默认模式——子 agent 想做危险操作时,你的主终端会弹出权限请求。

源码中的决策逻辑(runAgent.ts):

const shouldAvoidPrompts = agentPermissionMode === 'bubble' ? false // bubble 模式:始终显示权限提示 : isAsync // 其他模式:后台 agent 自动避免提示

后台 agent 如果遇到需要审批的操作,会自动拒绝(因为你看不到)。想让后台 agent 自由操作,设置 permissionMode: acceptEditsbypassPermissions


7. 并行执行和实际上限

在一条消息中同时发起多个 Agent 调用,它们会并行执行

"帮我同时做三件事: 1. 用 Explore agent 调研 auth 模块 2. 用 Explore agent 调研 payment 模块 3. 用 Explore agent 调研 notification 模块"

模型会在一次回复中生成三个 Agent tool_use,三个子 agent 同时启动。

源码中没有硬编码的 MAX_WORKERS 限制。但实际约束:

  • API 并发请求数(取决于你的订阅/API key)
  • 本地内存和 CPU——每个 agent 是一个独立的查询循环
  • 远程 bridge 模式默认 32 个并发(SPAWN_SESSIONS_DEFAULT = 32

Anthropic 官方博客的实战建议:5-8 个并行 agent,每个负责 5-8 个文件

一个 agent 有约 167K tokens 的工作空间。5 个并行 agent = 835K tokens 的总工作空间。对于大规模重构,这是从"线性处理"到"并行处理"的质变。


8. Agent Teams:让多个 Agent 互相对话

前面讲的 subagent 都是"主 agent 派活 → 子 agent 干活 → 返回结果"的单向模式。子 agent 之间互相看不到,也不能交流。

Agent Teams 是另一种模式——多个 agent 组成团队,共享任务列表,互相发消息讨论

Subagent Agent Team
通信 只能向主 agent 汇报 队友之间直接消息
协调 主 agent 管理所有工作 共享任务列表,自协调
场景 只需要结果的聚焦任务 需要讨论和协作的复杂工作
Token 成本 较低 较高(每个队友独立 context)

一个实际例子——用竞争假设做调试:

用户反馈 app 在发一条消息后就退出了。 创建 5 个 agent 队友分别调查不同的假设。 让他们互相讨论、尝试推翻对方的理论,像科学辩论一样。 把共识写到 findings.md 里。

5 个 agent 独立调查各自的假设,然后互相质疑——"你说是 WebSocket 断开,但我查了连接日志没有断开记录,你的证据是什么?"这种对抗式调查比单 agent 线性排查更容易找到真正的根因。

目前是实验性功能,默认关闭。开启方式:

// settings.json { "env": { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" } }

架构组件:

  • Team lead——主会话,创建团队、分配任务、综合结果
  • Teammates——独立的 Claude Code 实例,各自有完整 context
  • Task list——共享任务列表,支持 pending/in_progress/completed 和依赖关系
  • Mailbox——agent 间的消息系统

显示模式两种:in-process(同一终端内,Shift+Down 切换队友)或 split panes(需要 tmux/iTerm2,每个队友独立窗格)。

几个限制:

  1. 一个 lead 只能管一个团队
  2. 队友不能再创建子团队
  3. session 恢复不支持 in-process 模式的队友
  4. 建议 3-5 个队友,每人 5-6 个任务

什么时候该用 Team 而不是 Subagent?当你需要队友之间互相讨论、质疑、协调时。如果只是"去干活然后告诉我结果",subagent 就够了,成本更低。

因篇幅限制,本文不在此处展开讲解,如需要,可以在评论区提一下,后面会单独开一篇


9. 实际怎么用

几个从源码设计意图推导出的使用模式:

大规模改动 → 并行 subagent + worktree

每个子 agent 在独立 worktree 里改自己那几个文件,互不干扰。完成后各自 commit,主 agent 汇总结果。这就是内置的 /batch skill 的底层原理。

需要验证 → 独立 subagent 做 review

实现完功能后,启动一个新 subagent 做 code review。为什么不用主 agent 自己 review?因为主 agent 在实现过程中形成了"这样是对的"的上下文偏见。独立 subagent 没有这个包袱,能更客观地审查。

长对话保持质量 → 拆成多个 agent 阶段

不要在一个 agent 里干到 context window 满。把任务拆成阶段:研究阶段用 Explore agent,规划阶段用 Plan agent,实现阶段用 General Purpose agent。每个阶段是独立的 context,不会互相污染。

快速搜索 → Explore agent

找文件、搜代码不需要启动重量级 agent。Explore 跑 Haiku,只读模式,不加载 CLAUDE.md,启动快、成本低。调用时可以指定 thoroughness 级别:quick(定向查找)、medium(平衡探索)、very thorough(全面分析)。

临时测试 → --agents CLI flag

不想创建文件,可以用 JSON 直接传临时 agent 定义,这个会话结束就消失:

claude --agents '{ "quick-reviewer": { "description": "快速代码审查", "prompt": "你是一个代码审查专家,只关注安全问题。", "tools": ["Read", "Grep", "Glob"], "model": "haiku" } }' 网友解答:


--【壹】--:

前排支持


--【贰】--:

前排学习,追更追更


--【叁】--:

干货啊,支持大佬


--【肆】--:

厉害厉害,学习了


--【伍】--:

真能学到东西,但太懒了不知道啥时候能学进去


--【陆】--:

Agent 中无法再生成subagent,这种有什么解么,有时候 skill接入上游的 pipline, 上游已经 spawn 成agent了,skill里的multi agent就被拍平了


--【柒】--:

太强了大佬,来学习一下


--【捌】--:

佬!入站的意义,全部都想起来了!


--【玖】--:

前排支持,学习!


--【拾】--:

学习了,基于源码的讲解,太透彻了


--【拾壹】--:

mark一下


--【拾贰】--:

题主这三篇帖子都认真看了,很有价值。感谢。


--【拾叁】--:

写的真棒,感谢佬的分享对日常使用有很大的帮助


--【拾肆】--:

已严肃学习并点赞佬的三个深入浅出教程 ,学到好多技巧,给上下文管理增加了很多方法学,也感叹A÷的技术和工程积累。
补充:

  • 哈雷佬的指南里提到这个网站可以参考
《 Claude Code 终极版 FAQ 指南 》

鉴于没有推进SubAgent的内容,这里给到一个集合网站给予参考

  • http://subagents.cc
  • 风佬的CCG自带几个agents在~/.claude/agents/ccg
    【补档】CCG v2.1.1 : Claude Code 编排三 CLI 协作 | Codex + Gemini + Claude | 加入多种实用skills

--【拾伍】--:

前排学习


--【拾陆】--:

点赞的人越来越少,充分说明了一件事,大部分人都是知识的搬运工,哈哈哈。

还是要写点自己的感悟供大家分享:

  1. 默认模式下,某些简单工作不用调用 agent,原文也指出了本身 agent 都是从空白开始工作,不如直接调用工具。
  2. 原来模型用量里面总是有 Haiku 是因为 Explore 默认用 Haiku,我还以为是设置问题。后续试试覆盖内置 Agent ,让 Explore 用 Sonnet 而不是 Haiku,不知道能否设置为 opus 4.6。
  3. 什么时候该用 Team 而不是 Subagent,这个其实蛮重要的,我记得我曾经看过 Claude 复刻 Linux 就是用了类似的模式吧,可见复杂任务还是需要这个功能的。
  4. 第九点实在是太重要了,解决了工作流程问题。

--【拾柒】--:

学习了,感谢佬的分享


--【拾捌】--:

支持支持


--【拾玖】--:

前排支持