跳转至

Claude Code 深度解析:从使用到源码理解

核心主题:Claude Code 的架构设计、QueryEngine 核心循环、工具系统、权限模型、上下文管理与记忆系统

前置知识:AI Coding 基础概念、命令行操作、TypeScript/Python 基础

源码基础:2026年3月31日,Claude Code v2.1.88 的 51.2 万行 TypeScript 源码意外泄露,本教程基于该源码及 Claude Code 完全指南 V2 编写


目录


一、Claude Code 是什么

1.1 不是 CLI,是 Agent 平台

Claude Code 表面上是一个终端命令行工具,但它的系统形态远超普通 CLI:

维度 普通 CLI 工具 Claude Code
调度中心 无,或仅脚本顺序执行 LLM 持续规划、决策、纠错
I/O stdin/stdout 为主 终端 UI、Bridge、MCP、SDK 多通道
资源 单次命令作用域 工具、服务、会话状态 长期协作
安全 通常全有或全无 多层门控(权限、确认、沙箱策略)
扩展 子命令/插件零散 Plugins、Skills、MCP 形成生态位
主循环 解析参数 → 执行 → 退出 Agent 循环,可长期驻留

生活类比:普通 CLI 像自动售货机——你按按钮、掉货;Claude Code 像带门禁与工牌的办公楼——有前台(入口路由)、物业(服务层)、安保(权限)、装修队(工具执行),而"大楼的大脑"是 LLM。

1.2 四种入口

同一套核心能力,可通过四种方式进入:

Text Only
1. CLI 入口       → 终端直接使用(最常见)
2. MCP 服务入口   → 作为 MCP Server 被其他客户端调用
3. SDK 入口       → 通过编程接口嵌入应用
4. Bridge 入口    → 与 IDE(VS Code 等)协同

1.3 安装与快速上手

Bash
# 安装
npm install -g @anthropic-ai/claude-code

# 启动(在项目目录下)
claude

# 常用命令
claude "解释这个项目的架构"          # 单次提问
claude --resume                     # 恢复上次会话
claude --model claude-sonnet-4      # 指定模型
claude --allowedTools "Read,Write"  # 限制工具

二、架构总览:以 LLM 为内核的操作系统

2.1 分层架构

基于泄露源码的目录结构分析,Claude Code 可分为四层:

Text Only
┌─────────────────────────────────────────────────┐
│  L1 呈现层                                       │
│  React Ink 定制渲染器 / 组件树                     │
│  (src/ink/, src/components/)                      │
├─────────────────────────────────────────────────┤
│  L2 应用编排                                      │
│  commands / coordinator / assistant               │
│  (src/commands/, src/coordinator/)                │
├─────────────────────────────────────────────────┤
│  L3 模型内核                                      │
│  API 调用 / 流式解析 / tool_use                    │
│  (src/query/, src/QueryEngine.ts)                 │
├─────────────────────────────────────────────────┤
│  L4 能力与 IO                                     │
│  tools / services / bridge / remote / vim         │
│  (src/tools/, src/services/, src/bridge/)         │
└─────────────────────────────────────────────────┘

类比:L1 是屏幕和键盘;L2 是窗口管理与任务栏;L3 是 CPU 执行指令(这里换成 LLM 生成"下一步");L4 是磁盘、网卡、USB(工具与外部世界)。注意 L4 → L2 的回路:工具结果会回到编排层,进入下一轮推理——这是 Agent 循环,不是单次管道。

2.2 源码关键目录

目录 职责 关键文件
src/query/ QueryEngine 核心 QueryEngine.ts, query.ts
src/tools/ 工具定义与执行 Tool.ts, tools.ts
src/coordinator/ 多 Agent 协调 coordinator 相关
src/context/ 上下文管理 context.ts, 压缩相关
src/assistant/ 助手逻辑 assistant 相关
src/skills/ Skills 系统 技能加载与管理
src/bridge/ IDE 通信 Bridge 协议
src/memdir/ 记忆目录 CLAUDE.md 管理
src/services/ 基础服务 MCP、LSP、OAuth 等
src/state/ 状态管理 应用状态持久化
src/vim/ Vim 模式 Vim 键绑定
src/voice/ 语音 语音输入
src/buddy/ Buddy 系统 宠物/伙伴功能

