乐于分享
好东西不私藏

我读完了 Claude Code 源码!

我读完了 Claude Code 源码!

大多数人打开 Claude Code,输入一个提示,等待响应,再输入下一个提示。
这就像买了一辆法拉利,却只用一档开。
我想搞明白为什么有些人使用 Claude Code 的效率似乎是其他人的 10 倍。所以我做了任何理性的人都会做的事:我读完了整个源代码(当我说”我”的时候,当然是指 Claude Code 自己读的)。
11 层架构。数千行代码。一个伪装成终端聊天的 Agent 编排平台。

以下是源代码揭示的关于如何真正使用这个工具的内容。


1. CLAUDE.md 每一轮都会被加载。每一轮。每一次。

这是你能做的最高杠杆的事情,但几乎没有人做好。
大多数人要么 CLAUDE.md 文件里什么都没有,要么把整本圣经都写进去了。
源代码显示,Claude Code 在**每次查询迭代**时都会读取你的 CLAUDE.md 文件。不是在会话开始时。是每一轮。这意味着你每发送一条消息,它都会重新读取你的指令。
它有一整套层级体系:
  • ~/.claude/CLAUDE.md — 全局级(你的编码风格、偏好)
  • ./CLAUDE.md — 项目级(架构决策、约定)
  • .claude/rules/*.md — 模块化规则
  • CLAUDE.local.md — 私人笔记(被 gitignore 忽略)
你有 **40,000 个字符**的空间。这非常多。大多数人可能只用了 200 个。
把你的架构决策写进去。你的文件约定。你的测试模式。你的”绝对不要这样做”规则。模型每一轮都会读取它们。这就是 Claude Code 作为一个通用助手和作为**你的助手**(了解**你的代码库**的助手)之间的区别。
如果你读完这篇文章只做一件事,就是这个。

2. 子 Agent 共享提示缓存(并行基本上是免费的)

这是让我震惊的地方。
当 Claude Code 派生一个子 Agent 时,它会创建父上下文的**逐字节相同的副本**。API 会缓存这个。所以派生 5 个 Agent 来处理代码库的不同部分,成本几乎不比 1 个 Agent 按顺序执行多多少。
再读一遍。
**5 个 Agent。和 1 个的成本差不多。** 因为它们都命中了提示缓存。
大多数人把 Claude Code 当作一个单一工作者使用。一次一个任务。等它完成。再给下一个。
源代码实际上有三种子 Agent 执行模型:
  • fork — 继承父上下文,缓存优化
  • teammate — 在 tmux 或 iTerm 中独立面板运行,通过基于文件的邮箱通信
  • worktree — 获得自己的 git worktree,每个 Agent 一个独立分支
你可以让 Claude Code 启动 5 个 Agent:一个做安全审计,一个重构认证模块,一个写测试,一个更新文档,一个修复 Bug。全部同时进行。全部共享缓存。
这个架构就是**为此而生的**。单线程使用简直是暴殄天物。

3. 权限系统是设计来被配置的,不是用来点击的

每次 Claude Code 问你”允许此操作吗?”然后你点击”是”,这是**配置的失败**,不是功能。
源代码揭示了一个 5 层设置级联:
“`
policy > flag > local > project > user
“`
在 `~/.claude/settings.json` 中你可以设置 glob 模式来指定哪些操作始终被允许:
“`json
{
“permissions”: {
“allow”: [
“Bash(npm *)”,
“Bash(git *)”,
“Edit(src/**)”,
“Write(src/**)”
]
}
}
“`
有三种权限模式:
  • bypass — 完全不做权限检查(危险但快速)
  • allowEdits — 自动允许在工作目录中编辑文件
  • auto(这是新的) — 对每个操作运行一个 LLM 分类器。这是最佳平衡点。
auto 模式有自己的允许/拒绝列表可以配置。源代码显示它会**并行竞争多个解析器**:用户点击、hook 分类器、bridge,谁先响应谁赢。
每次你停下来点击”允许”都是浪费的时间。配置一次。再也不用点。

4. 有 5 种压缩策略。上下文压力是一个真实的问题

源代码有 **5 种**不同的方式来压缩过长的对话:
  1. **microcompact** — 基于时间清除旧的工具结果
  2. **context collapse** — 总结对话片段
  3. **session memory** — 将关键上下文提取到文件中
  4. **full compact** — 总结整个历史记录
  5. **PTL truncation** — 丢弃最旧的消息组
这告诉你一件重要的事:**上下文溢出是工程师们花了大量时间解决的核心问题。**
对你来说意味着什么:
  • 主动使用/compact。不要等系统自动压缩然后丢失你关心的上下文。
  • 默认窗口是 200K token。但你可以通过使用[1m] 模型后缀来选择 1M token。对于跨多个文件的大型重构,这很重要。
  • 长会话会积累”session memory”——任务规格、文件列表、工作流状态、错误和经验教训的结构化摘要。这就是为什么恢复会话比重新开始要好。
  • 大型工具结果会被存储到磁盘,只发送 8KB 预览给模型。如果你粘贴一个巨大的文件,模型可能只看到其中一小部分。保持输入聚焦。
真正高效使用 Claude Code 的人把 `/compact` 当作**电子游戏中的手动存档点**。保留重要的,清除不重要的,继续前进。

5. Hook 系统才是真正的扩展 API(25+ 个生命周期事件)

这是几乎没人知道的高级用户功能。
源代码揭示了 **25+ 个**你可以挂载的生命周期事件:
  • PreToolUse — 在任何工具执行前运行
  • PostToolUse — 在任何工具执行后运行
  • UserPromptSubmit — 在你发送消息时运行
  • SessionStart / SessionEnd — 会话生命周期
  • 以及20+ 个更多事件
有 **5 种** Hook 类型:
  • command — 运行 shell 命令
  • prompt — 通过 LLM 注入上下文
  • agent — 运行完整的 Agent 验证循环
  • HTTP — 调用 webhook
  • function — 运行 JS
实际使用示例:
  • 在每次文件写入前自动运行 lint 检查
  • 在每次编辑后运行测试
  • 自动将相关文档注入到每个提示中
  • 任务完成时发送 Slack 通知
  • 在代码发布前验证安全模式是否被遵循
`UserPromptSubmit` hook 尤其强大。你可以向你发送的**每一条消息**注入 `additionalContext`。想象一下,自动将测试输出、最近的 git diff 或项目状态附加到每个提示中,而不需要手动输入。
这才是你在 Claude Code 之上构建自定义开发环境的方式。不是通过写更好的提示。而是**挂载到系统本身**。

6. 会话是持久化和可恢复的(别再从头开始了)

每段对话都以 JSONL 格式保存在:
“`
~/.claude/projects/{hash}/{sessionId}.jsonl
“`
源代码支持:
  • --continue — 恢复你上一次的会话
  • --resume — 选择一个特定的过去会话
  • --fork-session — 从过去的对话分支出来(我个人很喜欢这个)
Session memory 提取会在压缩过程中保留关键上下文:任务规格、文件列表、工作流状态、错误和经验教训。
大多数人每次打开 Claude Code 都会开一个新会话。这就像每隔一小时关闭你的 IDE 然后从头重新打开一样。你正在做什么、什么失败了、学到了什么——所有上下文,全部消失。
使用 `–continue`。始终如此。让上下文积累。让 session memory 随时间积累经验教训。源代码**确实为此建立了基础设施**。用它。

7. 工具系统运行 60+ 个工具,并支持智能批处理

Claude Code 有 **60+ 个**内置工具。但有趣的是它**如何**运行它们。
源代码将工具调用分为两类:
  • 并发 — 只读操作(读取文件、搜索、glob 匹配)并行运行
  • 串行 — 变更操作(编辑、写入、bash 命令)逐个运行
这意味着当 Claude Code 需要读取 10 个文件来理解你的代码库时,它会**同时读取全部 10 个**。但当它需要编辑 3 个文件时,它会逐个执行以避免冲突。
在内置工具之上,你可以连接 MCP 服务器来添加更多工具。源代码使用**延迟加载**。MCP 工具只在需要时才加载,所以连接 5 个 MCP 服务器不会拖慢每个请求。
还有 **ToolSearch** 用于延迟发现 Agent 尚不知道的工具。
实际启示:如果你的工作流涉及外部系统(数据库、云服务商、CI/CD),为它们连接 MCP 服务器。架构会处理复杂性。你只需要获得更多能力。

8. 流式架构意味着中断的代价极低

整个管道使用异步生成器逐个产出事件。按 Escape 键可以干净地中止当前流,而不丢失之前的上下文。
这看起来很小,但它改变了你使用 Claude Code 的方式。
**不要等待一个你知道正在走偏的响应**。立即中断并重新引导。源代码就是为此设计的。你之前的上下文会被保留。中断的响应会被干净地丢弃。零惩罚。
把它想象成结对编程。如果你的搭档开始走错方向,你不会等他们写完。你会说”实际上,往这边走”。同样的道理。

9. 重试系统比你想象的更复杂

源代码揭示了:
  • 10 次重试,指数退避加抖动(500ms 基础值)
  • 在 401/403 时自动刷新 OAuth token
  • 模型降级:如果 Opus 连续 3 次返回 529 错误,会自动降级到 Sonnet
  • 90 秒空闲看门狗——如果流式传输停滞,会降级到非流式传输
  • 持久模式有无限重试,最大退避 5 分钟
这意味着 Claude Code 是设计来被**放在那里运行**的。它能优雅地处理 API 故障、速率限制和服务中断。你不需要守着它。让它在后台运行,回来看结果就好。

TL;DR:源代码揭示的最高杠杆操作

  • 写一个真正的 CLAUDE.md → 每轮都会加载。40K 字符。最高杠杆的配置。
  • 用子 Agent 并行化 → fork 模型共享提示缓存。5 个 Agent ≈ 1 个的成本。
  • 在 settings.json 中配置权限 → 永远消除点击疲劳。
  • 主动使用 /compact → 存在 5 种压缩策略,因为上下文压力是真实的。
  • 设置 hooks → 25+ 个事件,5 种类型。这才是真正的扩展 API。
  • 始终用 –continue 恢复会话 → JSONL 持久化 + session memory = 积累的上下文。
  • 连接 MCP 服务器 → 延迟加载意味着不使用时零成本。
  • 放心中断 → 异步生成器意味着重新引导零惩罚。

最后:

Claude Code 是一个**披着终端 UI 外衣的 Agent 编排平台**。
那些从中获得 10 倍产出的人不是更擅长写提示。他们**配置了它**。他们**并行化了它**。他们**挂载到了它**。他们**让上下文跨会话积累**。
源代码让这一切显而易见。现在你知道它在底层到底做了什么。
如果你觉得有帮助,请转发 🔁