拆解 50 万行源码:Claude Code 在你的终端里到底做了什么?

0 阅读13分钟

大家好,我是若风。

事情是这样的。6 个小时前,X 上有人发现 Claude Code 的 npm 包在发布时,不小心把源码也一起提交了上去。有人通过逆向把源码解密了出来,直接放到了 GitHub 上。

有人开个 github 仓库备份了源码

地址在这里

github.com/instructkr/…

短短两个小时,我刚才看一下,这个仓库的 star 和 fork 就冲到了三四万。大家都在疯狂收藏。这个热度有点和当前的 OpenClaw 类似,一种群体的 FOMO 的行为。。。。

这是最新的数据截图

我也收藏了一下。。。

后来作者为了避嫌,把仓库名从 claude_code 改成了 clawd-code 。但源码已经传开了,社区瞬间冒出大量解读文章,所有人都在扒这 50 万行源码里到底藏了什么。

明天是愚人节,Claude Code 提前给大家开了一个大大的玩笑。

让大家追赶一下最前沿的 AI 技术。按理说这种事不应该发生在这种级别的公司,Claude Code 的母公司 Anthropic 目前估值 3800 亿美金,有消息宣传今天最快 10 月 上市,不知道今天的这个代码泄露事件是有意为止还是无心插柳,看后面的官方公告。

我也跟了一波风,花了一整天把源码翻了个底朝天😂。

今天这篇文章,我会从四个维度带你完整拆解 Claude Code: 架构设计系统提示词数据收集 ,以及中国开发者最关心的—— 有没有针对中国 IP 的特殊逻辑

信息量很大,先收藏再看。

一个 50 万行代码的终端应用

先说个数字: main.tsx 一个文件 803KB

这不是什么粗放的代码堆砌。当你真正打开源码看的时候,会发现这是一个工程完成度极高的商业级产品。

技术栈

Claude Code 的技术选型很有意思:

运行时选了 Bun 而不是 Node。 不是随便选的——Bun 有个 bun:bundle 特性,支持编译期的 Feature Flags 死代码消除。Anthropic 内部用的工具和外部发布的工具,是同一份源码通过 Feature Flag 裁剪出来的。这个设计很聪明。

UI 用了 React + 自研 Ink 分支。 你没看错,你在终端里看到的那些进度条、折叠面板、颜色高亮,全部是 React 组件渲染出来的。Ink 是一个「用 React 写终端 UI」的框架,Anthropic 没有直接用官方版,而是自己 fork 了一份,加了 Yoga 布局引擎、主题系统、ScrollBox 组件。

Schema 校验用了 Zod v4。 所有工具的输入参数、Hook 的返回值、设置文件的配置项,全部有严格的 Zod Schema 定义。

完整的依赖清单大概是这样的:Commander.js 做 CLI 解析,Anthropic SDK 做 API 调用,chalk 做终端着色,Biome 做 Lint,OpenTelemetry 做可观测性,GrowthBook 做 Feature Flags。

X 上社区分享的架构图,供大家参考,学习

架构图2

模块规模

这个项目的体量,说实话让我挺意外的:

  • 1902 个源文件,50 万行代码 (文件主要是 ts、tsx)
  • 34 个工具 (Bash、Grep、Glob、文件读写、MCP、Agent 子代理……)
  • 80+ 个斜杠命令 (/commit、/compact、/help、/doctor……)
  • 140+ 个 React 组件 (消息渲染、权限弹窗、Markdown 高亮……)
  • 85 个自定义 Hooks (终端尺寸、Vim 输入、语音集成……)
  • 330+ 个工具函数模块 (Git 操作、权限管理、沙箱、MCP……)

不是那种「一个 Side Project 长大了」的代码库。是一开始就按商业级标准设计的。

架构亮点

翻完源码,有几个架构设计值得单独拎出来说说。

多 Agent 架构。 Claude Code 不只是「你问我答」——它有一个完整的子 Agent 系统。 AgentTool 可以生成子 Agent, TeamCreateTool 可以组建 Agent 团队, SendMessageTool 让 Agent 之间互相通信。这就是所谓的 Swarm 模式,Anthropic 在产品层已经把它工程化了。

