
Anthropic 最近做了一次精彩的公开教学,展示了如何构建当下最优秀的 AI Agent 执行框架。
Claude Code 的源码其实已经毫无保留地展示在公众眼前:55 个目录,331 个模块。这是目前经过实战检验、最为成熟的 Agent 架构之一。我逐一分析了每个文件,拆解了每一个架构决策、每一条重试路径、每一种压缩策略、每一个权限阶段。
这远不止一次简单的代码分析,而是一份关于生产级 Agent 架构的完整蓝图。
下面你将看到其内部的每一条设计原则,以及如何应用这些原则来构建你自己的、能在生产环境中稳定运行的 Agent 执行框架。
从 Claude Code 架构看行业普遍忽略的第四层
你一定听过经典的 AI 三层模型:模型权重、上下文、执行框架。整个行业,从技术大会到框架教程,都在重复这个分层:
- 模型权重:冻结的智能体,即通过 API 调用的部分。
- 上下文:提示词、对话历史、检索到的文档。
- 执行框架:模型周围的脚手架,负责工具调用、循环逻辑、错误处理。
这个分层本身没错。普林斯顿 NLP 团队的 SWE-agent 论文证实了这一点:在 SWE-bench 基准测试上,仅仅优化交互界面设计,就带来了 64% 的相对性能提升。同样的 GPT-4,同样的任务,只改变了运行环境。这巨大的提升来自第 2 层和第 3 层,而不是第 1 层。
但当你打开 Claude Code 的源代码,会意识到 Anthropic 的工程重点并非仅是模型,而是整个系统。
在 Claude Code 内部,有四层级的 CLAUDE.md 配置体系,允许企业管理员通过 MDM(移动设备管理)强制执行编码规范,项目维护者设定团队约定,开发者可在本地进行覆盖。有基于磁盘的任务队列,使用文件锁来确保并行子 Agent 不会互相污染状态。有 Git 工作树隔离机制,让多个 Agent 能在同一个仓库上并行工作而互不冲突。有七级权限流水线,从企业级到会话级的规则层层递进。
所有这些,都不属于传统的执行框架、上下文或模型权重。
它们属于 基础设施层:多租户、权限控制、资源隔离、状态持久化、分布式协调。
因此,一个真正完备的 Agent 框架应有四层:
- 模型权重:冻结的智能体
- 上下文:运行时输入
- 执行框架:Agent 的设计运行环境
- 基础设施:多租户、RBAC、资源隔离、状态持久化、分布式协调
多数团队只热衷于讨论前三层,因为它们听起来更“性感”。而第四层,才是大多数产品真正折戟的地方。Claude Code 是我见过的首个认真对待所有四层的 Agent 系统,其架构在每一层面都体现了这一点。
核心 Agent 循环:异步生成器,而非 While 循环
Claude Code 的核心位于 query.ts,共 1729 行 TypeScript 代码。其中最重要的决策,仅从函数签名上就能窥见一斑:

这个函数的份量远超其表象。异步生成器 可以逐步产出值,可按需暂停,调用者能在任意时刻终止整个流程。
Agent 循环不是一个简单的请求-响应周期,而是一个长时间运行、流式、可取消的进程。生成器原生提供了所有这些特性,无需额外封装。
对比一下几乎所有教程都会教你的传统写法:

