犀牛鸟 2026 研究笔记 estelledc.github.io

Claude Code 总架构:输入 → Prompt → API → Tool → State 全链路

一句话定位:Claude Code 是一个以 AsyncGenerator 驱动的 turn-loop Agent 运行时,通过「消息压缩管线 → 模型流式调用 → 工具并发执行 → 状态回写」的无限循环实现自主编程。

调研时间:2026-06-22
依据版本:泄露源码包(2026-03-31 npm source maps,约 1900 文件 / 512K+ 行)
CLI 版本:未实测(需 v2.1.154+),仅源码 + 文档分析
官方文档:code.claude.com/docs(截至 2026-06)


证据等级汇总

结论 来源
五层架构模型 [源码]
queryLoop 为 AsyncGenerator while(true) 循环 [源码] query.ts
消息压缩管线(snip → microcompact → collapse → autocompact) [源码] query.ts
Feature flag 使用 bun:bundle 编译时 DCE [源码] 全局
50+ feature flags 存在 [源码] grep 统计
AppState 全局单例 80+ 字段 [源码] bootstrap/state.ts
7 种 TaskType [源码] Task.ts
Dynamic Workflow 为 JS 编排脚本 [文档][引用]
Ultracode = xhigh + 自动 workflow 决策 [文档]

日常类比

把 Claude Code 想象成一个自助餐厅的智能服务员

类比边界:真实系统中”服务员”是异步流式的,可以同时切多道菜(并发工具执行),且有复杂的权限系统决定哪些菜能做。


五层架构模型

graph TB
    subgraph L1["Layer 1: CLI / 入口"]
        CLI[CLI Parser] --> Bootstrap[Bootstrap]
        SDK[SDK / Desktop] --> Bootstrap
    end

    subgraph L2["Layer 2: 会话管理"]
        Bootstrap --> ProcessInput[processUserInput]
        ProcessInput --> |"slash cmd"| SlashCmd[Slash Commands]
        ProcessInput --> |"bash"| BashCmd[Bash Mode]
        ProcessInput --> |"text"| QueryEntry[query() 入口]
    end

    subgraph L3["Layer 3: 核心循环 queryLoop"]
        QueryEntry --> CompressPipeline[消息压缩管线]
        CompressPipeline --> APICall[callModel 流式调用]
        APICall --> ToolDispatch[工具分发]
        ToolDispatch --> |"needsFollowUp"| CompressPipeline
        ToolDispatch --> |"完成"| StopHooks[Stop Hooks]
    end

    subgraph L4["Layer 4: 基础设施"]
        Permissions[权限系统]
        Compact[Compact 服务]
        Memory[Memory 系统]
        Analytics[Analytics / OTel]
    end

    subgraph L5["Layer 5: 多 Agent"]
        Coordinator[Coordinator Mode]
        Swarm[Swarm / Teams]
        Subagent[Subagent / AgentTool]
        Workflow[Dynamic Workflow]
    end

    ToolDispatch --> Permissions
    CompressPipeline --> Compact
    QueryEntry --> Memory
    APICall --> Analytics
    ToolDispatch --> L5

各层职责 [源码]

核心文件 职责
L1 入口 src/cli.ts, src/bootstrap/ 参数解析、环境初始化、AppState 创建
L2 会话 src/utils/processUserInput/ 用户输入分流(slash/bash/text)、图片处理、hook 拦截、ultraplan 关键词检测
L3 核心循环 src/query.ts (1730 行) while(true) 主循环、压缩管线、API 调用、工具执行、错误恢复
L4 基础设施 src/services/, src/utils/permissions/ 权限、压缩、记忆、分析、缓存
L5 多 Agent src/coordinator/, src/utils/swarm/, src/tasks/ 协调器、团队、子 agent、工作流

核心循环:queryLoop 详解

query.tsqueryLoop 是整个系统的心脏——一个 AsyncGenerator<StreamEvent | Message, Terminal>while(true) 中运行 [源码]