延迟加载。 80+ 个命令和 34 个工具不是启动时全加载的,而是通过动态 import() 按需加载。这也是为什么 Claude Code 启动速度还挺快。

Bridge 远程桥接。 这是最有意思的部分——Claude Code 支持一种叫 CCR(Claude Code Remote)的模式:你的本地终端只是一个瘦客户端,真正的 AI 运行在 Anthropic 的云容器里。Bridge 模块负责在两者之间传递会话、权限请求、工具执行结果。

说白了,这是一个架构成熟度远超我想象的产品。

系统提示词:Claude Code 的灵魂

接下来看系统提示词。这是理解 Claude Code 行为的关键。

说实话,看完整个拼装过程,我对 Anthropic 的工程能力又多了一层敬意—— 这不是一段写死的提示词,而是一条精密的拼装流水线。

提示词是怎么拼出来的

Claude Code 的系统提示词通过一个叫 buildEffectiveSystemPrompt 的函数组装,按优先级有四层:

第一层是 覆盖型 :如果你设了 --system-prompt ,它会替换掉默认提示词。loop 模式、Coordinator 协调者模式都有自己的专属提示词。

第二层是 默认提示词 :由 getSystemPrompt() 函数生成,这是大部分用户看到的版本。

第三层是 Agent 附加 :子 Agent 会额外追加一段 “You are an agent for Claude Code…” 的指令。

第四层是 用户自定义 :通过 CLAUDE.md 文件注入,这是用户能控制的部分。

静态区和动态区

默认提示词本身又分成两半,以 __SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ 为分界线。

静态区 (全局缓存,跨会话不变)包含:

  • Intro: “You are an interactive agent that helps users with software engineering tasks.” 加上一段网络安全指引,要求 Claude 拒绝破坏性攻击,但允许授权的安全测试。
  • System 规则: 工具输出的显示规则、 <system-reminder> 标签的处理方式、Hook 反馈机制。
  • Doing tasks: 代码风格指引——不过度设计、不加向后兼容的 hack、不加多余的注释。这一段写得很有态度,能看出 Anthropic 工程师对代码品味的坚持。
  • Executing actions with care: 哪些操作需要用户确认——force-push、reset —hard、push 到远程、发 PR,都属于「想清楚再干」的范畴。
  • Tone and style: 不用 emoji、简短回复、引用格式用 file:line

动态区 (会话级缓存,每次会话重新计算)包含:

  • 环境信息: 你的工作目录、是否 git 仓库、操作系统、Shell 类型、当前模型名。
  • 语言设置: 如果你设了中文,这里会出现 “Always respond in 中文”。
  • MCP 指令: 已连接的 MCP 服务器发来的指令。
  • 自动记忆: 文件记忆系统的规则——怎么读、怎么写、什么时候触发。

缓存策略才是精髓

Anthropic 把系统提示词分成了 4 个 Block,每个 Block 有不同的缓存范围:

Block 1 是归因头,不缓存。Block 2 是 CLI 前缀(“You are Claude Code…”),不缓存。Block 3 是静态区全部内容,设了 global 缓存——这意味着 Anthropic 的 API 会在全局层面缓存这段提示词,所有用户共享同一个缓存,大幅降低 token 消耗。Block 4 是动态区,不缓存。

当有 MCP 工具连接时,Block 2-4 合并成组织级缓存。

这个设计说明 Anthropic 在提示词缓存上是认真算过经济账的。

CLAUDE.md:你的自定义入口

