全球最强 AI 编程工具 Claude Code 的 50 万行 TypeScript 源码意外泄露,本文从源码视角深度拆解其 Agent 循环引擎、工具安全设计、读写分离并发、系统提示词缓存优化、三层记忆架构、五级上下文压缩等核心设计,每一个都是 AI 应用架构的教科书级案例。


一、源码是怎么泄露的?

Claude Code 通过 NPM 发布——NPM 就是程序员的"应用商店",开发者打包上传工具,别人一行命令就能安装。

正常情况下,代码上线前会经过压缩混淆处理。但开发阶段为了方便调试,打包工具会自动生成 Source Map 文件,相当于一张"翻译对照表",能把混淆后的代码还原成原始版本。这个文件只能在开发环境使用,上线前必须删除

然而,Anthropic 工程师在发布 Claude Code 2.1.88 版本时,打包工具默认生成了 Source Map 文件,而他们忘了在发布配置里排除 .map 文件。于是一个 59.8MB 的 map 文件就这么直接发到了公开的 NPM 仓库。

// Source Map 文件结构(本质是一个 JSON
{
  "sources": ["src/agent/query.ts", "src/tools/bash.ts", ...],      // 所有文件路径
  "sourcesContent": ["export function query() {...}", ...],           // 每个文件的完整源码
  // 两者一一对应,写个脚本解析即可还原全部源码
}

更离谱的是,去年 2 月 Claude Code 首次发布时就出过一模一样的事故,同样的错误居然犯了两次。


二、源码里有什么?

本次泄露的是 Claude Code 客户端源码(不含服务端模型训练和 API 后端逻辑),包括:

维度 数据
源文件 1900+ TypeScript 文件
代码量 ~51 万行
UI 框架 React Ink(用 React 写命令行界面)
核心模块 Agent 循环引擎、40+ 内置工具、系统提示词组装、记忆系统、上下文压缩、权限管理

整体架构六层分层

┌─────────────────────────────────────┐
│       CLI & 界面层(React Ink)       │  终端交互、渲染
├─────────────────────────────────────┤
│       Agent 循环引擎(ReAct)         │  思考 → 行动 → 观察 循环
├─────────────────────────────────────┤
│       工具系统(40+ 内置 + MCP)       │  文件读写、Bash、搜索...
├─────────────────────────────────────┤
│       记忆系统(三层分级)             │  MEMORY.md → 话题文件 → 历史对话
├─────────────────────────────────────┤
│       上下文压缩(五级漏斗)           │  裁剪 → 微压缩 → 折叠 → 自动 → 应急
├─────────────────────────────────────┤
│       权限 & 安全系统                 │  五重关卡 + 影子 AI 分类器
└─────────────────────────────────────┘

三、Agent 循环引擎:一个 while(true) 撑起整个大脑

很多人以为 AI 编程工具背后一定是什么复杂的多 Agent 框架,但打开 Claude Code 核心对话循环的 query.ts 文件一看——最核心的代码就是一个 while(true) 无限循环

// 简化后的核心循环逻辑
while (true) {
  // 1. 上下文压缩(防止 token 超限)
  await compressContext(messages);

  // 2. 调用大模型
  const response = await queryModel(messages);

  // 3. 如果模型返回了 tool_use,执行工具
  if (response.hasToolUse()) {
    const result = await executeTool(response.toolCall);
    messages.push(result);  // 追加到对话历史
    continue;               // 进入下一轮循环
  }

  // 4. 没有 tool_use → 任务完成,退出循环
  break;
}

这就是经典的 ReAct 机制(Reasoning + Acting):让 AI 自己形成 思考 → 行动 → 观察 → 再思考 的闭环。

每次循环中,queryModel 函数负责:发送请求 → 接收 SSE 流式输出 → 累积 Token 用量。模型返回的结果如果包含 tool_use,说明 AI 还想调用工具继续干活,循环就接着转;如果没有 tool_use,说明任务完成,循环结束。