┌─────────────────────────────────────────────────────────┐
│                    queryLoop (while true)                 │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  1. 消息压缩管线                                         │
│     snip → microcompact → contextCollapse → autocompact  │
│                                                          │
│  2. 组装 system prompt + 附件                            │
│     fullSystemPrompt + attachments + memory prefetch     │
│                                                          │
│  3. 调用模型 (deps.callModel)                            │
│     流式接收 assistant 消息 + tool_use blocks            │
│                                                          │
│  4. 工具执行                                             │
│     StreamingToolExecutor (并发) 或 runTools (串行)       │
│                                                          │
│  5. 循环决策                                             │
│     needsFollowUp? → 组合新 messages → continue          │
│     !needsFollowUp? → stopHooks → return Terminal        │
│                                                          │
│  错误恢复路径:                                           │
│     prompt_too_long → reactive compact → retry           │
│     max_output_tokens → escalate 64K → recovery ×3      │
│     model_fallback → 切换 fallback model                 │
│                                                          │
└─────────────────────────────────────────────────────────┘

关键伪代码(精简自 query.ts)[源码]

async function* queryLoop(params) {
  let state = { messages, turnCount: 1, ... }
  while (true) {
    // Phase 1: 压缩
    messages = snip(messages)          // 历史裁剪
    messages = microcompact(messages)  // 工具结果精简
    messages = collapse(messages)      // 上下文折叠
    messages = autocompact(messages)   // 全量摘要压缩

    // Phase 2: 调用模型
    for await (const msg of callModel(messages, systemPrompt, tools)) {
      yield msg  // 流式输出给 UI
      if (msg has tool_use) toolUseBlocks.push(...)
    }

    // Phase 3: 判断是否需要继续
    if (!needsFollowUp) {
      yield* handleStopHooks(...)
      return { reason: 'completed' }
    }

    // Phase 4: 执行工具
    for await (const result of runTools(toolUseBlocks)) {
      yield result
      toolResults.push(result)
    }

    // Phase 5: 组合下一轮消息
    state.messages = [...messages, ...assistantMsgs, ...toolResults]
    state.turnCount++
  }
}

消息压缩管线

Claude Code 的上下文管理是四级递进的 [源码]

级别 机制 触发条件 效果
L0 Snip 历史裁剪 HISTORY_SNIP flag 移除最早的消息块
L1 Microcompact 工具结果精简 每轮自动 大结果持久化到文件,替换为引用
L2 Context Collapse 上下文折叠 CONTEXT_COLLAPSE flag 折叠中间轮次的详细内容
L3 Autocompact 全量摘要 token 超阈值 用 Sonnet 生成摘要替换历史

Autocompact 的阈值计算 [源码]effectiveContextWindow - 13K buffer,连续失败 3 次后熔断。

与 LangGraph 对比

维度 Claude Code LangGraph
上下文管理 四级压缩管线,自动触发 Checkpoint + 手动 trim
状态持久化 AppState 单例 + 文件系统 Channel + StateGraph
恢复策略 reactive compact + escalate GraphInterrupt + resume

AppState:全局状态单例

bootstrap/state.ts 定义了一个 80+ 字段的全局状态对象 [源码],核心域:

AppState
├── 项目身份: cwd, projectRoot, sessionId
├── 模型配置: mainLoopModel, effortValue, advisorModel
├── 权限: toolPermissionContext (mode + rules)
├── 计费: totalCostUSD, modelUsage (per-model buckets)
├── 遥测: OpenTelemetry meter/counter/tracer
├── Agent: agentColorMap, sessionCreatedTeams
├── Prompt 缓存: afkModeHeaderLatched, fastModeHeaderLatched (sticky-on)
├── MCP: clients, tools, resources
├── 任务: taskStates (Map<id, TaskState>)
└── Skill: invokedSkills (Map, 跨 compaction 保留)

设计亮点:Prompt 缓存的 “sticky-on latch” 模式——beta header 一旦激活就不再关闭,避免反复切换导致服务端 prompt cache 被 bust(约 20K tokens/次)。


Feature Flag 系统:编译时 DCE

Claude Code 使用 bun:bundlefeature() 宏实现编译时死代码消除 [源码]

import { feature } from 'bun:bundle'

// 编译时求值,false 分支被完全剔除
const reactiveCompact = feature('REACTIVE_COMPACT')
  ? require('./services/compact/reactiveCompact.js')
  : null

这意味着存在至少两种构建产物:

已识别 50+ 个 feature flag,按功能域分类:

