目录

Claude Code 工具系统源码解读

Claude Code 工具系统源码解读

版本基于 main 分支 | 源码目录: /mnt/e/code/cc/claude-code-main

概述

Claude Code 的工具系统(Tools)是其 Agent 能力的核心基础设施,允许 AI 模型通过工具调用(Tool Use)与文件系统、Shell、第三方服务进行交互。本文档深入分析工具系统的五个核心维度:注册与发现执行与隔离结果序列化错误处理内置工具实现


1. 工具注册与发现机制

1.1 核心入口

工具系统的入口位于 src/tools.ts,负责所有内置工具的注册、过滤和组合。

// src/tools.ts
export function getAllBaseTools(): Tools {
  return [
    AgentTool,
    TaskOutputTool,
    BashTool,
    // ... 条件编译的工具
    ...(hasEmbeddedSearchTools() ? [] : [GlobTool, GrepTool]),
    // ... 更多工具
  ]
}

1.2 工具构建工厂

src/Tool.ts 中的 buildTool() 工厂函数是所有工具的统一入口:

// src/Tool.ts (L783)
export function buildTool<D extends AnyToolDef>(def: D): BuiltTool<D> {
  return {
    ...TOOL_DEFAULTS,
    userFacingName: () => def.name,
    ...def,
  } as BuiltTool<D>
}

默认属性填充(L757-769):

默认方法默认行为安全策略
isEnabled() => true-
isConcurrencySafe() => false默认不安全,需显式声明
isReadOnly() => false默认写入操作
isDestructive() => false默认非破坏性
checkPermissions{ behavior: 'allow' }默认允许
toAutoClassifierInput() => ''跳过分类器
userFacingName() => name回退到工具名

1.3 工具类型定义

Tool 接口(L362-695)是整个系统的核心类型契约:

export type Tool<
  Input extends AnyObject = AnyObject,
  Output = unknown,
  P extends ToolProgressData = ToolProgressData,
> = {
  readonly name: string
  readonly inputSchema: Input
  readonly outputSchema?: z.ZodType<unknown>
  readonly maxResultSizeChars: number  // 大结果阈值

  // 核心方法
  call(args, context, canUseTool, parentMessage, onProgress?): Promise<ToolResult<Output>>
  description(input, options): Promise<string>
  prompt(options): Promise<string>

  // 安全相关
  isConcurrencySafe(input): boolean
  isReadOnly(input): boolean
  isDestructive?(input): boolean
  validateInput?(input, context): Promise<ValidationResult>
  checkPermissions(input, context): Promise<PermissionResult>

  // UI 渲染
  renderToolUseMessage(input, options): React.ReactNode
  renderToolResultMessage(content, progress, options): React.ReactNode
  renderToolUseProgressMessage?(progress, options): React.ReactNode

  // 元数据
  aliases?: string[]                    // 向后兼容的别名
  searchHint?: string                    // 关键词提示
  isMcp?: boolean
  isLsp?: boolean
  shouldDefer?: boolean                 // 延迟加载
  alwaysLoad?: boolean                  // 始终加载
}

1.4 工具池组装

// src/tools.ts (L345-367)
export function assembleToolPool(
  permissionContext: ToolPermissionContext,
  mcpTools: Tools,
): Tools {
  const builtInTools = getTools(permissionContext)
  const allowedMcpTools = filterToolsByDenyRules(mcpTools, permissionContext)

  // 按名称排序保持提示词缓存稳定
  const byName = (a: Tool, b: Tool) => a.name.localeCompare(b.name)
  return uniqBy(
    [...builtInTools].sort(byName).concat(allowedMcpTools.sort(byName)),
    'name',
  )
}

关键设计:内置工具按名称排序后作为连续前缀,MCP 工具在后面。这是为了配合服务器的缓存策略——缓存断点放在最后一个内置工具之后。

1.5 条件注册机制

工具通过 feature() 标志和 process.env 实现条件编译:

// src/tools.ts
const cronTools = feature('AGENT_TRIGGERS')
  ? [
      require('./tools/ScheduleCronTool/CronCreateTool.js').CronCreateTool,
      require('./tools/ScheduleCronTool/CronDeleteTool.js').CronDeleteTool,
      require('./tools/ScheduleCronTool/CronListTool.js').CronListTool,
    ]
  : []

const MonitorTool = feature('MONITOR_TOOL')
  ? require('./tools/MonitorTool/MonitorTool.js').MonitorTool
  : null