三、QueryEngine:八步循环的心脏

3.1 核心定位

在泄露源码中,query.ts(约 1730 行)集中实现了 QueryEngine——把"用户输入 → 模型推理 → 工具执行 → 再推理"这条链路,编排成一个可中断、可观测、可预算的循环。

类比:QueryEngine 是"中央调度电梯"——决定这一趟先上谁、到哪层、是否继续跑。

3.2 八步循环

Text Only
口诀:准备 → 调用 → 收集 → 修复 → 执行 → 预算 → 继续 → 退出
flowchart TB
    START(["进入 queryLoop 一轮迭代"])
    S1["① 准备消息(含压缩判断)"]
    S2["② 调用 API(streaming)"]
    S3["③ 收集 assistant 消息与 tool_use"]
    S4{"④ 本轮 API 是否出错?"}
    S4R["静默修复:重试、退避"]
    S5["⑤ 执行工具(并行或串行)"]
    S6{"⑥ 预算是否通过?"}
    S7{"⑦ 是否存在 tool_use?"}
    S8["⑧ 无工具 → 组装最终结果 → 退出"]
    CONT["追加 tool_result → 继续 while"]
    FAIL(["预算或致命错误 → 终止"])

    START --> S1 --> S2 --> S3 --> S4
    S4 -->|是| S4R --> S2
    S4 -->|否| S5 --> S6
    S6 -->|否| FAIL
    S6 -->|是| S7
    S7 -->|否| S8
    S7 -->|是| CONT --> START

3.3 逐步详解

步骤 核心动作 主要产出 若失败
① 准备消息 组装 messages[],触发压缩 可发送的上下文窗口 压缩熔断、上下文爆炸
② 调用 API stream: true 调 Messages API SSE / chunk 流 网络错误 → 进入④
③ 收集响应 解析 content 文本 + tool_use 列表 解析异常 → 重试
④ 处理错误 分类错误、退避、重试 恢复后的流或终止决策 用户无感或温和提示
⑤ 执行工具 并行/串行执行工具 tool_result 权限拒绝、工具超时
⑥ 检查预算 估算 token、费用、轮次 continue / break 硬停止
⑦ 发送结果 把工具结果追加进历史 下一轮 messages 历史不一致
⑧ 退出 tool_use return 最终结果 正常结束

厨师类比

  • ① 开餐前清点食材,冰箱塞不下就做真空压缩
  • ②~③ 开火炒菜,师傅边做边尝(streaming),记下"要去冷库取哪些配料"
  • ④ 油烟机突然响了,关火等两秒再开(backoff)
  • ⑤~⑦ 小工取回配料,倒进锅,同一道菜继续炒
  • ⑧ 菜已装盘,关火收工

3.4 异步生成器设计

QueryEngine 使用 async function*(异步生成器)而非普通 async function

TypeScript
// 简化概念
async function* query(userInput: string): AsyncGenerator<StreamEvent> {
    while (true) {
        // ① 准备消息
        const messages = prepareMessages(state);

        // ② 调用 API(streaming)
        const stream = await callAPI(messages);

        // ③ 收集响应
        const { text, toolUses } = await collectResponse(stream);

        // yield 每个 StreamEvent → UI 立刻显示
        yield { type: "assistant_text", content: text };

        if (toolUses.length === 0) {
            // ⑧ 无工具则退出
            return;
        }

        // ⑤ 执行工具
        const results = await executeTools(toolUses);
        yield { type: "tool_results", results };

        // ⑥ 检查预算
        if (!checkBudget(state)) {
            return; // 预算耗尽
        }

        // ⑦ 追加结果,继续循环
        state.messages.push(...results);
    }
}

优势: - UI 不必等"所有货道清空"才能显示第一个字 - 用户中途按 Ctrl+C 可以在"下一步出货前"停住 - 工具执行结果可以逐步流式展示


四、工具系统与治理流水线

4.1 工具分类

Claude Code 内置了丰富的工具集:

类别 工具 用途
文件操作 Read, Write, Edit 读取、创建、修改文件
命令执行 Bash 执行 shell 命令
搜索 Glob, Grep 文件查找、文本搜索
Agent Agent (SubAgent) 委派子任务给子 Agent
外部工具 MCP Tools 通过 MCP 协议扩展
搜索增强 WebSearch, WebFetch 联网搜索与网页抓取

