123 lines
5.9 KiB
Markdown
123 lines
5.9 KiB
Markdown
---
|
||
tags: [claude-code, architecture, five-layer, agentic-loop, data-flow, source-analysis]
|
||
create time: 2026-06-09 22:30
|
||
---
|
||
|
||
# 架构全景 - Claude Code 五层架构详解
|
||
|
||
## 概述
|
||
|
||
从交互层到基础设施层,Claude Code 分为五个清晰的架构层次。本文基于源码级数据流分析,建立对整体系统的坐标系。
|
||
|
||
## 正文
|
||
|
||
### 五层架构
|
||
|
||
Claude Code 从上到下分为五个层次,每一层职责清晰、边界分明:
|
||
|
||

|
||
|
||
| 层次 | 职责 | 入口源码 | 关键词 |
|
||
|------|------|---------|--------|
|
||
| **交互层** | 终端 UI、用户输入、消息展示 | `src/screens/REPL.tsx` | React/Ink、PromptInput |
|
||
| **编排层** | 多轮对话、会话持久化、成本追踪 | `src/QueryEngine.ts` | QueryEngine、transcript |
|
||
| **核心循环层** | 单轮:发请求 → 拿响应 → 执行工具 → 循环 | `src/query.ts` | Agentic Loop、State |
|
||
| **工具层** | AI 的"双手"——读写文件、执行命令 | `src/tools.ts` → `src/Tool.ts` | Tool 接口、MCP |
|
||
| **通信层** | 与 Claude API 的流式通信 | `src/services/api/claude.ts` | Streaming、Provider |
|
||
|
||
### 一条主数据流的源码追踪
|
||
|
||

