用一个订单查询示例,讲清 Tool Description、Schema 和 Example

一个工具的 description 如果只写“查询订单信息”,模型仍然需要猜:输入的是订单 ID 还是支付交易号?能按姓名搜索吗?未找到是否代表不存在?

我会把工具定义分成三个部分:description 写使用语义,schema 写参数结构,example 展示实际怎么填。 下面用同一个订单查询工具,直接对比 OpenAI 与 Anthropic 的格式。

本文依据截至 2026 年 9 月 15 日核对的官方文档。工具是自拟示例,假设服务端已经实现相应的查询范围与返回行为,不代表平台内置能力。

1. Description 建议按什么格式写?

没有强制模板,建议按以下顺序组织:

做什么 → 什么时候用 → 不支持什么 → 返回什么 → 副作用与异常含义。

例如:

按订单 ID 查询当前状态,适用于用户询问指定订单的处理进度。仅支持精确 ID 查询,不支持按姓名搜索,也不会取消订单。成功返回订单状态和更新时间。查询范围限于当前身份可访问的订单,未找到不能直接解释为订单不存在。

每句话都在帮助模型决策:查询方式说明怎么用,适用范围帮助选择工具,“不会取消”避免误报操作完成,返回内容说明能回答什么,查询限制避免错误推断。

OpenAI 建议解释用途、参数格式和输出含义;Anthropic 也强调适用场景和限制,并建议至少使用三到四句话描述工具。这是写作建议,不是 API 要求的固定句式。OpenAI:Function callingAnthropic:Define tools

2. OpenAI 的工具格式:以 Responses API 为例

下面是放入请求 tools 数组中的一个工具定义,不是完整 API 请求:

{
  "type": "function",
  "name": "get_order_status",
  "description": "按订单 ID 查询当前状态,适用于用户询问指定订单的处理进度。仅支持精确 ID 查询,不支持按姓名搜索,也不会取消订单。成功返回订单状态和更新时间。查询范围限于当前身份可访问的订单,未找到不能直接解释为订单不存在。",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "用户或先前工具提供的订单 ID,例如 ord_123;不是支付交易号,不要自行编造。"
      }
    },
    "required": ["order_id"],
    "additionalProperties": false
  },
  "strict": true
}

这里有两个 description:工具级解释“何时调用、会发生什么”,参数级解释“字段怎么填、值从哪里来”。类型正确不代表业务含义正确,所以两者都需要。

strict 约束参数结构,不能保证订单真实存在,也不会自动实现权限检查。服务端仍然要校验身份和业务条件。OpenAI:Strict mode

OpenAI 自己的两种 API 外形也有区别:Responses 的函数定义平铺;Chat Completions 则在外层 type: function 下,用 function 对象包住名称、描述、parameters 和 strict。 不要把两种外形混用。

3. Anthropic 的工具格式:input_schema 与 input_examples

同一个工具可以这样定义:

{
  "name": "get_order_status",
  "description": "按订单 ID 查询当前状态,适用于用户询问指定订单的处理进度。仅支持精确 ID 查询,不支持按姓名搜索,也不会取消订单。成功返回订单状态和更新时间。查询范围限于当前身份可访问的订单,未找到不能直接解释为订单不存在。",
  "input_schema": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "用户或先前工具提供的订单 ID;不是支付交易号,不要自行编造。"
      }
    },
    "required": ["order_id"],
    "additionalProperties": false
  },
  "input_examples": [
    { "order_id": "ord_123" }
  ]
}

重点有两个:输入结构叫 input_schema,不是 OpenAI 的 parametersinput_examples 与 input_schema 同级,不在里面

Anthropic 会将这些完整输入示例与 schema 一起提供给模型。示例本身必须符合 input_schema,不合法会返回 400 错误。示例校验不等于启用严格工具调用,也不会把后续输入限定为这些示例。Anthropic:Providing tool use examples

4. 在 Schema 里面加 examples,有什么不同?

下面只是一个 JSON Schema 字段片段:

{
  "type": "string",
  "description": "订单系统分配的订单 ID。",
  "examples": ["ord_123", "ord_456"]
}

它和 Anthropic 的 input_examples 是不同机制:

写法 表达什么 是否约束实际输入
description 中写“例如 ord_123” 自然语言说明取值 不约束
schema 内的 examples 标准示例注解;字段级展示字段,根级可展示完整对象 不约束
Anthropic 工具级 input_examples 平台支持的完整输入示例,平台检查示例是否合法 不把输入限制为示例
schema 内的 enum 允许值集合 约束

例如 examples: ["ord_123", "ord_456"] 表示“可以参考这样的值”;换成 enum: ["ord_123", "ord_456"] 则表示“只允许这两个值”。需要查询任意合法订单时,不能把示例误写成枚举。

JSON Schema 的标准示例关键字是复数 examples。单数 example 可能来自其他规范或框架,不能默认等价。示例是注解,不参与输入合法性校验。JSON Schema:Annotations

还要区分标准和平台支持:JSON Schema 支持某个注解,不代表每家模型 API 都接受、保留或同样利用它。 尤其在严格模式下,需要核对目标 API 支持的 schema 子集,不能直接塞入任意关键字。

5. 实际开发中怎么选?

  1. 简单参数先写清描述。 例如订单 ID 的来源及其与支付交易号的区别,必要时附一个值的例子。
  2. 复杂组合提供完整示例。 对嵌套对象、可选字段和格式敏感参数,Anthropic 可用 input_examples 展示字段组合。
  3. 迁移时适配平台格式。 OpenAI 不要照搬 input_examples,可以在描述或提示中提供必要示例,再评测效果。
  4. 合法性要求用结构和代码表达。 类型、必填项、枚举和服务端校验不能由示例替代。
  5. 用真实任务检查效果。 观察工具是否选对、参数是否正确、结果是否解释准确,不按示例数量判断质量。

对这个订单工具,至少检查三种请求:“查询 ord_123 的状态”应原样使用该 ID;“查张三的订单”不应编造 ID;“帮我取消订单”不能把查询成功报告成取消完成。

Anthropic 的工具工程文章也建议通过任务评测和实际调用记录迭代工具,而不是只听模型自评。Anthropic:Writing tools for agents

description 消除语义歧义,schema 表达输入约束,example 展示填写方式。它们共同帮助模型用对工具,真实的权限与业务正确性仍由服务端和验证结果保证。