4.2 14 步工具治理流水线

每次工具调用都要经过 14 步治理流水线(这是 Claude Code 安全设计的核心):

Text Only
工具调用请求
① 工具注册表查找      → 验证工具是否存在
② Schema 校验         → 验证参数格式
③ 权限检查            → 当前模式是否允许
④ 用户确认(如需)     → 弹窗让用户审批
⑤ 输入净化            → 清理危险参数
⑥ 沙箱检查            → 是否在沙箱内执行
⑦ 资源限制            → 超时、内存等限制
⑧ 执行前 Hook         → 用户自定义前置钩子
⑨ 实际执行            → 调用工具逻辑
⑩ 结果净化            → 清理敏感信息
⑪ 执行后 Hook         → 用户自定义后置钩子
⑫ 错误处理            → 捕获并转换错误
⑬ 结果格式化          → 转为 LLM 可理解的格式
⑭ 审计日志            → 记录到遥测系统
返回给 QueryEngine

4.3 并行执行

工具根据 isConcurrencySafe 标记决定并行或串行执行:

TypeScript
// 简化概念
async function executeTools(toolUses: ToolUse[]): Promise<ToolResult[]> {
    const safe = toolUses.filter(t => t.isConcurrencySafe);
    const unsafe = toolUses.filter(t => !t.isConcurrencySafe);

    // 安全的工具并行执行
    const safeResults = await Promise.all(safe.map(executeOne));

    // 不安全的工具串行执行
    const unsafeResults = [];
    for (const tool of unsafe) {
        unsafeResults.push(await executeOne(tool));
    }

    return [...safeResults, ...unsafeResults];
}

规则: - 读取文件(Read)→ 可并行 - 搜索(Glob/Grep)→ 可并行 - 写入/编辑文件(Write/Edit)→ 串行(避免冲突) - 执行命令(Bash)→ 串行(避免副作用冲突)

4.4 Fail-Closed 设计

工具系统的安全哲学是 Fail-Closed(默认拒绝):

Text Only
如果工具执行出错 → 返回错误信息给 LLM,而不是静默忽略
如果权限检查失败 → 拒绝执行,而不是降级
如果 Schema 不匹配 → 拒绝调用,而不是猜测参数

4.5 懒加载

工具定义采用懒加载策略,减少启动时的上下文占用:

Text Only
启动时:只加载工具名称和描述(元数据)
使用时:按需加载完整的工具 Schema 和实现

五、权限模型:六种安全模式

5.1 六种权限模式

Claude Code 提供了从最严格到最宽松的六种权限模式:

模式 自动允许 需要确认 适用场景
Restricted 仅读取 写入、执行、网络 审计/审查代码
Default 读取 + 搜索 写入、执行 日常开发
Auto-accept 读取 + 搜索 + 写入 执行 信任写入的场景
Full Auto 全部 CI/CD、自动化
Plan 仅规划 所有执行 规划模式
Custom 自定义 自定义 精细化控制

5.2 Bash AST 分析

对于 Bash 命令,Claude Code 使用 AST(抽象语法树)分析来判断命令的安全性:

TypeScript
// 简化概念
function analyzeBashCommand(command: string): RiskLevel {
    const ast = parseBashAST(command);

    // 检查危险操作
    if (ast.contains("rm -rf /")) return RiskLevel.DANGEROUS;
    if (ast.contains("sudo")) return RiskLevel.ELEVATED;
    if (ast.modifiesSystemFiles()) return RiskLevel.HIGH;
    if (ast.readOnly()) return RiskLevel.SAFE;

    return RiskLevel.MEDIUM;
}

5.3 沙箱隔离

Claude Code 支持在沙箱环境中执行代码:

Text Only
沙箱类型:
  - Docker 容器(推荐)
  - 临时目录隔离
  - 系统级沙箱(macOS Seatbelt、Linux namespaces)

六、上下文管理:三层压缩机制

6.1 为什么需要压缩

Claude Code 的上下文窗口约为 200K tokens,但实际可用空间需要扣除系统提示、工具定义等固定开销。建议在上下文占用约 60% 时就开始主动整理(手动 /compact、拆分任务),为后续工具输出留出余量。当对话历史接近硬阈值(约 87%)时,自动触发压缩。

6.2 三层压缩