这种写法在教程里或许可行,但在生产环境中注定会崩溃,原因有五:
1. 没有流式输出:用户面对空白屏幕等待 10-30 秒,只能盯着加载图标转圈。而 Claude Code 的生成器会在 Token 到达时立即产出 StreamEvent 对象,用户可以逐字看到模型的工作进程。能看见 Agent 在做什么的用户会更信任它,信任会带来更高的自主权,而自主权正是产生价值的关键。
2. 没有取消机制:While 循环版本的 Ctrl+C 需要从外部引入一套单独的中断机制。对于生成器,调用者只需停止调用 .next() 即可。finally 代码块会自动执行,清理工作自然完成。Claude Code 在每一层都传递 AbortSignal,生成器让这一切变得异常自然。
3. 没有可组合性:REPL 界面可以消费这个生成器,子 Agent 可以消费它,测试用例也可以消费它。同一个 query() 函数,三种调用者,零重复代码。生成器是流式数据的通用接口。
4. 没有背压控制:如果模型生成速度快于终端渲染速度,While 循环会把所有内容缓冲在内存中。而生成器会在消费者停止拉取时自动暂停生产。在长会话中,这决定了你的内存是稳定可控,还是持续增长直至进程崩溃。
5. 循环内部没有错误恢复:这才是最严重的问题。
每一次循环迭代的五个阶段
Claude Code 的 Agent 循环每一次迭代都会经过五个精心设计的阶段。正是这些阶段,赋予了该执行框架真正的弹性。
阶段 1:前置准备
在调用模型之前,循环会先应用工具结果预算,如果对话过长则运行压缩策略,并验证 Token 计数。而大多数执行框架只是简单地把原始消息数组丢给模型,然后祈祷不出错。
阶段 2:模型调用
循环通过依赖注入的接口调用 queryModelWithStreaming(),外层包裹着一个能处理十种错误类型的重试系统。流式工具执行器会在这个阶段就开始执行工具,甚至在模型还未完成生成时。例如,一个 Grep 调用的输入 JSON 在流中一解析完成,就立刻开始运行,可能比下一个工具调用的开始还要早几秒钟。
阶段 3:错误恢复与压缩
模型响应后,循环检查可恢复的错误。提示词过长?压缩并重试。达到最大输出 Token?从 32K 模型升级到 64K 模型并重试。上下文溢出?对包含大量媒体的消息运行响应式压缩。这些在循环状态机中都是一等状态,而非外层 try-catch 处理的边缘情况。
阶段 4:工具执行
所有尚未被流式执行器运行的工具在此阶段执行。结果在完成时立刻流式输出到界面。像 Haiku 这样的轻量模型会异步生成工具使用摘要,避免主模型在记账工作上浪费 Token。
阶段 5:继续决策
模型的停止原因告诉循环是否需要更多工具调用。回合计数器检查最大回合限制。钩子可以请求停止。检查中断信号。如果需要继续,循环递增状态并回到阶段 1。
关键在于,错误恢复逻辑被设计在循环内部,而非外部包裹循环。每个阶段都清楚可能出什么问题,并有特定的恢复路径。这就是一个遇到速率限制就崩溃的 Agent,与一个会自动退避、重试、降级模型、然后继续工作的 Agent 之间的本质区别。
依赖注入让它变得可测试
循环通过 QueryDeps 接口接收其所有依赖:

注入一个能产出预设事件的模拟 callModel 函数,你就可以在不触碰真实 API 的情况下,验证上下文溢出处理、工具失败、取消逻辑等。大多数 Agent 执行框架根本无法有效测试,因为它们将 API 调用硬编码在循环内部。而 Claude Code 的循环是一个纯粹的状态机,所有副作用都是注入的。
工具执行:并发分类如何改变一切
Claude Code 自带 45+ 个内置工具。但数量并非重点,其执行方式才是革命性的。
大多数执行框架要么逐个串行运行工具(安全但慢),要么将所有工具并行运行(快但危险,如两个并行写入可能损坏同一文件)。
Claude Code 为每个工具定义了并发行为分类:

toolOrchestration.ts 中的编排层会将工具调用分成不同批次。只读工具(如 Glob、Grep、Read、WebFetch)最多可 10 个并行运行。会修改状态的写入工具(如某些 Bash 命令、Edit、Write)则串行执行。这消除了竞态条件。
这意味着 Claude Code 可以并行搜索五个文件,然后串行修改其中一个。同时获得了并行的速度和串行的安全性。在多工具回合中,这可带来 2-5 倍的速度提升,每个会话累计可节省数分钟。
流式工具执行器
流式工具执行器是更有意思的组件。大多数框架会等到模型完全生成后才开始执行任何工具。而 Claude Code 在流式响应的中途就开始执行。