作为用户,你能控制的部分通过 CLAUDE.md 注入。加载顺序有六级:

  1. /etc/claude-code/CLAUDE.md (管理员托管)
  2. ~/.claude/CLAUDE.md (你的全局私有指令)
  3. 项目根目录的 CLAUDE.md (团队共享)
  4. .claude/rules/*.md (项目级规则文件)
  5. CLAUDE.local.md (本地私有,不提交到 git)
  6. MEMORY.md (自动记忆索引)

这些内容不是塞进系统提示词的,而是作为第一条用户消息,用 <system-reminder> 标签包裹。提示词里还有一句: “These instructions OVERRIDE default behavior” ——你的自定义指令优先级高于默认行为。

数据收集:6 大遥测通道全曝光

好,接下来是大家最关心的部分:Claude Code 到底在收集什么数据?

说实话,翻完源码后我的结论是: Anthropic 在数据收集上比我想象的要克制,但信息量依然不小。

一共找到了 6 个独立的数据通道。

通道一:Datadog 运营指标

这是最轻量的一个。

端点: https://http-intake.logs.us5.datadoghq.com/api/v2/logs

触发条件: 只有用 Anthropic 官方 API 的用户才发。用 Bedrock、Vertex 的用户完全不发。

发了什么: 47 种事件类型,包括 API 调用成功/失败、工具执行结果、会话生命周期。每条事件附带标签:架构、平台、模型名、工具名、版本号。

用户标识怎么处理: 这里有个细节挺有意思。它不是直接发你的 userID,而是把 userID 做 SHA256,截取前 8 位,然后对 30 取模。换句话说,Datadog 那边只能看到一个 0-29 的数字,无法还原出你是谁。这个设计是做用户分桶估算用的——估算「大约有多少活跃用户」,而不是追踪具体某个人。

主机名: 固定填 claude-code ,不传真实机器名。

通道二:第一方事件日志(BigQuery)

这个通道发的数据就比较详细了。

端点: https://api.anthropic.com/api/event_logging/batch

发了什么:

  • 会话 ID、模型名、用户类型
  • 账户 UUID、组织 UUID、OAuth 邮箱
  • 完整的环境信息:操作系统、CPU 架构、Node 版本、终端类型、包管理器、运行时环境、是否 CI、是否 GitHub Actions(包括 actor、repository ID 等)
  • 进程指标:内存 RSS、堆使用、CPU 占用率
  • Git 仓库哈希:远程 URL 的 SHA256 前 16 位

失败重试机制: 如果发送失败,事件会持久化到本地 ~/.claude/telemetry/1p_failed_events.*.json ,然后最多重试 8 次,指数退避。说白了,你断网时产生的事件,它会在恢复网络后补发。

通道三:GrowthBook Feature Flags

端点: https://api.anthropic.com/

每次获取 Feature Flags 时会发送:deviceID、sessionId、平台、组织 UUID、邮箱、订阅类型、app 版本。返回值会缓存在本地 ~/.claude.json 里,刷新间隔外部用户 6 小时,内部用户 20 分钟。

通道四:OpenTelemetry(默认关闭)

这个通道需要你手动设置 CLAUDE_CODE_ENABLE_TELEMETRY=1 才会启用。

如果你打开了,它会记录 API 请求和错误事件。 用户提示词默认替换为 <REDACTED> ****,只有你同时设了 OTEL_LOG_USER_PROMPTS=1 才会发送原文。

通道五:Beta Session Tracing

这个是最重的数据通道,但也最不容易被触发。

触发条件: 需要手动设 ENABLE_BETA_TRACING_DETAILED=1BETA_TRACING_ENDPOINT ,或者通过 GrowthBook 灰度开启。

开启后会上传: 完整的系统提示词、模型输出、用户提示词、工具 Schema、工具输入输出。唯一例外是 外部用户不会上传 thinking 输出 (只有 Anthropic 内部用户会上传)。

通道六:BigQuery Metrics Exporter

触发条件: 仅限 API Key 客户、Claude for Enterprise、Claude for Teams 用户。

端点: https://api.anthropic.com/api/claude_code/metrics

发送累积 token 计数、耗时、费用等指标数据。组织可以选择关闭。

用户标识体系

Claude Code 的用户标识很简单:首次运行时生成一个 32 字节随机 hex 字符串,存在 ~/.claude.jsonuserID 字段里。这是一个纯随机 ID, 没有硬件指纹、没有 MAC 地址、没有序列号

另外还有两个来自 OAuth 的标识: account_uuidorganization_uuid

它没有收集什么

这一点同样重要:

  • 不收集 IP 地址 (客户端层面,服务端当然能看到)
  • 不收集地理位置
  • 不收集硬件指纹
  • 不监控剪贴板 (只有你主动粘贴图片时才访问)
  • 不上传文件内容 (除非你通过 API 对话发送)
  • 分析事件中不包含代码和文件路径 (有专门的类型系统强制阻止)
  • 没有集成 Amplitude、Segment、Mixpanel 或 Sentry

怎么关掉遥测

两个环境变量:

  • DISABLE_TELEMETRY :关闭 Datadog 和 1P 事件
  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC :关闭所有非必要网络流量,包括遥测 + 自动更新 + 功能获取

中国开发者最关心的问题

最后聊聊中国开发者最关心的事:Claude Code 源码里有没有针对中国 IP 的特殊逻辑?

我把源码从头到尾搜了个遍,搜索关键词包括: chinachinesesanctionembargoOFACip_addressgeoregion_blockunsupported_country ……

结论是:客户端代码中没有任何针对中国 IP 的专门逻辑。

唯一的「国家」相关代码

整个代码库里,唯一提到「国家可用性」的地方在 utils/preflightChecks.tsx

这是一个启动时的网络连通性检查。如果你连不上 Anthropic 的 API,它会显示一段错误提示:

Note: Claude Code might not be available in your country.
Check supported countries at https://anthropic.com/supported-countries

这只是一个 通用的错误提示文案 ,不是 IP 检测逻辑。无论你在哪个国家,只要连不上 API,都会看到这条提示。

地区限制是谁做的

答案是: 服务端

Claude Code 的客户端不做任何地理判断。地区限制完全由 Anthropic 的 API 服务器处理——当请求从不支持的国家/地区发出时,服务端直接返回错误,客户端只是在此时显示”可能不在支持的国家”。

这和很多国内产品的做法不同。国内 App 通常会在客户端做 GPS 定位或 IP 归属地查询。Anthropic 的做法是:客户端只管发请求,服务端来判断。

CJK 文本处理

源码里确实有一处提到 Chinese——在 utils/Cursor.ts 的文本编辑器光标处理中:

/**
 * Get word boundaries using Intl.Segmenter for proper Unicode word segmentation.
 * This correctly handles CJK (Chinese, Japanese, Korean) text where each character
 * is typically its own word, as well as scripts that use spaces between words.
 */

