AI 是怎么帮你查天气的?Function Calling 工具调用一次讲明白(2026入门)

问 AI「明天北京要不要带伞」,它张口就报降雨概率。训练数据里没有明天的天气,这个数从哪来的?

答案藏在一个叫 Function Calling(工具调用)的机制里。你平时用的联网搜索、查股价、设闹钟、读数据库,背后全是它在干活。

今天把这件事讲透。看完你就能自己给 AI 装上「手脚」。

AI 不替你干活,只给你递纸条

很多人以为 AI 会自己去查天气。其实不会。

它做的事情只有一件:输出一段 JSON,意思是「请帮我查北京的天气」。真正去调天气接口的,是你写的程序。

Kimi 官方文档里有个很清楚的比喻场景:用户、机器人、大模型三个角色。用户问机器人「今天北京天气怎么样」,机器人带着工具清单去问大模型,大模型回一张「参数纸条」,机器人照着执行,把结果再交回大模型,大模型这才生成用户看到的最终回答。

整个过程对用户是透明的。用户只看到一句「明天有雨,记得带伞」,看不到中间这张纸条飞了几个来回。

所以说白了:模型负责决定调什么、参数填什么;你的代码负责真的去干。

一轮完整的工具调用,只有六步

官方文档把流程列得很清楚,我压缩成六步:

1. 用 JSON Schema 定义工具(名字、功能、参数)

2. 通过 tools 参数把工具提交给模型,可以一次提交多个

3. 模型看当前对话,决定用哪个工具,也可以决定不用

4. 模型输出调用工具需要的参数,JSON 格式

5. 你的程序拿这些参数去执行工具,把结果回传给模型

6. 模型根据结果,生成给用户的回复

注意第三步:模型有选择权。你挂了工具,不代表它每次都用。聊「你好」这种闲聊,它直接就回了,不会碰工具。

动手定义一个工具

纸面上说完了,看真实代码。定义一个查天气的工具:

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询指定城市的实时天气。当用户问天气、温度、要不要带伞时调用。",
            "parameters": {
                "type": "object",
                "required": ["city"],
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名,如:北京、上海"
                    }
                }
            }
        }
    }
]

四个字段,每个都有讲究。

name 只能用英文、数字、减号、下划线。description 要写两件事:这个工具干什么、什么时候该用它。parameters 里的每个参数也都要写 description,模型是照着它填参数的。

description 不是装饰。模型选工具、填参数,全靠这些描述文字,写得含糊它就会选错工具。智谱官方给的三条设计原则:单一职责、清晰命名、完整描述。一个函数只干一件事,别贪。

最容易踩的坑:消息要原样放回去

工具调用最劝退新手的地方,是消息列表的管理。

平时聊天,消息就是 system、user、assistant 交替。有了工具调用,中间会插进 role 为 tool 的消息,序列变成这样:

system → user → assistant(带 tool_calls) → tool(执行结果) → assistant(最终回答)

官方文档专门强调:模型返回的 assistant 消息,必须完整包含 tool_calls 字段,原样放回 messages 列表。你要是只拷了文字、丢了 tool_calls 字段,下一轮请求直接报错 tool_call_id not found。

这段代码我第一次写就报了这个错,翻文档才发现,最稳的做法是每次收到响应就把返回的 message 整个 append 进去,别自己重新拼。

还有一条:每个 tool_call 都要有对应的 tool 消息,tool_call_id 要对得上。模型一次返回两个调用,你就得回传两条结果,少一条都报错。

tool_choice:给模型上紧箍咒

默认情况下,模型自己决定调不调工具(auto)。有些场景你需要更强的控制,tool_choice 参数就是干这个的,一共四个档位:

• auto:默认,模型自己看着办

• required:强制本轮至少调一个工具

• none:禁止调用,只许纯文本回复

• 指定函数:强制调用某个具体工具

强制检索的场景用 required 很顺手,比如要求模型必须查数据库、不许凭记忆编。none 能省 token、降延迟,纯聊天时开着挺干净。

两个细节要注意。指定函数这个模式,在思考模式开启时会直接报 400,Kimi 官方原话:tool_choice 'specified' is incompatible with thinking enabled。另外各家支持程度不一样,智谱目前就只支持 auto,写跨模型代码前先查文档。

三个进阶玩法

工具挂多了,新的问题就来了。

第一,tools 定义也吃 token。官方注意事项里明确写了,tools 参数的内容会计入总 token。你挂 50 个工具,每个定义几百 token,还没开始聊,上下文先烧掉一大块。token 怎么算钱,之前写过一篇AI API 计费,可以配套看。

第二,并行调用。Kimi 支持一次返回多个 tool_calls,互不依赖的调用模型会倾向并行给出。比如「北京和上海今天多少度」,它一次返回两个调用,你并发执行,一轮搞定。

第三,工具太多时用「工具搜索」。K3 最佳实践文档给的方案:平时只声明一个 search_tools 工具,模型先搜出要用哪几个,再按需把定义注入对话。几十上百个工具的场景,这比全量塞进去省得多,选工具也更准。

执行前,把参数再验一遍

模型输出的参数,本质是生成的文本,不是你写的代码。它会填错格式,偶尔也会填出你没想到的东西。这和temperature 采样是同一件事:输出有随机性。

所以工具执行侧要做三件事:验证参数(类型、范围、必填项),控制权限(危险操作加白名单),记日志(出了问题能回溯)。这也是智谱官方文档里的安全建议。

工具调用是 Agent 的地基。你看到的 AI 帮你订机票、操作电脑、跑代码,拆开看都是这一套循环在转:模型出主意,代码干活,结果回传,模型接着想。

把这篇看懂,再去看AI Agent 科普和Agent Skills的资料就顺了。

发表评论