工具的描述和参数怎么写,模型才能选对工具?

进阶高频实践约 7 分钟读完

一句话回答

模型只能通过名称、描述和参数 Schema 认识一个工具,这几段文字本质上就是写给模型的 Prompt。名称要见名知意;描述要写清做什么、什么时候用、什么时候不该用、返回什么;参数用 JSON Schema 的 enum、必填、取值范围来约束,格式和默认值在描述里再说明一遍。另外要避免功能重叠的工具,返回值只保留模型需要的字段。

详细解析

模型是怎么"看到"工具的

每次请求,工具定义都会和对话一起发给模型。选哪个工具、参数怎么填,模型全靠这些文字判断,它看不到你的代码。写工具定义就像给一位新同事写接口文档:他没读过源码,只能读文档。

部分 要写清楚什么 常见问题
名称 动词加对象,如 search_orders、cancel_order,同一组工具风格统一 query、handle 这类看不出用途的名字
描述 做什么、适用场景、不适用场景(以及该改用哪个工具)、返回什么、有什么限制 只有一句"查询订单",没有边界
参数 类型、是否必填、取值范围、格式、默认值、单位 全是不带说明的 string,格式靠模型猜
返回值 精简的字段、字段含义、是否被截断 原样返回几百个字段的接口响应

描述要平实、准确,和工具的真实行为一致,不要靠"必须""一定要"这类强硬措辞催模型调用。Anthropic 在自家模型的提示词建议里提到,有的模型对指令更敏感,为防止漏调而写的强硬措辞反而会让它在不需要时也去调用,改成"在……时使用"这样的平实说法即可;其他模型是否如此,要用评测验证。各家接口对工具名的字符和长度有限制,只用字母、数字、下划线和连字符最稳妥。

参数怎么约束

  • 能枚举就用 enum:订单状态、排序方式这类固定取值,不要让模型自由发挥
  • 分清必填和可选:真正必需的才放进 required,可选参数在描述里说明不传时的行为
  • 格式写进描述:format: "date" 这类关键字不是每个平台都会遵守,描述里再写一句"格式 YYYY-MM-DD"更稳妥
  • 默认值在代码里兜底:JSON Schema 的 default 只是说明,模型可能不传,执行时要自己补上
  • 写明单位和时区:金额是元还是分,时间按哪个时区
  • 少用深层嵌套:层级越深,模型越容易填错

避免功能重叠

同时有 search_orders 和 query_orders,或者三个只差一个查询条件的工具,模型只能靠猜。两种处理方式:

  • 合并成一个工具,用参数区分,比如 find_user 加一个取值为 email、phone 的 by 参数
  • 确实要分开时,在各自的描述里写清分工:"已知订单号用 get_order,按条件筛选用 search_orders"

返回值也要设计

工具结果会进入上下文,直接影响模型的下一步:

  • 只返回完成任务需要的字段,内部 ID、调试信息不要带
  • 把状态码转成可读的值,比如把 status: 3 转成"已发货"
  • 结果太多时截断,并说明总数和翻页方式:"共 230 条,只返回前 20 条,可传 page 参数翻页"
  • 出错时返回能指导修正的信息,见 工具调用出错了怎么处理

代码示例

同一个工具,写得差和写得好的对比(通用格式,各家 SDK 外层的字段名不同):

JSON
{
  "name": "orders",
  "description": "查询订单",
  "parameters": {
    "type": "object",
    "properties": {
      "q": { "type": "string" },
      "status": { "type": "string" },
      "date": { "type": "string" }
    }
  }
}

名称看不出动作,描述没有边界,参数没有说明:status 能填什么、date 是什么格式全靠猜,返回什么也没写。

JSON
{
  "name": "search_orders",
  "description": "按条件筛选当前登录用户的订单,返回订单号、商品名、金额(元)、状态和下单时间,按时间倒序,最多 20 条。用户问\"我的订单\"\"最近买了什么\"时使用。已知订单号时改用 get_order。",
  "parameters": {
    "type": "object",
    "properties": {
      "keyword": { "type": "string", "description": "商品名关键词,如\"耳机\"。可选" },
      "status": {
        "type": "string",
        "enum": ["unpaid", "paid", "shipped", "completed", "refunded"],
        "description": "订单状态。可选,不传表示全部状态"
      },
      "since": { "type": "string", "description": "起始日期,格式 YYYY-MM-DD。可选,不传表示最近 30 天" }
    }
  }
}

参数里没有 userId:工具只查当前登录用户的订单,身份由服务端从登录态获取,模型没法指定别人。

面试官可能追问

工具描述写多长合适?

以讲清"做什么、什么时候用、什么时候不该用、返回什么、有什么限制"为准,通常是几句话到一小段,实践中更常见的问题是写得太简略。但工具定义每次请求都会发送,工具一多,占用的上下文就很可观,见 工具太多时怎么办。参数说明里给一个示例值,往往比一大段解释更有效。

在 Schema 里写了约束,模型就一定会遵守吗?

不一定。普通模式下 Schema 只是给模型的提示,模型仍可能漏填、填错类型或编造取值。部分平台提供严格模式,用约束解码保证参数符合 Schema,但通常只支持 JSON Schema 的一个子集,以各平台文档为准。无论哪种模式,执行前都要在服务端再校验一次。

参数应该让模型填 ID 还是名称?

模型不知道系统内部的 ID,硬要它填,它可能编一个格式看起来正确的值。两种做法:提供查询工具,让模型先查到 ID 再用;或者让工具接收用户说得出来的标识(订单号、商品名),在服务端解析成内部 ID。用户身份这类参数不要交给模型,从登录态获取,见 工具调用的权限和安全。

怎么判断工具定义写得好不好?

用数据判断。准备一批真实的用户问题,标注期望调用的工具和参数,统计模型选对工具、填对参数的比例,同时检查"不需要工具时有没有乱调用"。再逐条看错误样本,针对性地改名称和描述,改完重跑对比。

易错点

  • 描述只有一句话,没写"什么时候不该用",相似的工具互相抢调用
  • 默认值只写在 Schema 的 default 里,执行代码没处理模型不传参数的情况
  • 把下游接口的完整响应原样返回,大量无关字段淹没了关键信息

AI 模拟面试官

用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮

登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录

这道题你掌握了吗?

选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。

学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。