一、AI Agent 设计模式:开篇

4 阅读3分钟

Claude Code CLI 是一个成熟的 AI Agent 实现。它不是简单的 "发送消息→接收响应",而是一个复杂的、多层次的 Agent 系统。这个系列将从 Agent 设计模式的角度,深入分析 Claude Code 的架构。

为什么研究 Claude Code?

Claude Code 是一个生产级的 AI Agent:

  • 真实场景:不是演示项目,而是每天被数千开发者使用的工具
  • 复杂任务:处理文件编辑、命令执行、多步任务编排
  • 安全边界:严格的权限控制,沙箱执行
  • 用户交互:实时进度、权限对话框、错误反馈
  • 扩展性:Skills、Hooks、MCP 协议

这些特性让它成为一个绝佳的 Agent 设计参考。

本系列主题

我们将从 11 个角度分析 Agent 设计:

篇数主题核心问题
01Agent 生命周期Agent 如何启动、运行、终止?状态如何流转?
02工具编排30+ 工具如何统一管理?执行流水线如何设计?
03上下文管理Token 预算如何分配?文件状态如何追踪?
04子 Agent 架构Fork 模式如何工作?父子 Agent 如何通信?
05MCP 协议集成外部工具如何接入?协议如何抽象?
06对话压缩Token 超限时如何压缩?信息如何保留?
07记忆系统如何跨会话记忆?持久化策略是什么?
08权限决策如何判断操作安全?AI 分类器如何辅助?
09流式响应如何实时显示进度?中断如何处理?
10并发与调度多 Agent 如何并发?资源如何管理?
11系列总结整体架构回顾,设计原则提炼

设计哲学

在深入细节之前,先看 Claude Code 的设计哲学:

1. AsyncGenerator 为核心

async function* query({ messages, ... }): AsyncGenerator<Message> {
  for await (const event of streamEvents) {
    if (event.type === 'content_block_start') { ... }
    if (event.type === 'content_block_delta') { ... }
    if (event.type === 'message_stop') { ... }
    yield message
  }
}

不是一次性返回结果,而是流式生成消息。这让 UI 可以实时更新。

2. 工具是独立的 Agent 能力单元

type Tool = {
  name: string
  call(args, context): Promise<ToolResult>
  checkPermissions(input): Promise<PermissionResult>
  isConcurrencySafe(input): boolean
  isReadOnly(input): boolean
}

每个工具封装一个能力,有自己的权限检查、并发声明。

3. 上下文是共享状态容器

type ToolUseContext = {
  abortController: AbortController
  readFileState: FileStateCache
  getAppState(): AppState
  messages: Message[]
  options: { tools, commands, mcpClients, ... }
}

所有执行状态在 Context 中——文件读取状态、消息历史、工具列表。

4. Hooks 是生命周期注入点

type HookEvent =
  | 'PreToolUse' | 'PostToolUse'
  | 'SessionStart' | 'SessionEnd'
  | 'PreCompact' | 'PostCompact'

关键事件可以注入自定义逻辑——验证、日志、通知。

5. 安全是分层防御

// 第一层:工具自身检查
tool.checkPermissions(input, context)

// 第二层:规则匹配
checkPermissionRules(toolName, input)

// 第三层:模式检查
checkPermissionMode(mode)

// 第四层:AI 分类器
classifyBashCommand(command)

不是单一检查点,而是层层把关。

核心架构图

用户输入
    │
    ▼
QueryEngine (会话生命周期管理)
    │
    ▼
query() (核心循环 AsyncGenerator)
    │
    ├─► API 调用 (Anthropic/Bedrock/Vertex)
    │       │
    │       ▼
    │   流式事件处理
    │       │
    │       ├─► 文本块 → yield Message
    │       │
    │       ├─► 工具调用 → 工具执行
    │       │       │
    │       │       ├─► 权限检查
    │       │       ├─► 执行 call()
    │       │       ├─► Hook 触发
    │       │       └─► yield ToolResult
    │       │
    │       └─► 消息结束 → 检查继续
    │
    └─► 对话压缩 (Token 超限)
    │
    └─► 子 Agent (AgentTool)
            │
            ├─► Fork 模式
            ├─► 独立 Context
            └─► 独立 query() 循环

与传统 CLI 的区别

传统 CLI:

用户输入 → 解析 → 执行 → 输出 → 结束

Claude Code:

用户输入 → Agent 思考 → 可能多次执行 → 可能多个工具 → 可能多个子Agent → 最终响应 → 可能继续...

这是一个开放式循环,结束条件由 Agent 决定,不是用户命令决定。

本系列读者

如果你是:

  • AI Agent 开发者:想了解生产级 Agent 的设计
  • CLI 开发者:想设计更智能的 CLI 工具
  • 安全工程师:想理解 AI Agent 的安全边界
  • 产品设计师:想思考 AI 工具的用户体验

这个系列对你都有价值。

下篇预告

下一篇,我们将深入 Agent 生命周期——看看 QueryEngine 如何管理会话状态,Agent 如何启动、暂停、恢复、终止。