对于一个包含三个工具调用的回合,这可以隐藏掉 2-5 秒的延迟。当模型还在生成下一步的描述时,第一个工具已经在运行了。等到模型完成生成,前面工具的结果可能已经准备就绪。
所有边界情况都得到了妥善处理:
- 如果并行批次中的某个工具失败,专用的
siblingAbortController 会终止所有兄弟进程。但父查询控制器保持存活,对话继续进行,模型会收到错误并尝试自行恢复。
- 如果流失败并回退到非流式模式,执行器会丢弃已排队的工具,并为所有进行中的任务生成合成错误结果。
- 即使工具 2 比工具 1 先完成,结果也会按照原始顺序产出,确保模型和用户看到的叙述连贯性。
工具结果预算
一个输出 1MB 日志的 Bash 命令,如果原样传给模型,会瞬间塞满上下文窗口。Claude Code 运行着一套预算系统:
- 每个工具都可以指定
maxResultSizeChars。
- 超过限制的结果会被持久化到磁盘。
- 模型收到的是文件路径引用加上前 N 个字符的预览。
- 每次 API 调用之前都会运行
applyToolResultBudget() 来约束工具结果的总 Token 数。
用户一定会 cat 巨大的日志文件,也一定会运行输出几兆字节的管道命令。没有预算机制,上下文会被噪音填满,Agent 就会失去连贯性。这个细节很少出现在架构图中,但它决定了你的 Agent 能否在真实用户手中存活下来。
大规模提示词工程:系统提示词是一个缓存优化问题
在 Claude Code 中,系统提示词不是一个单纯的字符串,而是一个带有缓存元数据的结构化节数组。

SYSTEM_PROMPT_DYNAMIC_BOUNDARY 标记将提示词分成了两个区域。此标记之上的所有内容(约占整个提示词的 80%),对所有用户和所有会话都完全相同,可以在 API 层面实现全局提示词缓存。你不需要为每个用户的每次 API 调用重新 Tokenize 这 577 行内容。
边界之下的部分,要么是会话级缓存(每个会话计算一次),要么是易变的(每个回合重新计算)。易变部分被最小化了,因为任何变化都会破坏它之后所有内容的缓存。
我从未在任何 Agent 教程、框架文档或技术大会演讲中,见过有人专门为缓存效率而设计提示词结构。这是整个代码库中杠杆效应最高的决策之一。在规模化场景下,这个设计直接决定了你的 Agent 每次会话成本是 0.02 美元还是 0.20 美元。
CLAUDE.md 层级体系
四层的指令层级体系构成了一个可组合的记忆系统:

