Function Calling 调用工具总出错?问题多半在这份 schema 里

文章来源声明: 原文作者:用户570846257440; 来源站点:掘金; 原文链接:https://juejin.cn/post/7692065346282913832; 本文基于上述来源整理/加工,觅优补充点评,仅供技术学习交流。版权归原作者所有。
觅优短评

把工具调用失败归因到 schema 和执行层,是排查 Agent 问题最高效的切入点。适合正在写工具描述、调试 Function Calling,或纠结要不要引入 MCP 的工程师。

上周排查一个 Agent 的问题,现象很怪:模型明明「调用」了工具,但传回来的参数永远差一个字段,重试三次全是同一个错。查到最后发现,问题不在模型,在我给它的工具描述里——那个字段压根没写进 `parameters`。

这件事让我把「Function Calling」这条链路重新捋了一遍。这篇从工程角度讲清楚:模型到底怎么决定调用哪个工具、参数是怎么来的、以及为什么你写的 schema 决定了它的成功率。

一、先纠正一个常见误解

很多人以为「AI 会调工具」= 模型自己去执行了函数。不是的。

模型做的唯一一件事,是根据上下文输出一段结构化文本,表示「我要调用 X,参数是 Y」。真正执行 X(Y) 的,是你的代码。

所以一条完整的调用链是:

用户问题 + 工具清单  ->  模型输出 tool_call 意图
                     ->  你的程序执行对应函数
                     ->  把执行结果回传给模型
                     ->  模型生成最终回答

模型是「决策层」,你的代码是「执行层」。分清楚这一点,后面所有排查都有方向:调用失败,先看执行层收到了什么,再看模型为什么这么给。

二、工具清单就是一份 JSON Schema

各家 API 的字段名略有差异,但结构是通的。一个工具长这样:

{
  "name": "search_article",
  "description": "在本平台已发布文章里按关键词检索,返回标题与链接",
  "parameters": {
    "type": "object",
    "properties": {
      "keyword": { "type": "string", "description": "检索关键词" },
      "limit":   { "type": "integer", "description": "返回条数,默认 5" }
    },
    "required": ["keyword"]
  }
}

注意 description 出现在两个层级:工具级和参数级。这两层描述,就是模型填参数的唯一依据。

三、参数填错,八成是 schema 的锅

我踩过的坑,基本都能归到这几类:

  1. required 漏标。模型不知道哪些必填,于是有时传有时不传,你的函数就收到 undefined。
  2. 参数级 description 缺失。模型只能靠参数名猜语义,limit 猜成「页码」也不奇怪。
  3. 类型不写。本该是整数,模型传了 "5",服务端校验直接 400。
  4. 工具级 description 太泛。两个工具都写「查询数据」,模型就随机挑一个。

第 4 条尤其隐蔽:出错时你以为是模型笨,其实是你给了两个它分不清的选项。

四、失败信息要原样回传

工具执行出错时,别只回一个 "error"。把真实原因带上:

Tool error: missing required property 'keyword'. 
Fix: provide the 'keyword' string argument.

模型看到具体缺什么、怎么改,才会换参数重试;只给一个 error,它大概率原地重试同一个调用,然后触发你的重试上限。

顺带加两层保护:参数校验(schema 之外再校一次类型和边界)和单轮调用次数上限(防止模型在失败里打转)。

五、MCP 解决的是另一个问题

上面这套是「模型怎么表达调用意图」。但工程上还有一层麻烦:同一个工具,想让它在不同客户端里都能用,每个客户端都得适配一遍。

MCP(Model Context Protocol)就是来标准化这一层的:工具方写一个 Server 声明能力,任何支持 MCP 的客户端都能自动发现并调用,换模型、换客户端,工具侧不用重写。

它和 Function Calling 不是二选一——MCP 管「工具从哪来、怎么被发现」,Function Calling 管「模型怎么把调用意图表达出来」。实际链路是:

MCP Server 暴露工具
   -> 客户端转成 Function Calling 所需的 schema
   -> 模型输出调用意图
   -> 客户端执行并回传

六、什么时候不用上 MCP

只有一个客户端、工具三五个、也不会换模型——直接用 Function Calling 就够了,多一层协议只是多一层维护。

值得上 MCP 的信号:工具要跨团队复用,或者你希望换模型时工具侧零改动。

小结(自查用)

  • 工具级 description:说清「什么场景用、什么场景别用」
  • 参数级 description + required + 类型:一个都不能省
  • 失败时把真实原因回传,别只给 error
  • 有参数校验,有单轮调用上限
  • 工具清单别堆相似项,模型会选错

一句话:模型负责决策,你负责执行和兜底。 把这两件事分清,工具调用的问题基本都能定位到具体那一层。


作者:信可维 · AI 实战。记录能跑通的方案。