源码注释里还有一段 Anthropic 工程师留下的"巫师守则":"年轻的巫师,好好遵守这三条关于 thinking block 的规则,不然你将受到整整一天 debug 和薅头发的惩罚。" ——程序员的浪漫。


四、工具系统:Fail-Close 安全设计

Claude Code 内置了 40+ 工具,在 tools.ts 文件中统一注册管理。

4.1 工具按需加载

当用户接了很多 MCP 插件、工具数量特别多时,Claude Code 不会把所有工具的完整描述都塞进系统提示词。而是:

  1. 先给模型一份工具名 + 一句话介绍的精简清单
  2. 让模型自己选择需要哪些工具
  3. 按需加载完整的工具定义

这从源头节省了大量 Token 开销。

4.2 默认危险原则(Fail-Close)

每个工具通过 buildTool 工厂函数创建,有一个非常巧妙的默认值设计:

function buildTool(config: ToolConfig) {
  return {
    isReadOnly: config.isReadOnly ?? false,    // 默认不是只读
    isReadSafe: config.isReadSafe ?? false,    // 默认不安全
    // ...
  }
}

isReadOnlyisReadSafe 都默认为 false。也就是说,如果开发者忘了声明"这个工具只是读文件、不会改东西",系统就会自动把它当作危险操作处理,不让它并发执行。

这就是 Fail-Close(失败时关闭) 设计思想:

就像公司的门禁系统——没刷卡,默认进不去。对于 AI 应用,你不知道它下一步会调用什么工具,在这种不确定性下,默认禁止比默认允许安全太多了


五、读写分离的工具并发

假设 AI 同时想读 3 个文件、再改 1 个文件,这 4 个操作是排队跑还是并发执行?Claude Code 设计了一套读写分离的并发调度机制

并发上限:默认最多 10 个工具同时执行(可通过环境变量调整)

分批逻辑:
  ✅ 连续多个只读工具 → 一起并发执行
  🚫 遇到写操作 → 排队,等前面的都完成才执行

异常处理:
  ⚠️ 如果工具的安全判断方法本身抛异常 → 当作"不安全"处理

结果应用:
  📋 并发执行完成后,上下文修改不会立刻生效
     → 先排队存着,等一个批次的所有工具都跑完
     → 再按顺序依次应用

这套机制保证了读操作的高并发性能,同时写操作的严格顺序性,避免了并发写入导致的数据竞争问题。


六、系统提示词的缓存分裂优化

Anthropic 的 API 支持 Prompt Cache(提示词缓存):如果每次发给模型的系统提示词前半部分不变,API 就能缓存这部分内容,后续请求直接复用。

Claude Code 在系统提示词组装时,用一个"动态边界"标记将提示词分成上下两部分:

┌──────────────────────────────────────┐
│  静态部分(全球数百万用户共享缓存)     │  ← 工具定义、基础规则等
│  ─ ─ ─ ─ 动态边界 ─ ─ ─ ─ ─ ─ ─ ─  │
│  动态部分(每个用户各不相同)           │  ← 当前时间、仓库状态、CLAUDE.md 等
└──────────────────────────────────────┘

源码注释里专门警告:

如果把动态内容不小心混到静态部分,每个用户的提示词都不一样,缓存就全废了。

实践启示: 如果你在做 AI 应用且调用量较大,这个"静态/动态分裂"的缓存优化技巧能帮你省下大量 API 费用


七、内容检索策略:不用 RAG,用 Grep

业界最流行的代码检索方案是 RAG(检索增强生成):先做 Embedding、存向量数据库、检索再回答。但 Claude Code 压根不用这套——不管是搜记忆文件还是搜历史对话,用的都是最朴素的 Grep 文本搜索

Claude Code 创始人 Boris Power 也说过:

"我们试过 RAG,但发现让 AI 自己决定搜什么、怎么搜,效果远好于 RAG。"

