核心智能体循环是一个简单的 while 循环。大部分代码都存在于围绕它的各类系统中。
| 设计问题 | Claude Code 的答案 | 替代方案 |
|---|---|---|
| 推理放在哪里? | 模型推理;harness 强制执行。约 1.6% AI 决策逻辑,98.4% 基础设施。 | LangGraph:显式状态图。Devin:多步规划器。 |
| 有多少个执行引擎? | 一个 queryLoop 供所有入口(CLI、SDK、IDE)共用。 |
按入口分别实现专用引擎。 |
| 默认安全姿态是什么? | 拒绝优先:拒绝 > 询问 > 允许。最严格的规则优先。 | 容器隔离(SWE-Agent)、git 回滚(Aider)。 |
| 最根本的资源约束是什么? | 约 200K token 上下文窗口。每次模型调用前运行 5 种压缩策略。 | 计算预算、显式草稿本。 |
- 用户 —— 提交提示、批准权限、审查输出
- 入口 —— 交互式 CLI、headless CLI(
claude -p)、Agent SDK、IDE/桌面/浏览器 - 智能体循环 ——
query.ts中的queryLoop异步生成器:模型调用 → 工具分派 → 结果收集 → 重复 - 权限系统 —— 拒绝优先规则 + auto 模式 ML 分类器 + 钩子拦截
- 工具 —— 最多 54 个内置工具 + MCP 提供的工具,通过
assembleToolPool组装 - 状态与持久化 —— 仅追加的 JSONL 转录稿、提示历史、子智能体侧链
- 执行环境 —— Shell(带沙箱)、文件系统、Web 获取、MCP 连接
所有入口最终都汇聚到同一个 queryLoop——交互式 CLI、headless 模式、SDK 和 IDE 共用同一套代码路径。QueryEngine 是一层会话包装,而不是引擎本身。
| 层 | 职责 | 关键组件 |
|---|---|---|
| 表层(Surface) | 入口与渲染 | CLI、headless、SDK、IDE(React + Ink 终端 UI) |
| 核心 | 上下文组装与智能体循环 | queryLoop、5 阶段压缩管道、子智能体生成 |
| 安全/行动 | 权限与工具 | 7 个权限模式、auto 模式分类器、27 个钩子事件、工具池、shell 沙箱 |
| 状态 | 运行时状态与持久化 | JSONL 转录稿、CLAUDE.md 层级、自动记忆、侧链文件 |
| 后端 | 执行环境 | Shell 执行、MCP 连接(7 种传输类型)、42 个工具子目录 |
请求必须通过所有适用层——其中任一层都可以将其拦下:
- 工具预过滤 —— 把被全局拒绝的工具从模型可见的工具清单中彻底剔除
- 拒绝优先规则评估 —— 拒绝始终覆盖允许,即使允许更具体
- 权限模式约束 —— 当前活跃模式决定基线处理
- Auto 模式 ML 分类器 —— 独立评估安全性的单独 LLM 调用
- Shell 沙箱 —— 对 shell 命令实施文件系统 + 网络隔离
- 恢复会话时权限永不自动恢复 —— 权限绝不跨会话边界保留
- 基于钩子的拦截 —— PreToolUse 钩子可以修改或阻止操作
每个轮次遵循9 步管道:
- 设置解析 → 2. 状态初始化 → 3. 上下文组装 → 4. 五个预模型整形阶段 → 5. 模型调用 → 6. 工具分派 → 7. 权限门控 → 8. 工具执行 → 9. 停止条件检查
在每次模型调用前按顺序执行,按开销从低到高:
| 阶段 | 策略 | 触发条件 |
|---|---|---|
| 预算削减 | 每条消息大小上限 | 始终启用 |
| 裁剪 | 裁剪较旧的历史 | 受特性开关控制(HISTORY_SNIP) |
| 微压缩 | 缓存感知的细粒度压缩 | 始终启用(基于时间),可选缓存感知路径 |
| 上下文折叠 | 读取时虚拟投影(非破坏性) | 受特性开关控制(CONTEXT_COLLAPSE) |
| 自动压缩 | 完整模型生成的摘要(最后手段) | 当其他阶段都失败时 |
- 最大输出 token 升级(每轮最多重试 3 次)
- 反应式压缩(每轮最多触发一次)
- 提示过长:用上下文折叠处理溢出 → 反应式压缩 → 终止
- 流式后备和后备模型切换
| 模式 | 行为 | 信任级别 |
|---|---|---|
plan |
用户在执行前批准所有计划 | 最低 |
default |
标准交互批准 | 低 |
acceptEdits |
文件编辑 + 文件系统 shell 自动批准 | 中 |
auto |
ML 分类器评估工具安全性 | 高 |
dontAsk |
无提示,仍强制执行拒绝规则 | 较高 |
bypassPermissions |
跳过大多数提示,仍保留安全相关的关键检查 | 最高 |
bubble |
内部:子智能体向父级上报 | 特殊 |
4 阶段流程:预过滤(从模型视野中剥离被拒绝的工具)→ PreToolUse 钩子(可以返回 permissionDecision)→ 规则评估(拒绝优先)→ 权限处理程序(4 个分支:协调器、swarm worker、推测式分类器、交互式)
yoloClassifier.ts:加载基础系统提示 + 权限模板(内部/外部各一套)。两阶段评估:快速过滤 + 思维链。预计算的分类结果与超时时限竞争。
| 机制 | 上下文成本 | 关键能力 |
|---|---|---|
| Hooks | 零 | 27 个事件,4 种执行类型(shell、LLM、webhook、subagent 验证器) |
| Skills | 低 | 具有 15+ YAML frontmatter 字段的 SKILL.md,通过 SkillTool 元工具注入 |
| Plugins | 中 | 10 种组件类型(命令、智能体、skills、hooks、MCP、LSP、样式...) |
| MCP 服务器 | 高 | 通过 7 种传输类型的外部工具(stdio、SSE、HTTP、WebSocket、SDK、IDE) |
基础枚举(最多 54 个工具)→ 模式过滤 → 拒绝规则预过滤 → MCP 集成 → 去重
- assemble() —— 模型看到的内容:CLAUDE.md、skill 描述、MCP 资源、钩子注入的上下文
- model() —— 模型能触及的内容:内置工具、MCP 工具、SkillTool、AgentTool
- execute() —— 操作是否/如何运行:权限规则、PreToolUse/PostToolUse 钩子、Stop 钩子
系统提示 → 环境信息 → CLAUDE.md 层级 → 按路径限定的规则 → 自动记忆 → 工具元数据 → 对话历史 → 工具结果 → 压缩摘要
| 级别 | 路径 | 范围 |
|---|---|---|
| 托管 | /etc/claude-code/CLAUDE.md |
系统范围(企业) |
| 用户 | ~/.claude/CLAUDE.md |
用户级 |
| 项目 | CLAUDE.md、.claude/CLAUDE.md、.claude/rules/*.md |
项目级 |
| 本地 | CLAUDE.local.md |
个人(被 gitignore 忽略) |
关键设计选择: CLAUDE.md 作为用户上下文传递(模型对其遵从是概率性的),而非系统提示(遵从是确定性的)。真正提供确定性强制的,是权限规则这一层。
- 不使用嵌入向量,也没有向量数据库——由 LLM 扫描记忆文件的文件头
- 按需挑出最多 5 个相关文件
- 用户可以直接查看、编辑,并纳入版本控制
内置:Explore、Plan、General-purpose、Claude Code Guide、Verification、Statusline-setup。
自定义:.claude/agents/*.md,YAML frontmatter 支持 tools、model、permissions、hooks、skills 等。
- SkillTool:将指令注入当前上下文(便宜,相同窗口)
- AgentTool:生成新的隔离上下文窗口(昂贵,约 7 倍 token,但上下文安全)
| 模式 | 机制 | 默认 |
|---|---|---|
| Worktree | Git worktree(文件系统隔离) | 否 |
| Remote | 远程执行(内部专用) | 否 |
| In-process | 共享文件系统,隔离对话 | 是 |
每个子智能体写入自己的 .jsonl 文件,只把摘要回传给父级,完整历史永远不会进入父级上下文。多实例之间通过 POSIX flock() 协调——零外部依赖。
| 通道 | 格式 | 目的 |
|---|---|---|
| 会话转录稿 | 仅追加的 JSONL | 完整对话,压缩边界采用链式修补 |
| 全局提示历史 | history.jsonl |
跨会话提示召回(反向读取用于上箭头) |
| 子智能体侧链 | 每个子智能体独立的 JSONL | 隔离的子智能体历史 |
信任总是在当前会话中重新建立。为了守住这一安全不变量,系统宁可让用户多经历一次授权。
仅追加的 JSONL 设计,体现了一次偏向可审计性与简单性、而非查询能力的取舍。每条事件既可被人工阅读,也能纳入版本控制,无需专用工具即可重建。






