我读了 Claude Code 的源代码,所以你不需要再读了

@mal_shaik
英语4个月前 · 2026年3月31日
1.7M
2.3K
334
54
6.0K

TL;DR

本文深入剖析了 Anthropic Claude Code CLI 的内部架构,揭示了如何优化 CLAUDE.md、免费使用并行 Agent,以及利用自定义钩子实现工作流自动化。

大多数人打开 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 — 私有笔记(被 git 忽略)

你有 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 工作树,每个 Agent 有隔离的分支

你可以让 Claude Code 同时启动 5 个 Agent:一个做安全审计,一个重构认证模块,一个写测试,一个更新文档,一个修 Bug。全部同时进行,全部共享缓存。

这套架构天生就是为这个设计的。只用单线程简直是暴殄天物。

3. 权限系统的设计是用来配置的,而不是用来点确认的

每次 Claude Code 问“允许这个操作吗?”然后你点“是”,这代表配置的失败,而不是功能。

源代码揭示了一个 5 层设置级联:

text
1policy > flag > local > project > user

~/.claude/settings.json 中,你可以设置全局模式,定义哪些操作总是允许的:

json
1{
2 "permissions": {
3 "allow": [
4 "Bash(npm *)",
5 "Bash(git *)",
6 "Edit(src/**)",
7 "Write(src/**)"
8 ]
9 }
10}

有三种权限模式:

  • bypass(绕过) — 不做任何权限检查(危险但快速)
  • allowEdits(允许编辑) — 自动允许在工作目录中的文件编辑
  • auto(自动,这是新的) — 对每个操作运行 LLM 分类器。这是最佳平衡点。

自动模式有自己的允许/拒绝列表可以配置。源代码显示它会并发运行多个解析器:用户点击、钩子分类器、桥接器,谁先响应谁赢。

每次你停下来点击“允许”就是浪费时间。一次性配置好,再也不用点。

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

源代码中有五种不同的方式来压缩过长的对话:

  1. microcompact(微压缩) — 基于时间清除旧工具结果
  2. context collapse(上下文折叠) — 总结对话片段
  3. session memory(会话记忆) — 提取关键上下文到文件
  4. full compact(完全压缩) — 总结整个历史
  5. PTL truncation(PTL 截断) — 丢弃最旧的消息组

这告诉你一个重要信息:上下文溢出是一个核心问题,工程师花了大量时间在上面。

这对你意味着什么:

  • 主动使用 /compact。不要等到系统自动压缩导致你关心的上下文丢失。
  • 默认窗口是 200K tokens。但你可以通过添加 [1m] 模型后缀选择 1M tokens 窗口。对于涉及多个文件的大型重构,这很重要。
  • 长会话会积累“会话记忆”——任务规范、文件列表、工作流状态、错误和学习总结的结构化摘要。这就是为什么恢复会话比重新开始更好。
  • 大的工具结果会存储到磁盘,只发送 8KB 预览给模型。如果你粘贴一个巨大的文件,模型可能只看到一小部分。保持输入集中。

那些把 Claude Code 用得最好的人,把 /compact 当作电子游戏中的手动存档点。保留重要的,清除不重要的,继续前进。

5. 钩子系统是真正的扩展 API(25 个以上的生命周期事件)

这是几乎没人知道的进阶用户功能。

源代码揭示了 25 个以上的生命周期事件,你可以挂钩进去:

  • PreToolUse — 在任何工具执行前运行
  • PostToolUse — 在任何工具执行后运行
  • UserPromptSubmit — 当你发送消息时运行
  • SessionStart / SessionEnd — 会话生命周期
  • 以及 20 多个其他事件

有 5 种钩子类型:

  • command(命令) — 运行 shell 命令
  • prompt(提示) — 通过 LLM 注入上下文
  • agent(Agent) — 运行完整的 Agent 验证循环
  • HTTP — 调用 webhook
  • function(函数) — 运行 JS

实际能做的事例如:

  • 每次文件写入前自动运行 lint
  • 每次编辑后自动运行测试
  • 自动在每个提示中注入相关文档
  • 任务完成时发送 Slack 通知
  • 在代码提交前验证安全模式是否遵循

UserPromptSubmit 钩子尤其疯狂。你可以自动为每条消息注入 additionalContext。想象一下,无需手动输入,就能把测试输出、最近的 git diff、或项目状态自动附加到每个提示上。

这就是在 Claude Code 之上构建自定义开发环境的方式。不是靠更好的提示词,而是靠挂钩到系统本身。

6. 会话是持久化且可恢复的(别再重新开始)

每次对话都保存为 JSONL 文件,位置在:

text
1~/.claude/projects/{hash}/{sessionId}.jsonl

源代码支持:

  • --continue — 恢复上次会话
  • --resume — 选择某个特定的历史会话
  • --fork-session — 从历史对话中分支(我个人非常喜欢这个)

会话记忆提取会在压缩过程中保留关键上下文:任务规范、文件列表、工作流状态、错误和学习总结。

大多数人每次打开 Claude Code 都开始一个新会话。这就像每过一小时就关闭 IDE 再重新打开。你正在做什么、什么失败了、学到了什么——所有这些上下文——都丢失了。

始终使用 --continue。让上下文积累,让会话记忆随时间构建学习成果。源代码中构建了相应的基础设施。用起来。

7. 工具系统运行 60 多个工具并智能批量处理

Claude Code 有 60 多个内置工具。但有意思的是它如何运行这些工具。

源代码将工具调用分为两类:

  • concurrent(并发) — 只读操作(读取文件、搜索、通配符匹配)并行运行
  • serial(串行) — 可变操作(编辑、写入、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 因 529 错误失败 3 次,它会自动回退到 Sonnet
  • 流式传输时 90 秒空闲看门狗 — 如果流式停顿,则回退到非流式
  • 持久模式有无限重试,最长退避 5 分钟

这意味着 Claude Code 的设计使它可以在后台一直运行。它能够优雅地处理 API 故障、速率限制和中断。你不需要盯着它。让它后台跑着,回来收结果。

总结:从源代码中得到的最高杠杆操作:

  • 写一份真正的 CLAUDE.md → 每轮对话都加载。40K 字符。最高杠杆配置。
  • 用子 Agent 并行化 → fork 模式共享提示缓存。5 个 Agent ≈ 1 个的成本。
  • 在 settings.json 中配置权限 → 永远消除点击疲劳。
  • 主动使用 /compact → 之所以有 5 种压缩策略,是因为上下文压力是真实存在的。
  • 设置钩子 → 25+ 事件,5 种类型。这是真正的扩展 API。
  • 始终 --continue 会话 → JSONL 持久化 + 会话记忆 = 累积上下文。
  • 连接 MCP 服务器 → 延迟加载意味着在用到之前零成本。
  • 自由中断 → 异步生成器意味着引导零代价。

核心要点:Claude Code 是一个穿着终端 UI 的 Agent 编排平台。

那些从中获得 10 倍产出的人,并不是提示词写得更好。他们配置了它。他们并行化了它。他们挂钩了它。他们让上下文跨会话积累。

源代码把这一切说得明明白白。现在你也知道它底层到底在干什么了。

觉得有用就转发 🫶

二次创作

使用 YouMind 创作爆款文章

收集素材、拆解爆点、生成视觉资产、撰写内容,并在一个 AI 工作空间里完成分发。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章