1. 先说清楚Claude Code是什么这份源码为什么值得读如果你最近在技术社区刷到过Claude Code源码泄漏这个词大概率会看到两种反应一种是就是个npm包里带了个source map没什么大不了另一种是这是理解现代Agent系统最好的免费教材。我属于后者而且在花了两周时间把还原出来的代码捋过一遍之后可以负责任地说Claude Code在架构层面做的事远比大多数人想象的复杂也远比调一个聊天接口要工程化得多。先说背景。Claude Code是Anthropic在2024年底到2025年初逐步对外开放的终端Agent编程工具你可以在命令行里用自然语言让它读写代码、执行测试、操作Git仓库。它本质上是一个AI结对程序员——但它要想真正在真实项目里干活就必须解决一系列普通聊天机器人不需要考虑的问题怎么在几万行代码的项目里找到相关文件怎么在执行命令失败后自己纠正怎么保证一轮对话里几十次工具调用不把上下文撑爆怎么在权限和安全之间找到平衡。2024年11月有开发者发现npm包anthropic-ai/claude-code里包含了未构建的source map文件通过它可以把发布版JS还原成接近原始源码的形式。消息很快在GitHub和X上传开Anthropic随后更新了npm包移除了这些映射文件但还原出来的代码已经在社区里流传开。这篇就是我基于还原源码做的第一轮阅读笔记重点放在Agent系统的整体架构设计上。这篇文章适合谁两类人。一类是已经在用Claude Code、想搞明白它内部怎么工作的人你会在里面找到很多原来这个功能是这么实现的时刻另一类是自己正在开发Agent应用、想从成熟产品里学架构经验的人我会把重点放在权限模型、上下文管理和工具调用链路这些可复用的设计模式上。如果你是纯小白只想装个Claude Code写代码那这篇可能偏深了但读完你对它的理解也会比绝大多数使用者深一层。2. 从源码流出的第一印象它根本不是大模型套壳很多人以为Claude Code就是一个把Claude API包了一层界面甚至有人问我是不是就是Anthropic官方做了一个OpenAI Codex的克隆版。看完代码之后我只能说这个判断错得离谱。它更像是一个围绕大模型能力构建的完整操作系统——有自己的进程模型、权限系统、文件管理和会话机制。2.1 进程模型的取舍先说最让我意外的部分。Claude Code不是跑在浏览器里也没有用Electron套壳它是纯粹的命令行工具用Node.js实现进程模型很轻量。主进程负责与用户交互、维护会话状态、调度模型API调用然后通过各种handler去执行具体的工具操作——比如文件读写、命令执行。工具的执行既有在主进程内直接做的也有通过子进程做的关键是它把交互层调度层执行层做了清晰的分离。这带来一个直接的工程价值任何一个环节出问题你可以单独重启或者降级而不至于整个工具崩溃。比如执行一个耗时很长的测试命令它不会阻塞模型对话模型等待工具结果的时候你还是可以输入新的指令来打断或者补充。它的进程模型还考虑了一个很实际的场景——长时间运行的Agent任务。Claude Code有一个--resume机制能把之前的会话打包恢复这个功能在源码里占据了不少代码量。这意味着整个会话状态不是放在内存里随缘的而是有完整的序列化、压缩和恢复逻辑。这套东西我在自己做的Agent项目里基本就是照着它抄的。2.2 权限系统Allow/Deny/Ask的三级设计这是我认为Claude Code里设计得最好、也最值得反复琢磨的部分。你可以通过/permissions命令设置工具的访问权限核心规则可以配置成三种模式allow无条件允许、deny无条件拒绝、ask每次询问用户。但它不是搞一个全局开关就完事了而是支持非常细粒度的规则匹配——你可以只允许Bash工具在某个特定目录下执行可以对Read工具配置任何地方都能读但对Write工具要求必须确认还可以在会话中让模型自己向用户申请临时权限。从源码的还原结构来看这个PermissionManager做得相当完整它维护了一套规则列表每条规则有具体的工具名匹配、路径匹配和操作类型然后提供check接口给上层调用。工具执行前会先过一遍权限检查如果被拒绝模型收到的不是执行成功或执行失败而是一个明确的没有权限信号模型可以基于这个信号向用户请求权限或者调整方案。这里有一个特别微妙的设计权限检查失败不是直接中断整个任务而是作为工具结果返回给模型。这个取舍太关键了。如果权限检查失败直接抛异常终止那模型根本没法自我纠偏——它不会知道你是不允许读这个文件还以为自己工具调用写错了。而把这个信息包装成工具结果模型就能理解哦这个操作不允许那我换一种方式。权限系统和模型之间的通信协议是经过精心设计的这一点的价值在小项目里不明显一旦你的Agent要操作真实系统它就是免于事故的安全网。3. 记忆与上下文CLAUDE.md和会话压缩是怎么设计的如果说权限系统是Claude Code的安全心脏那上下文管理就是它的大脑皮层。每个用过Claude Code的人都知道CLAUDE.md这个文件但很多人只是把它当成一个写项目说明的地方。源码告诉我它其实是一套精心设计的多层记忆系统。3.1 文件记忆层的分层策略Claude Code的记忆不是只有一层而是按作用域分了多个层级。从代码逻辑看它会在不同位置寻找记忆文件然后按特定顺序把它们注入到系统提示词里。大致顺序是企业级策略文件比如公司层面的规范、用户级全局记忆在~/.claude/CLAUDE.md、项目级记忆项目根目录的CLAUDE.md、以及可选的子目录级记忆。这几个文件不是简单拼接而是有优先级和去重逻辑的。比如企业级文件里写了禁止使用某个依赖那项目级的CLAUDE.md就没法通过后期指令绕过这个限制。这和权限系统形成了呼应——记忆系统不只是告诉模型背景知识它的一部分内容具有约束力权限系统负责任硬性拦截记忆系统负责软性引导。很多人在自己项目里模仿这个设计但只抄了一层CLAUDE.md这是在真正意义上没有理解它背后的分层思想。我的建议是如果你的Agent要服务多项目、多用户一定要做至少三层的记忆分层否则用户级的通用偏好在项目里会干扰项目级的具体规则早晚会出问题。3.2 上下文压缩的时机与方法大模型的上下文窗口是有限的哪怕Claude 3.5 Sonnet支持20万token真正处理一个大型代码库时也撑不过十几轮工具调用。所以Claude Code在源码里花了大量代码处理会话压缩compact。从流程上看它有两种压缩模式。一种是自动的当上下文使用量超过阈值比如80%它会触发一次摘要提取把前面的对话压缩成结构化摘要。另一种是手动的用户通过/compact命令主动触发。压缩动作不是简简单单让模型总结一下之前聊了啥而是把整个对话历史重新组织成一个会话摘要其中包含了用户需求、已完成步骤、未完成步骤、关键决策和待办事项。我最欣赏的细节是它在压缩时会对代码内容做特殊处理。原始代码片段不会直接塞进摘要——如果一段代码很长但已经不再需要被修改它会被替换成一个简短的文件路径引用索引。因为Agent后续还可能重新读取文件不需要在上下文里保留完整内容。这种能索引就不缓存全文的策略对上下文预算的精打细算到了令人发指的程度但就是这些细碎优化让长任务的可用性上了一个台阶。3.3 子代理与上下文隔离Context管理里另一个非常有意思的设计是子代理subagent。Claude Code在复杂任务里可以创建专门的子代理来处理特定子问题每个子代理有自己的系统提示词和上下文窗口不与主对话共享全部历史。这就像你把一个复杂项目拆给了多个不同职责的成员每个人只需要了解与自己相关的背景。源码揭示的子代理机制比大多数人猜的要完整。它有一套子代理的spec定义文件明确了子代理的角色、能力边界和可用的工具范围。主代理会把任务连同必要的上下文一起打包递给子代理子代理执行完把结果返回主代理。这个结果经过一层压缩只保留结论和关键产出不会把子代理的整个思维链和生活琐事都带回来。好处显而易见主上下文的消耗被控制住了而且每个子代理可以针对自己的任务进行局部深度思考不用在大上下文里大海捞针。每次想解决Agent的越聊越笨问题根源几乎总是上下文污染。子代理压缩层级记忆这三管齐下才真正缓解了它。4. 工具调用的工程化从系统提示词到函数调用的完整链路让模型读写文件、跑命令、操作Git这些能力在Demo里看着简单但真正要做到生产可用整个工具调用链路的设计才是重中之重。Claude Code在这一点上给出的答案很多细节值得反复品味。4.1 工具栈的形式不只是function calling如果你只调用过OpenAI或Anthropic的function calling接口你可能会理解成模型返回一个结构化JSON里面写了要调哪个函数、参数是什么然后代码执行它。Claude Code是这样做的但不只是这样。它的工具调用协议更像一个完整的请求-响应循环而且最妙的是它把工具执行的结果通过一个内部回调机制改写成一条特殊的系统消息塞回对话。从还原代码里可以看到一个tool_use的返回会被系统转换成中间消息再作为后续模型输入的组成部分。在这个回路里模型不只是拿到纯文本结果还会拿到一些非文本信号——比如工具执行过程的耗时、是否有警告信息、结果是否被截断等。这些用普通API拿不到的信号被组织成了后续模型决策的重要依据。还有一点在Claude Code的源码里表现得很明显工具列表本身是动态构建的。它并不是每次请求都把所有工具的完整定义发给模型而是根据当前场景动态裁剪。比如当模型不在Git仓库里工作时和Git相关的工具就不会出现在工具列表中。这个动态裁剪既省token又避免模型在不可用的工具上浪费时间属于大佬写着舒服、读者看着心疼的优化。4.2 MCP协议的作用把外部工具变成第一等公民Claude Code在2024年底支持了MCPModel Context Protocol这是一个让外部工具和数据源以统一方式接入Claude的开放协议。源码里可以看到MCP工具和内置工具在协议层面是平级的——外部MCP服务器提供的工具会被包装成和内置Read/Write工具一样的接口形式走同一个权限检查和结果回调链路。这个设计的工程价值很大。如果你接入一个MCP工具你不需要为它单独写权限逻辑不需要单独处理错误格式它天然就能享受到Claude Code的权限系统、会话恢复、上下文管理等等所有基础设施。作为开发者你想要让自己的工具被Agent用好最高效的方式不是写自定义插件而是提供一个MCP服务让宿主Agent用标准协议来调用你。4.3 重试、限流和幂等工业级系统的隐形工作量看源码的时候有一个强烈的感受真正的工程化工作量不在那些亮眼的功能上而是在那些看不见 的地方。比如模型API调用的限流——当你连续发起多个工具循环时Claude Code要面对的是Anthropic API的rate limit。源码里有一整套请求队列和退避重试机制它不会傻傻地失败退出而是会根据retry-after头信息做自适应等待。再比如命令执行的幂等和超时控制。Bash工具并不是把命令丢给shell就完事了它有超时机制、有输出截断机制、有伴随进程管理。一个npm test可能跑两分钟不结束这时模型还在等结果如果直接杀掉可能留下僵尸进程如果一直等又会卡死整个Agent。源码里对这类情况设计了专门的配置项——你可以指定某个命令运行的最长时间超过时间Agent会收到截断结果并有机会决定重跑或放弃这种决策权在模型手中的容错思路比硬编码超时就失败高明得多。5. 权限边界的再思考工具越多事故面越大前面提到了权限系统的设计框架但我觉得有必要单独开一节来聊Claude Code作为Agent工具怎么平衡给模型足够的操作能力和防止它做危险操作。因为这是任何做Agent产品的人都绕不开的设计难题。5.1 工具选择就是攻击面选择Claude Code默认提供的工具集其实是经过精心权衡的。它有Read、Write、Edit、Bash、Glob、Grep、Git等工具但它没有给模型直接访问网络的能力默认也没有暴露读取所有系统文件之类的超级工具。这种克制不是技术上的限制而是刻意为之——每一个工具都是模型获得能力的一条通道通道越多出事故概率越大权限系统需要覆盖的边界就越广。我们自己做Agent时最容易犯的错就是给工具不给权限或给权限不给审计。工具越加越多最后权限规则复杂到连开发者自己都记不住。Claude Code的做法反而是清晰边界灵活覆盖内置工具不多但每个工具都设计得足够通用权限规则可以精细到路径级别但默认策略是保守的。5.2 一份可直接参考的权限配置思路以下是我结合源码架构和实际使用经验整理的权限配置参考你可以直接用在自己项目的Agent上配置目标推荐策略备注只读操作默认放行或ask一次Grep、Glob等读取类工具基本安全文件写入限定目录ask确认防止模型改到不该改的地方命令执行只允许白名单命令超时约束Bash工具是最危险的必须重点管控网络请求默认禁止必要时单独授权一旦放开数据外泄风险陡增环境变量读取ask确认密钥信息不得随意暴露给模型在Claude Code里这些不是理论而是直接能用的配置规则。我实际跑项目的过程中最开始几乎全用ask模式但因为每次工具执行都要弹确认效率很低后来逐步细化成了按目录和命令的白名单。这里有个经验供参考不要一开始就把权限全放开先保守等你在真实任务里摸清了模型的调用模式再逐步放宽到够用且可控的程度。6. 实际测试跑通一个带权限约束的文件重构任务光谈架构容易飘我准备用一个实际任务来验证从源码里学到的那些设计到底有没有用。我拿了一个小的Python项目做测试目标是让Claude Code读取某个模块把里面所有硬编码的字符串抽到配置文件里然后跑一遍原有测试确认没被改坏。第一轮我故意没配置权限全程默认ask。结果是模型读文件读得很顺但它中途有一次提出要直接修改requirements.txt虽然问了我可如果我没有仔细看它可能会顺手动依赖文件。这就是宽容模式下的事故隐患。第二轮我按照前面说的思路把Write工具限定到项目目录Bash工具白名单只留了python和pytest然后重跑任务。效果非常明显模型在生成配置文件时很自然地走了项目内部路径没有再尝试越权操作所有命令都在白名单内执行。这次重构任务大约用了7轮工具调用就完成了测试也全部通过。实测下来合理的权限配置不会让Agent变笨反而会让它更专注。它有边界就不会去探索那些不该尝试的路径整个行为模式都会收敛到对你有利的范围里。很多人怕权限限制会影响Agent的灵活度这个担心有点多余——模型是适应力很强的系统给它清晰的边界它会在边界内找到最优解。7. 下一步源码阅读路线图与个人体会作为系列的第一篇我故意把内容聚焦在了整体架构感知这个层面进程模型、权限系统、上下文管理、工具调用链路。这些是理解Claude Code的骨架。按我的计划这个系列后面可以继续展开这些主题深入MCP协议层看外部工具接入的完整链路和调试方法深入会话压缩算法看它到底怎么决定该保留什么、丢弃什么深入Bash工具的进程管理看它怎么处理长任务、并发和信号深入CLAUDE.md的加载与合并逻辑看多级记忆的冲突处理策略最后分享一点个人体会。我在读完这套源码后最大的感触不是它的某个功能很聪明而是整个系统设计呈现出的那种工程克制——它在每一个能加功能的地方都做了权衡和限制。做Agent系统能力从来不是最大瓶颈边界设计才是。Claude Code把大量工程资源花在了确保模型行为可控这个目标上权限、上下文管理和工具协议的稳健性构成了它能在真实项目里被信赖的基础。我们做自己的Agent项目时如果也能有这样的克制意识很多翻车现场其实是可以提前避免的。