更高层级的配置会覆盖更低层级。企业管理员可以在整个组织内强制执行编码标准,用户可以设置个人偏好,项目可以定义团队约定,开发者则可以把私人覆盖放在版本控制之外。
@include 指令提供了强大的组合能力:
@./docs/coding-standards.md
@~/shared-rules.md
企业层级配置甚至可与 MDM(移动设备管理)系统集成,以实现策略的强制推行。这本质上是基础设施工程,而非单纯的执行框架工程。
为什么上下文信息在系统提示词之外注入
用户上下文信息(如 Git 状态、CLAUDE.md 内容、当前日期)是作为 第一条用户消息 注入的,包裹在 <system-reminder> 标签中:
<system-reminder>
在回答用户问题时,你可以使用以下上下文:
# claudeMd
[CLAUDE.md 文件内容]
# currentDate
今天的日期是 2026-04-07。
</system-reminder>
上下文信息每个回合都可能变化。如果将其放在系统提示词里,任何变化都会导致该点之后的所有缓存失效。将其移到用户消息中,可以让系统提示词在每个回合之间保持缓存稳定。一个很小的设计细节,却对成本有着巨大的影响。
上下文窗口管理:四种渐进式压缩策略
大多数执行框架遇到上下文限制时,要么粗暴地截断旧消息,要么直接崩溃。Claude Code 则通过四种压缩策略支持近乎无限长的对话,这些策略按照成本从低到高排序执行。
策略 1:微压缩
每个回合运行,在 API 调用之前触发。如果某个工具被调用过,且其结果从上一次调用后没有变化,系统会把完整结果替换成缓存引用。对于像 Read 这样在同一文件上反复调用的工具,这每个会话可节省数千 Token。成本:几乎为零。
策略 2:截断压缩
在接近 Token 限制时触发,作为一种在昂贵的摘要操作之前的廉价手段。从对话开头移除消息,同时保留最近消息的“保护尾部”。无需调用模型,速度快,但有信息损失。
策略 3:自动压缩
当 Token 使用量超过阈值且截断压缩不足时触发。系统发起一个单独的模型调用,对之前的对话进行摘要。旧消息被替换成摘要。系统会跟踪压缩状态,以避免陷入“摘要的摘要的摘要”这种循环。
策略 4:上下文折叠
针对长时间运行的会话(通过功能标志启用)。这是一个多阶段的分阶段压缩过程:先折叠工具结果,然后是思考块,最后是整个章节。这是最昂贵的选项,只留给那些已经运行了几个小时的会话。
为什么这种层级设计至关重要
最便宜的策略优先运行,最昂贵的策略只有在其他所有方法都无效时才会触发。
许多实现了压缩的执行框架会直接跳到“摘要”这一步。摘要既要在压缩调用时消耗 Token,又要在摘要内容本身消耗 Token。而微压缩和截断可以在零模型调用的情况下,处理很大一部分场景。这种层级设计意味着,你只在便宜的压缩失败时,才为昂贵的压缩付费。
“保护尾部”的概念同样重要。当压缩运行时,最近的消息永远不会被摘要掉。即使更早的上下文被压缩了,模型对最后 N 次交互仍然保持完整的保真度。模型可以继续执行它当前的计划,而不会忘记它刚刚做了什么。
权限系统:七级信任管道
大多数执行框架只有一个简单的二元开关:允许或拒绝。Claude Code 则运行着一个七级的精细化流水线。

规则使用类 glob 的模式来匹配工具名称和输入:

简单地“允许所有 Bash 命令”太粗糙(没人希望 Agent 运行 rm -rf /),“拒绝所有 Bash 命令”又会让 Agent 变得毫无用处。“允许 Git 命令和 npm test,其他所有情况都提示用户确认”才是理想的平衡点。Claude Code 的规则引擎正支持这种精细控制。
权限模式创造了渐进式的信任梯度:

