Claude Code is not a code completion tool. It is not a chat panel bolted onto an IDE. It is a fully autonomous coding agent that can read your codebase, plan changes, execute shell commands, edit files, and coordinate with other agents — all inside a single terminal session.
I spent a weekend reading through its open-source codebase. What I found was a carefully engineered system with several genuinely novel ideas. This article walks through the architecture piece by piece, with code references and diagrams where they add clarity.
引言
Claude Code 不是代码补全工具,也不是贴在 IDE 侧边的聊天面板。它是一个完全自主的编码智能体——能够阅读代码库、规划修改、执行 shell 命令、编辑文件,甚至与其他智能体协作——所有这些都在一个终端会话中完成。
我花了一个周末阅读它的开源代码,发现了几个真正新颖的设计。本文将逐一解析这些架构。
From Tools to Agents: Three Paradigms
To understand what Claude Code is, we need to understand the three levels of AI-assisted coding:
Level 1 — Code Completion (e.g., Copilot)
You type, the model predicts the next few tokens. It sees your cursor position and surrounding context, generates a completion suggestion. This is fundamentally a single-prediction problem — the model does not need to understand the entire project, does not execute anything, and only needs to generate reasonable code fragments based on local context. The user is always the driver; the model is just a copilot.
Level 2 — IDE Chat Assistants (e.g., Cursor Chat, Copilot Chat)
Users describe requirements in natural language, and the model generates code snippets or modification suggestions. This is more powerful than completion — the model can see more context and generate multi-file changes. But the critical limitation is: the model cannot execute operations. It generates a diff, and the user decides whether to apply it. If the diff has problems (e.g., depends on a non-existent function), the user must manually discover and report them.
Level 3 — Autonomous Agents (e.g., Claude Code)
The model not only generates code but autonomously executes multi-step operations. Consider a real scenario: you want to add a new REST endpoint. Copilot gives you a function body. IDE chat suggests a modification plan. Claude Code's approach: first use Grep to search existing route definitions to understand the project's routing patterns, use FileRead to examine middleware configuration, then create the handler file, register the route, write tests, run npm test to discover failures, read error messages, fix the code, re-run tests until they pass, and finally submit a git commit.
The entire process is an autonomous decision loop — the model decides what to do next, executes, observes results, then decides again.
Level 1: type --> predict --> insert
Level 2: describe --> generate diff --> user reviews --> apply
Level 3: think --> execute --> observe --> think --> ... --> done
This paradigm shift brings fundamental architectural differences. An agent needs:
- Loop: not a single call, but repeated "think → execute → observe" until task completion
- Tools: not just text generation, but file reading, writing, command execution
- Memory: not starting from zero each time, but remembering user preferences and project context
- Safety: because it executes real operations on the user's machine, strict permission management is essential
Every architectural decision in Claude Code revolves around these four needs.
从工具到智能体:三种范式
要理解 Claude Code 的定位,需要理解 AI 辅助编程的三级范式:
第一层——代码补全(如 Copilot)
本质上是一个单次预测问题——模型不需要理解整个项目,不需要执行任何操作,只需根据局部上下文生成合理的代码片段。用户始终是驾驶员,模型只是副驾。
第二层——IDE 聊天助手(如 Cursor Chat)
模型可以用自然语言描述需求并生成代码片段。但关键限制是:模型不能执行操作。它生成一个 diff,由用户决定是否应用。如果 diff 有问题,用户需要手动发现并反馈。
第三层——自主智能体(如 Claude Code)
模型不仅生成代码,还能自主执行多步操作。整个过程是一个自主决策循环——模型决定下一步做什么,执行后观察结果,再决定下一步。
第一层: 输入 --> 预测 --> 插入
第二层: 描述 --> 生成 diff --> 用户审查 --> 应用
第三层: 思考 --> 执行 --> 观察 --> 思考 --> ... --> 完成
这种范式跃迁要求智能体具备四个核心能力:循环(反复"思考→执行→观察")、工具(读写文件、执行命令)、记忆(记住偏好和上下文)、安全控制(严格的权限管理)。
The Agent Loop
At the heart of Claude Code is the agent loop — an async generator that alternates between calling the model API and executing tools. Let me walk through the key steps of each iteration:
Step 1: Four-Stage Compression Pipeline
Before each API call, the message history passes through a compression pipeline to ensure it fits within the context window. This is defensive design — even if a previous tool returned 100K tokens of output, the pipeline will bring it under budget before the API call.
// Stage 1: Tool Result Budget — cap each result at ~5000 tokens
messagesForQuery = await applyToolResultBudget(messagesForQuery, ...)
// Stage 2: History Snip — replace old tool results with one-line summaries
if (feature('HISTORY_SNIP')) {
const snipResult = snipModule.snipCompactIfNeeded(messagesForQuery)
messagesForQuery = snipResult.messages
}
// Stage 3: Microcompact — paraphrase older messages to save space
const microcompactResult = await deps.microcompact(messagesForQuery, ...)
messagesForQuery = microcompactResult.messages
// Stage 4: Context Collapse — summarize entire conversation (nuclear option)
if (feature('CONTEXT_COLLAPSE') && contextCollapse) {
const collapseResult = await contextCollapse.applyCollapsesIfNeeded(
messagesForQuery, toolUseContext, querySource
)
messagesForQuery = collapseResult.messages
}
The four stages escalate in aggressiveness:
-
Tool Result Budget — Each tool result is capped at a configurable size (default ~5000 tokens). A
catof a large file gets truncated with a[truncated]marker. This is the cheapest operation. -
Snip — When total conversation approaches the context limit, older tool results are replaced with one-line summaries like
[tool result snipped: BashTool "npm test" -- 2 lines]. The model knows what happened but no longer sees the raw output. -
Microcompact — At higher compression levels, older assistant messages are rewritten into shorter paraphrases. Key decisions and file paths are preserved; verbose reasoning is dropped.
-
Context Collapse — The nuclear option. A separate model call summarizes the entire conversation into a single message. History is replaced with that summary plus the most recent few turns.
Step 2: Building the API Request
Context injection order matters for prompt caching:
const fullSystemPrompt = asSystemPrompt(
appendSystemContext(systemPrompt, systemContext) // system context appended at back
)
// userContext prepended to messages via prependUserContext()
Stable content (tool definitions, instructions) goes at the front of the system prompt for cache hits. Volatile content (git status, user context) goes at the back. Across turns within the same session, the large block of tool definitions is served from cache — only the small volatile tail needs re-processing.
Step 3: Streaming Call + Parallel Tool Execution
callModel() returns an async generator. StreamingToolExecutor starts executing completed tool calls while the model is still streaming subsequent tokens — this is the key optimization we will examine next.
Step 4: Memory Prefetch
// Created at loop entry, `using` ensures dispose on all exit paths
using pendingMemoryPrefetch = startRelevantMemoryPrefetch(
state.messages, state.toolUseContext,
)
Memory prefetch runs in parallel with model generation. The using keyword (TypeScript Explicit Resource Management) ensures cleanup on every exit path — whether normal return or exception.
Agent 循环
Claude Code 的核心是 Agent 循环——一个在调用模型 API 和执行工具之间交替的异步生成器。
第一步:4级压缩流水线
每次 API 调用前,消息历史经过压缩流水线确保在上下文窗口内。这是防御性设计——即使上一轮工具返回了 100K token 的输出,流水线也会在 API 调用前将其控制在预算内。
四个阶段逐步升级:
- 工具结果预算 — 每个结果上限约 5000 token,最廉价的操作
- 摘要替换(Snip) — 旧工具结果替换为一行摘要,模型知道发生了什么但不再看到原始输出
- 微压缩(Microcompact) — 将旧消息重写为更短的释义,保留关键决策和文件路径
- 上下文折叠(Context Collapse) — 终极方案,通过单独的模型调用将整个对话总结为一条消息
第二步:构建 API 请求
上下文注入顺序对提示词缓存有影响:稳定内容(工具定义、指令)放在前部以命中缓存;易变内容(git 状态、用户上下文)放在后部。
第三步:流式调用 + 并行工具执行
StreamingToolExecutor 在模型还在流式生成后续 token 时就开始执行已完成的工具调用——这是我们接下来要详细分析的优化。
第四步:记忆预取
记忆预取与模型生成并行运行。using 关键字确保在所有退出路径上清理资源。
StreamingToolExecutor — Parallel Tool Execution
This is one of the most interesting pieces of engineering in the codebase. In a traditional agent loop, you wait for the model to finish generating its entire response, then execute tool calls sequentially. Claude Code does neither.
The Core Idea
As the model streams tokens, StreamingToolExecutor watches for complete tool_use blocks. The moment a block's JSON arguments are fully parsed, it is dispatched for execution — even though the model is still generating subsequent tokens and possibly more tool calls.
API streaming output
▼▼▼▼▼▼▼▼▼▼
┌──────────────────────────────────┐
│ StreamingToolExecutor │
│ │
│ tool_use_1 complete → execute ──→│ result ready
│ ...model keeps generating... │
│ tool_use_2 complete → execute ──→│ result ready
│ ...model keeps generating... │
│ tool_use_3 complete → execute ──→│ result ready
└──────────────────────────────────┘
Timeline comparison:
Serial: [===API===][tool1][tool2][tool3]
Parallel: [===API===]
[tool1] ← uses streaming window (5-30s)
[tool2] ← covers ~1s tool latency
[tool3]
[==results instantly available==]
By the time the model finishes generating, most tool results are already available — eliminating the serial execution bottleneck.
Implementation Details
StreamingToolExecutor (531 lines in src/services/tools/StreamingToolExecutor.ts) implements a tool execution queue with concurrency control. Each tool is tracked through four states: queued → executing → completed → yielded.
// Core dispatch logic type ToolStatus = 'queued' | 'executing' | 'completed' | 'yielded' // 1. Each complete tool_use block is immediately queued and dispatched addTool(block: ToolUseBlock, assistantMessage: AssistantMessage): void { const isConcurrencySafe = toolDefinition.isConcurrencySafe(parsedInput.data) this.tools.push({ id: block.id, block, status: 'queued', isConcurrencySafe }) void this.processQueue() // immediately attempt scheduling } // 2. Concurrency control: concurrent-safe tools can parallelize; exclusive tools run alone private canExecuteTool(isConcurrencySafe: boolean): boolean { const executingTools = this.tools.filter(t => t.status === 'executing') return executingTools.length === 0 || (isConcurrencySafe && executingTools.every(t => t.isConcurrencySafe)) } // 3. After streaming ends, harvest all completed results *getCompletedResults(): Generator<MessageUpdate, void> { for (const tool of this.tools) { if (tool.status === 'completed' && tool.results) { tool.status = 'yielded' for (const message of tool.results) yield { message, newContext: ... } } } }
Concurrency Model
Tools are classified into two categories:
-
Concurrent-safe (read-only):
FileReadTool,GlobTool,GrepTool,WebFetchTool. Multiple instances can run simultaneously. These are operations that do not modify state. -
Exclusive (side-effecting):
BashTool,FileEditTool,FileWriteTool. Only one exclusive tool runs at a time, and no other tools run alongside it. These operations modify the filesystem or execute arbitrary commands.
When an exclusive tool starts, any running concurrent tools are allowed to finish, but no new tools are dispatched until the exclusive tool completes.
Bash Error Cascade
When a BashTool invocation fails, a siblingAbortController aborts other in-flight tool calls from the same response. The rationale: Bash commands often have implicit dependencies — if mkdir fails, subsequent commands in the same batch are meaningless. However, failures in read-only tools (file reads, searches) do not trigger cascade cancellation since they are independent operations.
流式工具执行器——并行工具执行
这是代码库中最有趣的工程之一。传统 Agent 循环中,等待模型完成生成整个响应,然后按顺序执行工具调用。Claude Code 两样都不做。
核心思想
当模型流式输出 token 时,StreamingToolExecutor 监视完整的 tool_use 块。一旦一个块的 JSON 参数完成解析,就被分派执行——即使模型仍在生成后续 token 和更多工具调用。
到模型完成生成时,大部分工具结果已经可用——消除了串行执行的瓶颈。
并发模型
工具分为两类:
- 并发安全(只读):
FileReadTool、GlobTool、GrepTool、WebFetchTool。多个实例同时运行。 - 互斥(有副作用):
BashTool、FileEditTool、FileWriteTool。一次只运行一个。
Bash 错误级联
当 BashTool 失败时,siblingAbortController 中止同一响应中的其他工具调用。理由是 Bash 命令之间经常有隐式依赖——如果 mkdir 失败,同一批次中的后续命令就没有意义了。但只读工具的失败不会触发级联。
66+ Built-in Tools in 6 Categories
Claude Code ships with over 66 built-in tools organized into six functional categories:
File Operations (the foundation)
| Tool | Description |
|------|-------------|
| BashTool | Shell command execution — the most complex tool, with configurable timeouts, sandbox controls, and streaming output |
| FileReadTool | Read file contents — supports images, PDFs, Jupyter notebooks, with optional line ranges |
| FileEditTool | Exact string replacement editing — requires unique old_string match, fails if ambiguous |
| FileWriteTool | Create or fully replace files |
| GlobTool | Find files by pattern matching (e.g., **/*.ts) |
| GrepTool | Search file contents with regex (built on ripgrep) |
FileEditTool is worth special attention: it uses an exact-match-and-replace strategy rather than diff-based patching. This is more robust against whitespace and formatting variations, but requires the model to produce the exact existing text it wants to replace. This design choice reflects a practical trade-off: the model is very good at reproducing existing code it just read, and exact matching eliminates the ambiguity problems that plague diff-based systems.
Network
| Tool | Description |
|------|-------------|
| WebFetchTool | Retrieve a URL, convert to markdown, optionally run a prompt against it |
| WebSearchTool | API-driven web search returning result blocks |
Both are read-only and concurrent-safe.
Agent Management & Team Collaboration
| Tool | Description |
|------|-------------|
| AgentTool | Spawn sub-agents — isolated instances with their own conversation context |
| TaskOutputTool | Sub-agents return results to parent |
| TaskCreate/Get/Update/ListTool | Task management system for tracking work |
| SendMessageTool | Peer-to-peer messaging between agents |
| TeamCreateTool / TeamDeleteTool | Create and manage named agent teams |
| ListPeersTool | List sibling agents in a team |
User Interaction
| Tool | Description |
|------|-------------|
| AskUserQuestionTool | Pause execution and prompt user for input — used for clarifications and confirmations |
| TodoWriteTool | Manage a persistent task list for session visibility |
System Control
| Tool | Description |
|------|-------------|
| EnterPlanModeTool | Switch to read-only planning mode |
| ExitPlanModeTool | Exit planning mode |
| EnterWorktreeTool | Create isolated git worktree for parallel work |
| ConfigTool | Read and modify runtime configuration |
Tool Extensions
| Tool | Description |
|------|-------------|
| SkillTool | Load and execute registered skills |
| ToolSearchTool | Dynamically discover available tools |
| MCPTool | Bridge to Model Context Protocol servers |
| LSPTool | Language Server Protocol integration |
The tool design principle is "cover 95% of daily developer workflows." The remaining 5% is handled through BashTool (universal fallback), skills, and MCP extensions.
66+ 内置工具,六大类别
文件操作(基础)
BashTool(Shell 命令执行,最复杂的工具)、FileReadTool(读取文件,支持图片、PDF、Jupyter)、FileEditTool(精确字符串替换编辑)、FileWriteTool(创建/覆盖文件)、GlobTool(按模式匹配文件)、GrepTool(正则搜索文件内容)。
FileEditTool 使用精确匹配替换策略而非基于 diff 的补丁——对空白和格式变化更具鲁棒性,但要求模型生成它想替换的确切现有文本。
网络 / 智能体管理 / 用户交互 / 系统控制 / 工具扩展
- 网络:
WebFetchTool、WebSearchTool(只读,并发安全) - 智能体管理:
AgentTool(生成子智能体)、SendMessageTool(点对点通信)、TeamCreateTool(创建团队) - 用户交互:
AskUserQuestionTool(暂停执行询问用户)、TodoWriteTool(管理任务列表) - 系统控制:
EnterPlanModeTool(只读规划模式)、EnterWorktreeTool(Git worktree 隔离) - 工具扩展:
SkillTool(执行技能)、MCPTool(MCP 外部工具代理)、LSPTool(语言服务器协议)
工具集选择原则:"覆盖开发者日常工作流的 95% 场景"。剩下的 5% 通过 BashTool、技能和 MCP 扩展兜底。
Skills System — Dual-Call Innovation
A skill is, at its core, a prompt template + metadata + execution context — a markdown file with YAML frontmatter describing when and how to invoke it.
Skills solve a core problem: repetitive AI workflows. Every time you ask Claude to do a code review, you have to re-describe "check security vulnerabilities, look at edge cases, pay attention to naming conventions..." Skills codify these validated prompts — write once, use repeatedly.
Two Invocation Paths — The Dual-Call Innovation
Unlike traditional chatbot slash commands, Claude Code's skills have two invocation paths:
| Invocation | Trigger | Example |
|------------|---------|---------|
| User manual | User types /commit | User explicitly needs a specific workflow |
| Model automatic | Model judges current task needs a skill | User says "help me commit," model identifies intent and calls SkillTool |
Why is dual-call a good design? Traditional slash commands can only be manually triggered — users must know the command name and remember the syntax. This limits skill usage: if a user does not know /review exists, they will never use it.
Dual-call makes skills part of the agent's behavior. The model can judge "now I should invoke the review skill" based on the current task context and auto-execute. Users do not need to remember command names — they just express intent ("help me check this code for problems"), and the model selects the appropriate skill.
Skill File Format
Each skill is a directory containing a SKILL.md file:
.claude/skills/
└── review/
└── SKILL.md # frontmatter + prompt
└── templates/ # optional: resource files
└── report.md
Why a directory rather than a single file? Because skills may need accompanying resource files (templates, configs, reference docs), referenced via ${CLAUDE_SKILL_DIR}.
Lazy Loading
At startup, only frontmatter (name, description, whenToUse) is loaded — not full Markdown content. The complete prompt is loaded only when the skill is actually invoked.
// src/tools/SkillTool/prompt.ts export function estimateSkillFrontmatterTokens(skill: Command): number { const frontmatterText = [skill.name, skill.description, skill.whenToUse] .filter(Boolean) .join(' ') return roughTokenCountEstimation(frontmatterText) }
Why lazy loading? The system may register dozens of skills. Loading all content into context would: consume context space (each skill could be hundreds of lines), most skills would not be used in the current session, and full loading increases startup latency. By loading only frontmatter, the model knows "what skills are available" while deferring content loading to actual need — display cost is low, execution cost is pay-per-use.
Token Budget
Skill listing is budgeted at roughly 1% of context window × 4 chars/token, which is about 8KB for a 200K context. formatCommandsWithinBudget() implements a three-phase budget allocation algorithm to fit as many skill descriptions as possible within this space.
技能系统——双重调用创新
技能本质上是提示词模板 + 元数据 + 执行上下文。技能解决的核心问题:重复的 AI 工作流。
两种调用路径——双重调用创新
| 调用方式 | 触发者 | 示例 |
|----------|--------|------|
| 用户手动 | 用户输入 /commit | 用户明确需要某个流程 |
| 模型自动 | 模型判断当前任务需要调用技能 | 用户说"帮我提交代码",模型自动调用 SkillTool |
双重调用让技能成为 Agent 行为的一部分。模型可以根据上下文判断"现在应该调用审查技能"并自动执行。用户不需要记住命令名——只需表达意图。
延迟加载
启动时只加载前置数据(名称、描述、whenToUse),完整 Markdown 提示词在用户实际调用或模型触发时才读取。
为什么不全部加载?系统可能注册几十个技能,全量加载会严重挤占上下文空间。通过只加载前置数据,实现展示成本低、执行成本按需付。
Memory System — Four-Type Taxonomy
Claude Code has a persistent memory system that survives across sessions. It is distinct from the project instruction file (CLAUDE.md). The two are complementary:
| Dimension | CLAUDE.md | Memory System |
|-----------|-----------|---------------|
| Nature | Static config file | Dynamic knowledge base |
| Maintenance | User manually edits, checked into Git | Agent auto-writes or via /remember |
| Scope | Team-shared (project-level) or user-global | Personal private (optionally team-shared) |
| Content | Project specs, coding conventions, CI config | User preferences, behavioral corrections, project dynamics |
| Loading | Fully loaded each session | Index preloaded + semantic recall on demand |
CLAUDE.md stores "what the project is." Memory stores "what to know when collaborating with this person."
The Four Types
Every memory entry falls into exactly one of four types (closed taxonomy):
| Type | What it records | Example | When triggered | |------|----------------|---------|----------------| | user | User identity, preferences, background | "User is a data scientist focused on observability" | When learning about user's role/preferences | | feedback | Corrections AND confirmations of agent behavior | "Don't summarize at the end of responses — user can read diffs themselves" | When user corrects or confirms behavior | | project | Project progress, decisions, deadlines | "2026-03-05 merge freeze, mobile release" | When learning about what/why/deadlines | | reference | Location info for external systems | "Pipeline bug tracking is in Linear INGEST project" | When learning where info lives |
Why a closed taxonomy? It forces the agent to make explicit semantic classifications, preventing tag inflation that leads to fuzzy matching during recall. Each type has different storage structure and usage patterns.
Feedback Type: Not Just Recording Failures
A subtle design decision: feedback records both corrections and confirmations:
If you only save corrections, you will avoid past mistakes but drift away from approaches the user already validated — and potentially become overly cautious.
If a user says "this code style is great, write like this from now on," and this positive feedback is not recorded, the agent might "improve" the code style in the next session — drifting away from what the user was satisfied with.
Structured Format for Feedback and Project Memories
Both types require specific structure:
The rule or fact itself.
**Why:** The reason behind this feedback — usually a past incident or strong preference.
**How to apply:** When/where to apply this guidance.
Why the "Why"? As the source code explains: "Knowing why lets you judge edge cases instead of blindly following the rule."
Example: If memory only records "don't mock the database," the agent avoids mocking in all tests. But if it also contains "Why: last quarter mock tests passed but production migration failed," the agent can judge — this rule applies to integration tests, while lightweight mocking in unit tests might be fine.
Relative Dates Become Absolute
When a user says "merge freeze after Thursday," the memory must store "merge freeze after 2026-03-05." Reason: the memory may be read weeks later by another session, when "Thursday" is meaningless.
What Memory Explicitly Excludes
- Code patterns, conventions, architecture, file paths, project structure — read current code
- Git history, recent changes, who changed what — git log / git blame is authoritative
- Debugging solutions or fix steps — fixes are in code, context in commit messages
- Content already in CLAUDE.md
- Temporary task details: in-progress work, temporary state, current conversation context
These exclusions apply even when the user explicitly requests saving. Philosophy: memory is for things that would not be discoverable by reading the code.
记忆系统——四类分类法
Claude Code 有一个跨会话持久化的记忆系统。它与项目指令文件(CLAUDE.md)互补:
CLAUDE.md 存"项目是什么"。记忆存"和这个人协作时要注意什么"。
四种类型
| 类型 | 记录什么 | 示例 | |------|----------|------| | user | 用户身份、偏好、背景 | "用户是专注可观测性的数据科学家" | | feedback | 对 Agent 行为的纠正和确认 | "不要在响应末尾总结——用户能自己看 diff" | | project | 项目进展、决策、截止日期 | "2026-03-05 合并冻结,移动端发布" | | reference | 外部系统的定位信息 | "管道 Bug 追踪在 Linear INGEST 项目" |
封闭分类法强制 Agent 做出明确的语义分类,避免标签膨胀。
Feedback 类型:不只记录失败
同时记录纠正和确认。如果只保存纠正,会偏离用户已验证的好方法。
结构化格式
feedback 和 project 类型要求"Why"和"How to apply"结构。知道为什么让 Agent 能判断边界情况而非盲目遵循规则。
相对日期转换为绝对日期
"周四之后合并冻结"必须存为"2026-03-05 后合并冻结"。
什么不该保存
代码模式、Git 历史、调试步骤、CLAUDE.md 已有内容、临时任务细节。这些排除规则即使用户明确要求保存也生效。
Multi-Agent Architecture — Three Modes
Claude Code supports three multi-agent collaboration modes for different task complexities:
Mode 1: Sub-Agent (Fork-Return)
The simplest mode. The parent agent spawns a child agent with a specific task. The child runs in isolation — it has its own conversation context and cannot see the parent's history. When the child completes, it returns its result to the parent.
Parent: "Investigate the auth module"
|
+-- Sub-agent: reads files, runs grep, explores imports
| returns: "Auth uses JWT/RS256, tokens expire in 1h,
| refresh tokens stored in Redis"
|
Parent: integrates result into ongoing work
Sub-agents can run in the background (allowing the parent to continue other work) and can be spawned in isolated git worktrees (giving them a separate working copy for experimental changes without affecting the parent).
Mode 2: Orchestrator (Dispatch + Synthesize)
An orchestrator agent breaks a task into sub-tasks, dispatches multiple sub-agents in parallel, collects their results, and synthesizes a combined output.
The key distinction from simple sub-agent delegation: the orchestrator does not just relay results — it integrates them, resolves conflicts between findings, and produces a coherent output. For example, when auditing a codebase for security issues, an orchestrator might spawn three sub-agents (dependency vulnerabilities, SQL injection patterns, authentication logic) and combine their findings into a unified report.
Mode 3: Swarm Team (Peer-to-Peer Messaging)
The most sophisticated mode. A team of agents is created, each with a defined role (e.g., "frontend developer," "backend developer," "reviewer"). Agents communicate directly via SendMessageTool without a central coordinator.
[Frontend Agent] --"What fields does /api/user return?"--> [Backend Agent]
[Backend Agent] --"id, name, email, avatar_url"---------> [Frontend Agent]
[Frontend Agent] -- builds component using those fields
[Reviewer Agent] -- "avatar_url can be null, add a fallback"
[Frontend Agent] -- adds null check
This enables emergent collaboration — the frontend agent asks the backend agent about API response shapes and uses the answer directly, without an orchestrating model mediating.
This mode is the most flexible but also the hardest to control. Without a central coordinator, agents may pursue tangential discussions or duplicate work. It works best when roles are clearly delineated.
多智能体架构——三种模式
模式 1:子智能体(分叉-返回)
最简单的模式。父智能体生成带有特定任务的子智能体。子智能体在隔离环境中运行,完成后返回结果。可在后台运行或在隔离的 git worktree 中运行。
父智能体: "调查认证模块"
|
+-- 子智能体: 读取文件、运行 grep、探索导入
| 返回: "认证使用 JWT/RS256,令牌 1 小时过期,刷新令牌存储在 Redis"
|
父智能体: 将结果整合到当前工作中
模式 2:编排器(分派 + 综合)
编排智能体将任务分解为子任务,并行分派多个子智能体,收集结果并综合输出。关键区别:它整合结果、解决冲突,而非仅仅转达。
模式 3:群组团队(点对点消息传递)
最复杂的模式。创建具有定义角色的智能体团队,通过 SendMessageTool 直接通信,无需中央协调器。实现涌现式协作——前端智能体问后端智能体 API 结构并直接使用回答。
[前端智能体] --"/api/user 返回哪些字段?"--> [后端智能体]
[后端智能体] --"id, name, email, avatar_url"-> [前端智能体]
[审查智能体] --"avatar_url 可能为 null,加后备"-> [前端智能体]
最灵活但也最难控制,最适合角色明确划分的任务。
Conclusion
Claude Code represents a genuine architectural step beyond code completion and chat assistants. Here is what makes it distinctive:
-
The agent loop with its four-stage compression pipeline keeps long sessions viable — conversations that would overflow context windows in simpler systems are gracefully degraded through progressive compression.
-
The streaming tool executor turns the model's generation time from idle waiting into productive parallel execution. A 5-30 second streaming window becomes an opportunity to pre-execute tools.
-
66+ tools across six categories give it a broad action surface covering 95% of developer workflows.
-
The dual-call skill system makes reusable prompt templates first-class citizens that both the user and the model can invoke, with lazy loading that keeps context costs manageable.
-
The four-type memory system captures not just facts but the reasoning behind them — enabling the agent to judge edge cases rather than blindly following rules.
-
Three multi-agent modes provide a spectrum from simple delegation to emergent peer collaboration.
None of this is magic. It is careful systems engineering — async generators, concurrency controllers, compression heuristics, and well-defined abstractions. For developers building their own agent systems, the open-source code is an invaluable reference. The streaming tool executor pattern alone is worth studying — it is a pattern that could improve any agent framework that currently waits for full model responses before executing tools.
总结
Claude Code 代表了超越代码补全和聊天助手的真正架构进步:
- Agent 循环及其四阶段压缩管道使长会话保持可行
- 流式工具执行器将生成时间从空闲等待转变为高效的并行执行
- 66+ 工具覆盖开发者日常工作流的 95%
- 双重调用技能系统使用户和模型都能调用可复用的提示模板
- 四类记忆系统捕获推理而非仅仅是事实,使 Agent 能判断边界情况
- 三种多智能体模式提供从简单委托到涌现式对等协作的完整谱系
这些都不是魔法——而是精心的系统工程。对于构建自己智能体系统的开发者,这份开源代码是宝贵的参考。仅流式工具执行器模式就值得研究——它可以改善任何等待完整模型响应后才执行工具的框架。