第5章:工具调度算法

“When a tool is called, the real challenge isn’t executing it — it’s everything that happens before and after.” 5.1 问题引入 当LLM生成一段包含 tool_use 块的响应——例如"我需要读取文件 src/main.ts"——系统面临一连串精密的调度决策: 工具发现:从40余个注册工具中,根据名称(或别名)精确定位到 FileReadTool; 输入验证:用 Zod Schema 验证 LLM 生成的参数是否合法——模型并不总能生成正确的类型; 权限裁决:经过 PreToolUse Hook → 规则匹配 → 分类器 → 用户交互 的多级权限链,决定是否允许执行; 并发编排:如果 LLM 同时请求了5次文件读取和1次写入,系统需要判断哪些可以并行、哪些必须串行; 流式执行:工具在执行过程中通过 AsyncGenerator 逐步报告进度,而非等到完成才返回; 结果注入:将工具执行结果编排为 tool_result 消息,按正确顺序注入回消息流,形成下一轮对话的上下文; 推测执行:在用户还未确认提示建议时,系统就在后台预执行可能的工具调用,以减少端到端延迟。 这不是一个简单的"查表→调用→返回"的过程。它是一个涉及并发控制、流式处理、权限安全、容错回退的完整调度系统。本章将逐一拆解这些算法。 5.2 工具注册与发现算法 5.2.1 注册表的构建 Claude Code 的工具注册采用静态声明 + 动态过滤的两阶段模型。所有工具在 src/tools.ts 中被集中声明,形成一个"全量工具池": 源码位置:src/tools.ts — getAllBaseTools() function getAllBaseTools() -> Tool[]: baseTools = [ AgentTool, BashTool, FileReadTool, FileEditTool, FileWriteTool, GlobTool, GrepTool, WebFetchTool, WebSearchTool, NotebookEditTool, ... ] // 特性门控:根据环境变量和 feature flag 动态注入 if feature('AGENT_TRIGGERS'): baseTools.append(CronCreateTool, CronDeleteTool, CronListTool) if isWorktreeModeEnabled(): baseTools.append(EnterWorktreeTool, ExitWorktreeTool) if isToolSearchEnabledOptimistic(): baseTools.append(ToolSearchTool) // ... 更多条件注入 return baseTools 关键设计决策有三个: ...

June 9, 2026