新用户从默认模式开始,需要批准每一个操作。随着信任建立,他们可以切换到 acceptEdits(自动接受文件编辑)甚至 bypassPermissions(绕过所有检查,供高级用户使用)。这不是在安全和速度之间做二选一,而是一个连续的信任谱系。
钩子(Hooks)作为逃生舱口存在,允许外部干预:
{
"hooks": {
"PreToolUse": [{
"matcher": { "tool": "bash", "action": ".*rm.*" },
"commands": [{ "cmd": "/path/to/safety-check.sh" }]
}]
}
}
你的脚本会收到工具调用的详细信息,然后返回 {"decision": "approve"} 或 {"decision": "block"}。组织可以借此构建自定义护栏:阻止破坏性操作、任务完成后发布到 Slack、每次文件写入后运行 linter。所有这些都无需修改 Claude Code 的源代码。
错误恢复:823 行精心打磨的重试系统
services/api/withRetry.ts 这个文件有 823 行代码。可以说,每一行的存在,都源于某一次生产环境故障的教训。
429(速率限制):检查 Retry-After 响应头。小于 20 秒?进行重试,保持快速模式。超过 20 秒?进入长达 30 分钟的冷却期。如果存在 overage-disabled 头?则永久禁用快速模式并向用户解释原因。
529(服务器过载):跟踪连续的 529 错误计数。连续三次且存在备用模型?切换到备用模型。对于后台任务?可能选择放弃,以防止级联失败。对于前台任务?则进行退避重试。
400(上下文溢出):解析错误信息,提取实际 Token 计数和限制值。重新计算:可用 Token = 限制值 - 输入 Token - 1000(安全缓冲区)。强制设定最低 3000 输出 Token 的底线。使用调整后的预算进行重试。
401/403(认证失败):清除 API 密钥缓存。强制刷新 OAuth 令牌。使用新凭证进行重试。
网络错误(ECONNRESET, EPIPE, 超时):禁用 keep-alive 连接池。使用新的连接进行重试。
退避算法公式为:
delay = min(500ms × 2^尝试次数, 32s) + 随机(0, 0.25 × baseDelay)
对于无人值守的会话(如 CI/CD 流水线、后台 Agent),持久重试模式会对 429 和 529 错误进行无限重试。设定最大 5 分钟退避,6 小时重置上限,并通过每 30 秒发送心跳来防止进程因空闲被杀死。
流式层还有自己独立的可靠性机制:空闲超时看门狗在 90 秒未收到数据块时中止流,并在 45 秒时发出警告;停顿检测会记录首字节之后连续数据块间隙超过 30 秒的情况;流式回退机制在流式完全失败时,会切换到非流式请求,同时注意避免对连续 529 错误进行重复计数。
简单地在 fetch 外层包裹三层重试,并不等于生产级可靠性。一个能理解每一种错误类别的语义,并为每一种都设计了特定恢复路径的状态机,才是。
子 Agent 架构:具备隔离能力的并行性
Claude Code 可以生成子 Agent:即 Agent 循环的独立实例,每个都有自己的上下文、工具集和工作目录。

每个子 Agent 都获得隔离的上下文:

