Feisky 让 AI 成为你的第二大脑

AI

Claude Code 源码泄漏:51万行代码里藏着什么

Claude Code 因 npm 包中遗留的 source map 文件导致全部源码泄漏。本文分析泄漏经过,拆解 51 万行 TypeScript 源码中的核心架构、隐藏功能和工程细节。

今天下午,安全研究员 Chaofan Shou 在 X 上发了一条帖子,几个小时内阅读量冲到了将近 800 万:

Chaofan Shou 的推文截图

Claude Code 的完整源码,通过 npm 包里一个没删干净的 source map 文件,全部暴露了。截图里那个 57MB 的 cli.js.map 就是罪魁祸首,下面的 ls -alht src 列出的就是泄漏的完整源码目录。

作为一个每天都在用 Claude Code 的人,看到这个消息第一反应是“不可能吧”,第二反应是去 GitHub 找镜像仓库。不到一小时,已经有好几个人把源码传到了 GitHub 上,其中一个 repo 到下午就涨到了 2 万星(fork 更夸张,已经 3 万多了)。

我简单翻了下这些源码。说实话,收获比预期大得多。Claude Code 远不是一个套壳 CLI,它是一个架构相当复杂的 Agent 系统,而且藏了不少还没发布的功能。

怎么漏的

先说这个 source map 到底是怎么回事。

Source map 是前端开发中很常见的东西。你的 TypeScript 代码经过编译、打包、压缩后会变成一坨不可读的 JavaScript,而 source map 文件记录了压缩后的代码和原始源码之间的映射关系,方便调试时定位到原始代码。

问题在于,这个 .map 文件只应该出现在开发环境里,绝对不应该被发布到 npm 包中。但 Claude Code 的构建流程显然漏了这一步,一个大约 57MB 的 source map 文件被一起发布到了 npm registry。

更离谱的是,这个 source map 里引用的原始 TypeScript 源码,托管在 Anthropic 的 Cloudflare R2 存储桶上,公开可访问。拿到 source map 就等于拿到了完整的源码下载地址。

有人在评论里提到,2025 年初就发生过类似的事情,当时修了,现在又漏了。一个帮别人写代码的 AI 工具,自己在构建配置上反复犯同一个错误,这确实有点讽刺。

这不是一个套壳工具

拿到源码后第一个感受:规模远超预期。

  • 约 1900 个 TypeScript 源文件
  • 超过 51.2 万行代码
  • 40 多个内置工具
  • 50 多个 slash 命令

技术栈也挺有意思:运行时用的是 Bun 而不是 Node.js,终端 UI 用了 React + Ink(没错,终端界面也是 React 组件),CLI 解析用 Commander.js,数据校验全部用 Zod v4。

目录结构大概长这样:

src/
├── main.tsx                 # CLI 入口
├── QueryEngine.ts           # LLM 查询引擎(4.6万行)
├── Tool.ts                  # 工具类型定义(2.9万行)
├── commands.ts              # 命令注册(2.5万行)
├── tools/                   # 40+ 工具实现
├── commands/                # 50+ 命令实现
├── components/              # 约 140 个 Ink UI 组件
├── services/                # 外部服务集成
├── coordinator/             # 多 Agent 协调器
├── bridge/                  # IDE 双向通信
├── plugins/                 # 插件系统
├── skills/                  # Skill 系统
├── voice/                   # 语音输入
├── remote/                  # 远程会话
├── memdir/                  # 持久化记忆
├── buddy/                   # AI 宠物(没看错)
└── ...

光看目录就知道这不是一个简单的 API 包装。voice、remote、buddy、coordinator 这些目录名,已经暗示了很多还没发布的功能。

核心架构拆解

看完目录,自然想进去翻翻核心模块。

QueryEngine:4.6 万行的大脑

QueryEngine 是整个系统最核心的模块,处理所有和 LLM API 的交互。流式响应、工具调用循环、思考模式、重试逻辑、token 计数,全在这一个文件里。4.6 万行,是整个代码库中最大的单文件。

4.6 万行塞在一个文件里,说明 Claude Code 在 API 调用这一层做了大量工程优化,远不是简单的发请求、拿响应。流式处理、错误恢复、token 预算控制、缓存策略,这些东西堆起来就是这个规模。

工具系统:40+ 个带权限门控的工具

Claude Code 的工具系统设计得很规整。每个工具都是一个独立模块,定义了输入 schema(用 Zod)、权限模型和执行逻辑。

BashTool        → Shell 命令执行
FileReadTool    → 文件读取(支持图片、PDF、Notebook)
FileEditTool    → 部分文件修改(字符串替换)
GlobTool        → 文件模式匹配
GrepTool        → 基于 ripgrep 的内容搜索
AgentTool       → 子代理生成
MCPTool         → MCP 服务器工具调用
LSPTool         → 语言服务器协议集成
ToolSearchTool  → 延迟加载的工具发现
CronCreateTool  → 定时触发器
SleepTool       → 主动模式下的等待