|
||
|
||
整个系统的运转可以浓缩为一条核心数据流,以下是每一步对应的源码路径:
|
||
|
||
#### 1. 用户输入 → REPL
|
||
|
||
`src/screens/REPL.tsx` 是基于 React/Ink 的终端 UI 组件。用户输入经 `processUserInput()`(`src/utils/processUserInput/processUserInput.ts`)处理,支持斜杠命令、文件附件、图片等。
|
||
|
||
#### 2. QueryEngine 编排
|
||
|
||
`src/QueryEngine.ts` 是 REPL 与 `query()` 之间的中间层,管理:
|
||
|
||
- **会话状态**:消息数组、工具权限上下文(`ToolPermissionContext`)、文件历史快照
|
||
- **成本追踪**:`accumulateUsage()` / `getTotalCost()` 累计 token 用量
|
||
- **Transcript 持久化**:`recordTranscript()` 将对话序列化到磁盘,支持 `--resume`
|
||
- **文件历史**:`fileHistoryMakeSnapshot()` 在修改前创建快照,支持 undo
|
||
|
||
关键方法:`queryEngine.query()` 构造 `QueryParams`,调用 `query()` 异步生成器。
|
||
|
||
#### 3. Agentic Loop(`src/query.ts`)
|
||
|
||
`query()` 是一个 `AsyncGenerator`,`while(true)` 循环的每次迭代包含:
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["上下文预处理管道"] -->|"applyToolResultBudget → snipCompact → microcompact → contextCollapse → autocompact"| B["流式 API 调用"]
|
||
B -->|"deps.callModel() → AsyncGenerator StreamEvent"| C["收集 assistantMessages 和 toolUseBlocks"]
|
||
C --> D{"工具执行"}
|
||
D -->|"并行 StreamingToolExecutor"| E["toolResults"]
|
||
D -->|"串行 runTools"| E
|
||
E --> F{"终止/继续判定"}
|
||
F -->|"needsFollowUp = true"| A
|
||
F -->|"needsFollowUp = false"| G["返回 reason"]
|
||
```
|
||
|
||
> [!info] 状态传递
|
||
> 完整的状态机通过 `State` 类型(`src/query.ts:207`)在迭代间传递,包含 10 个字段(messages、autoCompactTracking、maxOutputTokensRecoveryCount 等)。
|
||
|
||
#### 4. 工具层(`src/tools.ts` → `src/Tool.ts`)
|
||
|
||
`getAllBaseTools()`(`src/tools.ts:195`)组装 50+ 工具列表,经过 `filterToolsByDenyRules()` 权限过滤后传给 API。
|
||
|
||
每个工具实现 `Tool<Input, Output, Progress>` 接口(`src/Tool.ts:368`),核心方法链:
|
||
|
||
```
|
||
validateInput() → canUseTool()(UI 层)→ checkPermissions() → call() → ToolResult
|
||
```
|
||
|
||
#### 5. 通信层(`src/services/api/claude.ts`)
|
||
|
||
API 客户端支持 7 种 Provider:
|
||
|
||
- **Anthropic Direct (firstParty)**:默认
|
||
- **AWS Bedrock**:`ANTHROPIC_BEDROCK_BASE_URL`
|
||
- **Google Vertex**:`ANTHROPIC_VERTEX_PROJECT_ID`
|
||
- **Foundry**:`ANTHROPIC_CODE_USE_FOUNDRY`
|
||
- **OpenAI**:兼容层
|
||
- **Gemini**:兼容层
|
||
- **Grok (xAI)**:兼容层
|
||
|
||
`deps.callModel()` 发起流式请求,返回 `BetaRawMessageStreamEvent` 事件流。支持 Prompt Cache(`cache_control`)、thinking blocks、multi-turn tool use。
|
||
|
||
### 四个核心设计原则
|
||
|
||
#### 流式优先 (Streaming-first)
|
||
|
||
所有 API 通信都是流式的——`deps.callModel()` 返回 AsyncGenerator,用户看到 AI "逐字打出"回答。StreamingToolExecutor 在流式过程中就开始并行执行工具,不等流结束。模型降级(Fallback)时,已收集的 assistantMessages 被标记为 tombstone 并清空,重试整个流式请求。
|
||
|
||
#### 工具即能力 (Tool as Capability)
|
||
|
||
每个工具是 `Tool<Input, Output, Progress>` 结构化类型,通过 `buildTool()` 工厂创建。`getTools()` 在每次 API 调用时组装(非全局缓存),因为 `isEnabled()` 可能随运行时状态变化。MCP 工具通过 `mcpInfo` 字段标记来源,支持 server 级别的 blanket deny。
|
||
|
||
#### 权限即边界 (Permission as Boundary)
|
||
|
||
每次工具调用经过 `validateInput() → checkPermissions()` 双重检查。权限规则从 5 个来源汇聚(session → project → user → managed → default),支持工具名、命令模式、路径前缀等匹配方式。Plan Mode 通过 `prepareContextForPlanMode()` 切换为只读模式,退出时自动恢复。
|
||
|
||
#### 上下文即记忆 (Context as Memory)
|
||
|
||
System Prompt 由 `fetchSystemPromptParts()` 动态组装,包含 CLAUDE.md、git 状态、日期、MCP 服务器列表。Auto-compact 在每轮迭代前评估 token 阈值,超出时触发压缩。压缩后的摘要通过 `buildPostCompactMessages()` 替换原始消息,`taskBudgetRemaining` 跨压缩边界累计。
|
||
|
||
### 入口与引导
|
||
|
||
| 入口 | 文件 | 说明 |
|
||
|------|------|------|
|
||
| CLI 启动 | `src/entrypoints/cli.tsx` | 注入 `feature()` polyfill(始终返回 false)、MACRO 全局变量 |
|
||
| 命令定义 | `src/main.tsx` | Commander.js 解析参数,初始化 auth/analytics/policy |
|
||
| 一次性初始化 | `src/entrypoints/init.ts` | 遥测配置、信任对话框 |
|
||
| 管道模式 | `src/main.tsx` `-p` flag | `echo "say hello" \| bun run dev -p` |
|
||
|
||
## 关联笔记
|
||
|
||
- [[what-is-claude-code]]
|
||
- [[why-this-whitepaper]]
|