中止父 Agent 会级联中止所有子 Agent。但子 Agent 不能修改父 Agent 的状态:appState 是一个空操作 setter。文件状态缓存会被克隆,防止一个 Agent 的读取操作污染另一个 Agent 的缓存。
Git 工作树隔离
需要对代码进行修改的子 Agent,会获得自己独立的 Git 工作树:
getOrCreateWorktree(repoRoot, slug)
→ 验证 slug(最大 64 字符,无路径遍历)
→ 检查工作树是否已存在(快速恢复)
→ git fetch(带无提示环境变量)
→ git worktree add(新分支: worktree-<slug>)
→ 符号链接大目录(node_modules, .cache)
→ 复制 CLAUDE.md、项目设置、.env 文件
→ 返回 { path, branch, headCommit }
一个 Agent,一个工作树。共享工作区的并行 Agent 会产生冲突。工作树隔离将每个 Agent 放在自己的分支上;变更只有在验证后才会被合并。对 node_modules 等目录使用符号链接,避免了磁盘空间膨胀:五个并行 Agent 不需要五份依赖的副本。
三种执行后端
多 Agent 系统支持三种执行后端:
- 进程内:直接 Node.js 调用,最快,共享内存。
- Tmux 窗格:利用终端多路复用器进行隔离,每个 Agent 在自己的标签页中可见。
- 远程:在 CCR 环境中运行,提供完整的机器隔离。
任务协调使用基于磁盘的任务列表,位于 ~/.claude/tasks/<taskListId>/<taskId>.json,并采用文件锁机制。锁争用通过指数退避处理(最多 30 次重试,间隔 5-100ms)。高水位标记机制防止系统重置后任务 ID 被重复使用。
第四层:不可或缺的基础设施
以上描述的所有精彩设计,都属于执行框架,即第三层。现在,让我们看看 Claude Code 在其周围构建了什么。
多租户
CLAUDE.md 层级体系本身就是一个多租户系统。/etc/claude-code/CLAUDE.md 中的企业策略适用于组织中的每一位开发者。.claude/CLAUDE.md 中的项目策略适用于所有贡献者。~/.claude/CLAUDE.md 中的用户偏好是个人化的。CLAUDE.local.md 中的本地覆盖是私有的。这本质上是 Agent 行为的 RBAC(基于角色的访问控制)。
跨会话状态持久化
压缩策略就是一种状态持久化。自动压缩产生的摘要会成为下一次循环迭代的起始上下文。CLAUDE.md 文件跨会话保留项目级记忆。钩子可以将任意状态持久化到磁盘。任务协调系统跨多个 Agent 进程维护状态。Claude Code 在三个层面解决了会话管理问题:会话内(压缩)、跨会话(CLAUDE.md)、跨 Agent(任务列表)。
资源隔离
Git 工作树隔离为每个子 Agent 提供独立的文件系统视图。siblingAbortController 将工具失败 containment 住,防止其级联到兄弟进程。企业级拒绝规则防止 Agent 访问其不该接触的资源。
分布式协调
任务列表上的文件锁就是一种分布式协调机制。父子 Agent 之间共享提示词缓存,是一种分布式资源优化。持久重试模式中的心跳是保活模式。工作树管理处理的是并发 Agent 访问共享仓库的问题。
所有这些都是典型的基础设施问题,需要基础设施级的解决方案:锁、协调、隔离、状态管理、访问控制、资源共享。
这对你的构建意味着什么
你迟早会遇到所有这些问题。关键在于,你是准备用临时性的“胶带”去修补,还是从一开始就为它们进行设计。
传统的三层模型没有为你应对这些挑战做好准备。它把执行框架描述成了天花板。但执行框架只描述了单个模型实例如何在单个会话中与一组工具交互。当你需要支持多个用户、多个会话、多个 Agent,或者将系统部署到你无法完全控制的环境中时,你就进入了第四层。
分布式系统工程正在成为 Agent 构建者的核心能力。生产级的 Agent 系统运行在 CI 服务器上,会生成子进程,需要在会话间共享状态,并为拥有不同权限的用户提供服务。理解这一点的团队构建出的是真正可用的 Agent,而停留在执行框架层面的团队,构建出的可能只是精美的演示品。
可扩展性:四种无需修改源码的机制
Claude Code 提供了四种扩展机制,没有一种需要修改其核心源代码。
1. 技能(Markdown 文件即命令)
---
name: commit
description: 用生成的消息提交暂存的变更
allowed-tools: [Bash, Read, Grep]
model: haiku
context: inline
user-invocable: true
---
审查暂存的变更并创建提交消息...
带有 YAML 前置元数据的 Markdown 文件。技能有五个来源:内置、项目、用户、插件、MCP。基于路径的发现机制意味着,一个指定了 paths: ["*.tsx"] 的技能,只会在 Agent 接触到匹配文件时被激活。Agent 只会看到相关的技能,而非所有技能。
2. 钩子(事件驱动自动化)
有六种类型:Shell 命令、LLM 评估、Agent 验证、HTTP 端点、TypeScript 回调、内存函数。可在 PreToolUse、PostToolUse、SessionStart、FileChanged、Stop 等事件时触发。钩子将执行框架连接到现有的基础设施,例如任务完成后发布到 Slack、每次 Bash 命令前运行安全扫描器、每次文件编辑后触发 CI,都无需修改 Agent 循环本身。
3. MCP(模型上下文协议)
支持五种传输类型:stdio、SSE、HTTP 流、WebSocket、进程内。可在三个层级配置:企业管理、项目、用户。MCP 通过标准化协议让 Agent 访问外部系统(如数据库、API、内部工具)。
4. 插件
包含技能、Agent、钩子和配置的目录。这是顶层的组合机制,通过“添加”而非“修改”来增加能力。
所有四种机制都遵循同一个核心原则:组合优于修改。通过添加来扩展,而不是改变核心。核心组件的更新不会破坏扩展,扩展之间也不会互相干扰。
界面是一种信任构建机制
Claude Code 的终端界面运行在 Ink(一个用于终端的 React 渲染库)的自定义分支上,渲染引擎约 251KB。对于一个 CLI 工具来说,这听起来可能有点重,实则不然。
它提供实时流式文本的逐字符渲染。动画加载指示器会根据停顿持续时间,从正常状态渐变为错误红色。差异渲染能够显示语法高亮、三行上下文、单词级别的变更标记。多 Agent 状态树清晰展示活跃 Agent 的层级结构。提供六种主题,包括色盲友好选项。状态行实时显示模型名称、估算成本、上下文窗口使用百分比、速率限制利用率等信息。
能够看到 Agent 在做什么、调用了哪个工具、结果如何、消耗了多少上下文、花费了多少钱的用户,会给予该 Agent 更多的自主权。而更多的自主权意味着能完成更多有价值的工作。因此,界面本身就是一个强大的信任构建与效率倍增器。
上下文窗口使用进度条让用户对剩余容量有直观感受,无需理解复杂的 Tokenization 概念。当进度条快满时,用户自然知道该结束当前任务,或让 Agent 执行压缩。
关键启示与行动指南
你无需照搬重建整个 Claude Code,但应吸收其背后的关键工程决策:
- 用异步生成器实现 Agent 循环。流式输出、优雅取消、高度可组合性、自动背压控制,都是这一抽象原生的特性。一个仅返回完整结果的 While 循环,会与所有这些优势失之交臂。
- 对工具进行并发分类。让只读工具并行运行,让会修改状态的工具串行运行。可获得 2-5 倍的速度提升,且完全避免竞态条件。在定义工具时就标记其并发特性,让编排层去处理分批逻辑。
- 在流式响应期间执行工具。增量式解析工具调用,输入 JSON 一解析完成就立刻开始执行。每个包含多个工具调用的回合,都能免费获得延迟节省。
- 为缓存边界设计系统提示词。将静态内容放在前面,动态内容放在后面,并用明确标记划定边界。这是生产环境中,成本优化杠杆效应最高的决策之一。
- 构建压缩策略层级,而非单一策略。让最便宜的策略(微压缩、截断)优先执行,最昂贵的策略(摘要、折叠)最后执行。只在便宜的压缩失败时,才为昂贵的压缩付费。
- 将错误恢复设计为循环内部的一等状态。让每种错误类型(速率限制、上下文溢出、认证失败、网络错误)在状态机内部都有自己特定的恢复策略,而不是简单地在外层包裹一个 try-catch。
- 从第一天就考虑第四层(基础设施)。状态在会话之间存储在哪里?权限如何扩展到团队规模?增加并行性时,协调如何工作?事后改造基础设施,比从一开始就进行设计要困难一个数量级。
- 提供无需修改源码的扩展点。Markdown 文件、Shell 脚本、基于标准化协议的工具,这三者应该能覆盖 95% 的扩展需求。如果用户必须 Fork 你的代码才能实现自定义行为,那说明你的架构存在缺陷。
模型已是商品,环境决定成败
普林斯顿 NLP 团队用 SWE-agent 证明了这一点:同样的模型,更好的运行环境,带来 64% 的性能提升。Anthropic 则通过 Claude Code 每天都在证明这一点:这个包含 55 个目录、331 个模块的 TypeScript 应用,将聊天界面中同一个 Claude 模型,转变成了一个可以无人值守运行数小时、能从 API 中断中自我恢复、能在长达千回合的会话中管理自身上下文、并且能在同一代码库上协调多个并行子 Agent 的编码助手。
这就是四层架构的力量。行业中大多数人仍在狂热地优化第一层:追求更大的模型,更高的基准测试分数。而真正能赢得未来的团队,正在大力投资第三层和第四层:构建更好的运行环境、更健壮的错误恢复机制、更精细的权限系统、更智能的上下文管理、更高效的协调策略。
Claude Code 的源码分析已经公开,其设计模式清晰可辨,所有工程决策都记录在代码之中。路径已经指明:先构建一个强大的执行框架,然后在它周围,系统地构建起坚实的基础设施。
对这个架构的深度探索和讨论,欢迎来云栈社区与更多开发者一起交流。