1.6 工具拒绝规则

// src/tools.ts
export function filterToolsByDenyRules<
  T extends {
    name: string
    mcpInfo?: { serverName: string; toolName: string }
  },
>(tools: readonly T[], permissionContext: ToolPermissionContext): T[] {
  return tools.filter(tool => !getDenyRuleForTool(permissionContext, tool))
}

1.7 协调器模式工具过滤

COORDINATOR_MODE 下仅允许特定工具:

// src/constants/tools.ts
export const COORDINATOR_MODE_ALLOWED_TOOLS = new Set([
  AGENT_TOOL_NAME,
  TASK_STOP_TOOL_NAME,
  SEND_MESSAGE_TOOL_NAME,
  SYNTHETIC_OUTPUT_TOOL_NAME,
])

2. 延迟加载与 ToolSearch 机制

2.1 延迟加载概述

当 MCP 工具数量庞大时,工具定义本身可能消耗大量上下文。ToolSearch 机制允许:

  1. 初始仅发送 defer_loading: true 的工具声明
  2. 模型通过 ToolSearchTool 按需发现和加载工具
  3. 工具引用(tool_reference)在消息历史中追踪已发现工具

2.2 工具搜索模式

// src/utils/toolSearch.ts
export type ToolSearchMode = 'tst' | 'tst-auto' | 'standard'

// tst: 始终延迟 MCP 和 shouldDefer 工具
// tst-auto: 超过阈值后自动启用
// standard: 所有工具直接暴露

阈值计算

function getAutoToolSearchTokenThreshold(model: string): number {
  const betas = getMergedBetas(model)
  const contextWindow = getContextWindowForModel(model, betas)
  const percentage = getAutoToolSearchPercentage() / 100  // 默认 10%
  return Math.floor(contextWindow * percentage)
}

2.3 已发现工具追踪

// src/utils/toolSearch.ts
export function extractDiscoveredToolNames(messages: Message[]): Set<string> {
  // 从 tool_result 中提取 tool_reference 块
  // 跨会话持久化(compact 边界保存快照)
}

2.4 延迟工具池变化检测

// src/utils/toolSearch.ts
export function getDeferredToolsDelta(
  tools: Tools,
  messages: Message[],
): DeferredToolsDelta | null {
  // 检测新增/移除的延迟工具
  // 通过 deferred_tools_delta 附件通知模型
}

3. 工具执行流程与隔离

3.1 执行入口

src/services/tools/toolExecution.ts 中的 runToolUse() 是工具执行的起点:

// src/services/tools/toolExecution.ts (L337)
export async function* runToolUse(
  toolUse: ToolUseBlock,
  assistantMessage: AssistantMessage,
  canUseTool: CanUseToolFn,
  toolUseContext: ToolUseContext,
): AsyncGenerator<MessageUpdateLazy, void>

3.2 完整执行流程

┌─────────────────────────────────────────────────────────────┐
│ 1. 工具查找 (L345-356)                                      │
│    findToolByName() → 工具实例                               │
│    别名回退查找 → 支持旧名称                                  │
├─────────────────────────────────────────────────────────────┤
│ 2. 输入验证 (L615-680)                                      │
│    tool.inputSchema.safeParse() → Zod 验证                  │
│    tool.validateInput?() → 自定义验证                        │
├─────────────────────────────────────────────────────────────┤
│ 3. PreToolUse Hooks (L800-862)                              │
│    runPreToolUseHooks() → 权限前置检查                        │
├─────────────────────────────────────────────────────────────┤
│ 4. 权限决策 (L921-1104)                                      │
│    resolveHookPermissionDecision()                          │
│    canUseTool() → 用户交互                                   │
├─────────────────────────────────────────────────────────────┤
│ 5. 工具调用 (L1207-1222)                                     │
│    tool.call() → 实际执行                                    │
├─────────────────────────────────────────────────────────────┤
│ 6. PostToolUse Hooks (L1483-1531)                           │
│    runPostToolUseHooks() → 后置处理                          │
├─────────────────────────────────────────────────────────────┤
│ 7. 结果序列化 (L1403-1478)                                   │
│    processToolResultBlock() → 持久化/映射                     │
└─────────────────────────────────────────────────────────────┘

3.3 并发安全与隔离

工具编排器 (src/services/tools/toolOrchestration.ts):

