Function Calling 实战:让大模型调用你的代码

Words: 1102Read Time: 3 minLast edited: 2026-8-4

模型不会做事,只会说话

用大模型写了半年 demo,我越来越频繁地撞上一堵墙:它知识再多,也答不了"我后台现在有多少条待发货订单",更干不了"把这条记录状态改成已处理"。它是个只会说话的大脑,没有手。
Function calling 就是给它装手的机制。思路很巧妙:模型依然只输出文本,但它可以按约定输出"我想调用某某函数、参数是什么",由你的代码真正执行,再把结果喂回给它。现在的 API 里这个能力通过 tools 参数提供(早期的 functions 参数已经被取代),这篇记录完整的实现循环。

tools 参数:把函数说明书交给模型

调用 API 时通过 tools 参数传一份 JSON schema,描述每个函数的名字、用途、参数。这份"说明书"的质量直接决定模型用得对不对,description 要认真写:
两个函数:查天气(调外部 API)和查待发货订单数(查自己的数据库)。

完整循环:调用、执行、回填、再生成

整个交互是一个循环,核心逻辑:
  1. 把用户问题和 tools 一起发给模型。
  1. 模型如果返回 tool_calls,说明它想调函数:本地执行,把结果以 role: "tool" 的消息追加回对话,再发一次请求
  1. 直到模型不再请求工具、直接输出文本,循环结束。
跑起来后,问"北京今天天气怎么样,顺便看看还有多少待发货订单",模型会连着调两个函数,最后汇总成一句人话。第一次看到它自己决定"该调哪个函数、参数填什么",还是挺震撼的。

一定要校验模型给的参数

实战里最大的坑:模型给的参数不能全信。arguments 是个 JSON 字符串,我见过这些幺蛾子:
  • 参数名对但值离谱:让查"北京"的天气,它传 "beijing" 甚至 "北京市今天"
  • JSON 本身解析失败(少见,但有)。
  • 自作主张加 schema 里没定义的参数。
所以执行前必须校验,不合法就把错误信息作为 tool 结果喂回去,让模型自我纠正,别让程序直接崩:
数据库那个函数更要小心。我的做法是只允许模型调预定义的查询,函数内部是写死的参数化 SQL,绝对不把模型生成的 SQL 直接丢给数据库执行——这和防 SQL 注入是一个道理,只不过注入源从用户换成了模型。
最后再强调一遍循环上限。模型偶尔会陷入"调工具→对结果不满意→再调"的死循环,不加限制就是把 API key 放在火上烤。我设的上限是 5 轮,超过就兜底返回。
Loading...
© 2024 - 2026 ihuadz
中文