ClaudeCode 源码泄露!浅析 51 万行源码
今天 Claude Code 的 npm 包被人发现暴露了 source map,顺着 .map 文件直接从 Anthropic 的 R2 存储桶下载到了完整的 TypeScript 源码。1900 个文件,51 万行代码。
我花了几个小时把整个代码库读了一遍。作为每天重度使用 Claude Code 的人,看到引擎盖下面的东西,有几个发现挺反直觉的。
多 Agent 协调没有编排引擎
这是整个代码库最让我意外的设计决策。
Claude Code 的 coordinator 模式——就是你用 Agent 工具派子任务、多个 worker 并行干活那个功能——整个模块只有一个文件,370 行代码,没有状态机,没有 DAG,没有 workflow engine。
它的”编排逻辑”是什么呢?一段 300 行的 system prompt。
就是用自然语言教模型”你现在是协调者,用 AgentTool 派 worker,只读任务并行、写任务串行、worker 结果通过 XML 标签注入消息队列”——然后模型就学会了协调。包括什么时候该 spawn 新 worker、什么时候该 SendMessage 续接老 worker、什么时候该自己动手,全部靠 prompt 驱动。
这让我重新思考了一个问题——在 LLM 能力足够强的前提下,很多传统的”编排框架”可能是过度工程。你不需要写一个 DAG executor 来管理任务依赖,你只需要把规则用自然语言说清楚。
终端 UI 是 React 渲染的
不是”用了 Ink 库”这么简单。他们把 Ink 做了深度 fork,重写了从布局到渲染到输出的整个管线,搞了一个完整的终端渲染引擎。
有多完整呢:
-
双缓冲帧系统——前后两个缓冲区交替渲染,目标 60fps -
字符串 interning 池——每个 cell 的样式和字符做 intern,diff 时用整数比较代替字符串比较 -
DECSTBM 硬件滚动——当只是滚动内容时,不重绘整个屏幕,用一条终端指令替代 O(rows×cols) 的重写 -
鼠标拖拽选择——支持双击选词、三击选行,还处理了滚动超出视口的边界情况 -
CJK IME 光标声明——组件可以声明”终端光标应该停在这里”,解决中日韩输入法的预编辑文本定位问题
还有 140 个 UI 组件全部经过 React Compiler 编译,自动做细粒度 memoization。
这个工程量放到任何公司都是一个独立产品级别的投入。但他们把它做成了一个 CLI 的渲染层。
五层压缩让对话永远不会爆
Claude Code 能处理超长会话——跑一天都不会 context overflow——背后是一套五层递进的压缩体系:
-
第一层 API Microcompact——服务端原生管理,自动清除旧的工具调用结果和 thinking 块 -
第二层 Client Microcompact——按时间维度清除可压缩工具(Read/Bash/Grep)的输出 -
第三层 Context Collapse——折叠冗余上下文 -
第四层 Auto Compact——fork 一个子 agent 生成对话摘要,替换原始消息 -
第五层 Reactive Compact——prompt too long 时按轮次从头部丢弃
有个细节很有意思——Auto Compact 有一个 circuit breaker,连续失败 3 次就停止重试。代码注释里写着原因:BigQuery 数据显示曾经有一个 session 连续压缩失败 3272 次,浪费了每天 25 万次 API 调用。
Compact 之后还会恢复最近读过的 5 个文件(各限 5000 token),加上 Skill 重注入(独立 25000 token 预算)。所以压缩完了你不会觉得模型”忘了之前在干嘛”。
89 个 Feature Flag 暴露了未发布的产品方向
Claude Code 用 Bun 的编译时 dead code elimination 做特性门控——feature('XXX') 在构建时被替换成 true/false,不满足条件的分支在外部构建版本中物理不存在。
一共 89 个开关。大部分是已有功能的灰度控制,但有几个暴露了还没发布的方向:
-
KAIROS——出现频率最高的未知代号,关联了 KAIROS_BRIEF、KAIROS_CHANNELS、KAIROS_DREAM、KAIROS_GITHUB_WEBHOOKS、KAIROS_PUSH_NOTIFICATION 五个子 flag。看起来是一个主动模式的 Agent 系统 -
PROACTIVE——主动模式,Agent 不等用户指令就能行动 -
DAEMON——守护进程模式,Claude Code 可以作为后台服务运行 -
VOICE_MODE——语音模式,hold-to-talk 语音输入,后端是 Deepgram STT -
BUDDY——一个宠物伴侣系统,18 种物种(鸭子、龙、水豚…),5 种稀有度,纯彩蛋
KAIROS + PROACTIVE + DAEMON 组合起来看,Anthropic 的方向很清楚——Claude Code 未来不只是一个你打开来用的 CLI,而是一个一直在后台跑的主动 Agent,能监听 GitHub webhook、主动推送通知、在你不在的时候帮你干活。
推测执行:你还没输入,它已经开始干了
源码里有一个 speculation 模块——在你还没输入下一条指令的时候,它会预测你的下一步,然后在一个 overlay 文件系统上提前执行。最多跑 20 轮、100 条消息。
写工具被限制在 overlay 目录里(不会真的改你的代码),但读工具可以访问真实文件系统。等你真的输入了,如果预测对了就直接用结果,预测错了就丢弃。
这个设计解释了为什么有时候你按回车,Claude Code 的响应速度快得不像是实时调 API 的——因为它可能在你打字的时候就已经算完了。
Prompt Cache 是一等公民
读完代码最大的感受是——Anthropic 对 prompt cache 的优化程度远超我的想象。几乎所有架构决策都在围绕”减少 cache bust”展开:
-
系统提示词被分成静态和动态两段,用边界标记分隔,静态部分可以跨组织全局缓存 -
Beta header 用 sticky-on latch——一旦触发就保持不变,防止 header 翻转导致 cache 失效 -
工具 schema 延迟加载——不常用的工具不在初始 prompt 里放完整 schema,模型通过 ToolSearch 按需获取 -
Agent Summary 生成进度摘要时,工具全部 deny 但不清空数组——因为清空会改变 tool schema 字段从而 bust cache -
Fork 子 agent(compact/记忆提取/推测执行)共享主对话的 prompt cache
每一条都不是什么惊天动地的优化,但叠在一起就是 Claude Code 用起来”又快又便宜”的原因。这种对成本的精细控制,从源码里能看到是融在每个设计决策里的,不是事后优化。
其他值得注意的设计
记忆系统用 LLM 做相关性检索
Claude Code 的记忆不是全量加载的。它会用 Sonnet 做一次 side query,从所有记忆文件的 frontmatter(标题和描述)里选最多 5 个最相关的加载。不用向量数据库,不用 embedding——直接让语言模型判断相关性。
Vim 模式是教科书级状态机
支持操作符+motion 组合(dw、c$)、计数前缀(3dd)、文本对象(diw、ci”)、dot repeat、寄存器——全部用纯函数实现,transitions.ts 里的状态转移表写得非常干净。
宠物彩蛋的 anti-leak 策略
Buddy 系统里有 18 种物种(鸭子、水豚、龙…),其中一个物种名和内部模型代号撞了。因为构建流程会 grep 构建产物检查代号泄露,所以这个物种名用 String.fromCharCode 编码来绕过检测。讽刺的是,这次泄露让源码里的绕过逻辑也暴露了。
读完之后的几个感受
1. 能用 prompt 解决的就不用代码——coordinator 模式是最好的例子。在模型能力足够强的前提下,300 行 prompt 比 3000 行编排框架更灵活、更好维护。
2. Fail-closed 是工具系统的正确默认值——所有工具默认不并发安全、不只读、不安全,需要显式声明。这意味着忘了标记一个属性的后果是”多问一次权限”而不是”数据损坏”。
3. 成本控制融入架构而非事后优化——prompt cache 的分段缓存、工具 schema 延迟加载、fork agent 共享 cache、compact 的 circuit breaker,每个设计决策都在考虑 API 调用成本。
4. 终端应用值得一流的 UI 工程投入——他们把 React + Yoga Layout 搬到了终端里,从字符级缓冲区到硬件滚动到 IME 支持全部从头做。这不是”差不多能用”,这是”浏览器级体验”。
然后回到一开始说的——这次泄露的核心不是安全问题(源码不含 API 密钥),而是让所有人看到了一个顶级团队怎么从零设计一个 AI 编程工具的内部架构。51 万行代码,每个模块读下来都有收获。
下面是完整的模块级架构拆解。如果你也在做 AI 工具或 Agent 框架,建议收藏慢慢看。
附录:完整架构拆解(34 个模块)
技术栈总览
代码量 ~1900 文件、51 万行 TypeScript。运行时 Bun,终端 UI React + 深度定制 Ink,CLI 框架 Commander.js,Schema 验证 Zod v4,布局引擎自研 Yoga-layout TS 移植,Feature Flag GrowthBook(89 个编译时开关),认证 OAuth 2.0 + JWT + macOS Keychain,遥测 OpenTelemetry + gRPC + BigQuery,协议 MCP SDK + LSP。
一、核心引擎(6 个模块)
query/ — LLM 查询引擎
核心是 queryLoop()——一个 while(true) 的 AsyncGenerator 循环,每次迭代代表一次”LLM 请求 + 工具执行”。单次迭代流程:applyToolResultBudget → snipCompact → microcompact → contextCollapse → autocompact → callModel (streaming) → StreamingToolExecutor 并行执行工具 → handleStopHooks → 决定 continue/return。7 种 continue 原因构成内部状态机——reactive_compact_retry(压缩后重试)、max_output_tokens_recovery(输出截断续写)、token_budget_continuation(预算还够继续干)等。Memory prefetch 在迭代开始时 fire-and-forget,利用模型流式输出的时间窗口做预加载。
tools/ — 工具系统
核心类型 Tool 约 700 行、35+ 方法。60+ 工具通过 buildTool() 工厂函数构建,安全默认值全部 fail-closed(isConcurrencySafe 默认 false、isReadOnly 默认 false)。工具分类:文件操作(Read/Edit/Write/Glob/Grep)、执行(Bash)、网络(WebFetch/WebSearch)、Agent 相关(AgentTool/SendMessage/TaskCreate 等)、团队(TeamCreate/Delete)、MCP(MCPTool 动态代理外部工具)、元工具(ToolSearch 延迟加载 schema、EnterPlanMode、Skill)。StreamingToolExecutor 在模型流式输出时就开始执行工具,不等流完。
coordinator/ — 多 Agent 编排
只有一个文件 370 行。没有状态机、没有 DAG、没有 workflow engine——全靠 ~300 行 system prompt 驱动。prompt 里教模型任务工作流(Research → Synthesis → Implementation → Verification)、worker prompt 写作规范、并发管理规则(只读并行/写串行)、Continue vs Spawn 决策矩阵。Worker 结果通过 XML <task-notification> 注入为 user message。
hooks/ — Hook 系统
两层架构。第一层:20+ 种生命周期事件(PreToolUse/PostToolUse/Stop/SessionStart/PreCompact/PermissionDenied/FileChanged/TaskCreated 等),Hook 是用户定义的 shell 命令,stdin 传 JSON、stdout 返 JSON,支持 matcher 模式匹配和异步模式。第二层:权限决策系统 useCanUseTool,决策链是规则匹配 → handler 分派 → ML 分类器(auto-mode)→ PreToolUse hook,多路 race 谁先到用谁。Bash 工具在权限请求前预先启动分类器检查(speculative)。
state/ — 状态管理
35 行极简 Store(Object.is 判等 + Set<Listener> 通知),没有 middleware。AppState 约 450 行的巨型类型用 DeepImmutable 包裹——涵盖权限规则、后台任务、MCP 连接、插件状态、推测执行、团队上下文、消息收件箱、Computer Use 状态等。子 agent 的 setAppState 可设为 no-op 防污染,但 setAppStateForTasks 始终连接根 store。
tasks/ — 任务系统
7 种任务类型:LocalShellTask、LocalAgentTask、RemoteAgentTask、InProcessTeammateTask、LocalWorkflowTask、MonitorMcpTask、DreamTask(记忆整理)。Ctrl+B 后台化当前查询时创建 LocalMainSessionTask,有独立 transcript 文件,完成后通过 task-notification 通知。DreamTask 的 kill 会回滚 consolidation lock 的 mtime,让下次 session 可以重试。
二、UI 与交互(8 个模块)
ink/ — 自定义终端渲染引擎
深度 fork 的完整渲染引擎。渲染管线:React 组件树 → reconciler → 自定义 DOM(7 种节点)→ Yoga 布局 → renderer → 字符级 Screen 缓冲区(CharPool/StylePool/HyperlinkPool 做字符串 interning)→ diff 优化器 → ANSI 写入。双缓冲帧系统 16ms/帧(60fps 目标),DECSTBM 硬件滚动替代全屏重绘,Alt Screen 模式进入备用屏幕缓冲区(ctrl+o 看 transcript 时主对话不丢失),完整的鼠标拖拽选择(双击选词/三击选行),CJK IME 光标声明系统。
components/ — 140+ React 终端 UI 组件
FullscreenLayout 三区布局(可滚动消息区 + 底部固定 prompt + 模态层),VirtualMessageList 虚拟滚动只渲染可见区域,PromptInput 20+ 文件(输入框/footer/模式指示器/自动补全/语音指示器),StructuredDiff 文件编辑 diff 可视化,design-system 包含 Dialog/Pane/Tabs/ProgressBar 等基础 UI 原语。所有组件经 React Compiler 编译自动细粒度 memoization。
screens/ — 三个独立应用模式
REPL.tsx(主交互界面,~700+ 行导入)、Doctor.tsx(诊断屏幕,类似 flutter doctor)、ResumeConversation.tsx(会话恢复,支持跨项目/worktree/PR 恢复)。REPL 的条件导入机制用 feature() + require 做编译时 DCE。
commands/ — ~80+ 斜杠命令
四种来源优先级(bundled skills → plugin skills → skill dir → workflows → plugin → COMMANDS)。三种类型:prompt(注入对话)、local(本地执行)、local-jsx(渲染 React UI)。主要命令:会话(/clear /compact /resume /rewind /tag)、开发(/commit /diff /review /bughunter /plan /autofix-pr)、配置(/config /model /theme /vim /keybindings /permissions /hooks)、MCP(/mcp /plugin /skills)、诊断(/doctor /help /cost /usage /stats)。/insights 用 lazy shim(113KB 实际调用才 import),getDynamicSkills 在文件操作中发现新 skill。
keybindings/ — 可自定义快捷键
17 个上下文、Chord 序列(如 ctrl+x ctrl+k,1 秒超时)、热重载(~/.claude/keybindings.json)、平台自适应(Windows 降级绑定)、保留键(ctrl+c/ctrl+d 时间双击检测不可重绑)。
vim/ — 教科书级有限状态机
纯函数实现:transitions.ts(状态转移表)、motions.ts(光标移动 h/j/k/l/w/b/e/0/^/$)、operators.ts(delete/change/yank)、textObjects.ts(iw/aw/i”/a()。支持操作符+motion 组合、计数前缀、dot repeat、寄存器、缩进、替换。MAX_VIM_COUNT = 10000 防止 99999dd。
outputStyles/ — 输出样式
98 行极简实现。扫描 .claude/output-styles/*.md,文件内容作为 system prompt 注入,keep-coding-instructions 标志控制是否保留默认编码规范。
voice/ — 语音模式
Hold-to-talk,WebSocket 连接 Anthropic voice_stream 端点(Deepgram 后端),二进制音频帧 + JSON 控制消息。Hold 检测:bare-char 绑定需 5 次连续快速按键才激活(避免误触),修饰键组合首次即可。三级超时 finalize。支持 20+ 种语言。Feature flag 做编译时 DCE,外部构建不含语音代码。
三、服务层(18 个子模块)
services/api——封装 Anthropic API 交互。queryModelWithStreaming 核心函数,withRetry 指数退避,errors.ts 解析 prompt_too_long 的 token gap 用于 compact 精确裁剪。
services/mcp——完整 MCP 客户端,4 种传输层(Stdio/SSE/StreamableHTTP/WebSocket)。Cross-App Access 实现 RFC 8693 Token Exchange + RFC 7523 JWT Bearer Grant。二进制 blob 自动持久化、图片自动缩放下采样。
services/oauth——Claude.ai 和 Console 两套 OAuth 流程,PKCE (S256)。URL 参数 code=true 触发 Claude Max 升级提示——产品增长策略直接写在代码里。
services/compact——五层压缩体系(API Microcompact → Client Microcompact → Context Collapse → Auto Compact → Reactive Compact)。Auto Compact 有 circuit breaker——BQ 数据显示曾有 session 连续失败 3272 次浪费 250K API 调用/天。Post-compact 恢复最近 5 个文件 + Skill 重注入(独立 25K token 预算)。
services/lsp——连接外部 LSP 服务器获取代码诊断,passiveFeedback 转换为 attachment 被动注入上下文。
services/extractMemories——每次对话结束 fork 主对话(共享 prompt cache),子 agent 模式自动提取记忆。工具限制只能 Read/Grep/Glob + Edit/Write(限 memory 目录)。
services/teamMemorySync——按 git repo 隔离的团队记忆同步,Pull server wins,Push 增量上传(content hash diff),上传前 secretScanner 扫描敏感信息。
services/SessionMemory——后台周期性维护的 markdown 会话记忆,forked subagent 模式,与 compact 协作同步 last summarized message id。
services/AgentSummary——coordinator 模式下每 30 秒 fork 子 agent 生成 3-5 词进度摘要。工具全部 deny 但不清空数组——否则会 bust prompt cache。
services/speculation——推测执行,用户没输入时在 overlay 文件系统预执行,最多 20 轮 100 条消息。写工具限制在 overlay 目录,读工具访问真实文件系统。
services/policyLimits + remoteManagedSettings——企业策略限制和远程设置。Fail-open 设计,ETag 缓存 + 每小时后台轮询。
services/autoDream——后台记忆整合(”做梦”),三级门控:时间门(≥24h)→ 会话门(≥5 session)→ 锁。
services/MagicDocs——检测到 # MAGIC DOC: [title] 标记的 markdown 后自动更新文档。
services/tips——spinner 等待时显示使用提示,LRU 策略选最久没显示的。
bridge/——IDE 集成桥接(Remote Control),两代架构并存:Env-based v1(Environments API poll/dispatch)和 Env-less v2(直连 session-ingress)。默认 32 session spawn 池,JWT 自动刷新,Trusted Device Token。
server/——Direct Connect 服务端,WebSocket 直连 Claude Code 实例。
remote/——CCR 远程会话客户端。WebSocket 订阅 + HTTP POST 发送,5 次重连,4001 有限重试(compaction 期间可能暂时找不到 session),4003 立即放弃。
plugins/ + skills/——插件 ID 格式 {name}@builtin,可提供 skills + hooks + MCP servers。技能三种来源:Bundled(编译到二进制)、Disk(~/.claude/skills/)、MCP Skills。
四、辅助模块(13 个)
bootstrap/——Import DAG 叶节点(ESLint 规则 bootstrap-isolation 强制),~80 字段 State 单例。Prompt cache 优化:beta header 用 sticky-on latch(一旦触发就保持不变),系统提示词缓存 Map。
cli/——print.ts(–print 非交互单次查询)、structuredIO.ts(SDK JSON 模式 I/O)、transports/(HybridTransport/SSE/WebSocket/CCR Client)。
constants/——16 个 Beta Header、89 个编译时 Feature Flag、系统提示词组装。提示词分静态(跨组织可全局缓存)和动态(session-specific)两段,用 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 标记分隔。动态部分包括 memory、env_info、language、output_style、mcp_instructions(uncached,因可热连接)、token_budget 等。
types/——Permission Modes(acceptEdits/bypassPermissions/default/dontAsk/plan/auto/bubble),决策三态(allow 可携带 updatedInput、ask 可携带 pendingClassifierCheck、deny 必须含 decisionReason),Yolo Classifier 两阶段(stage1 fast XML + stage2 thinking)。
utils/——最大模块 400+ 文件。bash/(tree-sitter AST 解析)、model/(模型配置/Bedrock/Vertex 适配)、permissions/(YOLO 分类器)、settings/(分层 user/project/local/flag/policy/MDM)、swarm/(tmux/iTerm/in-process 后端)、computerUse/、secureStorage/(macOS Keychain)、telemetry/(OTel/BigQuery/Perfetto)。
migrations/——9 个幂等迁移。模型名称链:Fennec → Opus → Opus[1m]、Sonnet[1m] → Sonnet 4.5 → Sonnet 4.6。
memdir/——四类记忆(user/feedback/project/reference),findRelevantMemories 用 Sonnet 侧查询从 frontmatter 选最多 5 个加载。安全性:autoMemoryDirectory 不接受 projectSettings 来源。
native-ts/——三个 Rust/C++ NAPI 依赖的纯 TS 重写:yoga-layout(Flexbox 引擎)、color-diff(highlight.js 替代 syntect,延迟加载 190+ 语言 ~50MB)、file-index(fzf-v2 风格评分,4ms 时间片异步索引构建)。
upstreamproxy/——CCR 容器专用。读 session token → prctl 禁止 ptrace → 下载 CA 证书 → CONNECT→WebSocket relay(GKE L7 不支持原生 CONNECT)→ 删除 token 文件。Fail-open。
buddy/——宠物彩蛋。18 种物种、6 种眼睛、5 种稀有度,Mulberry32 伪随机。有个物种名和模型代号碰撞,用 String.fromCharCode 编码绕过构建流程的代号泄露检测。
entrypoints/——cli.tsx 按顺序检查快速路径(–version/–dump-system-prompt/remote-control/daemon/ps/logs),ABLATION_BASELINE 一键关闭所有增强功能用于 A/B 对比。mcp.ts 让 Claude Code 自身作为 MCP 服务器运行(服务名 claude/tengu)。
assistant/——远程会话历史拉取(CCR 场景),OAuth 认证访问 /v1/sessions/{id}/events,分页游标。
五、跨模块依赖图
用户输入 → QueryEngine.submitMessage() ↓ queryLoop() [while(true) AsyncGenerator] ↓ callModel (streaming) → services/api → Anthropic API ↓ StreamingToolExecutor → toolOrchestration (partitionToolCalls) ↓ useCanUseTool → hooks/toolPermission → ML Classifier ↓ Tool.call() → 60+ 具体工具 ↓ PostToolUse hooks → handleStopHooks() ↓ extractMemories (fork) → memdir/ SessionMemory (fork) PromptSuggestion/speculation (fork) AgentSummary (fork) ↓ AppState → state/store.ts ↓ tasks/ → 7 种后台任务类型 ↓ UI: ink/ → components/ → screens/REPL.tsx
六、10 条核心设计理念
-
Forked Agent 模式——compact/extractMemories/SessionMemory/AgentSummary/speculation 全部 fork 主对话共享 prompt cache -
bootstrap isolation——全局状态是 import DAG 叶节点,ESLint 规则强制,杜绝循环依赖 -
Prompt cache 是一等公民——系统提示词静态/动态分段、beta header sticky latch、工具 schema 延迟加载、fork agent 共享 cache -
性能是一等公民——字符串 interning、DECSTBM 硬件滚动、blit 优化、帧时间追踪、yoga 缓存命中追踪 -
React 渲染终端——不是”使用 Ink”,而是自定义终端渲染引擎,保留 React reconciler 接口但重写整个管线
夜雨聆风