Text Only
┌─────────────────────────────────────┐
│  Layer 1: Micro Compaction          │
│  单条消息内压缩(截断长输出)          │
│  触发:单条工具结果超过阈值            │
├─────────────────────────────────────┤
│  Layer 2: Auto Compaction           │
│  自动压缩(摘要旧对话)               │
│  触发:上下文占用超过 ~87%            │
├─────────────────────────────────────┤
│  Layer 3: Full Compaction           │
│  完全压缩(重建上下文)               │
│  触发:Auto 压缩后仍不够              │
└─────────────────────────────────────┘

6.3 手动压缩

用户可以主动触发压缩:

Bash
# 在对话中使用 /compact 命令
/compact

# 带自定义指令的压缩
/compact 请保留所有代码修改记录,但压缩之前的讨论

6.4 缓存感知

Claude Code 的上下文管理是缓存感知的——它会尽量保持前缀不变以利用 API 的 Prompt Caching 功能:

Text Only
优化策略:
  1. 系统提示放在最前面(几乎不变,缓存命中率高)
  2. 工具定义紧随其后(较少变化)
  3. 历史消息从旧到新排列
  4. 压缩时尽量只动尾部(旧消息)
  5. 采用"手术刀式"编辑(cache_edits)——原地替换工具结果内容,
     而非重写整段对话,保持前缀字节级稳定

反模式提醒:每次压缩都 pretty-print JSON、随机重排消息、把时间戳写入静态前缀——这些行为会破坏缓存前缀,导致"省下的上下文"被"上涨的单价"反噬。


七、记忆系统

7.1 CLAUDE.md

Claude Code 通过 CLAUDE.md 文件实现项目级记忆:

Text Only
记忆层级(由广到窄拼接,窄范围覆盖宽范围):
  ~/.claude/CLAUDE.md          → 全局记忆(所有项目共享)
  项目根目录/CLAUDE.md         → 项目记忆(团队共享)
  子目录/CLAUDE.md             → 目录级记忆(上下文相关)
  .claude/CLAUDE.local.md      → 个人记忆(可 gitignore,不提交到仓库)

维护建议:CLAUDE.md 保持在 50~200 行甜区,过长难以维护且增加每轮 token 开销。

CLAUDE.md 示例

Markdown
# 项目:AI 学习创作网站

## 技术栈
- MkDocs + Material 主题
- 部署在 14.103.219.243:/var/www/docs-site/

## 代码规范
- 中文文档,代码注释可用英文
- 文件名使用中文,格式:XX-标题.md
- 所有代码块必须可运行

## 常用命令
- 本地预览:mkdocs serve
- 构建:mkdocs build
- 部署:scripts/deploy_docs_site.ps1

7.2 自动提取

Claude Code 会自动从对话中提取值得记住的信息:

Text Only
触发条件:
  - 用户明确说"记住这个"
  - 发现项目约定(如代码风格、测试命令)
  - 用户纠正 Claude 的错误理解

存储方式:
  - 写入 CLAUDE.md
  - 下次对话自动加载

7.3 双模型检索

记忆检索使用双模型策略,遵循精确度优先原则——宁可少注入,也不塞无关记忆:

Text Only
检索模型(快速 Sonnet):扫描记忆条目的标题/描述,做相关性打分
主模型:负责理解当前任务,使用检索结果

注入上限:最多 5 条记忆(平衡"有用"与"上下文成本")

这样做的优势:
  - 主模型专注于当前任务,不被记忆检索分散注意力
  - 检索模型可以更高效地扫描大量记忆
  - 限制注入条数避免 token 膨胀和行为偏移

7.4 Kairos Dreaming

Claude Code 有一个独特的"梦境"机制——在空闲时整理和蒸馏记忆:

Text Only
Kairos Dreaming 流程:
  1. 收集近期所有交互记录
  2. 提取关键模式和洞察
  3. 蒸馏为高密度记忆
  4. 写入持久化存储
  5. 清理过时的临时记忆

八、多Agent架构

8.1 六种内置 Agent

Claude Code 内部使用了六种专用 Agent:

Agent 职责 触发条件
Explore Agent 探索代码库、理解结构 需要了解项目时
Plan Agent 制定执行计划 复杂任务开始前
Coordinator 协调多个 Agent 多步骤任务
Verification Agent 验证执行结果 代码修改后
Anti-Lazy Agent 防止过早放弃 检测到偷懒行为
Anti-Recursion Agent 防止无限递归 检测到循环

