Agent 架构文档 · Markdown
Claude Code Agent 架构全景讲解
版本 :基于 v2.1.88 实际源码(npm sourcemap 还原,1906 个 TS 文件)校准。 上一版本基于 2026 04 官方文档撰写;本版于 2026 05 15 用源码校准了模型路由、工具系统、 权限层、hook 事件、记忆压缩、多 agent 机制等关键章节,并补全了 v2.x 引入的新能力 (Agent Team / Coordina
版本:基于 v2.1.88 实际源码(npm sourcemap 还原,1906 个 TS 文件)校准。 上一版本基于 2026-04 官方文档撰写;本版于 2026-05-15 用源码校准了模型路由、工具系统、 权限层、hook 事件、记忆压缩、多 agent 机制等关键章节,并补全了 v2.x 引入的新能力 (Agent Team / Coordinator mode / Fork subagent / ScheduleCron / ToolSearch / Buddy / Direct Connect 等)。
2026-06-08 官方复核补丁:npm
@anthropic-ai/claude-code已到2.1.168, 官方文档新增并明确 Dynamic workflows 与 Routines。本文源码级结论仍以v2.1.88为证据边界;涉及 workflows/runtime/routines/ultracode时,以official-update-check-2026-06-08.md与官方 docs 为准。以 Agent 的生命脉络 为主线,讲清楚 Anthropic 官方 CLI agent —— Claude Code —— 是怎么把 一个语言模型包装成"会读你的代码、会动你的文件、会跑你的命令"的执行体。所有机制 (subagent / skill / slash-command / hook / MCP / CLAUDE.md / permission / context window) 都将从"它支撑了 Agent 的哪个能力"这个角度切入,而不是按官方 sidebar 罗列。
适合:跨 agent 平台对比时建立 Claude Code 的心智模型 / 想自建 agent 时拆它的设计 / 选型时 看清它跟 SDK / Anthropic API / Claude.ai 的边界。
#目录
- 写在前面:项目身份与核心矛盾 0.5. 一张图看懂:Claude Code = Model + Harness
- Agent 是什么 —— 配置即身份的"无中心 agent"
- Agent 怎么活起来 —— 一次调用的完整链路
- Agent 怎么思考 —— 主循环 / 子代理 / 并发团队
- Agent 怎么行动 —— 工具系统的形态
- Agent 怎么记忆 —— 五层记忆与上下文压缩
- Agent 怎么开口 —— 输出回路 / UI / Hook 改写
- Agent 的外脑 —— 模型路由与 effort 调度
- 关键设计权衡(架构师视角)
- 附录:组件地图、概念表与源码索引
#零、写在前面:项目身份与核心矛盾
#0.1 项目身份消歧
讲 "Claude Code" 时容易和几个东西混淆,先把边界划清:
| 名字 | 是什么 | 跟本文关系 |
|---|---|---|
| Claude Code(CLI / Desktop / VS Code / JetBrains / Web) | Anthropic 官方推出的 agentic coding tool:在终端、IDE、浏览器里读代码、改文件、跑命令 | 本文主角 |
| Claude Agent SDK(前身 Claude Code SDK) | TS / Python 库,把 Claude Code 的 agent loop / 工具 / 上下文管理封装成可编程接口 | 是 Claude Code 的"库化版本",本文章节 7、8 会提 |
| Anthropic API / Client SDK | 直连模型 API,需要自己实现 tool loop | Claude Code 是它上面叠的 agentic harness |
| Claude.ai / Claude Desktop(聊天产品) | 通用对话产品,不是 agent harness | 本文不展开 |
| Anthropic Console | 计费 / API key 管理后台 | 仅作为 Claude Code 的 auth provider 出现 |
引用自官方 overview:"Claude Code is an agentic coding tool that reads your codebase, edits files, runs commands, and integrates with your development tools. Available in your terminal, IDE, desktop app, and browser." (来源:https://code.claude.com/docs/en/overview)
#0.2 三个核心矛盾
理解 Claude Code 的设计选择,先认这三个核心矛盾。每章后面都会反复回到它们:
| 矛盾 | Claude Code 的回答 |
|---|---|
| Agent 想"什么都能干",但 200K~1M context 也会满 | 五层记忆 + on-demand 加载(skill 描述常驻、body 用时才进;MCP 工具 schema 默认 deferred;subagent 各开独立上下文) |
| agent 越自由越不安全,越安全越不好用 | 6 档 permission mode(外部 5 档 + 内部 auto)+ 六层 settings + hook 拦截器 三件套,把"管制"做成可调旋钮 |
| 多人 / 多机 / 多场景,每个人想要不同的 agent | "agent = 一份 markdown 配置" 的极致化:subagents / skills / commands / CLAUDE.md / hooks 全部是文件,按 user / project / managed 三层覆盖 |
#0.3 风格约定
- 中文解释,技术词保留英文原名(
subagent/skill/hook/slash command/MCP等不译) - 大量 ASCII 框图与对比表
- 每章引言为单行斜体引语点题
- 章节序号用零 / 一 / 二 / 三...
#零·五、一张图看懂:Claude Code = Model + Harness
业界视角:Anthropic / Cursor / Codex / Aider / Cline 用的是同一批底层模型, 实际表现差距却很大。差的不是模型,是"模型之上的外壳(Harness)"——指令、工具、 基础设施、可观测性这四层共同决定了 agent 的真实能力上限。
Claude Code 自己就是这套术语的提出方之一。它把"agent harness"做成显式产品概念: 模型负责"想",剩下所有让 LLM 真正有用的工程层(CLAUDE.md / skill / subagent / hook / MCP / permission / OTel)就是 harness。下文按"4 层 + 8 支柱"反向索引本文档每个章节。
#0.5.1 四层 Harness 结构
┌──────────────────────────────────────────────────────────────────────┐
│ Agent = Model (LLM) + Harness (本平台四层外壳) │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ ① 指令层 │ System prompt(~4.2K tokens,Anthropic 固定) → §5.1 │
│ │ CLAUDE.md 四 scope(managed/project/user/local)→ §5.2 │
│ │ subagent / skill frontmatter + body → §1.2/§1.3│
│ │ UserPromptSubmit / SessionStart hook 注入 → §2.2 │
├──────────────────────────────────────────────────────────────────────┤
│ ② 能力层 │ 内置工具:Read/Edit/Bash/Glob/Grep/Agent/Skill → §4.1 │
│ │ MCP server(http/sse/stdio,schema deferred) → §4.3 │
│ │ skill(描述常驻、body 用时进、可带脚本资源) → §1.3 │
│ │ subagent(独立 ctx 的子执行体)+ agent team → §3.2/§3.4│
├──────────────────────────────────────────────────────────────────────┤
│ ③ 基础设施│ permission 7 步分层(hook→工具静态→mode→rule→protect)→ §4.5│
│ │ Auto memory ~/.claude/projects/<x>/memory/ → §5.3 │
│ │ Worktree + checkpoints(ESC ESC 回滚) → §1.2/§8.4│
│ │ Settings 六层合并(plugin→user→project→local→flag→policy)→ §2.1│
│ │ Sandboxing + protected paths(.git/.claude/...)→ §4.5 │
│ │ 多 surface 运行时:CLI / IDE Bridge / Web / Remote / Direct Connect → §6.2│
├──────────────────────────────────────────────────────────────────────┤
│ ④ 可观测 │ Session JSONL 持久化 + `--resume` 复用 → §6.1 │
│ │ OTel hooks(27 事件 × 4 种 handler) → §4.4 │
│ │ Notification hook(permission/idle/auth) → §6.3 │
│ │ ⚠ cost transparency / Auto mode classifier 决策不可见 │
└──────────────────────────────────────────────────────────────────────┘
#0.5.2 八支柱对照表
| # | Harness 支柱 | 一句话定义 | Claude Code 的实现 | 对应章节 |
|---|---|---|---|---|
| 01 | FS + Git | state 必须活在 context 之外 | ~/.claude/ + <repo>/.claude/ 文件树承载 agent / skill / memory / settings;worktree 给 subagent 物理隔离 git 状态 |
§1.2 / §9.3 |
| 02 | Bash 通用工具 | "随用随装",避免 token 爆炸 | Bash 工具原生 + MCP --transport stdio/http/sse 接外部进程;MCP schema 默认 deferred,靠 ToolSearch 用时拉 |
§4.1 / §4.3 |
| 03 | 沙箱 + 子工具 | 行动可隔离 + 可自检 | --worktree 临时 git 工作树;subagent isolation: worktree;PostToolUse hook 跑 lint/test 把失败 exit 2 回灌;checkpoints ESC ESC 回滚 |
§1.2 / §4.4 |
| 04 | 记忆 + 搜索 | 跨 turn / 跨 project 拿历史 | 五层记忆:System / CLAUDE.md / Auto MEMORY.md / skill / subagent memory;session JSONL --resume;MEMORY.md topic 文件 on-demand 读 |
§5.1 / §5.3 |
| 05 | 对抗 Context Rot | 长对话也别糊 | auto-compact 三段式(清 tool output → 总结对话 → 报错停手);prompt cache 自动开;CLAUDE.md / 已 invoke skill 压缩后 re-inject | §5.4 / §7.5 |
| 06 | 长程执行 | 多 phase 任务不跑偏 | plan mode 限制工具集 + 强制先汇报;opusplan 别名 plan 用 opus、execute 切 sonnet;agent team mailbox 跨 session 协作;2026-06 官方新增 Dynamic workflows,把大规模 subagent 编排落成可保存/复跑的 JS orchestration script |
§3.1 / §3.4 / §3.8 |
| 07 | Hooks 强制层 | 失败转成永久规则 | 27 事件点 × 4 种 handler(command/http/prompt/agent,v2.1.88 无 mcp_tool);exit 2 强阻断;PreToolUse 决策 deny>ask>allow(v2.1.88 已删除 defer);disableAllHooks 给企业兜底 |
§4.4 / §6.4 |
| 08 | 规划 + 工具选择 | 别什么都试,先想再调 | plan mode 把"先 plan 再 execute"打进会话状态;description 字段让模型自己挑 subagent / skill;ENABLE_TOOL_SEARCH=auto 控制工具 schema 预算 |
§3.1 / §4.2 |
#0.5.3 当前架构的短板(按 Harness 视角看出来的)
Claude Code 是 harness 设计的标杆,但放到 4 层 8 支柱里仍能挑出几条结构性缺口:
- subagent 之间没有共享状态:普通 subagent 虽然可以再 spawn 后台 subagent(v2.1.88 已放开嵌套,见 §3.3),但子之间仍不能直接通信,要协作必须升级到 experimental 的 agent team(贵且仍在打磨)。这是 §3.3 / §3.4 的明牌限制——多子任务依赖时,"父 agent 把摘要再转述"成了唯一通道,信息有损且 token 重复。
- cost transparency 是个洞:8 支柱里"02 工具" + "04 记忆"两条都依赖于"我能看到这次决策花了多少 token",但 Claude Code 没有内置的 per-session / per-subagent / per-tool 成本看板。
--max-budget-usd是个总闸而非可观测面板,agent team 多 instance 并发跑时尤其抓瞎。 - Auto mode classifier 是黑盒:文档元信息里明确写了——auto 模式那个二级 classifier 模型跑在 server、决策不可见、3 连封会回退到 prompt,但用户既看不到分数也看不到拒绝原因。这违背了"权限要可解释"的 harness 原则。
- cross-session 持久记忆只到 project 维度:Auto MEMORY.md 是 per-project(按 git repo id 切目录),跨 project / 跨机器的"用户级长期记忆"靠手写
~/.claude/CLAUDE.md,没有"模型自动萃取的跨项目偏好"这一层(这反而是 Cursor 的 Memories 在做的事)。 - Skill / subagent / command / hook 四套扩展机制的边界文档化但概念仍重:§8.5 自己也承认要"两轴判断"才能选对,对新用户的认知负担不低。harness 强但学习曲线陡是它的一体两面。
短板里最值得后续补的,是可观测层的 cost / classifier 维度。当前 Claude Code 把"权限 / 工具 / 记忆"三层都做得很厚,但"看到自己花了什么、为什么被拦"这一层薄于设计水准——而这恰恰是 agent team 等并发模式规模化用起来的前提。
#一、Agent 是什么 —— 配置即身份的"无中心 agent"
在 Claude Code 里,"一个 agent" 不是一段服务代码,而是一份 markdown 文件 + 一个执行引擎; 你可以零代码定义 N 种 agent,差别只是 frontmatter 的几行字段。
#1.1 Claude Code 的"agent"是分层概念
跟传统 "一个进程 = 一个 agent" 不同,Claude Code 里"agent"这个词其实指三种不同的东西:
┌──────────────────────────────────────────────────────────────────┐
│ Claude Code 进程(agentic harness) │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 主 agent(main session) │ │
│ │ - 一份 system prompt(默认 / --append-system-prompt) │ │
│ │ - 一个 context window(200K / 1M 看模型) │ │
│ │ - 全套内置工具 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │
│ │ │ subagent A │ │ subagent B │ │ skill X │ │ │
│ │ │ Explore/Plan │ │ code-reviewer│ │ commit │ │ │
│ │ │ 独立 context │ │ 独立 context │ │ 复用主 ctx│ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ agent team(experimental,并行 sessions 协作) │ │
│ │ lead session ⇆ teammate session ⇆ teammate session │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
| 层级 | 名字 | 启动方式 | 上下文关系 | 何时用 |
|---|---|---|---|---|
| L1 | main agent / main session | claude 启动后即生效 |
自己持有顶层 context | 默认 |
| L2 | subagent(含 built-in 的 Explore/Plan/general-purpose) | 主 agent 调 Agent 工具,或 --agent 启动作为主线程 |
独立 context window,只把摘要回传 | 副任务(搜索/审查)不污染主对话 |
| L2 | skill | 用户输 /name 或主 agent 自行 invoke |
默认在主 context 内联;context: fork 时 fork 到 subagent |
重复 playbook、长 reference 资料 |
| L3 | agent team teammate(experimental) | 主 session 通过 TeamCreate 工具拉起 |
每个 teammate 是完全独立的 Claude Code 实例,通过 mailbox 直接互聊 | 真正并行、需要互相挑战的任务 |
来源:https://code.claude.com/docs/en/sub-agents、https://code.claude.com/docs/en/agent-teams、https://code.claude.com/docs/en/skills
#1.2 一个 subagent 长什么样
最小的"自定义 agent"就是一个带 frontmatter 的 markdown 文件:
---
name: code-reviewer
description: Reviews code for quality and best practices. Use proactively after code changes.
tools: Read, Glob, Grep
model: sonnet
---
You are a code reviewer. When invoked, analyze the code and provide
specific, actionable feedback on quality, security, and best practices.
放在以下任一位置即生效(v2.1.88 优先级:policy(managed)> --agents CLI flag > local(settings.local.json)> project(.claude/agents/)> user(~/.claude/agents/)> plugin > built-in,源码 tools/AgentTool/loadAgentsDir.ts):
~/.claude/agents/code-reviewer.md ← 个人级,所有项目可见
<repo>/.claude/agents/code-reviewer.md ← 项目级,跟代码一起进 git
frontmatter 全集(来源:sub-agents 文档):
| 字段 | 用途 |
|---|---|
name / description |
必填;description 是 "什么时候 spawn 它" 的判定文本 |
tools / disallowedTools |
工具白 / 黑名单;前者覆盖式,后者扣减式 |
model |
sonnet / opus / haiku / 全模型 ID / inherit,默认 inherit |
permissionMode |
default / acceptEdits / dontAsk / bypassPermissions / plan(外部 5 档;auto 是 Anthropic 内部 mode,受 TRANSCRIPT_CLASSIFIER feature 门控,外部 settings.json 不可配置;bubble 是内部传递语义) |
maxTurns |
自动停机阈值 |
skills |
启动时全文注入(不是 invoke 接口)的 skill 列表 |
mcpServers |
仅这个 subagent 看到的 MCP server,可内联或引用名字 |
hooks |
局部 hook,PreToolUse / PostToolUse 等 |
memory |
user / project / local,开启跨 session 持久笔记 |
effort |
low/medium/high/max(v2.1.88 仅 4 档,无 xhigh),覆盖会话级 effort |
isolation |
worktree(独立 git worktree,无变更自动清理)/ remote(Ant 内部 CCR 容器,外部不可用) |
background: true |
总是在后台跑(spawn 立即返回 agentId/outputFile,模型靠 <task-notification> 收完成) |
color |
UI 显色 |
initialPrompt |
作为主线程时,第一条用户输入自动追加 |
omitClaudeMd: true |
v2.1.88 新增:built-in Explore/Plan 用此节省 token,不注入 CLAUDE.md 链 |
#1.3 一个 skill 长什么样
跟 subagent 极像,但语义不同:
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
allowed-tools: Bash(git push *) Bash(npm run build *)
context: fork # 可选:在 forked subagent 里跑
agent: Explore # 配合 context:fork 选执行体
---
Deploy $ARGUMENTS to production:
1. Run the test suite
2. Build the application
3. Push to the deployment target
skill 跟 subagent 的关键差异:
subagent (.claude/agents/*.md) |
skill (.claude/skills/<name>/SKILL.md) |
|
|---|---|---|
| 是什么 | 一个会自己开 context 的小 agent | 一段插进对话的 playbook(默认在主 ctx) |
| 触发 | 主 agent 通过 Agent 工具自动 spawn |
用户 /name 主动唤起,或主 agent 模型 invoke |
| 内容生命周期 | 一次调用、回传摘要 | 渲染后作为一条消息常驻在 session,auto-compact 后还会被 re-attach(前 5K tokens / 总 25K 预算) |
| 是否可带脚本 / 资源 | 否(仅一个 .md) | 是(同目录可放 reference / examples / scripts) |
| 用户能不能直接喊 | 否 | 是(disable-model-invocation: true 关掉自动) |
| 文件格式 | name.md |
一个目录 + SKILL.md |
注:官方明说 "Custom commands have been merged into skills."
.claude/commands/*.md仍可工作,但.claude/skills/<name>/SKILL.md是新做法(来源:skills 文档)。
#1.4 Built-in subagent 全集(v2.1.88,源码 tools/AgentTool/builtInAgents.ts)
| Built-in agent | 模型 | 工具集 | 用途 | 门控 |
|---|---|---|---|---|
| general-purpose | inherit | 全工具 | 复杂多步任务(探索+修改) | 默认启用 |
| statusline-setup | Sonnet | 精简 | 配置状态栏 | 默认启用 |
| Claude Code Guide | Haiku | 只读 | 回答关于 Claude Code 自身的问题 | 非 SDK entrypoint 自动加 |
| Explore | haiku(外部)/ inherit(Ant) | 只读(Read/Glob/Grep/LSP,禁 Agent/Edit/Write/NotebookEdit),omitClaudeMd=true |
快速代码库探索 | feature BUILTIN_EXPLORE_PLAN_AGENTS + GrowthBook tengu_amber_stoat |
| Plan | inherit | 同 Explore(只读 + omitClaudeMd) | 软件架构规划,输出实现步骤 | 同 Explore |
| verification | inherit | 全工具(含 WebFetch),background: true |
实现后验证,产出 VERDICT: PASS / FAIL / PARTIAL |
feature VERIFICATION_AGENT + GrowthBook tengu_hive_evidence |
#1.5 三个核心矛盾的回应
- "什么都能干 vs context 有限":把"agent 身份"碎片化成 subagent / skill / command,按需加载。description 始终在主 ctx 让模型决定要不要展开 body。
- "自由 vs 安全":每个 agent 可以独立设
tools/permissionMode/hooks,安全策略跟身份绑定而不是绑全局。 - "个性化":因为 agent = markdown 文件,所以可以放 user / project / local / managed / plugin 多个层级;同名时按 §1.2 的优先级解析(policy >
--agentsflag > local > project > user > plugin > built-in)。
#二、Agent 怎么活起来 —— 一次调用的完整链路
从你敲一行
claude "fix the auth bug"到屏幕第一个 token 流出来,发生了什么。
#2.1 启动序列
你敲:claude "fix the auth bug"
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ 1. CLI bootstrap │
│ - 解析 flag(--model / --permission-mode / --add-dir / --agent...)│
│ - auth:claude.ai 订阅登录 / Console API key / Bedrock / Vertex │
│ - 决定 binary 路径(native install / brew / SDK 内置) │
└────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ 2. settings 合并(v2.1.88,precedence 低 → 高,源码 settings.ts:674) │
│ plugin base (bundled plugin 的默认值,最低) │
│ → user (~/.claude/settings.json) │
│ → project (.claude/settings.json,跟代码进 git) │
│ → local (.claude/settings.local.json,gitignored) │
│ → flag (--settings CLI flag 传入的文件或内联 JSON) │
│ → policy (最高,enterprise 管控;内部优先级: │
│ remote API > HKLM/plist MDM > managed-settings.json │
│ > HKCU 注册表) │
│ 标量:高覆盖低;数组:去重合并 │
└────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ 3. instruction 加载(startup 阶段就进 context window) │
│ - System prompt(约 4.2K tokens,固定) │
│ - Auto memory: ~/.claude/projects/<proj>/memory/MEMORY.md │
│ (前 200 行 / 25KB,先到为准) │
│ - Environment info(cwd / platform / shell / git status) │
│ - CLAUDE.md 链:从 cwd 沿目录树向上找,每层的 CLAUDE.md + │
│ CLAUDE.local.md 全部 concat 进来;@import 最深递归 5 层 │
│ - .claude/rules/*.md(无 `paths` unconditional 启动加载;带 `paths` │
│ conditional 在工具调用路径上按需评估,源码 `claudemd.ts`) │
│ - skill 描述清单(不是 body,body 用时才展开) │
│ - MCP tool 名清单(默认 deferred;schema 用时才 fetch) │
└────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ 4. 第一条用户消息塞进去 │
│ "fix the auth bug" ← UserPromptSubmit hook 在此触发 │
└────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ 5. 进入 agentic loop(见第三章) │
└────────────────────────────────────────────────────────────────────┘
#2.2 一次工具调用的回路
模型决定:我要 Edit src/auth.ts
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PreToolUse hook(settings.json hooks.PreToolUse[]) │
│ - matcher 匹配 "Edit" │
│ - if 字段二次过滤(如 Edit(*.ts)) │
│ - command / http / prompt / agent 四种 handler │
│ (v2.1.88 源码 schemas/hooks.ts,**无 mcp_tool**) │
│ - 输出 hookSpecificOutput.permissionDecision │
│ = allow | deny | ask(v2.1.88 已无 defer) │
└─────────────────────────────────────────────────────────────┘
│
▼ permission rules(不被 hook 短路)
┌─────────────────────────────────────────────────────────────┐
│ permission rule 评估:deny → ask → allow,先匹配先赢 │
│ 当前 mode:default / acceptEdits / plan / auto / dontAsk / │
│ bypassPermissions │
│ + protected paths 永远拦截(.git/.claude/.vscode/.idea/.husky)│
└─────────────────────────────────────────────────────────────┘
│
▼ 允许通过 → 真正执行
┌─────────────────────────────────────────────────────────────┐
│ Tool execution │
│ - Bash:runtime 单独进程(cd 在主 session 持久,env 不持久) │
│ - Edit:先 snapshot 老内容(→ checkpoint,可 ESC ESC 回滚) │
│ - WebFetch:domain 白名单 │
│ - Skill / Agent:进入子环境(见第三、四章) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PostToolUse hook(成功)/ PostToolUseFailure(失败) │
│ - 可 decision: "block" 把结果毙掉、给模型反馈 │
│ - 常用于 lint / format / 二次校验 │
└─────────────────────────────────────────────────────────────┘
│
▼
工具结果回灌进 conversation(注意:auto mode 下结果会被 server-side
probe 扫一遍 prompt injection;classifier 拿不到 tool result 全文)
#2.3 一次 turn 结束
模型说 "done"(不再要工具)
│
▼
Stop hook(可 decision: "block" 强制让 agent 继续)
│
▼
等下一条 user input
#2.4 三个核心矛盾的回应
- "context 有限":MCP schema 默认 deferred、skill body 不预加载;
--exclude-dynamic-system-prompt-sections把 cwd / git 等机器特定段移出 system prompt 提高 prompt cache 命中率。 - "自由 vs 安全":每次工具调用都过
hook → rule → mode三道闸;checkpoints 把"撤销"做成本地默认能力(ESC ESC回滚到任一文件改前快照)。 - "个性化":startup 阶段的
--append-system-prompt/--system-prompt/ settingsenv/ hook 注入additionalContext,多个层都可以塞自己的 system 段。
#三、Agent 怎么思考 —— 主循环 / 子代理 / 并发团队
Claude Code 的"思考"是三种不同尺度的循环嵌起来:单 agent 内的 ReAct、单 session 内的 subagent fan-out、跨 session 的 agent team mailbox。
#3.1 单 agent 主循环:gather → act → verify
官方 how-claude-code-works 文档把它画成三段式:
┌─────────────────┐
┌────│ gather context │◀─────┐
│ └─────────────────┘ │
│ │ │
▼ ▼ │
user prompt → take action ───────┤ (chains dozens of steps,
│ │ 自我纠偏,直到 done 或被打断)
▼ │
┌─────────────────┐ │
│ verify results │──────┘
└─────────────────┘
每一步都是一次工具调用,结果回灌后模型决定下一步。这是经典 ReAct,没有专门的 planner / executor 拆分。
唯一例外是 plan mode:cycle 到 plan 模式后,模型只能用只读工具,先产出一份 plan,等用户批准再 execute。Plan mode 本质是一个"主 agent 切换 toolbox + 强制先汇报"的 hack。
#3.2 主 agent 怎么调 subagent —— 三条路径(v2.1.88)
Agent 工具(旧别名 Task 仍保留,源码 tools/AgentTool/constants.ts:1-3)按参数分三种调用路径:
路径 A:普通 subagent(指定 subagent_type)
Agent({ description, prompt, subagent_type: "researcher" })
subagent 拿到的不是主 ctx 历史,而是它自己的 system prompt(agentType 的 .md body)+ 环境信息 + CLAUDE.md。结果以 tool_result 同步返回;run_in_background: true 时改为异步 <task-notification>。
路径 B:Fork subagent(省略 subagent_type,需 FORK_SUBAGENT feature gate)
Agent({ description, prompt, name: "audit-worker" })
Fork child 继承父 agent 完整对话历史和 system prompt(字节级相同,最大化 prompt cache 命中),强制异步。FORK_BOILERPLATE_TAG 注入独立 directive;fork child 内部检测后禁止再 fork(递归防护)。与 Coordinator mode 互斥。
路径 C:Teammate spawn(同时传 name + team_name,需 isAgentSwarmsEnabled())
Agent({ description, prompt, name: "alice", team_name: "my-team", subagent_type: "researcher" })
生成独立进程/线程的 teammate(见 §3.4),加入 team 名册,可被 SendMessage 点名互通。
执行时 subagent ctx 组成(路径 A):
subagent system prompt = 它自己 .md body
+ 环境信息(cwd / platform)
+ skills 字段里列出的 skill 全文(preload,跟普通 session 不同)
+ CLAUDE.md(按 cwd 沿目录树向上找;built-in Explore/Plan 设 omitClaudeMd=true 跳过)
subagent first user message = 主 agent 写的 prompt
回到主 agent 的:
- 路径 A 普通 subagent → tool_result(同步)或
<task-notification>(async)摘要 - 路径 B fork → 强制
<task-notification>user-role 消息 - 路径 C teammate →
<task-notification>通知 + Mailbox 消息流
过程中读了多少文件、跑了多少命令都不会污染主 context,这是它压缩 context 的核心。
主 agent ctx subagent ctx
┌──────────────┐ ┌──────────────┐
│ user msg │ │ system = │
│ ... │ Agent │ subagent.md │
│ tool: Agent │──────────▶│ user = task │
│ (subagent) │ │ ... 几十轮 │
│ tool result: │◀──────────│ tool calls │
│ "找到3处bug"│ │ result msg │
└──────────────┘ └──────────────┘
▲ 只回这一行 这一坨全部丢弃
#3.3 嵌套限制(v2.1.88 精细化)
旧文档"subagent 不能再 spawn subagent"已不准确,v2.1.88 把限制细化为三条:
- 普通 subagent 可以 spawn subagent(异步后台),无强制阻断
- Fork child 检测到
FORK_BOILERPLATE_TAG(isInForkChild())→ 不能再 fork - Teammate(
isTeammate() && teamName && name)→ 不能再 spawn teammate - In-process teammate → 不能 spawn 后台 agent(受 AsyncLocalStorage 隔离限制)
绕路同前:用 tools: Agent(worker, researcher) 限制可 spawn 的 agentType。
#3.4 真正并行:agent teams(experimental)
subagent 是"主→子"单向的 fan-out,子之间不能通信。如果要多个 agent 互相讨论 / 挑战 / 分工,要开 agent teams:
- 环境变量
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 - 或 CLI flag
--agent-teams - GrowthBook killswitch
tengu_amber_flint(默认开,A/B 可关) - Ant 内部用户无条件开启
┌────────────────────────────┐
│ Team Lead session │
│ - 创建 team │
│ - spawn teammates │
│ - 综合结论 │
└─────┬───────────┬─────────┘
│ │
┌──────────┘ └──────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Teammate A │ │ Teammate B │
│ 完整独立 Claude Code │◀───mailbox──▶│ 完整独立 Claude Code │
│ session │ │ session │
│ 自己 ctx / 自己 model │ │ 自己 ctx / 自己 model │
└──────────────────────┘ └──────────────────────┘
▲ ▲
└──────────共享 task list──────────┘
(文件锁,避免抢任务)
| 维度 | 普通 subagent | Fork subagent | Agent team teammate | Coordinator worker |
|---|---|---|---|---|
| 触发 | subagent_type 指定 |
省略 subagent_type(fork gate on) |
name + team_name |
Coordinator 模式下 spawn |
| 初始 ctx | 自己 system prompt | 继承父完整历史 | 自己 system prompt | 自己 system prompt |
| 通信 | tool_result → 主 agent | 异步 <task-notification> |
SendMessage 双向 + 广播 + 结构化协议 | <task-notification> 到 coordinator |
| 嵌套 | 可(异步后台 spawn 子 subagent) | 不可(递归防护) | Teammate 不能再 spawn teammate;in-process teammate 也不能 spawn 后台 agent | 不直接嵌套;通过 SendMessage 复用已存在 worker ctx |
| 落盘 | outputFile 磁盘追踪 |
同上 | ~/.claude/teams/{sanitized}/config.json + ~/.claude/tasks/{sanitized}/ |
outputFile |
| Gate | 无 | FORK_SUBAGENT |
EXPERIMENTAL_AGENT_TEAMS=1 或 --agent-teams |
CLAUDE_CODE_COORDINATOR_MODE=1 |
| 适合 | 副任务一次性 | 并行分叉研究/实现 | 持续协作、共享 task list | research→implement→verify 流水线 |
team config 与 task list 的 {name} 是 sanitizeName() 后的结果;session 结束自动 cleanup(除非 TeamDelete 显式删除)。禁止手编 config,会被运行时覆盖。
SendMessage 工具支持 to: "*" 广播、to: "uds:<socket>" 本地 IPC、to: "bridge:<session-id>" 跨机 Remote Control 会话;结构化消息类型:shutdown_request/shutdown_response、plan_approval_response。对已停止的 agent 发 SendMessage 会自动 resume。
#3.5 Teammate 后端模式(v2.1.88 三种)
agent team 后端类型(源码 utils/swarm/backends/types.ts:5-9):
| 后端 | 触发 | 体验 |
|---|---|---|
tmux |
检测到 tmux 环境 | tmux split pane,每 teammate 独立终端 |
iterm2 |
macOS iTerm2 | iTerm2 原生 split panes(via it2 CLI) |
in-process |
非交互式 session、pane backend 不可用时降级 | 同一 Node.js 进程内用 AsyncLocalStorage 隔离;Shift+Down 在 lead 终端轮播 |
可强制 --teammate-mode in-process / tmux。
#3.6 Coordinator 模式(v2.1.88 新增,旧文档未提)
CLAUDE_CODE_COORDINATOR_MODE=1 时主 agent 切换为 coordinator 角色,拥有专属 system prompt(coordinator/coordinatorMode.ts:111-369):
- 工具集裁剪:
Agent + SendMessage + TaskStop + subscribe_pr_activity,禁用 shell 与文件写 - 工作流强制四阶段:Research → Synthesis → Implementation → Verification
- 所有 Agent spawn 强制异步,结果以
<task-notification>user-role 消息返回 - 通过
SendMessage({to: agentId})继续已有 worker 的上下文(避免重启 ctx) - 与 Fork subagent 互斥
#3.7 跟"显式 plan + execute"风格比
Claude Code 里没有 planner / executor 拆分服务(不像有些 agent 平台)。所有"分阶段"都是同一个模型在同一 session 里通过:
- plan mode:限制工具集
- opusplan model alias:plan 用 opus、execute 自动切 sonnet
- plan approval for teammates:lead 让 teammate 先在 plan mode 提方案再批准
来达成。优势是简单,劣势是 plan / execute 的"persona 切换" 完全靠 prompt + 工具集,没有结构化的状态机保证。
#3.8 Dynamic workflows(2026-06 官方新增)
官方文档已把 Dynamic workflows 定义成 Claude Code 的新编排层:Claude 会写一段
JavaScript orchestration script,由 workflow runtime 在后台执行,脚本可以批量创建、
协调、汇总几十到上百个 subagents。用户侧能用 /workflows 查看、暂停、恢复、保存;
保存后可放在 .claude/workflows/ 或 ~/.claude/workflows/ 作为可复用命令运行。
它跟前面三种并行机制的边界:
| 机制 | 本质 | 适合任务 |
|---|---|---|
| 普通 subagent | 主 agent 临时 fan-out,摘要回主 ctx | 小范围搜索、审查、并行读文件 |
| agent team | 多个 Claude Code session 通过 mailbox 互相发消息 | 需要互相挑战 / 分工讨论 |
| Coordinator mode | 特定 system prompt + 工具裁剪的四阶段协调 | 受控的软件工程流程 |
| Dynamic workflow | Claude 写出的 JS 编排脚本 + 后台 runtime | 大规模、可复跑、可保存的 agent orchestration |
触发方式按官方文档:自然语言可要求 "use a workflow",ultracode 会触发自动 workflow
planning,/deep-research 是内置 workflow。/effort ultracode = xhigh 推理强度 +
自动 workflow 编排。运行约束包括最多 16 个并发 agent、单次 workflow 最多 1,000 个
agent;workflow 脚本本身不直接读写文件或跑 shell,具体行动仍由子 agent 完成。
版本边界:v2.1.88 源码走读时本文没有覆盖 workflow runtime。
ScheduleCron是 定时触发器,Dynamic workflows 是编排脚本,两者不能互相替代。
#3.9 定时触发:ScheduleCron(v2.1.88 新增)
KAIROS feature gate 开启时,agent 可注册定时任务:
CronCreate({ cron: "0 9 * * 1-5", prompt: "检查 CI 状态", recurring: true, durable: false })
| 参数 | 行为 |
|---|---|
recurring: true(默认) |
每次匹配触发,自动 90 天过期 |
recurring: false |
下次匹配触发一次后自动删除("remind me at X") |
durable: true |
持久化到 .claude/scheduled_tasks.json,Claude 重启后继续有效 |
durable: false(默认) |
仅 session 内存,Claude 退出即消失 |
约束:最多 50 个 job;teammate 不能创建 durable cron(不跨 session 存活)。触发时 prompt 注入主 agent 消息队列,像用户消息一样驱动下一轮 agentic 循环。源码 tools/ScheduleCronTool/CronCreateTool.ts:27-157。
RemoteTrigger 工具(feature AGENT_TRIGGERS_REMOTE)则用于注册远端触发器(webhook 等)。
2026-06 官方 docs 里的 Routines 是另一层:它运行在 Anthropic-managed cloud
infrastructure,可以按 schedule / API / GitHub event 触发完整 Claude Code cloud session。
因此本文的 ScheduleCron 应理解为 v2.1.88 源码里看到的本地/session 触发器;生产级
无人值守重复任务,以 Routines 官方文档为准。
#3.10 三个核心矛盾的回应
- "context 有限":subagent 是"压缩器"——把脏活在子 ctx 干完只回摘要。
- "自由 vs 安全":plan mode 强制 read-only;auto mode 在 subagent 启动时、执行中、结束后三次过 classifier。
- "个性化":既支持低成本的 subagent 干活回执,也支持高成本但能讨论的 agent team;用户按规模选。
#四、Agent 怎么行动 —— 工具系统的形态
Claude Code 的"工具"不是单一概念,而是 5 类内置 + MCP + skill + hook 注入,外加一套 permission 系统贯穿全部。
#4.1 内置工具一览(v2.1.88 源码 tools.ts:193-251,46 个工具槽位)
注:46 = 注册表中的工具名条目(含同一实现的别名 / feature-gated 变体);
tools/子目录数 43,差额来自 alias(如Task↔Agent、Brief↔SendUserMessage)与并存的不同 feature 包装层。
按用途分组(斜体 = shouldDefer: true,ToolSearch 开启时不占初始 ctx):
| 组别 | 工具 | 是否要 permission |
|---|---|---|
| 文件读写 | Read Write Edit NotebookEdit |
Write/Edit/NotebookEdit 要 |
| 搜索 | Glob Grep LSP(需 ENABLE_LSP_TOOL=true) |
否 |
| 执行 | Bash PowerShell(isPowerShellToolEnabled() 控制)REPL(ant 专属,透明包装)Sleep(需 PROACTIVE/KAIROS)MonitorTool(需 MONITOR_TOOL) |
Bash/PowerShell 要 |
| 网络 | WebFetch WebSearch |
是 |
| 会话/Plan | Agent(spawn subagent,旧别名 Task)Skill(执行 skill)EnterPlanMode ExitPlanMode EnterWorktree ExitWorktree(subagent 不可用 PlanMode) |
Skill 要 |
| 任务系统 | TaskCreate TaskGet TaskList TaskUpdate TaskOutput TaskStop TodoWrite(仅 -p;前 4 个需 isTodoV2Enabled() 且仅 in-process teammate) |
否 |
| 调度 | CronCreate CronDelete CronList(需 AGENT_TRIGGERS;durable:true 持久化到 .claude/scheduled_tasks.json)RemoteTrigger(需 AGENT_TRIGGERS_REMOTE) |
否 |
| MCP | ListMcpResourcesTool ReadMcpResourceTool mcp__<server>__<tool>(默认全 deferred,除非 _meta['anthropic/alwaysLoad']=true)mcp__<server>__authenticate(OAuth 触发动态生成) |
跟 MCP server 一致 |
| 用户交互/发现 | AskUserQuestion(subagent 禁用)ToolSearch(自身不 deferred,发现并加载其他 deferred 工具)SendUserMessage(别名 Brief,subagent 向用户通知) |
否 |
| Team(experimental) | TeamCreate TeamDelete SendMessage(始终注册) |
否 |
| 结构化输出/内部 | SyntheticOutput(coordinator 返回 JSON 结果)Config(ant 专属)WorkflowTool(需 WORKFLOW_SCRIPTS)VerifyPlanExecution TestingPermission |
— |
工具名是字符串字面量,permission rule / hook matcher / subagent tools 字段全部用同一字符串:
Bash # 整个 Bash 工具
Bash(npm run *) # 通配特定命令
Bash(rm -rf *) # 通配特定危险命令
Read # 整个 Read 工具
Read(./.env) # 特定文件
Read(~/.zshrc) # 家目录
Read(//tmp/*) # 双斜杠 = 绝对路径
Edit(/src/**/*.ts) # 项目相对(注意只有一个 / 是项目相对,不是绝对!)
WebFetch(domain:github.com)
mcp__puppeteer # 整个 MCP server
mcp__puppeteer__navigate # 单个 MCP tool
Agent(Explore) # subagent 命名
Skill(commit) # skill 命名
#4.2 三种"工具"扩展方式对比
Claude Code 工具来源
┌───────────────────────┬───────────────────────┬───────────────────────┐
│ 内置工具 │ MCP server │ skill │
├───────────────────────┼───────────────────────┼───────────────────────┤
│ Read/Write/Edit/Bash...│ stdio / SSE / HTTP │ markdown 文件 │
│ binary 自带 │ 外部进程或远程 endpoint │ 不是工具,是 prompt 包 │
│ │ 工具走 mcp__server__ │ 通过 Skill 工具触发 │
│ │ tool_name 命名 │ │
├───────────────────────┼───────────────────────┼───────────────────────┤
│ 性能:原生快 │ 启动有 init 成本 │ 几乎零成本(描述常驻) │
│ 信任:Anthropic 写 │ 第三方,需谨慎 │ 用户自己写,可控 │
│ 范围:所有 session │ 按 scope(user/project │ 同 skill 多 scope │
│ │ /local)配置 │ │
└───────────────────────┴───────────────────────┴───────────────────────┘
什么时候用什么:
- 想加确定性逻辑(脚本、调用 API):写 skill,里面用
!bash 注入或者${CLAUDE_SKILL_DIR}/scripts/*` 调脚本。 - 想接第三方系统(Notion / Jira / Postgres):用 MCP server。
- 想做新原子能力(不是组合现有的):只能 fork Claude Code 或者 fork Agent SDK 用法。
#4.3 MCP 接入(最常被问的部分)
三种 transport:
# HTTP(推荐,云服务)
claude mcp add --transport http notion https://mcp.notion.com/mcp
claude mcp add --transport http secure-api https://api.x.com/mcp \
--header "Authorization: Bearer $TOKEN"
# SSE(已 deprecated,能用 http 优先用)
claude mcp add --transport sse asana https://mcp.asana.com/sse
# stdio(本地进程)
claude mcp add --transport stdio --env API_KEY=xxx airtable \
-- npx -y airtable-mcp-server
scope(高 → 低):local(仅当前 project local 文件) / project(.mcp.json,进 git)/ user(跨项目)。
managed 场景下还有:
allowManagedMcpServersOnly: true:仅 managed settings 里的 server 可用deniedMcpServers:黑名单跨层合并
Deferred 工具机制(v2.1.88,旧文档逻辑反了):
默认(不设 ENABLE_TOOL_SEARCH):所有 MCP 工具和 28 个 shouldDefer: true 内置工具以 defer_loading: true 发到 API,初始 ctx 只见名字,schema 按需由 ToolSearch 拉取。
ENABLE_TOOL_SEARCH |
模式 | 行为 |
|---|---|---|
不设 / true |
tst |
总是 defer(默认) |
auto / auto:N |
tst-auto |
MCP 工具描述超过 ctx 的 N%(默认 10%)才 defer |
false |
standard |
全部内联(最大兼容性) |
ToolSearch 查询语法:
select:<name>直选,逗号多选(如select:WebFetch,WebSearch)- 关键词搜索:按工具名(CamelCase 拆分)+ description + searchHint 加权评分
返回 tool_reference beta blocks(API 在模型侧展开为完整 schema)。第三方代理不支持时设 false 回退;或 CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=true 强制禁用所有 beta shapes。MCP 工具的 _meta['anthropic/alwaysLoad']=true 可使该工具永不 deferred。
#4.4 hook:在工具调用周围塞钩子
hook 是 Claude Code 最被低估的扩展点。它是用户定义的 shell command / HTTP / prompt / agent,挂在 27 种事件上(v2.1.88 源码 entrypoints/sdk/coreTypes.ts:25-53,旧文档曾列虚构事件 PostToolBatch/UserPromptExpansion,已删除):
| Cadence | 事件 | 可阻断 |
|---|---|---|
| Session | SessionStart SessionEnd PreCompact PostCompact InstructionsLoaded ConfigChange Setup |
PreCompact 可 |
| Turn | UserPromptSubmit Stop StopFailure TeammateIdle |
UserPromptSubmit / Stop 可 |
| Tool | PreToolUse PermissionRequest PermissionDenied PostToolUse PostToolUseFailure SubagentStart SubagentStop TaskCreated TaskCompleted WorktreeCreate WorktreeRemove Elicitation ElicitationResult |
PreToolUse/PermissionRequest/PostToolUse/Elicitation 可;WorktreeCreate 任何非零 exit 都阻断;其余 Post* 不阻断 |
| Async | CwdChanged FileChanged Notification |
否 |
事件总数:Session 7 + Turn 4 + Tool 13 + Async 3 = 27,与正文一致。
handler 类型 4 种(v2.1.88 源码 schemas/hooks.ts,旧文档 mcp_tool 不存在):
{ "type": "command", "command": "./scripts/check.sh", "timeout": 600 }
{ "type": "http", "url": "http://localhost:8080/hook" }
{ "type": "prompt", "prompt": "Should this be allowed? $ARGUMENTS",
"model": "claude-3-5-sonnet-20241022" }
{ "type": "agent", "prompt": "Verify safety: $ARGUMENTS" }
command:本地 shell 进程;stdin 收 JSON 事件,stdout 返回 JSON 决策;exit 2 阻断http:POST JSON 到 endpoint,按 HTTP 状态码 / 响应 JSON 决策;适合企业集中审计 / 跨机判断prompt:直接调指定 LLM(默认会话 model)做轻量判断;handler 自己不持有工具,只生成 yes/no/reasonagent:spawn 一个临时 subagent 跑判断流程,可调工具(如读 PR diff),比prompt重但能多步推理
阻断协议(关键且反直觉):
- exit
0= 成功 - exit
2= blocking error(会阻止动作,stderr 给到模型) - 其他 = 非阻断(注意 exit 1 也是非阻断,跟 Unix 习惯不一样)
- 例外:
WorktreeCreate,任何非零都 fail
PreToolUse 决策 3 档:allow(跳过 prompt)/ deny(不让做)/ ask(强制问)。冲突优先级:deny > ask > allow。
v2.1.88 修订:旧文档"4 档含
defer" 已不准确——defer不在types/permissions.ts:PermissionBehavior类型里。PermissionRequesthook 在权限弹窗前触发,可比 PreToolUse 更细粒度返回决策。
典型用法:
- 提交前自动 lint:
PostToolUsematcherEdit|Write→ 跑prettier --write - 阻止删根目录:
PreToolUsematcherBashifBash(rm -rf *)→ exit 2 - 桌面通知:
Notificationmatcheridle_prompt→osascript ...
#4.5 三个核心矛盾的回应
- "context 有限":MCP schema deferred;ToolSearch on-demand;hook 是外置进程,不占 ctx。
- "自由 vs 安全":permission rule 用同一字符串管所有工具来源(内置 / MCP / skill / agent);hook 可在调用前后做任意校验;protected paths(
.git/.claude/.vscode/.idea/.husky+.gitconfig/.mcp.json等)永远拦写。 - "个性化":subagent / skill 的
allowed-tools是"在该上下文内免审批",不是"额外权限",跟主 permission 规则共生而非冲突。
#五、Agent 怎么记忆 —— 五层记忆与上下文压缩
Claude Code 的"记忆"是个被严格分层的系统。每一层有谁写、什么时候加载、占多少 ctx,都是文档化的。
#5.1 五层记忆全景
写者 加载时机 进入 context 大小
┌──────────────────────────────┬─────────┬──────────────────────┬─────────────────┐
│ 1. System prompt │ Anthropic│ 启动 │ ~4.2K tokens │
│ (tool 调用规约 / 行为规则) │ 固定 │ │ 不可见 │
├──────────────────────────────┼─────────┼──────────────────────┼─────────────────┤
│ 2. CLAUDE.md 链 │ 你 │ 启动 + cwd 沿目录树 │ 全文(建议<200行)│
│ project / user / managed │ │ 向上递归 │ │
│ + .claude/rules/*.md │ │ + paths 字段 lazy │ │
│ + @import(最深 5 层) │ │ │ │
├──────────────────────────────┼─────────┼──────────────────────┼─────────────────┤
│ 3. Auto memory (MEMORY.md) │ Claude │ 启动 │ 前 200 行 / 25KB │
│ ~/.claude/projects/<x>/ │ 自己写 │ │ 先到为准 │
│ memory/MEMORY.md │ │ │ │
│ (每个 project 一份;同 git │ │ │ │
│ repo 多 worktree 共享) │ │ │ │
├──────────────────────────────┼─────────┼──────────────────────┼─────────────────┤
│ 4. skill descriptions │ 你 │ 启动 │ 名字 + 1.5K 字符 │
│ ~/.claude/skills/* + │ │ │ 描述/skill,共享 │
│ .claude/skills/* │ │ │ 1% ctx 预算 │
│ skill body │ 你 │ 用时(/name 或自动) │ 一条消息常驻 │
├──────────────────────────────┼─────────┼──────────────────────┼─────────────────┤
│ 5. subagent persistent memory │ subagent │ 子 session 启动 │ 前 200 行 / 25KB │
│ ~/.claude/agent-memory/ │ 自己写 │ │ 进 subagent ctx │
│ <name>/ │ │ │ 不进主 ctx │
└──────────────────────────────┴─────────┴──────────────────────┴─────────────────┘
加上对话本身:
6. 当前 conversation:tool calls + user msgs + tool results
───────────────── 其他都是为了延长 6 的 effective lifetime ─────────────────
#5.2 CLAUDE.md:工程级记忆
四种 scope(高 → 低):
| scope | 路径 | 共享给谁 |
|---|---|---|
| Managed policy | macOS /Library/Application Support/ClaudeCode/CLAUDE.md / Linux /etc/claude-code/CLAUDE.md / Windows C:\Program Files\ClaudeCode\CLAUDE.md |
整个组织(不可被 user 排除) |
| Project | <repo>/CLAUDE.md 或 <repo>/.claude/CLAUDE.md |
团队(进 git) |
| User | ~/.claude/CLAUDE.md |
当前用户的所有项目 |
| Local | <repo>/CLAUDE.local.md |
仅当前 worktree(gitignore 进) |
加载规则:从 cwd 沿目录树向上找,每层的 CLAUDE.md + CLAUDE.local.md 一起 concat。子目录里的 CLAUDE.md 不在启动时加载,只有 Claude 真的去读那子目录文件时才会被一并拉进来。
block-level HTML 注释 <!-- ... --> 在注入前被 strip(给 maintainer 留笔记不烧 ctx)。
AGENTS.md 不被 Claude Code 直接读,但很多 repo 已经有了。官方建议写 CLAUDE.md 里 @AGENTS.md 引入。
#5.3 Auto memory:Claude 自己写的笔记
v2.1.59 起默认开。每个 project 一个目录:
~/.claude/projects/<git-repo-derived-id>/memory/
├── MEMORY.md ← 索引;前 200 行 / 25KB 入 ctx
├── debugging.md ← 用时才读
├── api-conventions.md
└── ...
触发 / 写:Claude 自己判断哪些信息"以后还会用"——build 命令、project 习惯、调试坑——写进 MEMORY.md 和 topic 文件。可被用户开关:autoMemoryEnabled: false 或 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。
关键限制:MEMORY.md 超过 200 行 / 25KB(MAX_ENTRYPOINT_LINES=200、MAX_ENTRYPOINT_BYTES=25_000,源码 memdir/memdir.ts:34-38),超出部分启动时不加载。topic 文件不在启动时加载,模型用 Read 工具按需取。
四种 memory type(v2.1.88 实为 4 种非 5 种,源码 memdir/memoryTypes.ts:14-19):
| type | scope | 说明 |
|---|---|---|
user |
always private | 用户角色 / 偏好 |
feedback |
default private(project-wide 可 team) | 用户纠正 / 确认 |
project |
bias toward team | 工作目标 / 里程碑 / 约束 |
reference |
usually team | 外部系统(Linear/Grafana/Slack)指针 |
相关 memory 选择器(findRelevantMemories.ts:39-60):每次 query 把 memory 文件 header/description 送给 Sonnet sideQuery,最多选 5 个相关 topic files;alreadySurfaced Set 过滤已显示过的,避免重复。
Team Memory(v2.1.88 新增,feature TEAMMEM + GrowthBook tengu_herring_clock):启用后 auto memory 目录额外维护 memory/team/ 子目录供团队共享;private + team 两侧合并注入 system prompt(源码 memdir/teamMemPaths.ts:84)。
KAIROS assistant mode:启用后不写 MEMORY.md,改为每日追加 memory/logs/YYYY/MM/YYYY-MM-DD.md,由后台 /dream skill 异步整理成 topic files 和 MEMORY.md 索引(paths.ts:246)。
autoMemoryDirectory 安全限制(paths.ts:178-186):只读 policy/flag/local/user 四档 settings,故意排除 projectSettings——防止 supply chain 攻击把笔记写到敏感位置。
#5.4 上下文压缩(auto-compact,v2.1.88 校准)
触发阈值(源码 services/compact/autoCompact.ts:62-91):
token 阈值 = effectiveContextWindow - AUTOCOMPACT_BUFFER_TOKENS(13,000)
其中 effectiveContextWindow = contextWindowForModel - min(maxOutputTokens, 20_000)
实际算法(与旧文档"三步渐进"不同):
- 先尝试 Session Memory Compaction(
autoCompact.ts:287-310):从过去 sessions 提取相关内容替换大型 tool outputs,无 LLM 调用,成功则直接结束 - 若不足,再走 Snip Compaction(feature
SNIP,QueryEngine.ts:123-126):用snipCompact裁剪大型 tool results(仍无 LLM) - 若仍不足,调用 LLM forked agent 总结全部对话(最大输出 20K tokens,
COMPACT_MAX_OUTPUT_TOKENS):图片/document 在送 LLM 前 strip - compact 请求本身若 prompt-too-long → 按最旧的 API-round groups 截断后重试,最多 3 次(
MAX_PTL_RETRIES) - 熔断器:连续失败 3 次(
MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES)后停止本 session 的 auto compact,停下来报错
/compact <focus> 可手动触发并加 hint:/compact focus on the API changes。
幸存优先级 / PostCompact 预算(compact.ts:122-130):
- ✅ project root CLAUDE.md:会被 re-inject(重新从盘上读)
- ❌ 嵌套 CLAUDE.md:等下次 Claude 读那子目录文件时才会回来
- ✅ 已 invoke 的 skill:总预算 25,000 tokens,每 skill 上限 5,000 tokens
- ✅ 文件:最多恢复 5 个文件,每文件 5,000 tokens;files budget 50,000 tokens
- ❌ 对话里口头说的临时规则:会丢 → 所以官方建议持久规则放 CLAUDE.md
PreCompact / PostCompact hook 可以在压缩前后做事(比如把当前状态 dump 到外部,或注入 customInstructions 改写 summary 指令)。
#5.5 持久 subagent memory
subagent frontmatter 加 memory: user / project / local 后,得到一个 agent 专属的目录:
~/.claude/agent-memory/<agent-name>/ # user
.claude/agent-memory/<agent-name>/ # project(共享)
.claude/agent-memory-local/<agent-name>/ # local(不进 git)
子 session 启动时:MEMORY.md 前 200 行 / 25KB 进 subagent 的 ctx;Read/Write/Edit 自动启用让它能维护自己。
典型用法:code-reviewer subagent 跨 PR 累积"这 codebase 常见问题模式"。
#5.6 三个核心矛盾的回应
- "context 有限":分层 + lazy + 压缩三件套;MEMORY.md 主动限到 200 行;topic 文件 on-demand。
- "自由 vs 安全":managed CLAUDE.md 不可被排除,组织规则强制;
autoMemoryDirectory不可在 project settings 里改(防 supply chain 攻击把笔记写到敏感位置)。 - "个性化":CLAUDE.md / auto memory / agent memory 在不同时间尺度记不同东西,分层不打架。
#六、Agent 怎么开口 —— 输出回路 / UI / Hook 改写
Claude Code 的"输出"不只是流式文字,而是按 surface(terminal/IDE/web)、按 mode(interactive / -p) 走不同回路。
#6.1 两种基本模式
┌─────────────────────────────────────────┐ ┌────────────────────────────────────┐
│ Interactive 模式:claude / claude "..." │ │ Headless 模式:claude -p "..." │
│ │ │ │
│ - TUI(pure terminal)/ IDE WebView │ │ - 一次 prompt,跑完退出 │
│ - 流式渲染:tool call 卡片 + 文本 │ │ - 输出格式:text / json / stream-json│
│ - 可中断(ESC)/ 回滚(ESC ESC) │ │ - --max-turns / --max-budget-usd │
│ - skill autocomplete / mode 指示器 │ │ - 适合 CI / pipe / cron │
│ - notification hook / status line │ │ - --bare 跳过 hooks/skills/MCP/auto│
│ - session 保存到 ~/.claude/projects/ │ │ memory,启动更快 │
└─────────────────────────────────────────┘ └────────────────────────────────────┘
#6.2 UI 元素
每个 surface 都连同一个 underlying engine,所以 CLAUDE.md / settings / MCP servers 跨 surface 通用:
| Surface | 进入方式 | 特色 | 协议(v2.1.88 源码) |
|---|---|---|---|
| Terminal | claude |
默认;Shift+Tab 切 mode;Shift+Down 切 teammate | TUI(Ink)entrypoints/cli.tsx |
| VS Code | extension anthropic.claude-code |
inline diff、@-mention、plan review | REPL Bridge(V1/V2 + HybridTransport),本地 IPC bridge/replBridge.ts |
| JetBrains | plugin marketplace | inline diff | 同上 REPL Bridge |
| Desktop app | dmg / setup.exe | 多 session 平铺、scheduled tasks 跑在本机 | Bridge Main + JWT refresh bridge/bridgeMain.ts |
| Web | claude.ai/code | 跑在 Anthropic VM;可 --teleport 拉回本地终端 |
CCR + bridge,需 OAuth + GrowthBook tengu_ccr_bridge |
| Remote Control | claude --remote-control "name" |
本地跑、远端控;移动端可介入 | claude.ai WebSocket relay,ping 30s,重连 5 次 remote/RemoteSessionManager.ts |
| Direct Connect(v2.1.88 新增) | claude --server 或 SDK 直连 |
局域网/embedded 接入;HTTP POST /sessions + WebSocket,无需 claude.ai 认证 |
server/directConnectManager.ts |
| CCR (Cloud Compute Remote) | CLAUDE_CODE_REMOTE env |
容器内代理:CONNECT→WebSocket relay | upstreamproxy/upstreamproxy.ts |
| SSH | useSSHSession hook |
REPL 在本地,工具执行在远端 | ssh/createSSHSession.ts 桥接 |
| Slack / GitHub Actions / GitLab CI / Chrome / Channels | 各自 README | event-driven 进入 session | — |
三者差异(容易混淆):
| bridge(replBridge) | remote(RemoteSession) | server(DirectConnect) | |
|---|---|---|---|
| 协议 | ReplBridgeTransport(IPC/WS) | claude.ai WS relay | HTTP+WS 直连 |
| 用途 | IDE extension 控制本地 | 移动端远程控制本地 | 局域网/embedded |
| 需要 claude.ai | 否 | 是 | 否 |
| agent 位置 | 本地 | 本地 | 本地或远端 |
#6.3 Notification hook:让 agent 主动喊人
Notification hook 触发条件:
permission_prompt:要批准工具idle_prompt:跑完了等下一条auth_success:登录成功elicitation_dialog:模型主动问问题(AskUserQuestion)
例:macOS 上 idle 时弹通知
{
"hooks": {
"Notification": [{
"matcher": "idle_prompt",
"hooks": [{
"type": "command",
"command": "osascript -e 'display notification \"Claude done\" with title \"Claude Code\"'"
}]
}]
}
}
#6.4 输出 hook:改写 / 阻止 / 追加
不是所有输出都能改,但很多回路点可以:
| 场景 | 用什么 hook | 怎么干 |
|---|---|---|
| Edit 完自动 lint,把 lint 报错丢回模型 | PostToolUse matcher Edit|Write |
exit 2 + stderr |
| 在 turn 结束前强制再做一步 | Stop |
decision: "block" + reason |
| 在 prompt submit 前注入额外 context | UserPromptSubmit |
hookSpecificOutput.additionalContext |
| Session 启动时注入项目状态 | SessionStart |
additionalContext |
| compaction 前做备份 | PreCompact |
command 落盘 |
| 把每一步事件流到日志 | 任何 hook | http handler 推到 endpoint |
#6.5 status line / 提示
/statusline 可定制底部状态条(哪个 model、哪个 mode、token 余量)。这个 setup 流程本身是一个 built-in subagent statusline-setup(model: Sonnet)跑出来的 —— 又一个"agent 配置 agent"的小例子。
#6.6 Buddy / Companion 模式(v2.1.88 新增)
feature('BUDDY')(仅内部构建):一只由 hash(userId) 确定性生成的虚拟精灵(18 物种、5 档稀有度 common/uncommon/rare/epic/legendary、5 种属性 DEBUGGING/PATIENCE/CHAOS/WISDOM/SNARK)坐在输入框旁,通过 speech bubble 评论会话进展。
- bones(外观)每次从
hash(userId)Mulberry32 PRNG 重新生成,不存 config——防止用户手编伪造 legendary - soul(名字 / 个性)由 LLM 生成后持久化到
config.companion - 主模型通过
companion_introattachment 感知 companion 存在,当用户 @精灵名时简短作答(不抢主对话) /buddy命令 hatch;config.companionMuted静音- 时间窗口控制(
useBuddyNotification.tsx:12-21):2026-04-01~2026-04-07 彩虹色提示/buddy,之后正式开放
源码:buddy/(companion.ts / types.ts / prompt.ts / sprites.ts / CompanionSprite.tsx / useBuddyNotification.tsx)。
#6.7 三个核心矛盾的回应
- "context 有限":headless 模式
--bare完全不加载 hooks/skills/MCP/auto memory,CI 场景启动飞快。 - "自由 vs 安全":输出回路里 hook 也得跟 permission rule 一起配;
disableAllHooks/allowManagedHooksOnly让组织能锁死。 - "个性化":notification 完全用户写;status line / VS Code Webview 可以叠 plugin 进一步改。
#七、Agent 的外脑 —— 模型路由与 effort 调度
Claude Code 不只是"挂了个 LLM",它对每次请求挑哪个 model、用多少 thinking、走哪个 provider 都有路由层。
#7.1 模型清单与别名
支持的模型由 provider 决定:
| Provider | 主流路径 | env 切换 |
|---|---|---|
| Anthropic API(默认 firstParty) | Opus 4.6(claude-opus-4-6)/ Sonnet 4.6 / Haiku 4.5 |
无 |
| Amazon Bedrock | inference profile ARN | CLAUDE_CODE_USE_BEDROCK=1 |
| Google Vertex AI | version name | CLAUDE_CODE_USE_VERTEX=1 |
| Microsoft Foundry | deployment name | CLAUDE_CODE_USE_FOUNDRY=1 |
| 自建 LLM gateway | ANTHROPIC_BASE_URL 转发 |
— |
3P 默认模型比 1P 慢一版本:Sonnet 默认 4.5(1P 是 4.6),Haiku 全平台 4.5。Provider 解析在 utils/model/providers.ts:6 getAPIProvider()。
别名映射(v2.1.88 源码 utils/model/aliases.ts:1-10,MODEL_ALIASES):
| alias | 解析到 |
|---|---|
best |
当前最强 = opus(解析为 Opus 4.6) |
sonnet / opus / haiku |
各家最新可用版本 |
sonnet[1m] / opus[1m] |
同上 + 1M context window |
opusplan |
plan mode 用 opus,execute 时继承父 model(haiku + plan 自动升 sonnet) |
v2.1.88 校准:
default不是别名,是内置逻辑(不在MODEL_ALIASES数组中):Max/Team Premium → Opus 4.6,其余 → Sonnet 4.6(1P)/ Sonnet 4.5(3P)。Opus 4.7 在 v2.1.88 源码中暂未公开作为主推 alias 目标。
#7.2 多档"思考力度":effort levels(v2.1.88 实为 4 档)
Opus 4.6、Sonnet 4.6 支持(modelSupportsEffort() 判断,源码 utils/effort.ts)。
| Level | 适合 | 备注 |
|---|---|---|
low |
短 / 延迟敏感 | |
medium |
成本敏感 | Opus 4.6 + Pro/Max/Team 默认 |
high |
不指定时 API 侧默认 | |
max |
最强推理 | 仅 Opus 4.6(utils/effort.ts:52-65),其他模型遇到 max 会自动 downgrade 为 high |
v2.1.88 校准:源码无
xhigh级别,仅low/medium/high/max4 档。max不是"不限 token",是 Opus 4.6 专属的最强推理 budget。
设置优先级(高 → 低,utils/effort.ts:152-167 resolveAppliedEffort()):
CLAUDE_CODE_EFFORT_LEVEL 环境变量
→ AppState.effortValue(/effort 命令 / skill / subagent frontmatter)
→ getDefaultEffortForModel()(模型内置默认)
CLAUDE_CODE_EFFORT_LEVEL=unset 或 =auto → 不发送 effort 参数,完全由 API 决定。
ultrathink 关键字:isUltrathinkEnabled() 特性开启时会把模型默认 effort 降为 medium(utils/effort.ts:321-323),再由 prompt 里的 ultrathink 关键字驱使模型深度思考——两者结合使用,与旧文档"不改 effort 级别"的描述有别。
#7.3 子 agent 模型路由
resolve 顺序(v2.1.88 源码 utils/model/agent.ts:getAgentModel()):
1. CLAUDE_CODE_SUBAGENT_MODEL 环境变量(最高)
2. tool call 时传的 per-invocation toolSpecifiedModel 参数 ← 旧文档遗漏此步
3. agentDefinition.model 字段(frontmatter)
4. 'inherit'(默认,继承父 session 当前 model;走 getRuntimeMainLoopModel())
inherit 经过 getRuntimeMainLoopModel() 解析,opusplan 在 plan mode 下正确路由到 Opus。
Bedrock 跨区域前缀自动继承:子 agent 自动继承父 agent 的 cross-region inference profile 前缀(如 eu.、us.),避免 IAM 权限问题;若 frontmatter 显式指定带前缀的完整 model ID,则尊重子设置。
例:让所有 subagent 都跑 haiku 省钱:
export CLAUDE_CODE_SUBAGENT_MODEL=haiku
claude
#7.4 1M context
Opus 4.7 / 4.6 / Sonnet 4.6 支持(4.7 通过显式 model ID 可用,v2.1.88 别名表里 opus 仍解析到 4.6——见 §7.1)。Max / Team / Enterprise 自动给 Opus 1M;其他 plan 走 extra usage。
/model opus[1m]
/model claude-opus-4-7[1m]
CLAUDE_CODE_DISABLE_1M_CONTEXT=1 关掉。
#7.5 prompt cache
Claude Code 自动开 prompt cache。可按 model tier 关:
DISABLE_PROMPT_CACHING=1 # 全关
DISABLE_PROMPT_CACHING_HAIKU=1 # 仅 haiku
DISABLE_PROMPT_CACHING_SONNET=1 # 仅 sonnet(v2.1.88 新增,旧文档缺失)
DISABLE_PROMPT_CACHING_OPUS=1 # 仅 opus
源码 services/api/claude.ts:333-358 getPromptCachingEnabled()。
--exclude-dynamic-system-prompt-sections 把 cwd / git / env 这些"每机不同"的段从 system prompt 移到第一条 user message,显著提高跨用户跨机器的 cache 命中(适合多人共跑同一类任务的 -p 流水线)。
#7.6 Fast Mode 与成本追踪(v2.1.88 校准)
Fast Mode(utils/fastMode.ts,532 行):Opus 4.6 的"fast"模式(API 侧 usage.speed === 'fast'),定价从 $5/25 飙到 $30/150 per Mtok(COST_TIER_30_150):
getFastModeModel(): string {
return 'opus' + (isOpus1mMergeEnabled() ? '[1m]' : '')
}
v2.1.88 校准:
FAST_MODE_MODEL_DISPLAY = 'Opus 4.6',4.7 暂未在 fast mode allowlist。
Cost 追踪(cost-tracker.ts,323 行 + utils/modelCost.ts):
| 模型 | 定价层($/Mtok 输入/输出) |
|---|---|
| Haiku 3.5 | 0.8 / 4 |
| Haiku 4.5 | 1 / 5 |
| Sonnet 3.5/3.7/4/4.5/4.6 | 3 / 15 |
| Opus 4 / 4.1 | 15 / 75 |
| Opus 4.5 / 4.6 (normal) | 5 / 25 |
| Opus 4.6 (fast) | 30 / 150 |
按 model 维度的 usage breakdown 由 getModelUsage() / getUsageForModel() 暴露——v2.1.88 已支持查看每个模型各自的 token 消耗(旧文档未提)。
#7.7 三个核心矛盾的回应
- "context 有限":1M 是上限不是默认;effort + opusplan 让"重 model"只在需要时上场。
- "自由 vs 安全":
availableModels在 managed settings 里能限制 picker;modelOverrides把 alias 映射到具体 ARN/deployment 给企业治理用。 - "个性化":每个 subagent / skill 都能 frontmatter 里覆盖 model + effort,不用动会话设置。
#八、关键设计权衡(架构师视角)
从 7 个章节拉出 5 条关键问题,看 Claude Code 是怎么回答的,以及对自建 agent 平台的启发。
#8.1 "agent = 文件"还是"agent = 服务"
问题:当 agent 数量起来(10、100、1000 个),怎么避免 N 套服务的运维负担?
Claude Code 的回答:把 agent 身份完全文件化(.md + frontmatter),用 markdown + YAML 双语种解决"配置 + 文档"。本地 file watcher 让改动秒级生效;多 scope 优先级让企业 / 团队 / 个人不打架。没有 agent registry 服务,靠 ~/.claude/ + .claude/ 两个目录就够。
复用启发:在 SaaS 类 agent 平台里,"agent registry"通常是 DB 表 + admin 后台。Claude Code 的做法相当于把 registry 倒置进客户端文件系统,省了一层服务但只适合"客户端 agent"形态。如果你的 agent 要让多机器同时调度同一份配置,registry 还是必要的,但可以参考它的"frontmatter 字段集"作为 schema。
#8.2 "并行" vs "串行"的颗粒度
问题:subagent / agent team / parallel session 三种并行度,哪个该用?
Claude Code 的回答:分三档,按"沟通需求"切:
- 不需要互聊、只要副结果 → subagent(便宜)
- 需要互聊互挑战 → agent team(贵但强,experimental)
- 需要完全隔离的代码改动 → worktree + 多 session(手动)
复用启发:很多 agent 平台只做了"主→子 fan-out",没做"子↔子 mailbox"。其实 mailbox 是把 LLM 之间从"层级 RPC"升级成"协作组"的关键,但代价是状态机复杂度(task list 的 file lock、orphan 清理)。如果团队规模小,subagent + worktree 已经够用;上 mailbox 之前先想清楚同步语义。
#8.3 "permission"做成几道闸
问题:怎么让 LLM "默认安全又不挡路"?
Claude Code 的回答:5 道闸串联:
hook(PreToolUse) → permission rule(deny>ask>allow) → permission mode → protected paths → tool execution
↓ 失败
hook(PostToolUseFailure)
关键设计是每道闸独立可配置且互不替代:mode 决定基线(plan / acceptEdits / bypass...)、rule 是细粒度白黑名单、hook 是动态判断、protected paths 是硬约束、auto mode 还多一个 ML classifier。
复用启发:很多 agent 平台只有一个粗粒度 "工具白名单"。Claude Code 这种"模式 × 规则 × 钩子 × 硬保护"组合很值得抄。但实现要点是字符串语法的统一:permission rule、hook matcher、subagent tools 字段全部用同一套 Tool(specifier) 语法,避免用户在三个地方学三套语法。
#8.4 context 是不是该自己管
问题:让用户管 context(手动 /compact),还是 agent 自己管?
Claude Code 的回答:自动 + 手动并行。auto-compact 默认开,但保护以下不丢:project root CLAUDE.md(re-inject)、最近 invoked skill(按 token 预算 re-attach)。同时给 /compact <focus> 让用户在关键节点手动触发并指定方向。失败(thrashing)时不无限重试,停下来报错。
复用启发:纯自动会丢重要规则、纯手动会让用户被打断。Claude Code 的"分层加载 + 重要的会 re-attach"是个好折中。要点是让用户清楚什么会幸存(文档表格化)、并提供 PreCompact hook 让 advanced 用户自己 dump 状态。
#8.5 "工具"的边界在哪里
问题:内置工具 / MCP / skill / hook / subagent,五种都能"扩展能力",到底什么时候用什么?
Claude Code 的回答:分两个轴判断 ——
- 是不是新原子能力:是 → 内置 / MCP;否(组合现有)→ skill / subagent
- 是确定性还是模型决定:确定性 → hook(每次必跑);模型决定 → skill(描述合适才 invoke)
确定性 模型决定
新原子 ┌──────────────────┐ ┌──────────────────┐
能力 │ 内置工具 / MCP │ │ 内置工具+ allowed-│
│ + permission rule │ │ tools 让模型选 │
└──────────────────┘ └──────────────────┘
组合 ┌──────────────────┐ ┌──────────────────┐
现有 │ hook(强制) │ │ skill / subagent │
│ + slash command │ │ (description) │
└──────────────────┘ └──────────────────┘
复用启发:很多平台把"工具"做成单层,结果用户一个 playbook 也得写成 tool,权限管不住。Claude Code 这种"hook 是确定性、skill 是模型决定、subagent 是 ctx 隔离的执行体"的三轴划分非常工程化。如果要抄,建议先把这三轴的策略文档化再开发。
#8.6 v2.1.88 新增权衡:Deferred Tool
问题:MCP server 数量起来后,工具 schema 把首轮 ctx 撑爆怎么办?
Claude Code 的回答:把工具加载分两阶段——
- 首轮:MCP 工具 + 28 个
shouldDefer: true的内置工具以defer_loading: true发到 API,初始 ctx 只见名字 - 按需:模型用
ToolSearch工具(自身永不 deferred)查询 → 返回tool_referencebeta blocks → API 在模型侧展开完整 schema
权衡曲线:
- 省了:首轮 ctx(一个大 MCP server 可能省 5-10K tokens)
- 付出:每次新工具的"首次使用" 多一次 ToolSearch round-trip(增加延迟);要求 API 支持
tool_referencebeta(第三方代理不一定行,需要ENABLE_TOOL_SEARCH=false回退)
alwaysLoad: true 标记给逃生通道——核心工具永远在初始 ctx 可见。
复用启发:当工具数量超过一定规模(经验值 ~50 个),单层加载注定撑爆 ctx。Deferred + 搜索是必经之路。但要点是 API/runtime 必须配合:如果 LLM 端不支持"按 reference 加载工具 schema",这套方案落不了地。这也是 Claude Code 能做但很多通用 agent 平台做不到的能力——它跟 Anthropic API 是同一家。
#九、附录:组件地图、概念表与源码索引
#9.1 组件地图
Claude Code Agent Harness
┌────────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌────────────┐ ┌─────────────────┐ ┌──────────────────────────────┐ │
│ │ Surfaces │ │ Agent Identity │ │ Memory Layer │ │
│ │ ─ CLI │ │ ─ subagent │ │ ─ system prompt │ │
│ │ ─ VS Code │ │ ─ skill │ │ ─ CLAUDE.md (4 scopes) │ │
│ │ ─ Desktop │ │ ─ slash command │ │ ─ auto MEMORY.md │ │
│ │ ─ Web │ │ ─ agent team │ │ ─ subagent persistent memory │ │
│ │ ─ JetB. │ │ ─ main agent │ │ ─ session JSONL │ │
│ └────────────┘ └─────────────────┘ └──────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Agentic Loop(gather/act/verify) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌──────────────────────────┐ │
│ │ Tools │ │ Permission Stack │ │
│ │ ─ 内置(Bash/Edit..)│ │ ─ hook (PreToolUse/...) │ │
│ │ ─ MCP(http/sse/ │ │ ─ rule (deny>ask>allow) │ │
│ │ stdio) │ │ ─ mode (plan/auto/...) │ │
│ │ ─ Skill │ │ ─ protected paths │ │
│ │ ─ Agent (subagent) │ │ ─ classifier (auto mode) │ │
│ └─────────────────────┘ └──────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ External LLM(Anthropic / Bedrock / Vertex / Foundry)│ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ Settings 层级(v2.1.88,低→高):plugin > user > project > local > flag > policy │
│ CLI 入口:claude / -p / -c / --resume / --teleport / --bare / --agent / │
│ --worktree / --add-dir / --permission-mode / --model / │
│ --agent-teams / --remote-control / --server / --settings ... │
└────────────────────────────────────────────────────────────────────────────┘
#9.2 关键概念对照表
| 概念 | 一句话 | v2.1.88 源码 |
|---|---|---|
| Main agent | 你 claude 启动的那个会话本体,持有顶层 context |
query.ts, QueryEngine.ts |
| Subagent | 主 agent spawn 的子任务执行体,独立 ctx、回执摘要;可异步后台 | tools/AgentTool/runAgent.ts |
| Fork subagent(v2.1.88) | 省略 subagent_type 时触发,继承父完整历史 + system prompt(最大化 prompt cache);强制异步;不可嵌套 |
tools/AgentTool/forkSubagent.ts |
| Coordinator mode(v2.1.88) | CLAUDE_CODE_COORDINATOR_MODE=1;主 agent 切到 orchestrator 角色,工具裁剪到 Agent+SendMessage+TaskStop+subscribe_pr_activity,强制 Research→Synthesis→Implementation→Verification 四阶段 |
coordinator/coordinatorMode.ts |
| Skill | markdown playbook;描述常驻、body 用时进 ctx;可带脚本资源;context: fork 可跑在 subagent 里 |
skills/loadSkillsDir.ts |
| Slash command | .claude/commands/*.md;现已合并进 skill 系统 |
commands.ts, commands/ |
| Hook | 27 事件点的回调(command/http/prompt/agent 4 种 handler,无 mcp_tool);exit 2 阻断;PreToolUse 决策 deny>ask>allow(无 defer) | entrypoints/sdk/coreTypes.ts:25-53, schemas/hooks.ts |
| MCP server | 外接工具源;http / sse / stdio 三 transport;scope user/project/local;schema 默认 deferred | services/mcp/MCPConnectionManager.tsx |
| CLAUDE.md | 项目 / 用户 / managed / local 四 scope 的工程指令;启动加载;@import 最深 5 层 |
utils/claudemd.ts |
| Auto memory | Claude 自己写的笔记;前 200 行 / 25KB 进 ctx;4 种 type(user/feedback/project/reference) | memdir/memdir.ts:34-38, memdir/memoryTypes.ts:14-19 |
| Team Memory(v2.1.88) | feature TEAMMEM;memory/team/MEMORY.md 团队共享记忆 |
memdir/teamMemPaths.ts:84 |
| Plan mode | 只读工具集 + 强制先汇报方案;Shift+Tab 切;/plan 一次性 |
tools/EnterPlanModeTool/ |
| Permission mode | 外部 5 档:default/acceptEdits/plan/dontAsk/bypassPermissions(auto 是 Anthropic 内部 TRANSCRIPT_CLASSIFIER mode,外部不可配置) |
types/permissions.ts:16-38, utils/permissions/PermissionMode.ts:44-91 |
| Permission 检查链(v2.1.88) | 7 步分层(hasPermissionsToUseToolInner):alwaysDeny → alwaysAsk → tool.checkPermissions → safety paths → bypass → alwaysAllow → passthrough→ask |
utils/permissions/permissions.ts:1158-1310 |
| Auto mode | classifier 模型实时审动作;Max/API 等才有;3 连封或 20 总封会回退到 prompt | utils/permissions/yoloClassifier.ts |
| Worktree | --worktree <name> 在 .claude/worktrees/ 建独立 git 工作树;subagent 可 isolation: worktree 或 remote(Ant CCR) |
tools/EnterWorktreeTool/, tools/ExitWorktreeTool/ |
| Agent team | experimental,多 Claude Code 实例 + mailbox + 共享 task list;CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 或 --agent-teams |
tools/TeamCreateTool/, utils/swarm/ |
| Teammate 后端 | tmux / iterm2 / in-process 三档;非交互式 session 强制 in-process | utils/swarm/backends/types.ts:5-9, registry.ts:396 |
| Task system V2(v2.1.88) | TaskCreate/Update/List/Get/Output/Stop 工具;~/.claude/tasks/{taskListId}/;并发安全;支持 owner claim、blockedBy/blocks 依赖 |
tools/TaskCreateTool/(isTodoV2Enabled()) |
| ScheduleCron(v2.1.88) | CronCreate/Delete/List;5 字段 cron;durable:true 持久化 .claude/scheduled_tasks.json;MAX_JOBS=50;recurring/one-shot;teammate 不能 durable |
tools/ScheduleCronTool/CronCreateTool.ts |
| Effort level | low/medium/high/max 4 档(v2.1.88 无 xhigh);max 仅 Opus 4.6 |
utils/effort.ts |
| Fast Mode | Opus 4.6 高速推理(API usage.speed=fast);定价 $30/150;utils/fastMode.ts |
utils/fastMode.ts:143 |
| Deferred Tool(v2.1.88) | shouldDefer:true 工具以 defer_loading:true 发到 API;ToolSearch 按需加载完整 schema;返回 tool_reference beta blocks |
Tool.ts:439-448, tools/ToolSearchTool/ |
| ToolSearch 模式 | tst(默认 defer)/ tst-auto(超阈值才 defer)/ standard(全内联);env ENABLE_TOOL_SEARCH |
utils/toolSearch.ts:164-197 |
| Output Style | /output-style 切换响应风格;frontmatter keep-coding-instructions;project 覆盖 user |
outputStyles/loadOutputStylesDir.ts |
| Buddy / Companion(v2.1.88,BUDDY 内部) | hash(userId) 决定的虚拟精灵(18 物种 5 稀有度)+ LLM 生成的 soul;/buddy hatch |
buddy/companion.ts, buddy/types.ts |
| Direct Connect(v2.1.88) | claude --server;HTTP /sessions + WebSocket,无需 claude.ai 认证 |
server/directConnectManager.ts |
| Checkpoints | 每次 file edit 自动快照;ESC ESC 回滚;只覆盖文件改动,不覆盖 DB/API | — |
| Headless / -p | 一次性 prompt-then-exit;--bare 跳过所有扩展启动飞快;适合 CI |
entrypoints/cli.tsx |
| Remote Control | 本地起 claude remote-control,通过 claude.ai 浏览器或 iOS 接管 |
remote/RemoteSessionManager.ts |
| Web session | 跑在 Anthropic VM;可 claude --teleport 拉回本地终端 |
bridge/bridgeMain.ts |
| DreamTask(v2.1.88,KAIROS) | 异步后台长任务类型;与 LocalAgent/InProcessTeammate 并列 | tasks/DreamTask/DreamTask.ts |
#9.3 文件 / 目录速查
~/.claude/ # 用户级所有配置
├── CLAUDE.md # 用户级指令
├── settings.json # 用户级 settings
├── agents/ # 用户级 subagent
├── skills/ # 用户级 skill
├── commands/ # 用户级 command(向后兼容)
├── rules/ # 用户级 path-scoped rule
├── projects/<git-id>/memory/ # 项目维度 auto memory
│ ├── MEMORY.md
│ └── <topic>.md
├── agent-memory/<agent-name>/ # 用户级 subagent persistent memory
├── tasks/<team-name>/ # agent team 任务列表
├── teams/<team-name>/config.json # agent team 元数据
└── keybindings.json # 自定义快捷键
<repo>/ # 项目级(进 git 部分)
├── CLAUDE.md # 团队共享指令
├── CLAUDE.local.md # 个人项目指令(gitignore)
├── AGENTS.md # 兼容 IDE-agnostic(需 @AGENTS.md 引入)
├── .claude/
│ ├── CLAUDE.md # 等价于上面 CLAUDE.md
│ ├── settings.json # 项目共享 settings
│ ├── settings.local.json # 个人 override(gitignore)
│ ├── agents/ # 项目级 subagent
│ ├── skills/ # 项目级 skill
│ ├── commands/ # 项目级 command
│ ├── rules/ # 项目级 path-scoped rules
│ ├── agent-memory/<agent-name>/ # 项目共享 subagent memory
│ ├── agent-memory-local/<agent-name>/ # 项目本地 subagent memory(gitignore)
│ ├── worktrees/<name>/ # --worktree 的隔离工作树
│ └── hooks/*.sh # hook 脚本
└── .mcp.json # 项目级 MCP server 配置
Managed policy(不可被 user/project 覆盖)
├── macOS /Library/Application Support/ClaudeCode/{CLAUDE.md,managed-settings.json}
├── Linux /etc/claude-code/{CLAUDE.md,managed-settings.json}
└── Windows C:\Program Files\ClaudeCode\{CLAUDE.md,managed-settings.json}
#9.4 v2.1.88 源码一级目录全景(35 个子目录)
源码根:agents/claude-code/source/src/(npm @anthropic-ai/claude-code@2.1.88 sourcemap 还原,1906 个 TS 文件)
根级关键文件:
| 文件 | 行数 | 用途 |
|---|---|---|
main.tsx |
4683 | CLI 入口,参数解析,session 初始化(启动最早做 MDM + keychain 并行预读) |
QueryEngine.ts |
1295 | 顶层 agentic session 管理器 |
query.ts |
1729 | 单轮 LLM 交互核心,处理 streaming/tool use |
Tool.ts |
792 | 工具基类,含 shouldDefer / alwaysLoad / searchHint 标记 |
tools.ts |
389 | 所有内置工具的注册表 |
commands.ts |
754 | slash command 注册与路由 |
setup.ts |
477 | session 启动准备(swarm 初始化、worktree 等) |
cost-tracker.ts |
323 | Token/cost 统计聚合,按 model 拆分 |
Task.ts / tasks.ts |
125 / ~50 | Task 基类与注册表 |
history.ts |
~200 | session history 持久化 |
context.ts |
~50 | React context 入口 |
ink.ts |
~50 | Ink TUI 入口(包装 ThemeProvider) |
子目录(按用途):
| 目录 | 文件数 | 用途 | 关键文件 |
|---|---|---|---|
assistant/ |
1 | LLM 返回 turn 的历史存储 | sessionHistory.ts |
bootstrap/ |
1 | 全局状态 store(token/cost/session 计数) | state.ts(~1300 行) |
bridge/ |
31 | Web/IDE Bridge 通信层 | replBridge.ts, bridgeMain.ts |
buddy/ |
6 | Companion/Buddy 玩伴 | CompanionSprite.tsx, useBuddyNotification.tsx |
cli/ |
19 | CLI 输出、structured IO、transports | print.ts(2638+ 行) |
commands/ |
189 | 内置 slash commands | 每命令一个子目录 |
components/ |
377 | React/Ink UI 组件 | ModelPicker.tsx, App.tsx |
constants/ |
~20 | 全局常量(prompts、output styles、工具名、XML tags) | prompts.ts, outputStyles.ts |
context/ |
9 | React context(mailbox/modal/notifications/voice) | mailbox.tsx |
coordinator/ |
1 | Coordinator 模式 | coordinatorMode.ts |
entrypoints/ |
8 | SDK 入口(agentSdkTypes、coreSchemas、controlSchemas、sandboxTypes) | agentSdkTypes.ts, sdk/coreSchemas.ts |
hooks/ |
104 | React hooks(useCanUseTool / useMainLoopModel / useTaskListWatcher 等) | useCanUseTool.tsx |
ink/ |
6 | Ink 渲染层、ANSI/bidi 文本 | state.ts, colorize.ts |
keybindings/ |
14 | 快捷键系统 | defaultBindings.ts, resolver.ts |
memdir/ |
8 | Auto memory(MEMORY.md / age / team memory 路径) | memdir.ts, paths.ts |
migrations/ |
11 | 设置迁移脚本(model 别名、sonnet45→46、opus1m 合并) | migrateSonnet45ToSonnet46.ts |
moreright/ |
1 | Internal-only 右侧面板 hook(外部 stub) | — |
native-ts/ |
4 | 原生 TS 加速模块(color-diff / file-index / yoga-layout) | hooks.ts |
outputStyles/ |
1 | Output Style 加载 | loadOutputStylesDir.ts |
plugins/ |
2 | Plugin 系统(v2.1.88 bundled 注册为空) | builtinPlugins.ts, bundled/index.ts |
query/ |
4 | query() 的 config 与辅助 | config.ts, tokenBudget.ts |
remote/ |
4 | Remote Control 远程会话 | RemoteSessionManager.ts |
screens/ |
3 | TUI 全屏幕(Doctor / REPL / ResumeConversation) | REPL.tsx |
server/ |
3 | DirectConnect server | directConnectManager.ts |
services/ |
130 | API client / MCP / compact / analytics / oauth / voice STT | api/claude.ts, mcp/, compact/ |
skills/ |
20 | Skill 加载系统(含 17+ bundled skills) | loadSkillsDir.ts, bundledSkills.ts, bundled/index.ts |
state/ |
6 | AppState(Zustand store / selectors) | AppStateStore.ts |
tasks/ |
12 | Task 类型实现(Dream / InProcessTeammate / LocalAgent / LocalShell / RemoteAgent) | types.ts, DreamTask/DreamTask.ts |
tools/ |
184 | 43 个内置工具(每工具一子目录) | AgentTool/, BashTool/, ScheduleCronTool/, ToolSearchTool/ |
types/ |
7 | 跨域 TS 类型 | message.ts, permissions.ts |
upstreamproxy/ |
2 | 上游 HTTP 代理(CCR) | upstreamproxy.ts |
utils/ |
564 | 工具函数(model/effort/cost/permissions/settings/swarm/...) | model/model.ts, effort.ts, swarm/ |
vim/ |
5 | Vim 编辑模式 | transitions.ts, motions.ts |
voice/ |
1 | Voice mode 开关 | voiceModeEnabled.ts |
#9.5 源码索引:按"用户问题→去哪看"
模型与推理
| 问题 | 去哪看 |
|---|---|
| 当前用的什么 model | utils/model/model.ts:getMainLoopModel() |
| 哪些别名支持 | utils/model/aliases.ts:MODEL_ALIASES |
| Provider 切换(Bedrock/Vertex) | utils/model/providers.ts:getAPIProvider() |
| subagent model 路由 | utils/model/agent.ts:getAgentModel() |
| effort level 计算 | utils/effort.ts:resolveAppliedEffort() |
| max effort 哪些模型支持 | utils/effort.ts:modelSupportsMaxEffort() |
| fast mode 价格 | utils/modelCost.ts:COST_TIER_30_150 |
| 每次 API 调用花了多少钱 | cost-tracker.ts, utils/modelCost.ts:calculateUSDCost() |
| prompt cache 开关 | services/api/claude.ts:getPromptCachingEnabled() |
Agentic Loop
| 问题 | 去哪看 |
|---|---|
| agentic loop 主循环 | query.ts:241 queryLoop() |
| 顶层 session 管理 | QueryEngine.ts |
| tool use 执行 | Tool.ts:call() + query.ts 的 dispatch |
| streaming 处理 | query.ts + services/api/claude.ts |
| deferred tool 加载 | Tool.ts:shouldDefer/alwaysLoad, services/api/claude.ts:deferredToolNames |
| auto-compact 触发 | services/compact/autoCompact.ts:241 autoCompactIfNeeded() |
| compact 算法 | services/compact/compact.ts:387 compactConversation() |
| maxTurns 检查 | query.ts:1705 |
工具与权限
| 问题 | 去哪看 |
|---|---|
| 所有内置工具列表 | tools.ts:193-251, tools/ 目录 |
| 权限 7 步检查 | utils/permissions/permissions.ts:1158-1310 hasPermissionsToUseToolInner() |
| dontAsk/auto 包装 | utils/permissions/permissions.ts:473-700+ hasPermissionsToUseTool() |
| permission rule 解析 | utils/permissions/permissionRuleParser.ts |
| hook 事件触发 | services/api/claude.ts 的 hook dispatch |
| hook 事件类型 | entrypoints/sdk/coreTypes.ts:25-53 HOOK_EVENTS(27 个) |
| MCP 连接管理 | services/mcp/MCPConnectionManager.tsx, entrypoints/mcp.ts |
| ToolSearch 模式 | utils/toolSearch.ts:164-197 getToolSearchMode() |
多 Agent / Swarm
| 问题 | 去哪看 |
|---|---|
| agent team 启用判断 | utils/agentSwarmsEnabled.ts:isAgentSwarmsEnabled() |
| teammate 间通信 | utils/mailbox.ts:Mailbox, utils/teammateMailbox.ts |
| swarm 后端类型 | utils/swarm/backends/(InProcess / Pane / iTerm2 / Tmux) |
| Coordinator system prompt | coordinator/coordinatorMode.ts:111-369 |
| Fork subagent 实现 | tools/AgentTool/forkSubagent.ts:107-168 buildForkedMessages() |
| TeamCreate 实现 | tools/TeamCreateTool/TeamCreateTool.ts:128-212 |
| SendMessage 路由 | tools/SendMessageTool/SendMessageTool.ts:67-87 |
| ScheduleCron 实现 | tools/ScheduleCronTool/CronCreateTool.ts:56-157 |
| Task system V2 | tools/TaskCreateTool/TaskCreateTool.ts:48-138 |
| in-process teammate | tasks/InProcessTeammateTask/InProcessTeammateTask.tsx |
配置与状态
| 问题 | 去哪看 |
|---|---|
| 全局状态 | bootstrap/state.ts |
| AppState(UI) | state/AppStateStore.ts, state/selectors.ts |
| settings 6 层合并 | utils/settings/settings.ts:645-720 loadSettingsFromDisk() |
| settings sources | utils/settings/constants.ts:7-22 SETTING_SOURCES |
| CLAUDE.md 加载 | utils/claudemd.ts, memdir/memdir.ts |
| Auto memory 路径 | memdir/paths.ts:30-55, 223-235 |
| Output Style 加载 | outputStyles/loadOutputStylesDir.ts:26-92 |
| worktree 创建 | tools/EnterWorktreeTool/, setup.ts:231 |
SDK / 集成
| 问题 | 去哪看 |
|---|---|
| SDK 公开类型 | entrypoints/agentSdkTypes.ts, entrypoints/sdk/coreTypes.ts |
| SDK control protocol | entrypoints/sdk/controlSchemas.ts |
| Bridge(IDE 集成) | bridge/replBridge.ts |
| Bridge Main(Web/Desktop) | bridge/bridgeMain.ts |
| Remote control | remote/RemoteSessionManager.ts |
| Direct Connect | server/directConnectManager.ts |
| CCR upstream proxy | upstreamproxy/upstreamproxy.ts |
#9.6 官方文档索引
所有官方页都在 https://code.claude.com/docs/en/<page>(旧域名 docs.claude.com/en/docs/claude-code/... 会 301 到这里):
#9.7 一句话总结
Claude Code 是一个把"agent 身份 / 工具 / 记忆 / 权限"全部文件化、靠 markdown + YAML 编织的 agentic harness。 它的工程美学集中在三件事:把"agent = markdown"做到极致;把"权限"切成 5 层独立可配;把"context"做成可观测、可分层、可压缩的 token 经济体系。
#文档元信息
- 路径:
docs/architecture/claude-code-agent-architecture.md - 当前版本:v2.1.88-calibrated(2026-05-15)
- 官方复核:2026-06-08 复核 npm
@anthropic-ai/claude-code@2.1.168与官方 docs; 新增 Dynamic workflows / Routines 说明,源码级细节仍不外推到 v2.1.168。 - 数据采集:
- 旧版:2026-04-25
code.claude.com/docs/en/*官方文档 - 本次校准:2026-05-15 基于
@anthropic-ai/claude-code@2.1.88npm sourcemap 还原源码(1906 个 TS 文件,路径agents/claude-code/source/src/)
- 旧版:2026-04-25
- 校准范围:5 人 agent team 并行分析(§0-2 / §3 / §4 / §5-6 / §7-9),共修订约 30 处过时描述、新增 12+ 处 v2.x 能力(Agent Team / Coordinator mode / Fork subagent / Task V2 / ScheduleCron / Buddy / Direct Connect / Team Memory / KAIROS / Deferred Tool / Fast Mode 等)
- 法律:源码版权归 Anthropic 所有,本文档仅作架构学习用途
- 最不确定的几点(v2.1.88 仍未完全公开):
- agent team 的 mailbox IPC 细节:源码确认有 in-process(AsyncLocalStorage)+ tmux/iterm2 三种后端;in-process 用 Mailbox 直接调用,tmux/iterm2 跨 pane 通信的具体协议(pipe / socket / file watcher)需进一步源码追踪
- auto mode classifier 决策细节:源码
utils/permissions/yoloClassifier.ts显示classifyYoloAction()是 LLM 调用,但 prompt / 阈值 / scoring 未在 v2.1.88 源码中暴露(应在 server 端配置) - CCR remote agent / DreamTask 的具体调度细节:仅在
tasks/DreamTask/、upstreamproxy/中看到外壳,背后的 Anthropic 服务端调度逻辑不可见
- 后续可继续校准:
agents/claude-code/source/src/services/(130 个文件,含 API / MCP / compact / analytics / oauth / voice STT 等子系统,本次仅抽样)