// 核心分区逻辑
function partitionToolCalls(
  toolUseMessages: ToolUseBlock[],
  toolUseContext: ToolUseContext,
): Batch[] {
  return toolUseMessages.reduce((acc: Batch[], toolUse) => {
    const tool = findToolByName(toolUseContext.options.tools, toolUse.name)
    const isConcurrencySafe = tool?.isConcurrencySafe(parsedInput.data) ?? false

    if (isConcurrencySafe && acc[acc.length - 1]?.isConcurrencySafe) {
      // 可并发工具合并批次
      acc[acc.length - 1]!.blocks.push(toolUse)
    } else {
      // 非并发安全工具单独批次
      acc.push({ isConcurrencySafe, blocks: [toolUse] })
    }
    return acc
  }, [])
}

并发执行runToolsConcurrently() 使用 all() 生成器实现:

  • 可并发工具(只读)并行执行
  • 非并发安全工具串行执行
  • 最大并发数:CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY(默认 10)

3.4 流式执行器

StreamingToolExecutorsrc/services/tools/StreamingToolExecutor.ts)处理流式场景:

export class StreamingToolExecutor {
  private tools: TrackedTool[] = []

  // 核心调度逻辑
  private canExecuteTool(isConcurrencySafe: boolean): boolean {
    const executingTools = this.tools.filter(t => t.status === 'executing')
    return (
      executingTools.length === 0 ||
      (isConcurrencySafe && executingTools.every(t => t.isConcurrencySafe))
    )
  }
}

关键设计

  • Bash 错误级联:Bash 工具错误会中止所有兄弟工具
  • 中断行为:通过 interruptBehavior() 控制 ('cancel' | 'block')
  • 进度优先:进度消息立即 yield,完整结果按顺序返回

3.5 进度报告机制

// toolExecution.ts L140-168
function streamedCheckPermissionsAndCallTool(...) {
  const stream = new Stream<MessageUpdateLazy>()
  checkPermissionsAndCallTool(
    tool,
    toolUseID,
    input,
    toolUseContext,
    canUseTool,
    assistantMessage,
    messageId,
    requestId,
    mcpServerType,
    mcpServerBaseUrl,
    progress => {
      // 进度事件入队
      stream.enqueue({
        message: createProgressMessage({
          toolUseID: progress.toolUseID,
          parentToolUseID: toolUseID,
          data: progress.data,
        }),
      })
    },
  )
}

4. 工具结果序列化

4.1 Schema 缓存

工具模式在提示词中位于位置 2(系统提示之前),任何字节级变化都会破坏整个 ~11K token 的工具块。toolSchemaCache.ts 实现会话级缓存:

// src/utils/toolSchemaCache.ts
const TOOL_SCHEMA_CACHE = new Map<string, CachedSchema>()

export function clearToolSchemaCache(): void {
  TOOL_SCHEMA_CACHE.clear()
}

