一篇读懂 Function Calling:模型怎么学会调用工具

模型并不真的调用函数

大语言模型(LLM)的能力边界很明确:输入文本,输出文本。它没有网络连接,不能碰文件系统,也不知道现在几点。那「让模型调用一个真实函数」是怎么实现的?关键认知是:**模型从不执行任何函数——它只是输出一段结构化的「我想调用哪个函数、传什么参数」的意图,真正执行的是你的应用代码。**模型出意图,代码出行动,结果再喂回模型继续推理。整个 Function Calling(函数调用)机制建立在这个分工之上。

一个完整回合的流程

  1. 定义工具:应用在请求里附带工具列表,每个工具包含三样东西——函数名、参数 schema(用 JSON Schema 描述参数的类型与结构)、一段自然语言描述。
  2. 模型发起调用:模型读完对话与工具列表后决定是否调用。要调用时,它输出的不是普通文本,而是结构化的调用意图(函数名加按 schema 填好的参数)。
  3. 应用执行真实函数:你的代码解析这段意图,调用真实的函数——查数据库、调内部接口、读写文件都可以。
  4. 结果回传:函数执行结果以「工具消息」的身份追加进对话,再发给模型。
  5. 模型继续作答:模型基于结果生成面向用户的回答;也可能信息不够,再次发起调用——如此循环,直到给出最终答复。

整条链路上唯一的「智能」发生在第 2 步,其余都是确定性的工程代码——这既是这套机制可靠的原因,也意味着执行侧的安全与校验不能指望模型自觉。

模型是怎么「学会」的

没有神秘机制。工具定义会作为上下文的一部分进入模型,而模型在训练阶段见过大量「这个场景该调哪个工具、怎么填参数」的样本,于是工具选择本质是一个上下文学习问题:描述给得足,模型就能对号入座。

由此得到一个实用推论:工具描述的质量就是工具的「提示词」。「发送一封邮件」和「给指定收件人发送邮件,用于必须人工跟进的通知场景;查询类操作不要用此工具」——后者能让模型在边界场景做出正确选择。描述里写清楚何时该用、何时不该用,比多注册十个工具都管用。

一个最小示例

工具定义与模型返回的调用意图,主流大模型 API 的通用形态大致如下(字段名与具体结构以各家文档为准):

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "查询指定城市的当前天气",
      "parameters": {
        "type": "object",
        "properties": {
          "city": { "type": "string", "description": "城市名,例如「上海」" },
          "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
        },
        "required": ["city"]
      }
    }
  }]
}

模型在对话中判断需要天气数据时,返回的不是一句话,而是调用意图:

{
  "role": "assistant",
  "tool_calls": [{
    "name": "get_weather",
    "arguments": { "city": "上海", "unit": "celsius" }
  }]
}

两张清单对照着读:description 与参数的 description 是给模型看的说明书,写得越具体,参数填得越准;required 告诉模型哪些参数必须提供。这些元数据不参与执行,却直接决定调用质量。应用执行真实查询后,把结果(比如 {"temp": 18, "condition": "多云"})作为工具消息回传,模型再据此组织回答。

并行调用与 Agent 循环

两个进阶形态值得知道。并行调用:用户问「北京和上海今天天气怎么样」,模型可以一次返回两个调用意图,应用并行执行、一起回传,省去多轮往返。多步工具链:复杂任务里一次调用的结果可能触发下一次调用——先查到订单号才查得到物流。把这个「模型出意图、代码执行、结果回传」的循环跑到任务完成,就是 Agent 的基本骨架,与本站 Coding Agent 一文里的循环结构是同一回事。

常见的坑

  • 参数幻觉:模型编造 schema 里不存在的参数名,或给参数填了看似合理、实际错误的值。防御手段是应用侧严格校验参数,校验失败就把错误信息回传,让模型带着反馈重试。
  • 该调不调、不该调乱调:多数是描述含糊造成的。模型对「什么时候必须用这个工具」缺乏判断依据,就只能凭感觉走。
  • schema 过度复杂:几十个参数、层层嵌套的工具定义会明显拉低工具选择与参数填充的准确率。工具要小而清晰,一次只做一件事。

与 MCP 的关系

一句话:Function Calling 是模型侧的能力——理解工具描述、发起调用;MCP(Model Context Protocol)是工具分发的协议层——解决工具从哪来、如何标准化地接入不同应用。两者是上下层关系,不互相替代。

小结

Function Calling 的全部机制可以压缩成一条链:定义工具、模型输出调用意图、应用执行、结果回传、模型继续作答。模型只负责「说」,不负责「做」;描述质量决定选择质量;执行与校验永远在应用侧。

← 返回资讯列表

读者留言

COMMENTS 暂无
仅本站原创文章开放留言 · 请勿留下手机号、邮箱等个人信息

还没有留言,来说第一句?