Claude Code 多层架构划分方法详解(解析各层解决的工程问题)

Claude Code 内部按”页面层、核心层、安全/行动层、状态层、后端层”五层拆分,每层只关心自己的职责,向上提供接口、向下委托工作。这种分层并不是教科书式的过设计,而是 50 万行 TypeScript 代码维持可维护性的现实选择。下文把每一层的职责、关键文件、解决的工程问题拆开讲。

一、五层架构的职责对照

层级 核心模块 解决的关键工程问题
页面层 src/screens/、src/components/、src/entrypoints/ 多种入口(交互 CLI、无头 CLI、IDE、SDK、桌面)复用同一内核
核心层 queryLoop() 异步生成器 + 五步压缩流水线 模型调用、工具分发、上下文压力的迭代节拍
安全/行动层 权限系统、Hook 流水线、工具池、沙箱、子代理 任何工具调用都先过安全闸,避免”模型即执行”
状态层 上下文装配、运行时状态、JSONL 持久化、CLAUDE.md 让会话可恢复、可回放、可分叉
后端层 Shell 沙箱、远程执行、MCP 多传输 把”工具能跑到哪”和”工具是什么”解耦

二、页面层:入口多、渲染统一

页面层负责”用户怎么接触 Claude Code”。交互式 CLI、无头 CLI(claude -p)、Agent SDK、IDE 扩展、桌面应用、浏览器入口都从这里出。UI 主体用 React + Ink 写——把 React 的组件化搬到终端,配合 Chalk 做颜色,得以让权限弹窗、进度条、流式输出统一响应式更新。

解决的实际问题是”多入口统一内核”。如果每种入口都自带一套交互逻辑,几万行重复代码跑不掉;抽到页面层之后,所有入口最终都进入同一个 query() 路径,差异化只剩”渲染什么”和”如何把用户输入喂进去”。

三、核心层:节拍器与压缩流水线

核心层只做两件事:驱动模型调用,以及在每次调用前压一次上下文。

驱动调用的实现是 queryLoop() 异步生成器。它消费状态层装配好的上下文,把模型输出提交给安全/行动层,工具结果以 tool_result 形式回到循环里。交互式 CLI 和无头 CLI 共享同一条 query() 路径,这才能保证”交互里能跑的事,脚本里也能跑”。

压缩流水线在每次模型调用前跑,按五步顺序缩减:预算缩减 → 截段(Snip)→ 微压缩(Microcompact)→ 上下文塌缩(Context Collapse)→ 自动压缩(Auto-Compact)。它的存在不是因为模型有”洁癖”,而是因为上下文窗口是硬约束、且压缩本身不可关闭——把压缩做成流水线,比让模型临时挤窗口更稳。

四、安全/行动层:默认拒绝的多层防御

安全/行动层是 Claude Code 区别于普通聊天客户端的关键。模型发出的每一次工具调用,先经过权限规则评估,再经过 Hook 流水线,再经工具自身的输入校验,最后才进入沙箱执行。任何一个环节拒绝,循环就拿到拒绝原因回灌给模型,让它重选动作。

// 权限规则求值的简化示意(概念代码)
function evaluate(toolCall, rules) {
  for (const rule of rules) {
    if (matches(rule, toolCall)) {
      if (rule.action === "deny") return { decision: "deny", rule };
      if (rule.action === "ask")  return { decision: "ask",  rule };
      if (rule.action === "allow") return { decision: "allow", rule };
    }
  }
  return { decision: "ask" }; // 未识别动作升级给人
}

解决的实际问题有三个:

  • “模型即执行”风险。工具调用从根上就不直接落到环境,必须经一道闸;
  • 沙箱边界。Shell 命令可以强制走沙箱后端,避免在主环境里裸跑;
  • 子代理隔离。Agent 工具派生的子代理在独立窗口里跑,防止主会话被一次性噪声打满。

五、状态层:可回放、可分叉、可恢复

状态层把”这次会话到底发生过什么”完整记录。sessionStorage.ts 维护追加式 JSONL 转录,history.ts 维护全局提示历史,子代理另开 sidechain 文件互不污染。CLAUDE.md 与长期记忆按文件加载,跨会话延续但不进实时窗口。

这套机制让”昨天那次调试到底读没读过 auth.ts“变成可查的事实,也让 /rewind 回到任意消息、/resume 续上挂掉的会话成为可能。配合”可恢复 + 可分叉”,Claude Code 才有底气把无人值守的 8 小时长任务列为可支持的形态。

六、后端层:把”工具能跑哪”解耦

后端层统一管理 Shell、文件系统、Web 抓取、MCP 多传输(stdio / SSE / HTTP)以及远程执行环境。工具定义写在 tools/ 目录里通过 assembleToolPool() 组装,而”这些工具跑在本地机器、容器、还是远端服务器”由后端层决定。

这样做的工程价值是”工具描述和执行环境解耦”——同一份工具实现,可以跑在开发机、CI 容器、企业远程沙箱里,只需切换后端配置,不用改工具代码。

七、各层之间的协作节拍

以”修一个 bug”为例,看看一次循环里五层怎么联动:

  1. 页面层把用户输入喂进 query();
  2. 核心层组装上下文(含 CLAUDE.md、历史、状态层产物),跑一次压缩;
  3. 模型给出动作(如”读取 payment.ts“),动作送到安全/行动层;
  4. 安全/行动层先按规则评估(读取通常在默认允许里),工具读取文件,把结果以 tool_result 回到核心层;
  5. 状态层把这一轮写入 JSONL;
  6. 回到第 2 步,循环直到模型给出最终回复或被用户中断。

八、五层分解的工程价值

  • 复用:交互 CLI、SDK、IDE 共享同一内核,少写一遍循环;
  • 可测试:每层都可以独立 mock,权限评估、压缩策略、状态持久化都能离线验证;
  • 可演进:在某层加新能力(如换沙箱实现、新增 Hook)不会波及其它层;
  • 可治理:审计/合规要看的是状态层 JSONL;性能调优要看核心层压缩与状态层装配;安全审计则盯紧安全/行动层。

常见问题(FAQ)

Q1:五层划分和”七个高层组件”是什么关系?

组件是按”功能角色”切(用户、接口、循环、权限、工具、状态、执行环境),五层是按”工程位置”切,两者交叉映射。

Q2:QueryEngine 是核心引擎吗?

严格说不是,它是无头 / SDK 路径的会话包装类,共享代码路径是 query() 与内部 queryLoop()。

Q3:新增一个工具要改几层?

一般只需在 tools/ 加实现、在 tools.ts 注册;权限规则、Hook、沙箱边界在配置层声明,工具本体与具体层解耦。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
命令行手艺人的头像命令行手艺人普通用户

相关推荐

返回顶部