基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-10-28 21:06

让智能体选对工具的描述设计方法

dev.to · AI#Agent#MCP#工具调用
Editor brief · 编辑速览

文章围绕工具名称、描述和输入结构,讲解如何明确工具用途、适用条件、限制及错误恢复方式。结合自行构造的租车案例,讨论工具职责重叠、隐含调用顺序和描述自动检查。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

Agent 调错工具,不一定是模型能力不够,也可能是工具根本没把使用条件交代清楚。原文用一个虚构的自行车租赁服务说明:工具描述是模型做决策的输入,名称、参数约束、调用顺序和错误提示,都应该按接口契约来设计。

最值得借鉴的是两件事:把容易误用的条件写进工具定义,再通过实际暴露给客户端的工具列表做自动检查。不过,提供的原文代码中途截断,测试结果也有待核对,不能把它直接当成可运行教程。

模型选工具时,看不到你的实现

在原文讨论的 MCP 工具选择流程里,宿主先获取 tools/list,模型根据工具定义选择工具、填写参数,宿主执行后再把结果交回来。模型不会通过这份定义看到背后的业务代码。

作者引用的 MCP 规范版本是 2026-07-28。工具定义包含唯一标识 name、面向人的展示名称 title、description、参数 JSON Schema inputSchema,以及可选的 outputSchema 和行为提示 annotations。其中,模型主要依赖名称、描述和参数 Schema,包括每个参数的说明。

所以,book 配上一句 Books a bike.,留下的空白远比看起来多:id 从哪里来,日期能不能写「下周一」,是否需要用户确认,失败后重试会不会重复预订?模型只能猜。

工具描述是模型执行任务时的输入,应该按接口契约维护。

原文转述 Anthropic 的建议:每个工具至少写三到四句话,并提到描述的小幅修改曾改善基准表现。但原文没有提供具体分数、模型和对照条件,我们能接受它的设计方向,不能据此推算收益。

好的定义,要把调用顺序和重试规则写出来

租车示例有两个站点 ostbahnhof、hafen,车型是 city、ebike、cargo。作者把模糊的 book 改成 rental_book_bike,让名称同时表达领域、动作和对象,也减少多个 MCP server 同时加载时的重名问题。

按文中引用的规范,名称允许 1 到 128 个字符,可使用字母、数字、下划线、连字符和点;Claude API 不允许点,因此作者推荐 snake_case。

下面的定义解决了最关键的几项歧义:预订上限、用户确认、ID 来源,以及重复请求的行为。

// Excerpt from src/server.ts: the booking tool
server.registerTool(
  'rental_book_bike',
  {
    title: 'Book rental bike',
    description:
      'Books an available rental bike for a period of up to 14 days. ' +
      'Use it only after the user has explicitly confirmed the bike and the period. ' +
      'The bikeId always comes from rental_search_bikes, never make one up. ' +
      'The same requestKey returns the same booking, so a retry never books twice.',
    inputSchema: z.object({
      bikeId: z.string().describe('ID from rental_search_bikes, e.g. "bike-hafen-01"'),
      from: isoDate.describe('First rental day, YYYY-MM-DD'),
      to: isoDate.describe('Last rental day, YYYY-MM-DD, same as or after "from"'),
      requestKey: z.string().min(8).describe('Unique key per booking request, e.g. a UUID'),
    }),
    annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
  },
  async ({ bikeId, from, to, requestKey }) => {
    // ... see step 3
  },
);

重点看 bikeId 的来源说明和 requestKey 的重试约定。前者告诉模型必须先调用 rental_search_bikes;后者约定同一个请求键返回同一笔预订,也就是幂等性。

但文字约定需要实现支撑。.min(8) 只检查字符串长度,不会验证 UUID,也不能保证请求键唯一。to 的描述要求不早于 from,这段字段定义本身也没有实现跨字段校验。

能由机器检查的约束,应继续放进 Schema:日期用 z.iso.date(),车型用 z.enum(),结果数量用整数及范围限制。搜索工具的 limit 是 1 到 20,默认 5;responseFormat 支持 concise 和 detailed,默认返回简短结果。

这种设计同时减少选择成本和上下文消耗。相比给每条 API 路由都包一个工具,作者建议合并常见工作流,避免 list_bikes、find_bikes、search_available_bikes 之间边界不清。原文引用的简短响应案例约用了详细响应三分之一的 token,但那不是这个租车服务的实测数据。