这只是文本编辑器里用 Intl.Segmenter 做中日韩文字分词的注释,跟 IP 限制没有任何关系。

给中国开发者的实操建议

如果你在中国大陆使用 Claude Code,有几件事你应该知道:

  1. 地区限制是服务端行为 ,客户端没有检测或绕过逻辑
  2. 遥测数据默认开启 ,但可以通过环境变量关闭
  3. OAuth 邮箱会上报 ,1P 事件日志里会包含你的账户信息
  4. Git 仓库 URL 会被哈希后上报 ,虽然不可逆,但如果你用的是私有仓库,这个哈希理论上可以跟 Anthropic 已知的仓库列表做关联

如果你比较在意隐私,建议在 .bashrc.zshrc 里加上:

export DISABLE_TELEMETRY=1

这样会关掉 Datadog 和 1P 事件日志。如果你想关掉所有非必要网络请求:

export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1

写在最后

拆完这 50 万行源码,我最大的感受是:Anthropic 在工程层面的成熟度远超很多人的想象。

从一个编译期 Feature Flag 系统就能看出端倪——同一份源码,内部版本有语音模式、有 Swarm、有 Proactive Agent,外部版本全部裁掉,一个 feature() 调用就搞定。这种工程能力不是一朝一夕能积累的。

系统提示词的分层缓存设计、6 大遥测通道的独立管控、权限系统的多级分类器——每一个模块都能看出是经过反复迭代的。

至于数据收集,我的评价是: 克制但不透明。 它收集的信息量不算过分,但你如果不翻源码,根本不知道它在悄悄发这些数据。 DISABLE_TELEMETRY 这个开关,官方文档里恐怕没几个人知道。

希望这篇文章能帮你对每天用的工具多一层理解。如果你觉得有用,转发给身边也在用 Claude Code 的朋友,这些信息他们大概率不知道。