8.2 消息路由

多 Agent 之间的消息路由机制:

Text Only
用户输入
Coordinator(协调器)
  ├── 判断任务复杂度
  ├── 简单任务 → 直接执行
  └── 复杂任务 → 分解并委派
       ├── Explore Agent → 探索阶段
       ├── Plan Agent → 规划阶段
       ├── 执行 → 主循环
       └── Verification Agent → 验证阶段

8.3 缓存优化

子 Agent 的结果会被缓存,避免重复计算:

Text Only
优化策略:
  - 子 Agent 在独立上下文中运行(Fork 前缀利于缓存命中)
  - 结果以摘要形式返回给主 Agent(蒸馏返回)
  - 相似的子任务可以复用缓存结果
  - 子 Agent 之间不共享完整上下文(隔离原则)
  - 子 Agent 不能再嵌套生成子 Agent(防无限递归)

九、隐藏功能与 Easter Eggs

9.1 Undercover 模式

Claude Code 有一个隐藏的"卧底模式",让它在回答时更加谨慎:

Bash
# 激活方式(隐藏功能)
# 使 Claude Code 以更严格的标准审查自己的输出

9.2 Buddy Pet

一个有趣的宠物系统——Claude Code 可以有一个虚拟"伙伴":

Text Only
功能:
  - 在空闲时显示状态
  - 提供轻松的对话体验
  - 记录用户偏好

9.3 Deep Planning

深度规划模式——在执行复杂任务前进行更深入的分析:

Text Only
触发条件:
  - 检测到复杂的多文件修改
  - 用户明确要求规划
  - 任务涉及架构变更

行为:
  - 先完整分析影响面
  - 生成详细的执行计划
  - 获得用户确认后再执行

9.4 反作弊机制

Claude Code 内置了反作弊检测,防止被恶意 Prompt 诱导:

Text Only
检测内容:
  - 尝试读取环境变量中的 API Key
  - 尝试修改权限配置
  - 尝试注入系统提示
  - 尝试绕过安全检查

十、Token 经济学与成本优化

10.1 成本构成

Text Only
每次对话的 Token 消耗:
  系统提示        → ~2K-5K tokens(固定,可缓存)
  工具定义        → ~3K-8K tokens(固定,可缓存)
  历史消息        → 随对话轮次增长
  工具结果        → 取决于工具类型
  模型输出        → 取决于任务复杂度

10.2 省钱策略

策略 节省幅度 说明
Prompt Caching ~90% 保持前缀不变,利用 API 缓存
及时 /compact ~50% 主动压缩历史,避免自动压缩的开销
限制工具范围 ~20% --allowedTools 减少工具定义占用
子目录启动 ~30% 在子目录启动,减少项目扫描范围
CLAUDE.md 精简 ~10% 保持记忆文件简洁

10.3 成本速查

Text Only
典型场景估算(Claude Sonnet 4):
  简单问答(1-3 轮)    → $0.01 - $0.05
  代码修改(5-10 轮)   → $0.10 - $0.50
  复杂重构(20+ 轮)    → $1.00 - $5.00
  全项目重构(100+ 轮) → $10.00 - $50.00

十一、实战工作流

11.1 需求澄清 → Spec → 实现

Text Only
最佳实践流程:
  1. 先给目标 → "我想解决什么问题"
  2. 再给边界 → "不改什么、必须满足什么"
  3. 再给上下文 → 相关文件、日志、架构
  4. 再限定输出 → 要 spec、要设计对比表、要变更清单

好的提问方式

Text Only
❌ "帮我做一个知识库系统"

✅ "目标是为内部研发团队做一个带引用的知识问答系统。
    约束是只支持公司文档,不做开放互联网搜索;
    必须带权限控制和引用来源;
    先不要写代码,请先输出:
    1. MVP 范围
    2. 架构图草案
    3. 风险点
    4. 评测指标
    5. 两周内可交付版本的任务拆解。"

11.2 代码审查与 Bug 修复

Bash
# 让 Claude Code 审查代码
claude "审查 src/auth/login.py 的安全性,重点关注:SQL 注入、XSS、权限绕过"

