Tool System
Abstract
Tool System 是 Coding Agent 与外部世界交互的接口:读文件、搜代码、执行命令、修改文件、访问外部上下文,都要通过工具完成。
- Codex CLI 更偏向 少量通用工具,尤其依赖 shell 和 patch 能力
- Claude Code 更偏向 专用工具体系,把搜索、读取、编辑、执行、权限确认等能力拆成更明确的工具边界
Codex
Codex 的工具系统体现了它的核心哲学:与其为每种任务都设计一个专用工具,不如给模型一个强大的 shell,再用沙箱和审批系统约束风险。
强 shell,少专用工具
Codex 默认相信模型能有效使用 shell:搜代码直接跑 rg,找文件用 find 或 rg --files,多步任务则靠管道、重定向和脚本串联。
工具面因此保持精简,也能复用模型在终端操作上的训练经验;代价是输出更原始、执行权限更强,且依赖本机是否安装了相应工具。
Tool Definition
Codex 的工具由 Rust 侧的 runtime / handler 负责实现。当前仓库中,通用执行契约主要体现在 ToolExecutor,而 core 层会在其上叠加 hook、telemetry、tool search、参数 diff 等运行时能力。
#[async_trait]
pub trait ToolExecutor: Send + Sync {
fn tool_name(&self) -> ToolName;
fn spec(&self) -> ToolSpec;
fn exposure(&self) -> ToolExposure {
ToolExposure::Direct
}
fn supports_parallel_tool_calls(&self) -> bool {
false
}
async fn handle(
&self,
invocation: Invocation,
) -> Result<Box<dyn ToolOutput>, FunctionCallError>;
}
关键设计
Tool runtime 不只是“执行函数”。它还要提供模型可见的工具 spec,声明工具暴露方式,并把执行结果转成模型可理解的输出。core 层再负责把这些工具接入审批、沙箱、hook 和事件系统。
内置工具
Codex 的公开仓库中可以看到多类工具 handler。具体文件名可能随版本调整,但整体可以分成以下几类:
| 类别 | 代表能力 | 作用 |
|---|---|---|
| Shell / Exec | shell、unified_exec |
执行命令,是最主要的工具 |
| File Mutation | apply_patch |
使用 patch / diff 方式修改文件 |
| Inspection | list_dir、view_image |
查看目录、图片等本地资源 |
| Planning / UX | plan、request_user_input |
维护计划、向用户请求输入 |
| Permission | request_permissions |
在运行中请求权限变更 |
| MCP | mcp、mcp_resource |
调用 MCP 工具或读取 MCP 资源 |
| Multi-agent | agent_jobs、multi_agents |
派发子任务或协调多个 agent |
| Dynamic Tools | dynamic、tool_search、tool_suggest |
动态注册、搜索或推荐可用工具 |
执行流程
模型生成工具调用(结构化 JSON)
↓
解析参数
↓
执行 pre-tool-use hooks
↓
权限 / 审批检查
↓
应用沙箱策略
↓
调用对应 ToolExecutor / runtime
↓
执行 post-tool-use hooks
↓
将结构化结果返回给模型
Tool Orchestrator
ToolOrchestrator 负责把模型产生的工具调用接到实际 handler 上,并处理审批、沙箱选择、执行错误和结果回填等流程。
边界
可以把 orchestrator 理解为工具调用的调度层:它不负责“决定模型下一步该做什么”,而是负责“当模型已经决定调用工具时,如何安全、可控地执行这个工具”。
代码位置
- Tool handlers:
codex-rs/core/src/tools/handlers/ - Tool registry / router:
codex-rs/core/src/tools/registry.rs - Tool orchestration:
codex-rs/core/src/tools/orchestrator.rs - Tool executor:
codex-rs/tools/src/tool_executor.rs - Tool definition:
codex-rs/tools/src/tool_definition.rs
Claude Code
Claude Code 的工具系统体现了另一种哲学:把常见开发任务拆成更明确的专用工具,并为每类工具配置输入校验、权限判断和输出格式。
多专用工具,明确边界
Claude Code 更倾向于让每类任务走专门工具,而不是把一切交给 shell:搜索用搜索工具,读写文件用文件工具,只有需要执行命令时才进入 Bash 等执行工具。
这样系统更容易优化输出、控制权限、约束副作用,也能把工具结果做成对模型更友好的结构;代价是工具系统更复杂,需要维护更多 schema、权限逻辑和使用说明。
Tool Definition
从设计上看,Claude Code 的工具更像带 schema 的 TypeScript 对象:每个工具都有名称、描述、输入 schema、执行函数、权限判断和输出格式化逻辑。由于 Claude Code 闭源,下面是概念模型,不代表稳定的官方源码接口。
type Tool = {
name: string
description: string | (() => string)
inputSchema: Schema
execute: (input, context) => Promise<Result>
checkPermissions?: (input, context) => PermissionDecision
isConcurrencySafe?: boolean
getPath?: (input) => string
}
关键设计
专用工具的价值在于边界明确:搜索工具只负责搜索,文件编辑工具只负责编辑,命令工具只负责执行命令。每个工具都可以拥有自己的参数校验、权限策略和结果格式。
内置工具类型
| 类别 | 代表能力 | 作用 |
|---|---|---|
| File Ops | 读取文件、写文件、编辑文件、列目录 | 管理代码库内容 |
| Search | 文件 glob、文本 grep、Web 搜索、Web 获取 | 搜索本地或外部信息 |
| Execution | Bash、PowerShell 等命令执行 | 执行脚本、测试、构建命令 |
| Agents | 子 agent / task 工具 | 把复杂任务拆给子 agent |
| Planning | 计划模式、任务列表 | 管理多步骤任务 |
| Code Intel | 语言服务、定义跳转、引用查找 | 提供代码理解能力 |
| Notebook | Notebook 编辑 | 面向 notebook 场景 |
| User / Permission | 向用户提问、请求确认 | 接入人类反馈和审批 |
| MCP / Skills | 外部工具、技能和上下文扩展 | 扩展 Agent 能力边界 |
执行流程
模型在响应中生成工具调用
↓
从 assistant 消息中提取工具请求
↓
对每个工具调用:
├── 根据 schema 校验输入
├── 检查权限
│ ├── 可自动允许
│ ├── 需要用户确认
│ └── 直接拒绝
├── 执行工具
└── 格式化工具结果
↓
将工具结果追加到对话
↓
继续 Agent Loop
对比
| 维度 | Codex CLI | Claude Code |
|---|---|---|
| 工具数量 | 少量核心工具 + 动态 / MCP 扩展 | 多个面向任务的专用工具 |
| 主要工具 | shell + apply_patch |
搜索、读取、编辑、执行等专用工具 |
| 搜索 | 模型通过 shell 调用 rg、find 等 |
使用专门的搜索 / glob 工具 |
| 文件编辑 | 以 patch / diff 修改为主 | 以文件编辑工具处理替换、写入等操作 |
| Schema | 工具 spec / JSON schema | 工具 schema / 参数校验 |
| 权限 | 统一审批、沙箱和工具 handler 协作 | 更强调每个工具自己的权限边界 |
| 动态扩展 | MCP、动态工具 | MCP、skills、外部集成 |
| 输出格式 | 更接近真实命令输出 | 更容易做结构化、截断和 token 优化 |
Tool Schema Delivery
工具定义最终都要传给模型,否则模型不知道有哪些工具可用、参数是什么、什么时候应该调用。
- Codex CLI:工具 schema 主要作为 API 请求中的 tool definitions 提供给模型;系统提示词更多描述通用行为,具体参数和工具说明由 schema 承载。
- Claude Code:工具 schema 同样会进入模型可见的工具定义,但专用工具通常还会有更细的使用说明、权限约束和场景提示。
Tradeoffs
Codex 的少量强工具路线
- 系统更简单,工具面更小
- shell 灵活性高,可以组合管道、脚本和本地工具
- 更适合熟悉终端工作流的开发任务
- 依赖本机命令是否可用,例如
rg、git、构建工具等 - 原始 shell 输出可能更长,需要模型自己筛选重点
Claude Code 的多专用工具路线
- 每个工具边界清晰,权限和副作用更容易解释
- 输出可以按工具优化,例如路径缩短、分页、截断、结构化结果
- 对常见任务更稳定,不完全依赖模型自己拼 shell 命令
- 系统复杂度更高,需要维护更多工具、schema 和权限规则
- 固定工具接口可能限制某些灵活的 shell 组合方式
小结
工具系统决定了 Coding Agent 的行动方式。
Codex 的思路是:给模型一个强 shell,再用沙箱和审批管住边界。Claude Code 的思路是:把行动拆成更多专用工具,并在每个工具边界上做校验、权限和格式控制。
这两种设计没有绝对优劣。前者更像系统工程,后者更像产品工程;前者更灵活,后者更可控。