# 我如何使用 Claude 为我的代理构建框架代码泄露
**作者**: Rohit
**日期**: 2026-04-07T16:09:01.000Z
**来源**: [https://x.com/rohit4verse/status/2041548810804211936](https://x.com/rohit4verse/status/2041548810804211936)
---

Anthropic 刚刚教会了你如何构建最好的 AI 代理框架。
Claude Code 的源代码完全公开:55 个目录,331 个模块,这是目前生产环境中经过实战检验的代理架构。我仔细分析了每一个文件、每一个架构决策、每一条重试路径、每一种压缩策略以及每一个权限阶段。
这不是拆解分析,而是设计方案。
这里包含了其中的每一个原理,以及如何利用每一个原理来构建你自己的、能够经受住生产考验的安全带。
## Claude Code 的架构揭示了业界最受欢迎框架的哪些特性
你肯定听说过这三个层次:模型权重、上下文和框架。业界在每次会议、每篇教程、每个框架的 README 文件中都会反复提及它们。
模型权重 :冻结的智能,即通过 API 调用的东西。
上下文 :提示信息、对话历史记录、检索到的文档。
框架 :围绕模型构建的脚手架。工具、循环、错误处理。
就其本身而言,这种表述是正确的。普林斯顿大学自然语言处理系的 SWE-agent 论文表明,在仅改变界面设计的情况下,SWE-bench 的性能提升了 64%。GPT-4 模型不变,任务也相同,唯一改变的是环境。性能提升体现在第 2 层和第 3 层,而非第 1 层。
然后你打开克劳德·科德的源代码,就会发现人为因素并非在为模型构建产品,而是在为系统构建产品。
在 Claude Code 内部,四级 CLAUDE.md 层级结构允许企业管理员通过 MDM 强制执行策略,项目维护者设置约定,而各个开发人员则可以在本地进行覆盖。基于磁盘的任务列表和文件锁定机制可防止并行子代理相互干扰。Git 工作树隔离机制确保五个代理在同一个仓库中拥有五个分支,且不会发生任何冲突。权限管道将拒绝规则从企业层级传递到项目层级,再到用户层级,最终传递到会话层级。
这些都不是束缚。这些都不是背景。这些都不是重量。
这就是基础设施 :多租户、基于角色的访问控制、资源隔离、状态持久化、分布式协调。
实际框架包含四个层次:
模型权重 :冻结的智能。
上下文 :运行时输入。
工具 :代理的设计环境。
基础设施 :多租户、基于角色的访问控制、资源隔离、状态持久化、分布式协调。
大多数团队会讨论前三点,因为它们值得思考。而第四点往往是产品走向失败的根源。Claude Code 是我见过的第一个认真对待这四点的智能体系统,其架构在各个层面都体现了这一点。
## 核心代理循环:异步生成器,而非 while 循环
Claude Code 的核心在于 query.ts 文件:1729 行 TypeScript 代码。其中最重要的决定在于函数签名:

异步代理循环
这个函数*比看起来更重要。异步生成器会随时间生成值,可以根据需要暂停,并允许任何调用者随时退出。
代理循环并非请求-响应循环,而是一个长时间运行、流式传输且可取消的过程。生成器无需任何额外功能即可提供所有这些特性。
将其与大多数教程的内容进行比较:

教程垃圾
这在教程中可行。但在生产环境中会因以下五个原因而崩溃。
没有实时流。 用户会观看空白屏幕 10-30 秒,模型会进行生成。Claude Code 的生成器会在收到标记时生成 StreamEvent 对象。用户可以逐个字符地观察模型的运行过程。能够看到代理运行过程的用户会更加信任它。信任代理的用户会赋予它更大的自主权。而自主权正是有效工作发生的前提。
无法取消。 在 while 循环版本中,Ctrl+C 需要一个单独的外部中止机制。使用生成器,调用者会停止调用 `.next()`。`finally` 代码块执行,清理工作完成。Claude Code 将 `AbortSignal` 传递到每一层,而生成器使这一过程自然而然。
不支持组合。REPLUI 使用生成器,子代理使用生成器,测试也使用生成器。只有一个 query() 函数,三个调用者,零重复。生成器是流式数据的通用接口。
没有反压。 如果模型生成速度快于终端渲染速度,while 循环会将所有内容缓冲到内存中。生成器会在消费者停止拉取数据时暂停生成。在长时间会话中,这种速度差决定了内存使用量是保持有限还是持续增长直至进程终止。
循环内部没有错误恢复机制。 问题就出在这里。
每次迭代五个阶段
Claude Code 的代理循环的每次迭代都会经历五个阶段。正是这些阶段保证了该安全机制的弹性。
第一阶段:设置。 在调用模型之前,循环会应用工具结果预算,如果对话过长则运行压缩策略,并验证令牌计数。大多数框架会将原始消息数组传递给模型,并祈祷一切正常。
第二阶段:模型调用。 循环通过依赖注入接口调用 `queryModelWithStreaming()`,该接口封装在一个重试机制中,可处理十种错误类型。流式工具执行器在此阶段,此时模型尚未生成完成。Grep 调用会在其输入 JSON 数据完整到达流中时立即开始运行,甚至在下一个工具调用到达之前几秒就开始运行。
第三阶段:错误恢复与压缩。 循环会在模型响应后检查可恢复的错误。提示信息过长?压缩并重试。达到 max_output_tokens 限制?将输出令牌数从 32K 增加到 64K 并重试。上下文溢出?对媒体密集型消息执行响应式压缩。这些是循环状态机中的一级状态,而不是外部 try-catch 块中的边界情况。
第四阶段:工具执行。 流式执行器尚未执行的工具在此阶段运行。执行完成后,结果会显示在用户界面上。Haiku 异步生成工具使用摘要,因此主模型不会因记录日志而消耗代币。
阶段 5:继续决策。 模型的 stop_reason 参数告知循环是否需要更多刀具调用。转弯计数器检查 maxTurns。钩子可以请求停止。中止信号也会被检查。如果继续,循环状态递增并返回阶段 1。
错误恢复机制存在于循环内部,而非循环之外。每个阶段都清楚可能出现的问题,并拥有特定的恢复路径。这正是代理程序因速率限制而崩溃与代理程序能够回退、重试、回退到其他模型并继续运行之间的区别。
依赖注入使其可测试。
循环通过 QueryDeps 接口接收其依赖项:

查询依赖项
注入一个模拟的 callModel,使其产生预设事件,这样就可以在不触及真实 API 的情况下验证上下文溢出处理、工具故障和取消操作。大多数代理框架都无法测试,因为它们将 API 调用硬编码到循环中。Claude Code 的循环是一个纯状态机,并注入了副作用。
## 工具执行:并发分类为何改变一切
Claude Code 内置了 45 多个工具。数量不是重点,重点在于它们的执行方式。
大多数代理框架都是逐个运行工具:模型生成工具调用,框架按顺序执行这些调用,然后将结果返回。这种方式安全但速度较慢。有些框架则并行运行工具。这种方式速度很快但存在风险:两个并行写入同一路径的文件可能会损坏该文件。
Claude Code 根据并发行为对每种工具进行分类:

克劳德代码代码并发
toolOrchestration.ts 中的编排层将工具调用划分成多个批次。只读工具(Glob、Grep、Read、WebFetch)并发运行,最多可并行运行 10 个。写入工具(带 mutation 的 Bash、Edit、Write)串行运行。不存在竞态条件。
Claude Code 并行搜索五个文件,然后编辑其中一个。它同时兼具并行处理的速度和串行执行的安全性。多工具操作速度提升 2-5 倍,每次操作可节省数分钟。
流媒体工具执行器
StreamingToolExecutor 是更有意思的组件。大多数工具框架都会等待模型生成完成后再执行任何工具,而 Claude Code 则会在模型生成过程中途开始执行。

流媒体工具执行器
对于包含三次工具调用的回合,这会隐藏 2-5 秒的延迟。模型在第一个工具运行的同时生成下一步的描述。等到模型完成时,之前工具的运行结果可能已经出来了。
疑难案件已处理完毕:
如果并行批处理中的某个工具发生故障,则每个工具对应的 siblingAbortController 会终止同级进程。父查询控制器保持运行。通信继续进行。模型接收到错误并进行恢复。
如果流式传输失败并回退到非流式传输,执行器将丢弃已排队的工具,并为任何正在进行的操作生成合成错误结果。
即使工具 2 比工具 1 先完成,结果仍按原始顺序产生,从而保持模型和用户叙述的连贯性。
工具结果预算
如果将一条输出 1MB 日志的 Bash 命令直接传递给模型,上下文窗口将被垃圾信息填满。Claude Code 运行着一个预算系统:
每个工具都指定了最大结果大小字符数。
超出限制的结果将保存到磁盘。
该模型接收文件路径引用以及前 N 个字符的预览。
applyToolResultBudget() 在每次 API 调用之前运行,以限制工具结果令牌的总数。
用户会对巨大的文件运行 cat 命令,还会通过管道发送产生数兆字节输出的命令。如果没有资源预算,上下文就会充斥着噪声,导致代理失去连贯性。架构图中并未体现这一细节,但它却决定了代理能否在实际使用中存活下来。
## 大规模提示工程:系统提示是一个缓存问题
Claude Code 中的系统提示符不是字符串,而是一个包含缓存元数据的结构化数组,数组由多个部分组成。

系统提示结构.md
SYSTEM_PROMPT_DYNAMIC_BOUNDARY 标记将提示符分为两个区域。其上方的所有内容:对所有用户、所有会话都相同,全局访问 API 级别的提示符缓存。这大约占提示符的 80%。您无需在每个用户的每次 API 调用中重新标记 577 行以上的内容。
在边界以下,数据段分为缓存型(每个会话计算一次)和易失型(每回合重新计算)。易失型数据段的数量会尽量减少,因为每次更改都会破坏其后所有内容的缓存。
我所见过的所有代理教程、框架文档和会议演讲中,都没有讨论过如何设计提示符以提高缓存效率。这在代码库中是影响性能的关键决策之一。规模化应用后,这决定了你的代理每次会话的成本是 0.02 美元还是 0.20 美元。
CLAUDE.md 层级结构
四级指令层次结构充当可组合存储器:

Claude.md hierarchy
更高级别的代码会覆盖更低级别的代码。企业管理员负责在全组织范围内强制执行编码标准。用户可以设置个人偏好。项目定义了约定。开发人员会将私有代码覆盖项排除在版本控制之外。
一个 @包括指令支持组合:
企业级架构与移动设备管理 (MDM) 集成,以实现策略执行。这是基础设施工程,而非硬件工程。
为什么上下文注入存在于系统提示之外
第一条用户消息注入
每回合上下文都会发生变化。如果将其放在系统提示符中,会在上下文发生变化后导致缓存失效。将其移至用户消息中,则可以确保系统提示符缓存每回合都保持稳定。这是一个小细节,但对成本影响巨大。
## 上下文窗口管理:四种压缩策略
大多数代理在达到上下文限制时会截断旧消息或崩溃。Claude Code 通过四种压缩策略支持无限长的对话,这些策略按成本从低到高排列。
策略一:微型紧凑型
每回合都会运行,在 API 调用之前。如果某个工具被调用,但其结果自上次调用以来没有改变,系统会将完整的结果替换为缓存的引用。对于像 Read 这样对同一文件重复调用的工具,这可以为每个会话节省数千个令牌。成本:几乎为零。
策略二:精简
当接近令牌上限时触发,在执行开销较大的摘要操作之前。移除对话开头的消息,同时保留最近消息的“受保护尾部”。无需模型调用。有损但速度快。
策略三:小型汽车
当令牌使用量超过阈值且仅提供摘要信息不足以解决问题时,系统会触发此操作。系统会调用一个单独的模型来总结之前的对话。旧消息将被摘要信息替换。系统会跟踪压缩状态以防止循环(即对摘要的摘要进行再次摘要)。
策略四:情境崩塌
此功能适用于长时间运行的会话,可通过功能标志启用。多阶段分阶段压缩:首先压缩工具结果,然后压缩思考模块,最后压缩整个章节。此选项开销较大,仅适用于运行数小时的会话。
为什么层级结构很重要
成本最低的策略优先执行。只有在其他策略都无效的情况下,才会执行成本最高的策略。
大多数实现了压缩的框架都会直接跳到摘要。摘要操作会在压缩调用和摘要本身生成时都消耗令牌。Microcompact 和 snip 可以处理很大一部分无需模型调用的情况。这种层级结构意味着只有在低成本的压缩失败时,才需要为昂贵的压缩付费。
“受保护的尾部”概念也至关重要。压缩运行时,最近的消息不会被汇总丢失。即使早期上下文被压缩,模型也能完整保留最近 N 次交换的信息。模型可以继续执行当前计划,而不会丢失刚刚执行的操作。
## 许可系统:信任的七个阶段
大多数代理程序都提供一个二元开关:允许或拒绝。Claude Code 运行的是一个七阶段流水线。

Permission system tool call requested.
规则对工具名称和输入使用类似 glob 的模式匹配:

glob-like pattern
“允许所有 bash 命令”过于粗略。没人希望代理运行 `rm -rf /` 命令。“拒绝所有 bash 命令”则会让代理形同虚设。“允许 git 命令和 npm test,其他所有命令提示”才是最佳方案。Claude Code 的规则引擎恰好支持这种方案。
权限模式逐步建立信任:

新用户初始采用默认设置,需要批准每个操作。随着信心的增强,他们可以升级到“接受编辑”或“绕过权限”。安全性和速度之间没有非此即彼的选择,而是一个连续的过程。
钩子就像逃生通道:
您的脚本接收工具调用详情并返回 {"decision": "approve"} 或 {"decision": "block"}。组织可以构建自定义防护机制:阻止破坏性操作、在操作完成后发布到 Slack、在每次文件写入后运行代码检查器。无需修改源代码。
## 错误恢复:823 线重试系统
services/api/withRetry.ts 文件共有 823 行。每一行代码的出现都是由于生产环境故障所致。
429(速率限制): 检查 Retry-After 标头。如果在 20 秒以内,则重试并保持快速模式。如果超过 20 秒,则进入 30 分钟的冷却期。如果存在 overage-disabled 标头,则永久禁用快速模式,并说明原因。
529(服务器过载): 跟踪连续 529 的次数。如果连续出现三次且有备用模型可用,则切换模型。后台任务?中止以防止级联。前台任务?使用退避策略重试。
400(上下文溢出): 解析错误以提取实际令牌数和限制令牌数。重新计算:可用令牌数 = 限制令牌数 - 输入令牌数 - 1000 安全缓冲区。强制输出令牌数至少为 3000。使用调整后的预算重试。
401/403(身份验证): 清除 API 密钥缓存。强制刷新 OAuth 令牌。使用新凭据重试。
网络错误(ECONNRESET、EPIPE、超时): 禁用保持连接套接字池。使用新连接重试。
退避公式:
延迟 = min(500ms × 2^attempt, 32s) + random(0, 0.25 × baseDelay)
对于无人值守会话(CI/CD 流水线、后台代理),持久重试模式会无限期地重试 429 和 529 错误。最大回退时间为 5 分钟。重置上限为 6 小时。30 秒的心跳信号可防止因空闲而被终止。
流媒体层自行负责可靠性:
如果 90 秒内没有数据块到达,空闲超时监控程序会中止流,并在 45 秒时发出警告。停滞检测程序会在计算首字节到达时间后,记录连续数据块之间超过 30 秒的间隔。如果流传输完全失败,流回退机制会切换到非流式请求,并保留连续 529 的计数,以避免回退逻辑重复计数。
对 fetch 操作进行三次重试的封装并不能保证生产环境的可靠性。而能够理解每种错误类型的语义并为每种错误类型提供特定恢复路径的状态机才是。
## 子代理架构:并行与隔离
Claude Code 会生成子代理:代理循环的独立实例,每个实例都有自己的上下文、工具和工作目录。

parallelism with isolation
每个子代理都拥有独立的上下文:

each subagents gets isolated context
中止父进程的操作会波及所有子进程。但子进程无法修改父进程的状态:appState 是一个空操作设置器。文件状态缓存会被克隆,以防止一个代理的读取操作污染另一个代理的缓存。
Git 工作树隔离
修改代码的子代理拥有自己的工作树:
一个代理,一个工作树。并行代理共享同一个工作空间会导致冲突。工作树隔离机制将每个代理置于其自身的独立分支上;变更经验证后合并。node_modules 符号链接可以防止磁盘空间膨胀:五个并行代理不需要五个依赖项副本。
三个生成后端
该多代理系统支持三种执行后端:进程内(直接使用 Node.js,速度最快,共享内存)、Tmux 面板(终端复用器隔离,每个代理在其自己的标签页中可见)、远程(CCR 环境,整机隔离)。
任务协调使用磁盘支持的任务列表,并在 ~/.claude/tasks/ 目录下使用基于文件的锁定机制。<taskListId> /<taskId> .json 文件。锁争用采用指数退避算法处理(30 次重试,每次 5-100 毫秒)。高水位线可防止重置后任务 ID 被重复使用。
## 第四层:基础设施
以上内容描述的是线束。第三层。现在来看看克劳德·科德围绕它构建了什么。
多租户
CLAUDE.md 层级结构是一个多租户系统。位于 /etc/claude-code/CLAUDE.md 的企业策略适用于组织中的所有开发人员。位于 .claude/CLAUDE.md 的项目策略适用于贡献者。位于 ~/.claude/CLAUDE.md 的用户首选项是个人设置。位于 CLAUDE.local.md 的本地覆盖设置是私有的。
这是基于角色的访问控制 (RBAC),用于控制代理行为。企业管理员设置规则,项目维护者设定规范,开发人员设定偏好。每一层级的设置都会覆盖其下一层级。冲突会确定性地解决。
跨会话的状态持久性
压缩策略旨在实现状态持久化。自动压缩会生成一个摘要,作为下一次循环迭代的起始上下文。CLAUDE.md 文件会在会话之间保存项目级内存。钩子会将任意状态持久化到磁盘。任务协调系统会在多个代理进程之间维护状态。
Claude Code 从三个层面解决了会话管理问题:会话内部(压缩)、跨会话(CLAUDE.md)、跨代理(任务列表)。
资源隔离
Git 工作树隔离机制为每个子代理提供独立的文件系统。siblingAbortController 会捕获工具故障,防止故障级联到其他同级代理。企业级拒绝规则可以防止代理访问不应访问的资源。
分布式协调
基于文件的任务列表锁定是一种分布式协调机制。父子代理之间的提示缓存共享是一种分布式资源优化机制。持久重试模式下的心跳机制是一种保持连接模式。工作树管理负责处理代理对共享存储库的并发访问。
这些是基础设施问题,需要用基础设施解决方案来解决:锁定、协调、隔离、状态管理、访问控制、资源共享。
为什么这对你的构建很重要
你会遇到所有这些问题。关键在于你是用临时拼凑的方法解决,还是从一开始就针对这些问题进行设计。
三层模型并不能让你做好准备。它将框架视为上限。但框架描述的是一个模型实例如何在一次会话中与一套工具进行交互。一旦你需要多个用户、多个会话、多个代理,或者部署到你无法控制的环境中,你就进入了第四层。
分布式系统工程正逐渐成为代理构建者的核心能力。生产环境中的代理系统运行在持续集成(CI)服务器上,会生成子进程,跨会话共享状态,并为具有不同权限的用户提供服务。理解这些的团队能够构建出真正有效的代理,而那些止步于搭建演示环境的团队则不然。
## 可扩展性:四种机制,零源代码修改
Claude Code 有四种扩展机制。这些机制都不需要修改源代码。
技能(Markdown 文件作为命令)
查看已暂存的更改并创建提交消息……
带有 YAML 前置元数据的 Markdown 文件。五个来源:捆绑包、项目、用户、插件、MCP。基于路径的发现意味着,仅当代理程序访问匹配的文件时,才会激活指定路径 ["*.tsx"] 的技能。代理程序会查看相关的技能,而非所有技能。
钩子(事件驱动自动化)
六种类型:shell 命令、LLM 评估、代理验证、HTTP 端点、TypeScript 回调、内存函数。触发条件:PreToolUse、PostToolUse、SessionStart、FileChanged、Stop。
钩子将框架连接到现有基础设施。任务完成后发布到 Slack。在每次执行 bash 命令前运行安全扫描程序。每次文件编辑后触发 CI。代理循环无需更改。
MCP(模型上下文协议)
五种传输类型:stdio、SSE、HTTP 流、WebSocket 和进程内传输。配置分为三个级别:企业管理、项目和用户。MCP 通过标准化协议使代理能够访问外部系统(数据库、API 和内部工具)。
插件
包含技能、代理、钩子和配置的目录。顶级组合机制:无需修改现有文件即可添加功能。
这四种机制都遵循相同的原则:组合优于修改。扩展是通过添加而非改变来实现的。核心更新不会破坏扩展。扩展之间互不干扰。
## 用户界面是一种信任机制
Claude Code 的终端 UI 运行在 Ink(终端版 React)的定制分支上:渲染引擎仅 251KB。对于一个命令行界面来说,这听起来似乎很庞大,但实际上并非如此。
实时流式文本逐字符渲染。动画加载指示器会根据卡顿持续时间在正常和错误红色之间切换。差异渲染显示语法高亮、三行上下文信息以及单词级别的更改标记。多代理状态树显示活动代理的层级结构。六种主题包含对色盲用户友好的选项。状态栏显示模型名称、美元价格、上下文窗口使用率和速率限制使用情况。
用户如果能够看到代理正在做什么、调用了哪些工具、结果如何、消耗了多少上下文信息以及成本是多少,就能赋予代理更大的自主权。更大的自主权意味着完成更多有用的工作。用户界面能够倍增效率。
上下文窗口的使用情况栏让用户能够直观地了解剩余容量,而无需了解分词技术。当容量用完时,用户就知道该结束操作或让代理进行压缩了。
## 你从中获得了什么
你不需要重写克劳德的代码,你需要的是它背后的工程决策。
代理循环的异步生成器。 流式传输、取消、可组合性、反压:这些都是抽象固有的特性。返回完整结果的 while 循环则保留了这四项特性。
工具的并发分类。 只读工具并行运行。状态修改工具串行运行。速度提升 2-5 倍,无竞态条件。在定义时标记每个工具,并让编排层处理批处理。
流式传输期间执行工具。 增量解析工具调用。输入 JSON 完成后立即开始执行。每次多工具旋转都能节省延迟。
系统提示专为缓存边界设计。 静态内容优先,动态内容最后。边界已明确标记。在生产环境中实现最高杠杆成本优化。
这是一个压缩层级结构,而非单一策略。 先执行低成本的压缩(微压缩、snip),最后执行高成本的压缩(摘要、折叠)。只有当低成本压缩失败时,才需要执行高成本的压缩。
错误恢复是循环中的一级状态。 每种错误类型(速率限制、上下文溢出、身份验证失败、网络错误)在状态机内部都有其自身的恢复策略,而不是外部的 try-catch 语句。
从一开始就考虑第四层。 状态在会话之间存储在哪里?权限如何扩展到团队?添加并行处理后,协调机制如何运作?基础设施的改造难度比设计之初高出一个数量级。
无需修改代码的扩展点。Markdown 文件、shell 脚本和基于协议的工具可以满足 95% 的扩展需求。如果用户 fork 你的代码来定制行为,那么你的架构就存在缺陷。
## 模型是商品,环境决定结果。
普林斯顿大学自然语言处理中心 (Princeton NLP) 通过 SWE-agent 证明了这一点:同样的模型,更好的环境,性能提升了 64%。Anthropic 公司每天都在用 Claude Code 验证这一点:这是一个包含 55 个目录、331 个模块的 TypeScript 应用程序,它将用于聊天界面的同一 Claude 模型转换为一个编码代理,该代理可以无人值守运行数小时,能够从 API 中断中恢复,在数千次会话中管理自身的上下文,并在同一代码库上协调多个并行子代理。
四层架构。大多数业界人士都在优化第一层:更大的模型,更高的基准测试分数。而最终获胜的团队则将资源投入到第三层和第四层:更好的环境、更好的错误恢复、更好的权限系统、更好的上下文管理以及更好的协调。
源代码就在那里。模式都有文档记录。决策清晰易懂。
先搭建框架,再围绕框架搭建基础设施。
## 相关链接
- [Rohit](https://x.com/rohit4verse)
- [@rohit4verse](https://x.com/rohit4verse)
- [256K](https://x.com/rohit4verse/status/2041548810804211936/analytics)
- [@包括](https://x.com/@include)
- [升级至高级版](https://x.com/i/premium_sign_up)
- [12:09 AM · Apr 8, 2026](https://x.com/rohit4verse/status/2041548810804211936)
- [256.6K Views](https://x.com/rohit4verse/status/2041548810804211936/analytics)
- [View quotes](https://x.com/rohit4verse/status/2041548810804211936/quotes)
---
*导出时间: 2026/4/8 22:02:15*