> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/context_engineering_guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/context_engineering_guide/di-san-bu-fen-jin-jie-ji-shu-yu-jia-gou/08_tools/8.2_tool_design.md).

# 8.2 工具定义与设计

## 8.2.1 优秀工具定义的特征

一个优秀的工具定义应该：

* **清晰明确**：模型能准确理解工具的用途
* **参数完整**：所有必要参数都有定义
* **易于使用**：参数设计简洁合理
* **文档充分**：描述和示例足够详细

## 8.2.2 工具定义结构

```jsonc
{
  "name": "search_products",
  "description": "在产品数据库中搜索商品",
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "搜索关键词"
      },
      "category": {
        "type": ["string", "null"],
        "enum": ["electronics", "clothing", "books", null],
        "description": "产品类别"
      },
      "price_max": {
        "type": ["number", "null"],
        "description": "最高价格限制"
      },
      "sort_by": {
        "type": ["string", "null"],
        "enum": ["price", "rating", "newest", null],
        "description": "排序方式；为空时由服务端使用默认排序"
      }
    },
    "required": ["query", "category", "price_max", "sort_by"],
    "additionalProperties": false
  }
}
```

生产环境应优先使用严格 JSON Schema：关闭额外字段、明确所有属性的 required 语义，并用 `null` 或显式枚举表达可选值。不同供应商对 strict mode、默认值、流式部分 JSON 和复杂 schema 关键字的支持不完全一致，工具层仍需使用成熟 JSON Schema 库做服务端校验，不能只依赖模型“按格式输出”。

## 8.2.3 设计原则

### 原则一：单一职责

每个工具只做一件事，避免功能过于复杂：

```
❌ 不好：process_order(action, ...)  # 可创建、更新、取消
✓ 好：create_order(...)、update_order(...)、cancel_order(...)
```

### 原则二：参数设计清晰

参数应该直观、类型明确：

```
❌ 不好：date="20260301"  # 字符串，格式不清
✓ 好：date="2026-03-01"  # ISO 格式，有说明
```

### 原则三：提供足够的描述

描述应该帮助模型理解何时以及如何使用：

```jsonc
{
  "name": "calculate_shipping",
  "description": "计算订单的运费。当用户询问运费或下单时需要计算运费时调用。需要提供收货地址和商品重量。"
}
```

### 原则四：合理使用枚举

受限的参数使用枚举限制：

```json
{
  "priority": {
    "type": "string",
    "enum": ["low", "medium", "high"],
    "description": "任务优先级"
  }
}
```

## 8.2.4 常见工具类型

| 类型  | 示例       | 特点       |
| --- | -------- | -------- |
| 查询类 | 搜索、获取信息  | 只读，无副作用  |
| 操作类 | 创建、更新、删除 | 有副作用，需确认 |
| 计算类 | 数学运算、转换  | 确定性输出    |
| 通信类 | 发送邮件、消息  | 外部影响     |

## 8.2.5 工具数量的权衡

工具数量影响效果和成本：

* **太少**：能力受限
* **太多**：模型选择困难、Token 开销大

建议：

* 核心场景所需工具优先
* 动态加载相关工具
* 按场景分组管理

## 8.2.6 工具分组策略

将工具按功能分组，动态加载：

```mermaid
graph TB
    A["全部工具"] --> B["通用工具组"]
    A --> C["数据查询组"]
    A --> D["订单操作组"]
    A --> E["客服工具组"]
```

图 8-2：工具分组策略

根据对话场景选择加载哪个工具组。

## 8.2.7 工具文档最佳实践

**描述模板**

```
[用途]。当[触发条件]时调用。[返回内容概述]。
```

示例：

```
获取用户的订单历史。当用户询问过去的订单或购买记录时调用。返回订单列表，包含订单号、日期、金额和状态。
```

**参数说明**

每个参数都应有清晰的描述，必要时给出示例：

```json
{
  "phone": {
    "type": "string",
    "description": "用户手机号码，格式如 13812345678"
  }
}
```

## 8.2.8 工具测试

工具定义需要测试：

1. **理解测试**：模型是否能正确理解何时调用
2. **参数测试**：参数提取是否准确
3. **边界测试**：模糊情况如何处理
4. **拒绝测试**：无关请求是否不会调用

## 8.2.9 上下文感知的工具设计

下面是一些业界常用的高级工具设计技巧，重点在于优化上下文使用效率。

### 命名空间

当智能体需要访问数十个 MCP 服务器和数百个工具时，工具功能重叠或用途模糊会导致选择困难。

命名空间策略：

* **按服务分组**：`asana_search`、`jira_search`、`github_search`
* **按资源分组**：`asana_projects_search`、`asana_users_search`

```
✓ 好：github.createPullRequest、slack.sendMessage
❌ 不好：create_pr、send_msg
```

### 响应格式优化

工具返回信息应优先考虑上下文相关性，避免低级技术标识符：

```
❌ 避免：uuid、256px_image_url、mime_type
✓ 推荐：name、image_url、file_type
```

**灵活的响应格式**

通过添加 `response_format` 参数，让智能体控制返回详细程度：

```json
{
  "response_format": {
    "type": "string",
    "enum": ["concise", "detailed"],
    "description": "concise 返回精简信息；detailed 包含完整 ID 和元数据"
  }
}
```

| 模式         | Token 消耗 | 适用场景           |
| ---------- | -------- | -------------- |
| `concise`  | 低（相对）    | 最终展示、无后续操作     |
| `detailed` | 高        | 需要 ID 进行后续工具调用 |

### 工具使用示例

JSON Schema 能定义结构有效性，但无法表达使用模式。通过提供示例，展示：

* 格式约定：日期用 `YYYY-MM-DD`，ID 用 `USR-XXXXX`
* 可选参数相关性：关键任务填写所有字段，简单任务只需核心字段
* 嵌套结构用法

```jsonc
{
  "name": "create_ticket",
  "input_schema": {...},
  "input_examples": [
    {"title": "紧急：登录页面 500 错误", "priority": "critical", "labels": ["bug"]},
    {"title": "添加暗色模式支持", "labels": ["feature-request"]},
    {"title": "更新文档"}
  ]
}
```
