乐于分享
好东西不私藏

Claude Code 源码:8大新功能/26个隐藏指令/6级安全架构,全被扒光了

Claude Code 源码:8大新功能/26个隐藏指令/6级安全架构,全被扒光了

keywords: [“Claude Code”, “源码泄露”, “prompt engineering”, “AI编程”, “system prompt”, “Agent”, “反蒸馏”, “KAIROS”] source: “Claude Code 源码泄露事件”


昨天整个技术圈都炸了。

Anthropic 在发布 Claude Code v2.1.88 的 npm 包时,意外地把 .js.map 源码映射文件打包进去了。一个 Bun 的 bug(oven-sh/bun#28001)导致本应在生产环境禁用的 source map 被完整地发到了 npm registry 上。任何人只需要一行命令:

ounter(linenpm pack @anthropic-ai/claude-code --registry=https://registry.npmjs.org/

就能拿到完整的 TypeScript 源代码。

Hacker News 上那篇 alex000kim 的拆解帖拿了 1200+ points、489 条评论,V2EX 上同时有 4 个帖子在讨论,话题热度在过去 24 小时内持续霸榜。Anthropic 已经从 npm 撤包,但源码早就在 GitHub 上被广泛传播了。

我花了一整晚把源码翻了个底朝天。说实话,看完之后的感受不是「哇,好厉害」,也不是某些人说的「草台班子」——而是这帮人比我们想象的要认真得多,也要狠得多

这篇文章把我发现的 6 个最「神级」的机制逐一拆解。不是泛泛地聊概念,而是带你看源码级别的设计逻辑。如果你在用 Claude Code、在做 prompt engineering、或者在构建自己的 Agent 系统,这些东西直接可以抄——或者至少,知道该防什么。

关于 V2EX 上「屎山」的讨论: 有人吐槽 print.ts 单文件 5,594 行、单函数 3,167 行、12 层嵌套。确实不好看。但如果你仔细读下去,会发现这些「丑代码」背后有清晰的工程决策。屎山和精心设计的妥协是两回事。

机制一:Fake Tools 反蒸馏 —— 给竞争对手下毒

这是整个泄露里最让我震惊的发现。

源码文件 claude.ts 里有一个 flag 叫 ANTI_DISTILLATION_CC。当它开启时,API 请求里会带上一个字段:

ounter(lineanti_distillation: ['fake_tools']

它的作用是:让服务端在返回给客户端的响应中静默注入虚假的工具定义(decoy tool definitions)。

为什么?因为 Anthropic 知道有竞争对手在录制 Claude API 的流量来训练自己的模型——这在 AI 行业是公开的秘密。通过注入虚假工具定义,任何试图从 API 流量中蒸馏 Claude 能力的训练数据,都会被污染。你以为你在学 Claude,实际上你在学一堆不存在的工具。

这个功能被 GrowthBook 的 feature flag tengu_anti_distill_fake_tool_injection 控制,只对第一方 CLI 会话生效。

ounter(lineounter(lineounter(line触发条件:第一方 Claude Code CLI 会话控制方式:GrowthBook feature flag(tengu_anti_distill_fake_tool_injection)作用范围:仅服务端注入,客户端不可感知

反思

这不只是一个技术手段,这是一个竞争策略被编码为代码的案例。大多数公司的反蒸馏策略是法律手段(ToS)或者频率限制。Anthropic 直接把毒药放进了数据流里。这种程度的防御思维,是我在开源代码里第一次看到。

不过,作者 alex000kim 也指出了几个绕过方式:MITM 代理可以剥离这个字段,环境变量 CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS 可以禁用它,第三方 API provider 完全绕过检查。所以它更像是一个「增加成本」的防线,而不是不可突破的堡垒。

机制二:Undercover 潜伏模式 —— AI 的「反侦察」

源码里有一个 undercover.ts 文件,大约 90 行,功能简单但意义深远。

当 Anthropic 员工在外部仓库(非 Anthropic 内部项目)使用 Claude Code 时,这个模式会自动剥离所有 Anthropic 内部信息

  • 阻止提及内部代号如「Capybara」「Tengu」
  • 屏蔽内部 Slack 频道引用
  • 甚至移除「Claude Code」这个名字本身

可以通过 CLAUDE_CODE_UNDERCOVER=1 强制开启,但——注意——没有强制关闭的选项。而且在外部构建版本中,这段代码被编译时死码消除(dead-code-eliminated),是一个「单向门」。

这意味着什么

Anthropic 员工向开源项目提交的 AI 生成代码,不会有任何 AI 生成的痕迹。

在当前「AI 生成代码是否应该标注」的争论背景下,这个设计选择非常微妙。它不是一个 bug,不是一个疏忽——它是一个精心设计的「隐身」系统。

Claude Code Agent 调度架构

机制三:Frustration 情绪检测 —— 用正则识别你在骂人

userPromptKeywords.ts 文件里有一段正则表达式,专门用来检测用户是否在发火骂人。

是的,一家做大语言模型的公司,用正则表达式来做情绪分析。

alex000kim 的原文里也吐槽了这一点的讽刺性。但如果你从工程角度想,这其实是一个务实到极点的选择:

  • 正则匹配几乎零延迟,每次用户输入都要跑,不可能等 LLM 推理
  • 它不需要高精度——只需要捕获最明显的情绪信号
  • 一旦检测到用户 frustration,可以调整后续回复的策略(更谨慎、更道歉、更直接)

这给我们的启发是:不是所有问题都需要 AI 来解决。在延迟敏感的路径上,老派技术可能是更好的选择。

用 LLM 做情绪分析?每次 200ms+ 延迟,每天千万次调用的成本,还要处理模型幻觉。用正则?0.01ms,零成本,准确率对于这个场景够用。工程是关于 trade-off 的,不是关于用最新技术的。

机制四:KAIROS —— 还没发布的自主 Agent 模式

这是整个泄露里最让人兴奋的发现——一个尚未发布的功能,代号 KAIROS

源码中散布着大量 KAIROS 相关的引用,拼凑起来可以看到一个完整的自主 Agent 架构:

ounter(lineounter(lineounter(lineounter(lineounter(line/dream      — 「每夜记忆蒸馏」skill每日追加日志  — append-only logsGitHub webhook 订阅后台守护进程  — daemon workers5 分钟 cron 刷新周期

这不是一个简单的「后台运行 Claude Code」——这是一个始终在线的 AI Agent,它可以:

  1. 订阅你的 GitHub 仓库事件
  2. 在后台持续运行守护进程
  3. 通过 /dream 在夜间整理和蒸馏当天的记忆
  4. 以 5 分钟为周期刷新状态

整个功能被重重 feature flag 包裹,显然还在早期阶段。但架构已经搭好了——Anthropic 在构建的不是一个「你问我答」的工具,而是一个主动工作的 AI 同事

为什么这很重要

当前所有的 AI 编程工具——Claude Code、Cursor、Copilot——本质上都是「被动响应式」的。你给指令,它执行。KAIROS 的设计表明 Anthropic 的野心是跨过这条线,进入「主动式」领域。

想象一下:你早上打开电脑,Claude 已经帮你 review 了昨晚的 PR,整理了 issue 列表,甚至根据代码变更预判了可能的 bug。这不是科幻——架构都已经在源码里了。

Plan → Execute → Review 完整链路

机制五:Native Client Attestation —— 比你想象的更硬核的身份认证

system.ts 文件里有一个细节让我反复看了三遍。

API 请求的 header 中有一个字段 cch=00000,看起来像是个无意义的占位符。但真实情况是:Bun 的原生 HTTP 栈(用 Zig 写的)会在请求离开进程之前,用计算出的哈希值覆盖这串零。

ounter(lineounter(lineounter(lineounter(lineounter(lineJavaScript 层:cch=00000(占位符)         ↓ 请求即将发出Zig 原生层:cch=a3f7b(计算后的哈希)         ↓服务端验证哈希 → 确认是合法的 Claude Code 二进制

这个设计的精妙之处有两个:

  1. 占位符长度不变——避免 Content-Length 变化暴露操作
  2. 计算发生在 JavaScript 运行时之下——JS 层完全看不到真实的哈希值,即使你 hook 了所有 JS 函数也截获不到

当然,它也有弱点:受 NATIVE_CLIENT_ATTESTATION 编译时 flag 控制,可以通过 CLAUDE_CODE_ATTRIBUTION_HEADER 环境变量禁用,在原生 Bun/Node 上重新打包可以绕过。但这种「在运行时层级以下做安全」的思路,值得学习。

机制六:多 Agent 调度架构 —— prompt 即算法

最后一个机制回到了 Agent 本身。

源码中最反直觉的发现是:Claude Code 的多 Agent 协调算法不是写在代码里的——它写在 system prompt 里。

这意味着调度逻辑、任务分配、冲突处理,全部以自然语言的形式存在于提示词中。代码只负责把这些提示词组装起来,真正的「智能」全在 prompt 里。

prompt 中有两条规则让我印象极深:

“Do not rubber-stamp weak work” — 不要对质量差的工作盖橡皮章

“Never hand off understanding” — 永远不要把「理解」这件事交给别人

第一条是对 Code-reviewer Agent 的约束——你的工作是审查,不是走过场。第二条是对所有 Agent 的约束——你可以委派执行,但不能委派理解。这两条规则本身就值得贴在每个工程团队的白板上。

主对话调度决策流程

Agent 调度的内部结构

拆开来看,Claude Code 内部维护了多个专用 Agent,每个有独立的系统提示词和工具权限白名单:

  • Explore Agent — 只读权限,三级精度(quick/medium/very thorough),不能调用其他 Agent
  • Plan Agent — 只读权限,输出分步计划和架构评估,不执行任何修改
  • General-purpose Agent — 唯一拥有完整工具集的万能执行者,也是默认兜底路由
  • Code-reviewer Agent — 仅在里程碑完成后触发,对照计划审查实现质量
  • Code-simplifier Agent — 默认只精简最近修改的代码,保留全部功能
  • Claude-code-guide Agent — 回答关于 Claude Code 自身的问题,有 WebFetch 联网能力
6 个 Agent 的工具权限对比

用户感知到的是一个连贯的对话,但底层是主对话作为调度器,根据语义把任务分发给最合适的 Agent。这个设计的核心在于:权限最小化——6 个 Agent 里只有 General-purpose 拥有全部工具,其他都被严格限制。

还有一些值得注意的细节

终端渲染优化

源码里的终端渲染用了游戏引擎级别的技术:

  • Int32Array 支撑的 ASCII 字符池
  • 位掩码编码的样式元数据
  • Patch 优化器合并光标移动
  • 自淘汰的行宽缓存(token 流式输出时 stringWidth 调用减少约 50 倍)

这解释了为什么 Claude Code 的终端输出比其他 AI CLI 工具明显流畅。不是模型快,是渲染快。

Bash 安全检查

bashSecurity.ts 里有 23 条编号的安全检查规则,18 个被屏蔽的 Zsh 内建命令。防御范围包括:

  • Zsh equals expansion
  • Unicode 零宽空格注入
  • IFS null-byte 注入
  • 一个通过 HackerOne 报告的格式错误 token 绕过

Prompt 缓存架构

promptCacheBreakDetection.ts 追踪了 14 种缓存失效向量。有一种叫「sticky latches」的机制,防止模式切换破坏缓存。代码里甚至有一个函数被标注为 DANGEROUS_uncachedSystemPromptSection()——光看名字就知道动它要三思。

一个让人哭笑不得的 bug

autoCompact.ts 的注释里记录了一个数据:1,279 个会话出现了 50 次以上的连续失败,每天浪费约 25 万次 API 调用。修复方式简单粗暴:MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3。有时候最值钱的优化就是加一个上限。

从源码泄露中提炼的 5 条工程哲学

看完整份源码,我总结了 Anthropic 工程师的几个核心设计原则:

一、防御不是附加功能,是基础架构

Fake tools、native attestation、bash security checks——安全不是在产品做完之后「加上去」的,而是从第一天就编织在架构里的。这和大多数创业公司「先跑起来再说安全」的思路完全不同。

二、不是所有问题都需要 AI

Frustration regex 是最好的例子。在一个全栈 AI 产品里,他们选择用正则表达式而不是 LLM 来做情绪检测。选择不用 AI 的场景,和选择用 AI 的场景一样重要。

三、prompt 是一等公民

多 Agent 调度逻辑写在 prompt 里而不是代码里——这意味着 Anthropic 把 prompt 当作和代码同等重要的工程产出。它有版本控制、有 review 流程、有测试覆盖。如果你还在把 prompt 当成「随手写的字符串」,这个认知需要升级。

四、权限最小化到极致

6 个 Agent 里只有 1 个拥有完整权限。Explore 只能读、Plan 只能规划、Guide 只能查资料。每个 Agent 的工具白名单都是「刚好够用」,多一个都不给。这是安全设计里的最小权限原则,被执行到了极致。

五、务实的丑代码好过优雅的慢代码

print.ts 的 5,594 行确实不好看。但终端渲染用游戏引擎技术做了极致优化,autoCompact 的 3 次失败上限直接省了 25 万次日调用。在工程里,「能用且快」永远优先于「好看但慢」。

这件事的影响

V2EX 上有人说「真正值钱的是模型本身,客户端代码没什么技术含量」。这话对了一半。

客户端代码确实不是护城河——Codex、Gemini CLI 早就开源了。但 Claude Code 源码里暴露的不只是代码,还有战略意图:KAIROS 的自主 Agent 路线图、反蒸馏的竞争策略、undercover 的行业博弈姿态。这些信息的价值远超代码本身。

alex000kim 的那句总结说得好:

「意外地把源码映射文件发到 npm 上,这种事听起来不可能——直到你想起来,这个代码库的相当一部分可能就是你正在发布的那个 AI 自己写的。」

最后说一句:这次泄露最大的教训不是 Anthropic 犯了错,而是它让我们看到了 AI 工具开发的真实水位线。 大多数团队还在研究「怎么写 prompt 让 AI 更聪明」,Anthropic 已经在做反蒸馏毒药、运行时级别的身份认证、和始终在线的自主 Agent。

这个差距,才是真正该焦虑的。

想围观我的朋友圈去年跟全国各地开发者一起掌握行业动态可就就爱我微信。

我是码哥,我们下期见……