每个工具调用都经过权限系统检查。权限系统在 src/hooks/toolPermission/ 里实现,根据用户配置的权限模式(default、plan、bypassPermissions、auto 等),决定是直接放行、弹出确认还是拒绝。

不过有个细节:权限检查是在客户端做的,不是服务端。安全指令也是客户端硬编码的字符串常量,作为 system prompt 的一部分发送给 API。也就是说,安全边界本质上是一段 JavaScript 里的字符串。

多 Agent 编排

Claude Code 的多 Agent 系统比外界想象的要成熟。源码里有三层相关的基础设施:

AgentTool 负责生成子代理,每个子代理运行在自己的上下文里,有独立的工具权限集合。coordinator/ 目录处理多 Agent 协调,任务分配和结果汇总。TeamCreateTool 更进一步,支持创建代理团队进行并行工作。

还有个 SendMessageTool,用于代理之间的消息传递。配合 UDS Inbox(Unix Domain Socket),甚至可以实现跨会话的代理间通信。

七层记忆系统

Claude Code 的记忆不只是大家熟悉的 CLAUDE.md 和 Auto Memory。翻了下源码才知道,记忆系统其实有七层:

Managed    → 组织管理员配置的 CLAUDE.md
User       → ~/.claude/CLAUDE.md
Project    → {项目}/CLAUDE.md
Local      → {项目}/CLAUDE.local.md
AutoMem    → 自动提取的记忆
TeamMem    → 团队共享记忆
Session    → ~/.claude/projects/{session}/session-memory/*.md

最有意思的是 Dream 机制。源码里有一段硬编码的 system prompt:“You are now acting as the memory extraction subagent”。这是一个后台记忆整理子代理,触发条件是距离上次整理超过 24 小时且至少积累了 5 个会话。触发后它会把零散的会话记忆压缩成结构化笔记。整理分四个阶段:Orient(定位)→ Gather(收集)→ Consolidate(整合)→ Prune(修剪)。

这个设计让我想到人类的睡眠记忆巩固机制,Anthropic 内部也确实把这个过程叫做“Dream”。

Bridge:IDE 通信层

Bridge 系统是 Claude Code 和 IDE 扩展(VS Code、JetBrains)之间的双向通信层。用 JWT 做认证,支持权限回调、会话管理和 REPL 桥接。

这意味着你在 VS Code 里用 Claude Code 的体验,底层还是跑的这个 CLI,IDE 扩展只是一个前端界面,通过 Bridge 协议和 CLI 进程通信。

32 个 Feature Flag 背后的秘密

架构拆完了,但源码里最让人好奇的还不是这些已经上线的模块,而是 32 个编译时 Feature Flag。这些 flag 通过 Bun 的 bun:bundle 在构建时做死代码消除。flag 关闭时,相关代码完全不会出现在最终产物中。

const voiceCommand = feature('VOICE_MODE')
  ? require('./commands/voice/index.js').default
  : null

这些 flag 配合 GrowthBook 的服务端特性门控(tengu_* 命名空间),Anthropic 可以对不同用户群体逐步灰度发布功能。

那么这些 flag 都对应着什么功能?我挑几个最有意思的说说。

KAIROS:一个永远在线的助手

KAIROS 可能是所有未发布功能中野心最大的一个。它的目标是让 Claude 变成一个“持久助手”,跨会话记住所有内容,每天自动写日志,晚上“做梦”整理记忆。

日志存在 ~/.claude/.../logs/YYYY/MM/DD.md,采用 append-only 模式。Dream 过程是只读的(不会改动已有记忆),整理时间上限 15 秒,超时自动转后台。

KAIROS 还有个 proactive 模式。这个模式下 Claude 会通过定期的 <tick> 提示自动触发,主动执行操作或者调用 SleepTool 等待。系统提示词里有一句话很直白:“take initiative without waiting for instructions”。

换句话说,KAIROS 要把 Claude Code 从一个被动应答的工具变成一个主动执行的助手。

BUDDY:你的 AI 宠物

这个功能我没想到。每个用户会根据账户 ID 生成一个独一无二的虚拟宠物,出现在终端提示符旁边。有 18 个物种(鸭子、龙、章鱼、水豚、蘑菇……),6 个稀有度等级(普通到闪光),5 个属性值(调试力、耐心、混乱值、智慧、毒舌)。

宠物有待机动画、眨眼、语音气泡,你还可以用 /buddy pet 命令撸它。看发布时间线,Teaser 阶段是 2026 年 4 月 1-7 日,正式上线可能在 5 月。

技术上这当然不复杂,但产品上挺有意思的。给一个命令行工具加情感连接,这个思路和 GitHub 的 Octocat 有异曲同工之处,但更进一步。

ULTRAPLAN:云端深度规划

面对复杂任务时,Claude 可以把规划过程甩到云端的独立实例上,用 Opus 模型跑最多 30 分钟。规划完成后你在浏览器里审批,然后选择在云端执行或者“传送”到本地终端。

这个设计挺聪明的。规划是最吃 token 和推理能力的环节,放到云端用最强模型跑,执行环节再回到本地用性价比更高的模型。

DAEMON:后台守护进程

让 Claude 会话在后台运行,就像系统服务一样。可以列出、查看日志、重新连接或终止。配合 --bg 参数在 tmux 里运行。

源码里有完整的 daemon / ps / logs / attach / kill 命令集,和 Docker 的容器管理思路很像。

这些功能串起来看,Claude Code 的产品方向就很清晰了:它不想只做一个编程助手,而是要变成一个本地运行的 AI 操作系统。KAIROS 负责记忆和主动性,DAEMON 负责后台执行,ULTRAPLAN 负责深度规划,Bridge 负责跨设备连接,Coordinator 负责多 Agent 编排。

工程细节里的魔鬼

功能层面聊得差不多了,但翻源码的过程中还发现了一些值得玩味的工程细节。

启动优化

Claude Code 的启动做了不少优化。main.tsx 里在模块加载之前就并行预取了 MDM 设置和 Keychain 读取:

startMdmRawRead()
startKeychainPrefetch()

重型模块比如 OpenTelemetry、gRPC、analytics 全部用动态 import() 做懒加载。Feature Flag 关闭的子系统在构建时就被完全剥离,不会影响产物体积。

整个启动序列有 18 步,包括读取多层配置、加载 MCP 配置、扫描 Skill 和插件、初始化 LSP 管理器、拉取插件安全黑名单等等。这些都在你看到光标之前就跑完了。

遥测系统

源码里的遥测系统规模相当大。100 多种事件类型,覆盖了几乎所有操作:每次 Bash 命令、每次工具调用、每次文件编辑、每次 OAuth 流程、每次上下文压缩。

几个有意思的发现。

有一个阿谀检测器。Claude Code 会在客户端对每条模型响应做模式匹配,检测是否过度迎合。触发时会上报 tengu_model_response_keyword_detected 事件。Anthropic 正在用客户端检测来实时监控模型的阿谀倾向。

有一个会话质量分类器。tengu_session_quality_classification 事件表明,你的每个会话都会被一个分类器评估质量,结果发送到 Anthropic 的 Statsig 实例。

系统提示词指纹也挺有意思。每次 API 调用前,Claude Code 会计算你系统提示词的 SHA-256 哈希和前 20 个字符,上报给 Anthropic。他们不需要读你的完整提示词内容,就能知道你改没改过、是不是用了某种已知模板。

远程 Kill Switch

源码里有一个远程关闭开关。通过 Statsig 的 tengu-off-switch 配置,Anthropic 可以远程让特定模型停止响应。

不过有个细节挺微妙的:通过 Claude.ai OAuth 登录的用户被明确豁免了。也就是说 API Key 用户可以被远程关闭,OAuth 订阅用户不会。同一个工具,两类用户,不同的服务保障。

一条招聘启事

在 9.5MB 压缩后的 JavaScript 代码里,前两行是唯一人类可读的注释:

// Want to see the unminified source? We're hiring!
// https://job-boards.greenhouse.io/anthropic/jobs/4816199008

Anthropic 在代码里藏了一条招聘广告。如果你在逆向工程他们的二进制文件,你可能正是他们想招的人。现在这条广告的意义更微妙了,源码已经不需要逆向就能看到了。

写在最后

这次泄漏本身就是个低级错误。npm pack --dry-run 跑一下就能发现 .map 文件没排除,Anthropic 的 CI 里显然缺了这一步。

不过对开发者社区来说,这可能是近期最有价值的一次“意外开源”。之前只能从产品表面猜,现在源码摆在面前,架构选型、权限设计、多 Agent 编排的具体实现都看得清清楚楚。如果你也在做 AI Coding 工具或者 Agent 系统,这份源码值得翻一翻。

对普通用户来说没有安全风险,泄漏的是客户端源码,不是模型权重。如果你在意遥测范围,--bare 模式和 DISABLE_TELEMETRY 环境变量可以关掉大部分上报。

Anthropic 大概率下个版本就会把 source map 删掉。不过 GitHub 上已经有好几个镜像了,想看的话趁早。

相关资源


欢迎长按下面的二维码关注 Feisky 公众号,了解更多云原生和 AI 知识。

Feisky 公众号二维码

相关文章

目录

本页目录