缓存失效场景

  • GrowthBook 特性开关变化(tengu_tool_pear, tengu_fgts
  • MCP 服务器重连
  • tool.prompt() 中的动态内容

4.2 结果存储策略

src/utils/toolResultStorage.ts 实现大结果持久化:

// 持久化阈值判断
export function getPersistenceThreshold(
  toolName: string,
  declaredMaxResultSizeChars: number,
): number {
  // Infinity = 硬性拒绝持久化(如 Read 工具)
  if (!Number.isFinite(declaredMaxResultSizeChars)) {
    return declaredMaxResultSizeChars
  }
  // GrowthBook 覆盖 > 硬编码默认值
  const overrides = getFeatureValue_CACHED_MAY_BE_STALE(...)
  if (typeof override === 'number') {
    return override
  }
  return Math.min(declaredMaxResultSizeChars, DEFAULT_MAX_RESULT_SIZE_CHARS)
}

4.3 大结果持久化流程

// 持久化决策
async function maybePersistLargeToolResult(
  toolResultBlock: ToolResultBlockParam,
  toolName: string,
  persistenceThreshold?: number,
): Promise<ToolResultBlockParam> {
  // 1. 空结果处理(防止尾随停止序列问题)
  if (isToolResultContentEmpty(content)) {
    return { ...toolResultBlock, content: `(${toolName} completed with no output)` }
  }

  // 2. 跳过图片内容
  if (hasImageBlock(content)) {
    return toolResultBlock
  }

  // 3. 大小检查
  const size = contentSize(content)
  if (size <= threshold) {
    return toolResultBlock
  }

  // 4. 持久化到磁盘
  const result = await persistToolResult(content, toolResultBlock.tool_use_id)
  return { ...toolResultBlock, content: buildLargeToolResultMessage(result) }
}

持久化路径{projectDir}/{sessionId}/tool-results/{id}.txt|.json

4.4 消息级预算

工具结果不仅在单工具级别控制,还在消息聚合级别限制:

// 按 API 级别消息分组
function collectCandidatesByMessage(messages: Message[]): ToolResultCandidate[][] {
  // 同一次 AssistantMessage 的 tool_result 合并计算
  // 确保 normalizeMessagesForAPI 的合并行为一致
}

// 预算执行
export async function enforceToolResultBudget(
  messages: Message[],
  state: ContentReplacementState,
  skipToolNames: ReadonlySet<string> = new Set(),
): Promise<{ messages: Message[]; newlyReplaced: ToolResultReplacementRecord[] }>

预算策略

  • 优先持久化最大的新鲜结果
  • 已见结果(seenIds)的命运被冻结
  • 缓存的替换(replacements)保证提示词缓存稳定

4.5 结果预览生成

export function generatePreview(
  content: string,
  maxBytes: number,
): { preview: string; hasMore: boolean } {
  // 在换行符边界截断,避免切割行
  const lastNewline = truncated.lastIndexOf('\n')
  const cutPoint = lastNewline > maxBytes * 0.5 ? lastNewline : maxBytes
  return { preview: content.slice(0, cutPoint), hasMore: true }
}

4.6 内容替换状态

跨会话保持一致性:

// src/utils/toolResultStorage.ts
export type ContentReplacementState = {
  seenIds: Set<string>           // 已见过的 tool_use_id
  replacements: Map<string, string>  // id → 替换文本
}

设计目标:缓存共享 fork(如 agentSummary)需要相同决策保证提示词前缀一致。


5. 工具错误处理

5.1 错误分类

src/services/tools/toolExecution.ts 中的 classifyToolError()

export function classifyToolError(error: unknown): string {
  // 1. TelemetrySafeError → 使用 telemetryMessage
  if (error instanceof TelemetrySafeError) {
    return error.telemetryMessage.slice(0, 200)
  }

  // 2. Node.js 文件系统错误 → 使用错误码 (ENOENT, EACCES)
  if (error instanceof Error) {
    const errnoCode = getErrnoCode(error)
    if (typeof errnoCode === 'string') {
      return `Error:${errnoCode}`
    }
    // 3. 命名错误类型 (ShellError, ImageSizeError)
    if (error.name && error.name !== 'Error' && error.name.length > 3) {
      return error.name.slice(0, 60)
    }
    return 'Error'
  }
  return 'UnknownError'
}

5.2 错误格式化

src/utils/toolErrors.ts

export function formatError(error: unknown): string {
  if (error instanceof AbortError) {
    return error.message || INTERRUPT_MESSAGE_FOR_TOOL_USE
  }

  // 截断长错误信息(保留首尾)
  const parts = getErrorParts(error)
  const fullMessage = parts.filter(Boolean).join('\n').trim()
  if (fullMessage.length <= 10000) {
    return fullMessage
  }
  const halfLength = 5000
  return `${start}\n\n... [${fullMessage.length - 10000} characters truncated] ...\n\n${end}`
}

export function formatZodValidationError(
  toolName: string,
  error: ZodError,
): string {
  // 分类错误:缺失参数、意外参数、类型不匹配
  const missingParams = error.issues
    .filter(err => err.code === 'invalid_type' && err.message.includes('received undefined'))
    .map(err => formatValidationPath(err.path))

  const unexpectedParams = error.issues
    .filter(err => err.code === 'unrecognized_keys')
    .flatMap(err => err.keys)

  const typeMismatchParams = error.issues
    .filter(err => err.code === 'invalid_type' && !err.message.includes('received undefined'))
    // ...
}

5.3 错误处理流程

工具调用失败
    │
    ├─→ AbortError → 中断消息
    │
    ├─→ ShellError → Exit code + stderr + stdout
    │
    ├─→ McpAuthError → MCP 客户端状态 → 'needs-auth'
    │
    └─→ 其他错误 → 格式化 → 日志记录
                    │
                    ├─→ PostToolUseFailureHooks
                    │
                    └─→ 错误消息返回给模型

5.4 权限拒绝处理

权限拒绝不触发常规错误,而是生成特殊的 tool_result

// 权限拒绝结果
const messageContent: ContentBlockParam[] = [
  {
    type: 'tool_result',
    content: errorMessage,
    is_error: true,
    tool_use_id: toolUseID,
  },
]

6. 内置工具实现

6.1 工具实现模式

BashTool 为例 (src/tools/BashTool/BashTool.tsx):

export const BashTool = buildTool({
  name: BASH_TOOL_NAME,
  searchHint: 'execute shell commands',
  maxResultSizeChars: 30_000,
  strict: true,

  // Zod 输入/输出模式
  get inputSchema(): InputSchema {
    return inputSchema()
  },
  get outputSchema(): OutputSchema {
    return outputSchema()
  },

  // 安全方法
  isConcurrencySafe(input) {
    return this.isReadOnly?.(input) ?? false
  },
  isReadOnly(input) {
    return checkReadOnlyConstraints(input, compoundCommandHasCd).behavior === 'allow'
  },
  async checkPermissions(input, context): Promise<PermissionResult> {
    return bashToolHasPermission(input, context)
  },

  // 渲染方法
  renderToolUseMessage,
  renderToolResultMessage,
  mapToolResultToToolResultBlockParam({ stdout, stderr, ... }, toolUseID) {
    // 映射到 API 格式
    return {
      tool_use_id: toolUseID,
      type: 'tool_result',
      content: [stdout, errorMessage, backgroundInfo].filter(Boolean).join('\n'),
      is_error: interrupted
    }
  },

  // 核心执行
  async call(input: BashToolInput, toolUseContext, _canUseTool, parentMessage, onProgress) {
    // 执行命令,返回结果
    return { data: { stdout, stderr, interrupted, ... } }
  },
})

6.2 BashTool 命令分类

BashTool 通过静态分析将命令分类为可折叠显示:

// 搜索命令
const BASH_SEARCH_COMMANDS = new Set(['find', 'grep', 'rg', 'ag', 'ack', 'locate', 'which', 'whereis'])

// 读取命令
const BASH_READ_COMMANDS = new Set(['cat', 'head', 'tail', 'less', 'more', 'wc', 'stat', 'file', 'jq', 'awk', 'cut', 'sort', 'uniq', 'tr'])

// 列表命令
const BASH_LIST_COMMANDS = new Set(['ls', 'tree', 'du'])

// 静默命令(成功无输出)
const BASH_SILENT_COMMANDS = new Set(['mv', 'cp', 'rm', 'mkdir', 'rmdir', 'chmod', 'chown', 'chgrp', 'touch', 'ln', 'cd', 'export', 'unset', 'wait'])

6.3 工具执行隔离

BashTool 使用 SandboxManager 实现进程隔离:

// 沙箱决策
shouldUseSandbox: shouldUseSandbox(input)

// 注释说明隔离策略
// - 动态配置禁用命令
// - 用户配置的排除命令 (settings.json)
// - 模式匹配支持(前缀、通配符)

6.4 核心内置工具一览

工具文件职责
BashTooltools/BashTool/BashTool.tsxShell 命令执行
FileEditTooltools/FileEditTool/FileEditTool.ts文件编辑
FileReadTooltools/FileReadTool/FileReadTool.ts文件读取
FileWriteTooltools/FileWriteTool/FileWriteTool.ts文件写入
GlobTooltools/GlobTool/GlobTool.ts文件模式匹配
GrepTooltools/GrepTool/GrepTool.ts内容搜索
WebFetchTooltools/WebFetchTool/WebFetchTool.ts网页抓取
WebSearchTooltools/WebSearchTool/WebSearchTool.ts网络搜索
AgentTooltools/AgentTool/AgentTool.tsx子 Agent 调用
TaskCreateTooltools/TaskCreateTool/TaskCreateTool.ts任务创建
TaskListTooltools/TaskListTool/TaskListTool.ts任务列表
MCPTooltools/MCPTool/MCPTool.tsMCP 服务器集成
NotebookEditTooltools/NotebookEditTool/NotebookEditTool.tsJupyter 笔记本编辑

7. 钩子系统

7.1 钩子类型

// PreToolUseHooks - 工具执行前
// PostToolUseHooks - 工具执行后
// PostToolUseFailureHooks - 工具失败后

7.2 钩子执行流程

// src/services/tools/toolHooks.ts
export async function* runPreToolUseHooks(...): AsyncGenerator<
  | { type: 'message'; message: MessageUpdateLazy }
  | { type: 'hookPermissionResult'; hookPermissionResult: PermissionResult }
  | { type: 'hookUpdatedInput'; updatedInput: Record<string, unknown> }
  | { type: 'preventContinuation' }
  | { type: 'stopReason' }
  | { type: 'stop' }  // 停止执行
>

关键能力

  • 钩子可修改输入 (hookUpdatedInput)
  • 钩子可提供权限决策 (hookPermissionResult)
  • 钩子可阻止继续执行 (preventContinuation)

7.3 权限决策解析

// resolveHookPermissionDecision() 关键逻辑
if (hookPermissionResult?.behavior === 'allow') {
  // Hook 允许 ≠ 跳过 settings.json 拒绝/询问规则
  const ruleCheck = await checkRuleBasedPermissions(tool, hookInput, toolUseContext)
  if (ruleCheck === null) {
    return { decision: hookPermissionResult, input: hookInput }
  }
  // ...
}

8. MCP 工具集成

8.1 MCP 工具发现

MCP 工具通过 MCPTool 包装:

export type Tool<
  Input extends AnyObject = AnyObject,
  Output = unknown,
  P extends ToolProgressData = ToolProgressData,
> = {
  // MCP 特有
  mcpInfo?: { serverName: string; toolName: string }
  isMcp?: boolean
  // ...
}

8.2 MCP 服务器类型检测

// toolExecution.ts
function getMcpServerType(
  toolName: string,
  mcpClients: MCPServerConnection[],
): McpServerType {
  // stdio, sse, http, ws, sdk, sse-ide, ws-ide, claudeai-proxy
}

8.3 MCP 工具执行

// toolExecution.ts 中检测 MCP 工具
if (tool.isMcp) {
  // MCP 特定处理
  await addToolResult(toolOutput)
}

9. 关键设计模式

9.1 工厂模式

所有工具通过 buildTool() 工厂创建,保证一致性:

// 默认值集中定义
const TOOL_DEFAULTS = {
  isEnabled: () => true,
  isConcurrencySafe: () => false,
  isReadOnly: () => false,
  // ...
}

9.2 生成器模式

工具执行使用 AsyncGenerator 实现流式处理:

export async function* runToolUse(...): AsyncGenerator<MessageUpdateLazy, void> {
  // 流式产出进度和结果
  yield { message: createProgressMessage({ ... }) }
  yield { message: createUserMessage({ ... }) }
}

9.3 策略模式

权限检查、安全验证等使用可替换策略:

// 多种权限来源
checkPermissions()  hook  rule  classifier  canUseTool

9.4 记忆化模式

工具结果持久化状态确保提示词缓存稳定:

// 结果替换状态跨会话保持一致
ContentReplacementState = {
  seenIds: Set<string>,        // 已见 ID
  replacements: Map<string, string>  // ID → 替换文本
}

9.5 提示词缓存稳定性

工具系统多处设计确保提示词缓存稳定:

  1. 工具排序:内置工具按名称排序作为连续前缀
  2. Schema 缓存:会话级缓存防止重复渲染
  3. 内容替换状态冻结:已见结果的命运不变

10. 工具限制常量

// src/constants/toolLimits.ts
export const DEFAULT_MAX_RESULT_SIZE_CHARS = 50_000  // 单工具结果阈值
export const MAX_TOOL_RESULTS_PER_MESSAGE_CHARS = 200_000  // 消息聚合阈值
export const BYTES_PER_TOKEN = 4
export const MAX_TOOL_RESULT_TOKENS = 100_000

11. 总结

Claude Code 的工具系统是一个精心设计的复杂基础设施:

  1. 注册机制:条件编译 + 工厂模式,灵活可控
  2. 延迟加载:ToolSearch 机制优化大工具集场景
  3. 执行隔离:并发安全分区 + 流式执行 + AbortController
  4. 结果管理:多层持久化策略 + 预算控制 + 预览生成
  5. 错误处理:分类处理 + 格式化 + 钩子集成
  6. 安全模型:多层权限检查 + 沙箱隔离 + 规则匹配

系统核心在于 提示词缓存稳定性用户体验流畅性的平衡,通过状态冻结、预算分配、进度优先等机制实现。


文档更新: 2026-04-03