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

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

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

一、先纠正一个常见误解

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

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

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

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

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

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

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

json 复制代码
{
  "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"。把真实原因带上:

vbnet 复制代码
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 管「模型怎么把调用意图表达出来」。实际链路是:

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

六、什么时候不用上 MCP

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

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

小结(自查用)

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

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


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

相关推荐
X54先生(人文科技)1 天前
社会嵌入式终身学习机器与修复时代-ELR架构和技术演化探讨
人工智能·深度学习·学习·架构·开源协议
喜欢吃豆1 天前
Better Auth 深度解析:从用户认证到企业级身份基础设施
数据库·架构·权限·多租户
珠海西格电力1 天前
零碳园区管理系统的性能评估体系的行业标准
大数据·网络·人工智能·物联网·机器学习·架构·能源
Swot1 天前
知识点:关于数据库范式比较好理解的解释
架构
肝不动了老板1 天前
SeaweedFS 原理与实践:从文件上传到分布式存储
架构
爱吃馒头不吃辣1 天前
加一道题,改一天代码:题库即数据的降维打击
前端·架构
RaaS1001 天前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构
HelloWorld0011 天前
告别手动 SSH 扔包!基于 GitHub Actions + Docker 打造全自动化 CI/CD 极速零停机部署实战(全套脚本+避坑)
架构
这个DBA有点耶1 天前
索引建了查询却更慢——优化器选错索引与Index Merge的隐藏代价
数据库·架构·代码规范
吴建旭 智宅焕1 天前
智能家居全国交付中售后服务判断层与执行层的架构分离:上门检测责任边界与交付确定性设计
架构·智能家居