自动检查能挡住敷衍定义,挡不住业务错误

错误结果也是工具接口的一部分。原文区分两类错误:未知工具等协议错误通过 JSON-RPC 返回;输入或业务规则导致的执行错误,通过普通结果携带 isError: true,让模型获得纠正机会。

作者用这个辅助函数构造后一类结果:

// Errors the model can learn from: what is wrong, and how to do it right?
function toolError(message: string) {
  return { content: [{ type: 'text' as const, text: message }], isError: true };
}

关键是 isError: true,而具体消息还要说明下一步。示例遇到未知站点时,会列出 ostbahnhof、hafen,要求向用户确认,不让模型继续猜。没有可用车辆则返回正常的空结果说明,建议换日期或站点。

配套检查通过 InMemoryTransport.createLinkedPair() 在内存中连接服务端和客户端,再用 client.listTools() 读取工具定义。这比只检查源码字符串更贴近宿主实际接收到的内容。

检查规则包括名称格式、rental_ 前缀、描述至少三句、出现 use 或 nutze,以及每个顶层参数都有描述。有问题就设置 process.exitCode = 1,适合放进 CI。

作者称示例测试环境为 Node.js 22 或更新版本、TypeScript SDK v2,具体使用 @modelcontextprotocol/server 和 @modelcontextprotocol/client 2.4.0、Zod 4.6、TypeScript 7.0。配置文件进一步写到 Zod ^4.6.7、TypeScript ^7.0.2、tsx ^4.23.15、@types/node ^26.6.5。安装命令使用的是 zod@4,这些版本信息也应区分看待。

验证入口是 npx tsc --noEmit、npm test、npm run check:tools。作者预期四项测试通过,检查输出 2 tools checked, no findings.。

不过,检查器只能守住形式底线:出现 use 不代表使用条件写对,名称正则也不能理解哪个词是动作。原文测试还有一个具体疑点:简短定义的断言写了 5 项发现,但按所示句子拆分表达式,句点后的空字符串也可能被计入,相关逻辑需要核对。

我的判断

我赞成把描述、Schema 和错误反馈一起设计。单独润色一段介绍,解决不了参数非法、调用顺序错误和重复写入。相较于只在系统提示词里解释业务规则,把规则放到相应工具旁边,更方便维护和审查。

但这篇提供的是设计经验和示例测试,没有给出完整的 Agent 任务成功率对照。三到四句话是写作建议,不是稳定性的保证;工具合并到什么程度,也要看任务边界,不能只追求数量少。

annotations 同样不能承担安全保证。readOnlyHint、destructiveHint、idempotentHint、openWorldHint 都是提示。写上 idempotentHint: true,不会自动获得幂等实现;要求用户确认,也不等于服务端已经强制验证授权。

提供的原文在预订处理函数中途截断,结尾关于测试发现错误的叙述也未完成。因此,14 天限制、完整时段冲突检查等逻辑无法核实。可见的存储实现使用内存 Map,搜索也只检查某一天,尚不足以支撑生产环境的并发预订。

它适合拿来审视工具契约,完整可运行性仍需自行验证。

能拿来做什么

  • 给现有 Node MCP 工具做一次定义审查,逐个补齐用途、使用条件、限制和参数来源,优先处理写入类工具。
  • 用 Zod 固化日期、枚举和数量范围,再给参数补上示例;跨字段关系与业务规则另外验证,避免文字承诺超过实际约束。
  • 在 CI 中读取真实工具列表检查基础质量,同时为错误恢复和重复请求保留行为测试,别把句数达标当成验收完成。
  • 调查 AI 编程中的误调用时,先看模型收到的工具定义和错误结果,确认它是否获得了正确 ID、调用前提与修复路径。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
拆解 Claude Code 日志中的上下文成本
下一篇
让业务AI的操作权限受用户身份约束

资讯速览

dev.to · AI · 2026-10-28 21:06

AI 评分 8.0 / 10

相关标签

#Agent#MCP#工具调用

继续阅读

  • 用工作树隔离多个 Claude Code 会话
  • 拆解 Claude Code 日志中的上下文成本
  • 让业务AI的操作权限受用户身份约束
  • 邮件 Agent 防注入:提示词加固为何失效
  • 模型方向消除实现:测试覆盖与运行边界