对比 RAG 方案 Claude Code(Grep)
类比 帮实习生整理好资料打包给他 给他公司文档库权限,让他自己找
工程复杂度 高(需维护向量数据库、索引更新) 极低(Grep 即用)
索引过期 存在 不存在
检索质量 取决于 Embedding 质量 取决于模型能力(模型越强越好)

核心洞察: 随着模型能力越来越强,很多以前需要复杂工程方案解决的问题,现在直接交给 AI 自己搞定就行了。哪些能力该交给工程系统、哪些该留给 AI 模型,这个边界值得深思。


八、三层记忆架构(Self-Healing Memory)

这是整份源码里设计最精妙的部分,也是 Context Engineering(上下文工程) 领域最值得学习的案例。

第一层:MEMORY.md(热记忆 - 目录索引)

就像一本书的目录,每次对话都会加载到上下文,因此有严格的大小限制:

// 限制规则
const MAX_LINES = 200;
const MAX_BYTES = 25 * 1024;  // 25KB
const MAX_LINE_LENGTH = 150;   // 每行不超过 150 字符

// 只存指针,不存内容
// 示例:- [Auth重构踩坑](auth_refactor.md) — JWT过期处理的edge case

// 截断逻辑:行数截断 + 字节截断双保险
// 截断时在最后一个换行符处切开,不会切到一行中间
// 截断后追加 warning,让 AI 知道索引未完整加载

第二层:话题文件(温记忆 - 按需加载)

编码偏好、项目架构约定、踩过的坑等细节信息都存在单独的话题文件里。新对话开始时,Claude Code 会用 Sonnet 小模型挑选最多 5 个与当前对话相关的文件加载。

记忆召回的提示词中有一条 punch line:

如果某个工具正在被使用,就不要加载它的使用文档(你都在用了,说明你会用),但一定要加载它的已知问题和坑点。

第三层:历史对话(冷记忆 - 搜索召回)

更早的历史对话会被存成特定格式的文件,需要时用 Grep 搜索关键词召回。

关键设计原则

记忆不记代码,只记人的偏好和判断。 因为代码会变化,但记忆不会自动更新。如果记忆里说"函数 X 在第 30 行",重构后这条记忆就变成误导了。代码的事实,永远在源码里实时读取。

做过后端开发的同学都知道,缓存和数据库不一致是最坑的 bug 之一。Claude Code 的做法等于从根源上消灭了不一致的可能性。

不同"温度"的数据 → 不同的管理方式

🔴 热数据(MEMORY.md)→ 每次对话都加载,严格限制大小
🟡 温数据(话题文件)  → 按需加载,小模型智能召回
🔵 冷数据(历史对话)  → Grep 搜索,用时再取

九、五级上下文压缩

大模型的上下文窗口有上限,随着对话越来越长、工具调用结果越来越多,Token 用量会快速膨胀。Claude Code 设计了五级压缩策略,像漏斗一样层层过滤:

级别 策略 说明
L1 裁剪(Trim) 最轻的一刀:旧的工具调用结果只保留结构,不保留内容
L2 微压缩(Mini Compress) 把体积大的工具执行结果卸载到缓存(不是直接丢弃)
L3 上下文折叠(Fold) 对中间的对话进行折叠摘要,只保留关键信息
L4 自动压缩(Auto Compress) 上下文占用超阈值时,触发全量摘要压缩
L5 应急压缩(Emergency) API 返回 413(Prompt 太长)时紧急触发

五级从轻到重依次触发,能裁的先裁,实在不够再上更重的方案。

断路器机制(Circuit Breaker)

源码注释中记录了一个真实事件:

2026 年 3 月 10 日统计发现,有 1000+ 会话连续压缩失败了 50 次以上。最夸张的一个会话连续失败了 3000+ 次,还在不停重试。