# 修复 Bug
claude "这个测试失败了:pytest tests/test_auth.py -v。请分析原因并修复。"

# 重构
claude "将 src/utils/helpers.py 中的函数按职责拆分到独立模块中,保持向后兼容。"

11.3 项目初始化

Bash
# 让 Claude Code 帮你搭建项目
claude "创建一个 FastAPI 项目,包含:
  - 用户认证(JWT)
  - PostgreSQL 数据库
  - Docker Compose 配置
  - 单元测试骨架
  - CI/CD GitHub Actions 配置"

11.4 与 IDE 协同

通过 Bridge 模式,Claude Code 可以与 VS Code 等 IDE 深度集成:

Text Only
Bridge 功能:
  - 在 IDE 中直接调用 Claude Code
  - 实时显示文件修改的 diff
  - 支持点击跳转到修改位置
  - 保持 IDE 的语法高亮和智能提示

十二、从求职角度的价值

12.1 面试官为什么在意

不是因为想看你会不会按按钮,而是因为你是否具备:

  • 把模糊需求转成可执行任务的能力
  • 把复杂系统讲清楚的能力
  • 在多轮协作中稳定推进任务的能力
  • 理解 AI Coding 工具底层原理的能力

12.2 简历怎么写

不要写: - 熟练使用 Claude Code - 熟练使用 Artifacts

建议写: - 理解 Claude Code 的 QueryEngine 八步循环和工具治理流水线,能基于源码分析优化 Agent 工作流 - 使用 AI Coding 工具辅助完成需求澄清、方案比较和代码审查,将复杂设计讨论沉淀为结构化文档 - 基于 Claude Code 的上下文管理和记忆系统设计原则,优化长周期任务的 Token 效率和执行稳定性

12.3 面试高频问题

  1. Claude Code 的 QueryEngine 是如何工作的? → 八步循环
  2. 工具调用的安全机制是什么? → 14 步治理流水线 + Fail-Closed
  3. 如何管理长对话的上下文? → 三层压缩 + 缓存感知
  4. 多 Agent 如何协作? → Coordinator + 专用 Agent + 消息路由
  5. CLAUDE.md 的设计哲学是什么? → 渐进式披露 + 项目级记忆

十三、实战练习

练习 1:理解 QueryEngine 循环

用 Python 实现一个简化版的 QueryEngine:

Python
import anthropic
from typing import Generator

client = anthropic.Anthropic()

# 简化的工具定义
tools = [
    {
        "name": "read_file",
        "description": "读取文件内容",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": {"type": "string", "description": "文件路径"}
            },
            "required": ["path"]
        }
    }
]

def execute_tool(name: str, input: dict) -> str:
    """模拟工具执行"""
    if name == "read_file":
        try:
            with open(input["path"], "r") as f:
                return f.read()[:2000]  # 截断长文件
        except FileNotFoundError:
            return f"错误:文件 {input['path']} 不存在"
    return "未知工具"

def query_engine(user_input: str, max_turns: int = 5):
    """简化版 QueryEngine"""
    messages = [{"role": "user", "content": user_input}]

    for turn in range(max_turns):
        print(f"\n--- 轮次 {turn + 1}/{max_turns} ---")

        # ② 调用 API
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=4096,
            tools=tools,
            messages=messages
        )

        # ③ 收集响应
        tool_uses = []
        text_parts = []
        for block in response.content:
            if block.type == "text":
                text_parts.append(block.text)
            elif block.type == "tool_use":
                tool_uses.append(block)

        if text_parts:
            print(f"助手: {''.join(text_parts)}")

        # ⑧ 无工具则退出
        if not tool_uses:
            break

        # ⑤ 执行工具
        tool_results = []
        for tu in tool_uses:
            print(f"  调用工具: {tu.name}({tu.input})")
            result = execute_tool(tu.name, tu.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": tu.id,
                "content": result
            })

        # ⑦ 追加结果
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_results})

    return messages
💡 参考答案:测试用例
Python
# 测试
if __name__ == "__main__":
    # 创建测试文件
    with open("test_sample.py", "w") as f:
        f.write("def hello():\n    print('Hello, World!')\n\ndef add(a, b):\n    return a + b\n")

    result = query_engine("请读取 test_sample.py 并解释代码功能")

    # 清理
    import os
    os.remove("test_sample.py")