代表性 Flag
压缩 REACTIVE_COMPACT, CACHED_MICROCOMPACT, CONTEXT_COLLAPSE, HISTORY_SNIP
多 Agent COORDINATOR_MODE, WORKFLOW_SCRIPTS, FORK_SUBAGENT, TEAMMEM
助手模式 KAIROS, KAIROS_DREAM, KAIROS_CHANNELS, PROACTIVE
工具 CHICAGO_MCP, MONITOR_TOOL, WEB_BROWSER_TOOL, EXPERIMENTAL_SKILL_SEARCH
安全 TRANSCRIPT_CLASSIFIER, NATIVE_CLIENT_ATTESTATION, BASH_CLASSIFIER
性能 TOKEN_BUDGET, QUICK_SEARCH, FAST_MODE (via GrowthBook)

运行时 flag:除编译时 DCE 外,还有 GrowthBook(远程配置平台)提供的运行时 flag,通过 getFeatureValue_CACHED_MAY_BE_STALE() 读取。


Task 类型系统

Task.ts 定义了 7 种任务类型 [源码]

TaskType ID 前缀 用途
local_bash b/ 本地 shell 命令
local_agent a/ 本地子 agent(AgentTool)
remote_agent r/ 远程 agent(CCR)
in_process_teammate t/ 进程内队友(Swarm)
local_workflow w/ 本地工作流脚本
monitor_mcp m/ MCP 监控
dream d/ 自主思考(KAIROS)

tasks.ts 使用 feature flag 条件加载 [源码]


模块依赖表

模块 可读性 说明
src/query.ts [源码] 完整 1730 行 核心循环
src/utils/processUserInput/ [源码] 4 文件 输入处理
src/utils/systemPrompt.ts [源码] 完整 Prompt 优先级逻辑
src/constants/systemPromptSections.ts [源码] 完整 Section 缓存机制
src/services/api/claude.ts [源码] 3420 行 API 调用全链路
src/services/tools/toolOrchestration.ts [源码] 189 行 工具调度
src/services/tools/StreamingToolExecutor.ts [源码] 531 行 流式工具执行
src/services/tools/toolExecution.ts [源码] 1746 行 单工具执行
src/services/tools/toolHooks.ts [源码] 651 行 Hook 生命周期
src/utils/permissions/permissions.ts [源码] 1487 行 权限管线
src/services/compact/compact.ts [源码] 1706 行 全量压缩
src/services/compact/autoCompact.ts [源码] 自动压缩触发
src/Task.ts [源码] Task 类型定义
src/tasks.ts [源码] Task 注册表
src/utils/task/framework.ts [源码] 309 行 任务轮询框架
src/coordinator/coordinatorMode.ts [源码] 协调器模式
src/utils/swarm/ [源码] 22 文件 团队系统
src/memdir/ [源码] 记忆系统
src/bootstrap/state.ts [源码] 全局状态
LocalWorkflowTask 实现 [引用] 仅 stub 被 WORKFLOW_SCRIPTS flag 守护
Dynamic Workflow JS 脚本 [文档] 官方文档描述

数据流全链路

sequenceDiagram
    participant User
    participant PUI as processUserInput
    participant QL as queryLoop
    participant Compress as 压缩管线
    participant API as claude.ts
    participant Tools as toolOrchestration
    participant Perm as permissions

    User->>PUI: 输入文本/图片/slash命令
    PUI->>PUI: 分流(slash/bash/text)
    PUI->>PUI: 执行 UserPromptSubmit hooks
    PUI->>QL: messages + shouldQuery=true

    loop while(true)
        QL->>Compress: snip → micro → collapse → auto
        Compress-->>QL: 压缩后 messages
        QL->>API: callModel(messages, prompt, tools)
        API-->>QL: stream assistant + tool_use blocks

        alt 无 tool_use
            QL->>QL: handleStopHooks
            QL-->>User: return Terminal
        else 有 tool_use
            QL->>Tools: runTools / StreamingToolExecutor
            Tools->>Perm: hasPermissionsToUseTool
            Perm-->>Tools: allow/deny/ask
            Tools-->>QL: tool results
            QL->>QL: messages += assistant + results
        end
    end

局限性


下一步