光浪费的 Token 费用就是天文数字。所以他们加了断路器连续失败 3 次就自动停下来,避免无限重试带来的资源浪费。


十、五重安全关卡 + 影子 AI

Claude Code 的 --dangerously-skip-permissions(又叫 YOLO 模式)可以跳过所有权限确认。但源码揭示,即使在 YOLO 模式下,背后还偷偷跑着一个"影子 AI"在把关

yolo_classifier.ts 文件中,每次主 AI 要执行操作,这个独立的 AI 分类器都会过一遍。完整的权限检查至少要过 5 个关卡

1️⃣ 用户权限配置检查
2️⃣ 工具级别的安全属性检查isReadOnly / isReadSafe
3️⃣ YOLO 模式的影子 AI 分类器
4️⃣ Bash 命令安全检查20+ 种规则严格程度远超预期
5️⃣ 文件路径安全校验

十一、Feature Flag 与隐藏功能

源码中到处可见 feature_xxx 的判断——这些功能开关无意中泄露了 Claude Code 的产品路线图

Feature Flag 功能 说明
carrots 长期助手模式 AI 可以 24 小时持续运行不结束
auto_dream 自动做梦 AI 白天干活记笔记,晚上自动整理记忆
multi_agent 多 Agent 协作 一个 AI 指挥多个 AI 干活
voice_mode 语音模式 语音交互
browser_tool 浏览器操作 AI 直接操控浏览器

十二、反蒸馏 & 卧底模式

反蒸馏(Anti-Distillation)

竞争对手可能通过录制 Claude Code 的 API 流量来蒸馏它的能力(把大模型的输入输出录下来训练小模型)。Anthropic 的应对策略堪称一绝:

主动往 API 请求里注入假的工具定义,让你拿去训练的模型越训越差。

这不是单纯的加密或限速,而是主动喂假数据,颇有反间计的意思。

卧底模式(Stealth Mode)

Anthropic 内部员工用 Claude Code 往开源项目提交代码时会自动启用此模式:

  • 默认开启,不能强制关闭
  • 只有当仓库被确认为内部仓库时才会关掉
  • 目的:防止内部模型代号等隐私信息通过开源贡献泄露

十三、有趣的彩蛋

  1. 数字宠物系统:源码的某个目录下藏了一套数字宠物系统——鸭子、鹅、猫咪应有尽有,原本计划后续上线
  2. 硬编码提示优化:因为 Claude 之前老是浪费一轮对话去执行 ls 检查目录是否存在,工程师干脆在提示词里硬编码了一行:"这个目录已经存在了,直接用 Write 工具往里写就行"
  3. 启动速度偏执:Claude Code 对启动速度有近乎偏执的追求,大量细节优化都是为了更快的冷启动

总结

看完这份源码你会发现,Claude Code 里没有什么惊天动地的新算法——并发控制、读写分离、分层缓存、断路器、Feature Flag……用的都是程序员接触过的基础知识。但 Claude Code 团队把这些东西巧妙地组合到了 AI 场景里,打造出了体验极致的产品。

核心设计理念总结:

设计 理念
Agent 循环 用最简单的 while(true) + ReAct,不过度设计
工具安全 Fail-Close,默认禁止比默认允许安全
并发调度 读写分离,读操作高并发,写操作严格有序
提示词缓存 静态/动态分裂,全球共享缓存省钱
内容检索 不用 RAG,让 AI 自己 Grep,简单但有效
记忆系统 三层分级,不记代码只记偏好,消灭缓存不一致
上下文压缩 五级漏斗 + 断路器,从轻到重逐级触发
安全机制 五重关卡 + 影子 AI,YOLO 模式也有底线

这份源码是目前最好的 AI 应用架构教材。Agent 循环怎么写、工具系统怎么设计、记忆怎么管理、安全怎么做——答案全在里面。


如果觉得有帮助,欢迎点赞收藏关注,后续持续分享 AI 编程工具的架构设计与实战经验。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