练习 2:实现上下文压缩

实现一个简单的上下文压缩器:

Python
class ContextCompressor:
    def __init__(self, max_messages: int = 20, summary_threshold: int = 15):
        self.max_messages = max_messages
        self.summary_threshold = summary_threshold

    def should_compress(self, messages: list) -> bool:
        """判断是否需要压缩"""
        # TODO: 实现
        pass

    def compress(self, messages: list) -> list:
        """压缩消息列表"""
        # TODO: 实现
        pass

    def summarize_old_messages(self, old_messages: list) -> dict:
        """将旧消息摘要为一条"""
        # TODO: 实现
        pass
💡 参考答案
Python
class ContextCompressor:
    def __init__(self, max_messages: int = 20, summary_threshold: int = 15):
        self.max_messages = max_messages
        self.summary_threshold = summary_threshold
        self.summary_model = "claude-sonnet-4-20250514"

    def should_compress(self, messages: list) -> bool:
        return len(messages) > self.summary_threshold

    def compress(self, messages: list) -> list:
        if not self.should_compress(messages):
            return messages

        # 保留最近的几条消息
        keep_recent = self.max_messages // 2
        old_messages = messages[:-keep_recent]
        recent_messages = messages[-keep_recent:]

        # 将旧消息压缩为摘要
        summary_msg = self.summarize_old_messages(old_messages)

        return [summary_msg] + recent_messages

    def summarize_old_messages(self, old_messages: list) -> dict:
        # 提取文本内容
        texts = []
        for msg in old_messages:
            if isinstance(msg.get("content"), str):
                texts.append(f"[{msg['role']}]: {msg['content'][:200]}")
            elif isinstance(msg.get("content"), list):
                for block in msg["content"]:
                    if hasattr(block, "text"):
                        texts.append(f"[{msg['role']}]: {block.text[:200]}")

        summary_text = "\n".join(texts[-10:])  # 只用最后10条做摘要

        return {
            "role": "user",
            "content": (
                f"[上下文摘要] 之前的对话要点:\n{summary_text}\n"
                f"请基于以上上下文继续对话。"
            )
        }

# 测试
compressor = ContextCompressor(max_messages=10, summary_threshold=7)
messages = [
    {"role": "user", "content": f"消息 {i}"}
    for i in range(12)
]
compressed = compressor.compress(messages)
print(f"原始: {len(messages)} 条 → 压缩后: {len(compressed)} 条")

练习 3:思考题

  1. QueryEngine 为什么使用异步生成器而不是普通异步函数? 请从用户体验和系统设计两个角度分析。

  2. 14 步工具治理流水线中,哪些步骤对安全性最关键? 如果只能保留 3 步,你会保留哪些?

  3. 三层压缩各自的适用场景是什么? 在什么情况下应该手动触发 /compact 而不是等待自动压缩?

  4. CLAUDE.md 的设计如何体现"渐进式披露"原则? 请结合记忆层级分析。


总结

关键要点

模块 核心设计 关键洞察
架构 四层:呈现→编排→模型→工具 不是 CLI,是以 LLM 为内核的操作系统
QueryEngine 八步循环 异步生成器实现可中断、可流式、可恢复
工具系统 14 步治理流水线 Fail-Closed,默认拒绝
权限 六种模式 从 Restricted 到 Full Auto 的渐进信任
上下文 三层压缩 Micro → Auto → Full,缓存感知,60% 主动介入
记忆 CLAUDE.md + 自动提取 + 双模型检索 精确度优先(最多 5 条),渐进式披露
多 Agent 六种专用 Agent Coordinator 协调,蒸馏返回,防递归
成本 Token 经济学 Prompt Caching 是最有效的省钱策略

核心洞察

Claude Code 的真正价值不在于"能生成代码",而在于它展示了一个成熟的 Agent 系统应该如何设计——从 QueryEngine 的八步循环到工具治理流水线,从三层压缩到多 Agent 协调,每一个模块都在回答同一个问题:如何让 LLM 在长周期、复杂任务中稳定、安全、高效地运行?

延伸阅读


⚠️ 核验说明:本页基于 Claude Code v2.1.88 泄露源码及社区分析编写。源码细节可能随版本更新而变化,请以官方文档和实际运行环境为准。

最后更新日期:2026-04-22