关于 Claude Code工具列表的构建机制及调用优先级问题。
大模型本身并不直接感知“官方”、"MCP"、"Skills"或"Workflow"这些分类标签,它看到的只是一个统一的 tools JSON 数组。
以下是详细的架构解析、注入方式及优先级逻辑:
一、工具是如何写入 tools 列表提示词中的?
在 API 请求层面,所有工具最终都会被标准化为 Anthropic Tool Use 的 JSON Schema 格式。客户端(如 Claude Code CLI)负责在发送请求给模型前,将不同来源的工具“组装”成一个列表。
1. 17 个官方工具 (Built-in Tools)
- 来源:硬编码在 Claude Code 客户端或 SDK 中。
-
注入方式:客户端在初始化时,会将这些工具的定义(Name, Description, Input Schema)直接放入
tools数组。 -
特点:这些工具通常拥有最高权限(如
bash,edit,write),其描述(Description)经过高度优化,以确保模型能准确理解其副作用。 -
示例结构:
{ "name": "bash", "description": "Execute a bash command...", "input_schema": { ... } }
2. 自定义 MCP 工具 (Model Context Protocol)
- 来源:通过 MCP Server 动态提供。
-
注入方式:
- 客户端启动时连接配置的 MCP Server。
- 调用
tools/list接口获取 MCP 工具列表。 - 客户端将 MCP 返回的工具定义转换为 Anthropic 兼容的 JSON Schema。
- 追加到官方工具列表之后(或之前,取决于客户端实现,通常是追加)。
-
关键点:对模型而言,MCP 工具和官方工具在
tools列表中地位平等,区别仅在于description的内容。
3. Skills (技能)
-
定义歧义:在 Anthropic 原生 API 中并没有 "Skills" 这个原生对象。通常有两种实现方式:
-
系统提示词 (System Prompt):将“技能”作为行为准则写入 System Message(例如:“你是一个 Python 专家,擅长数据清洗”)。这不进入
tools列表,但影响工具选择。 -
封装为工具:将复杂的技能封装为一个 Tool(例如
run_data_analysis_skill),内部可能触发工作流。
-
系统提示词 (System Prompt):将“技能”作为行为准则写入 System Message(例如:“你是一个 Python 专家,擅长数据清洗”)。这不进入
-
注入方式:如果是工具化技能,则像 MCP 工具一样注入
tools列表;如果是提示词技能,则写入system参数。
Sill的desscription完整内容:
4. Workflows (工作流)
- 定义:工作流通常是多步工具调用的编排逻辑,而不是单个原子工具。
-
注入方式:
-
原子化暴露:将整个工作流暴露为一个工具(例如
deploy_app_workflow),模型调用该工具后,由客户端执行后续一系列操作。 - Prompt 指导:在 System Prompt 中定义工作流步骤(“第一步调用 A,第二步调用 B"),模型自主按顺序调用工具。
-
原子化暴露:将整个工作流暴露为一个工具(例如
- 在 Tools 列表中:通常以“复合工具”的形式存在,或者根本不在 Tools 列表中,而是由客户端逻辑控制。
组装后的最终 tools 列表示例
模型收到的 tools 参数是一个扁平的 JSON 数组:
"tools": [
// 1. 官方工具 (通常排在前面)
{ "name": "bash", "description": "...", "input_schema": {...} },
{ "name": "edit", "description": "...", "input_schema": {...} },
// ... 其他官方工具
// 2. MCP 工具 (动态追加)
{ "name": "query_database", "description": "Query the production DB via MCP...", "input_schema": {...} },
// 3. 技能
{ "name": "skills", "description": "available skills: -skill1:skill1 desc -skill2:skill2 desc ...", "input_schema": {...} }
// 4. 工作流封装的工具
{ "name": "run_code_review_skill", "description": "Perform a deep code review...", "input_schema": {...} }
]
二、大模型有调用优先级吗?
简短回答:没有硬性的代码级优先级,但有基于概率和提示词的“软优先级”。
模型是概率生成的,它不会像代码里的 if-else 那样优先执行列表第一个工具。优先级的体现主要依赖以下三个因素:
1. 描述(Description)的语义匹配度 (最重要)
-
机制:模型会根据用户的 Prompt 意图,去匹配
tools列表中哪个工具的description最符合当前需求。 -
影响:如果官方工具
bash的描述是“运行命令”,而 MCP 工具safe_run的描述是“安全地运行命令(推荐)”,当用户说“安全运行”时,模型会优先选safe_run。 - 优化:在 MCP 工具的 description 中明确写出适用场景(例如:“当需要访问数据库时,优先使用此工具而不是 bash")。
2. 系统提示词 (System Prompt) 的指令
- 机制:这是控制优先级的核心手段。你可以在 System Prompt 中显式规定优先级。
-
示例:
"You have access to multiple tools. When modifying files, always prefer the 'edit' tool over 'write' to preserve context. When accessing data, prioritize MCP tools over bash scripts."
- 效果:这会给模型施加强烈的注意力偏向, effectively 实现优先级控制。
3. 工具列表的顺序 (Ordering)
- 机制:虽然 Anthropic 未官方文档化顺序对注意力的影响,但在 Transformer 架构中,列表靠前的内容有时在 Context 中拥有微弱的注意力优势(Recency/Primacy Effect)。
-
实践:Claude Code 客户端通常将官方核心工具(如
edit,read)放在列表前面,将扩展 MCP 工具放在后面。这暗示模型优先使用核心能力,除非任务明确需要扩展能力。
4. 客户端过滤 (Client-Side Filtering)
- 机制:真正的“硬优先级”往往发生在请求发送之前。
-
逻辑:聪明的客户端(如 Claude Code)会根据当前上下文,动态隐藏不相关的工具。
- 例如:如果当前不在代码目录,可能暂时不注入
git相关工具。 - 例如:如果检测到敏感操作,可能暂时禁用
bash中的rm -rf参数(通过 Schema 限制)。
- 例如:如果当前不在代码目录,可能暂时不注入
- 结果:模型根本看不到低优先级的工具,从而被迫选择高优先级工具。
三、总结与最佳实践
如果你正在开发基于 Claude 的 Agent 或配置 MCP 工具,想要控制工具调用优先级,请遵循以下策略:
| 控制维度 | 操作方法 | 优先级影响 |
|---|---|---|
| System Prompt | 明确写出“优先使用 X 工具”、“仅在 X 不可用时使用 Y"。 | ⭐⭐⭐⭐⭐ (最高) |
| 工具描述 | 在 Description 中强调场景(“这是处理 SQL 的首选工具”)。 | ⭐⭐⭐⭐ |
| 工具命名 | 使用语义清晰的名称(safe_delete vs delete)。 |
⭐⭐⭐ |
| 列表顺序 | 将高频、核心工具放在 tools 数组的前部。 |
⭐⭐ (微弱) |
| 动态过滤 | 在客户端代码中,根据上下文移除不需要的工具。 | ⭐⭐⭐⭐⭐ (硬性控制) |
关于 Skills 和 Workflows 的特别建议:
不要试图让模型去“理解”什么是 Skill 或 Workflow。将它们工具化。
- ❌ 错误:在 Prompt 里说“你有代码审查技能”。
- ✅ 正确:定义一个
code_review工具,描述为“执行标准的代码审查工作流”,让模型调用它。
通过这种方式,无论底层是官方工具、MCP 还是自定义逻辑,对模型来说都是平等的“能力选项”,而你通过 System Prompt 和 Description 来引导它的选择。







网友评论