# 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": "更新文档"}
  ]
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET 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?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
