Function Calling 是什么:模型只做决策不执行,工具调用链路拆成五段看

工具调用常被误解成模型自己去执行函数,实际上模型只负责输出一段结构化的调用意图,真正的执行、鉴权与结果回填都发生在应用侧。本文把 Function Calling 拆成工具声明、意图判断、结构化输出、执行、结果回填五段链路,讲清每段的实现细节、常见坑与验证方式。

很多团队第一次接触大模型时会撞上同一堵墙:模型能写文案、能总结文档,却查不到今天的库存,也改不了一条工单状态。原因不在模型本身,而在于它的知识停在训练数据截止的那一刻,又没有任何通道去触碰外部世界。工具调用要解决的正是这个断层,它让模型从只会说,变成能驱动一件事发生。 先回答最常被追问的问题:Function Calling 是什么。它不是模型内置了一个能联网、能读数据库的超能力,而是一套约定。开发者在请求里附带一份工具清单,说明有哪些函数可用、各自需要什么参数;模型在判断需要外部信息或动作时,不再输出自然语言答案,而是输出一段结构化的调用意图,通常包含工具名称和一组参数。至于函数到底跑不跑、怎么跑、跑完给谁,全部由应用侧决定。 把这条链路摊开,大致是五段。第一段是工具声明,第二段是模型做意图判断,第三段是结构化输出,第四段是应用侧真正执行,第五段是把执行结果回填给模型,让它生成最终答复。五段里只有中间两段发生在模型内部,其余都归工程侧管,这个分工决定了后面所有的设计方式与风险控制方式。 工具声明的写法比很多人想象的重要。主流做法是用 JSON Schema 描述函数名、用途说明和参数结构,其中用途说明是模型唯一的说明书。同一个查询函数,写成查询数据,和写成根据订单号查询该订单当前物流状态、仅在用户明确给出订单号时调用,命中率完全不在一个量级。参数的类型、枚举范围、必填项也尽量写严,模型对约束的遵循度会明显上升。 意图判断这一段,容易被忽略的是不调用同样是一种正确结果。用户问一句你好,模型直接回话才是对的;如果工具描述写得过于宽泛,它反而会在无关场景频繁触发。多数接口提供强制调用与自动判断两种模式,前者适合做确定性的流水线,后者适合对话式入口。采样温度也会影响判断的稳定性,涉及工具选择时通常不宜调得太高。 到了执行段,真正的边界才出现。模型输出的是建议,不是命令,参数可能缺失、类型可能不符,甚至可能出现清单里根本不存在的字段。因此执行前必须做参数校验、工具白名单、权限与租户隔离,写操作还要考虑幂等键和重试,避免同一笔操作被模型循环触发两次。调用日志要留全,包括原始参数与返回,这是后续排查与效果评估的唯一依据。 结果回填这一步常被写坏。回填内容会作为带对应标识的工具消息重新拼进上下文,如果直接把整页 HTML 或几千行日志塞回去,既推高成本,也稀释了模型的注意力。更稳的做法是先裁剪成结构化要点,比如状态、时间、金额、异常原因,控制在几百 token 内。回填失败时也要把错误信息明确写回,模型才有可能据此换策略或如实告知用户。 复杂任务往往不止一轮。模型调用工具、拿到结果、发现还需要另一个信息,于是再次发起调用,这就形成了循环。成熟的实现会给循环加步数上限、总超时和重复调用检测,并支持一轮内并行发起多个互不依赖的调用,把往返次数压下来。没有这些护栏,一个措辞不当的工具描述就可能把任务拖进无止境的往复。 流式场景下还有一个细节:工具调用的参数是以增量片段的形式陆续到达的,客户端需要按索引把碎片拼接完整,再决定解析时机,不能每收到一段就尝试反序列化。同时要处理连接中断后的恢复,否则半截参数最容易变成脏数据。这类实现细节在文档里往往一笔带过,却是自己动手时最先踩到的坑。 国产模型在这条链路上各有各的脾气。有的工具调用格式与主流规范接近,有的在参数容错度、并行调用支持、多轮稳定性上差异明显,同一段提示词换一个模型可能就从稳定触发变成时灵时不灵。对开发者来说,逐个厂商接 SDK、逐个对齐字段是纯消耗。统一到 OpenAI 兼容格式的中转入口,用同一份工具声明去跑不同模型,改的往往只是模型名,验证效率会高很多。 快米兔的模型 API 中转走的正是这条路:一个入口对接多家国产合规模型,工具声明与调用格式按统一规范处理,开发者不必为每家单独重写适配层。注册送 5 元测试金,按量计费,不设月付门槛,适合先把一条工具调用链路小成本跑通,再决定长期用哪几个模型;具体费率与支持范围以官方说明为准。它更像一个低成本的试验台,让工具调用这类需要反复比对的工程活少绕几圈。 落地时的顺序建议是:先从只读工具开始,比如查询订单、检索知识库,把声明、校验、回填三段跑顺;确认稳定后再放开写操作,并补齐权限、幂等与人工确认。工具调用从来不是模型单方面的能力展示,而是一条被工程约束包住的链路,路修得好不好,决定了它究竟是个能用的助手,还是一个偶尔失控的接口。