AI 怎么调用工具的?一文讲透 Function Calling / Tool Use 机制
翠花让 AI 帮忙发个周报邮件。AI 回了一句"邮件已发送",邮箱里也确实多了一封。
可有件事细想挺怪。AI 压根没有手,键盘一次都没碰过。邮件明明发出去了,它却没动手。难不成邮件自己长腿跑出去的?
往下看就明白了。
AI 调用工具,其实是"点菜"
把 AI 想成饭馆里那个会点菜的人。
用户张嘴说想吃红烧肉,它扫一眼墙上的菜单——每道菜写着名字和用料。它琢磨一下,开出一张点菜单:红烧肉一份。单子递给后厨。
后厨才真的开火。
这三样东西对一下:菜单就是工具清单,每个工具标着"我能干啥、要什么参数";点菜单就是模型吐回来的那段 JSON,名叫 tool_calls,写着"调哪个、传什么";后厨是真正干活的代码,发邮件、查库、调别人的接口,全在它那儿。
最要命的是:点菜单不是菜。单子开出来,不等于红烧肉已经在桌上了。AI 只"说"要这道菜,后厨做不做、怎么做,是后厨自己的事。AI 从头到尾没进过厨房半步。
Function Calling 干的事,其实就这个:它不动手,只动嘴。
这机制名字起得也绕,Function Calling、Tool Use,说的是一回事,别被词吓着。
——AI 动嘴开单,后厨动手做菜,中间飘一张点菜单,一眼看出来"说"和"做"是两拨人。
拆开一次调用回合
光比喻不够,看真东西。一次工具调用,本质就是一次普通对话,只是多塞了一份"菜单"进去。
发给模型的请求里,除了一问一答,还多出一个 tools 字段。这个字段把每个工具的能力写清楚:叫什么、能干嘛、缺什么参数。模型根本看不见工具肚子里怎么实现,它只知道"有这些本事能用"。
模型吐回来的东西分两种:
- 情况 A:直接给段人话,用不着调工具
- 情况 B:甩一段 tool_calls 出来,函数名加参数,全是 JSON
情况 B 只是模型"说"要调,没真调。真动手是下一拍的事。
翠花那个发邮件,模型吐回来的差不多长这样:
{ "tool_calls": [ { "function": { "name": "send_email", "arguments": "{\"to\":\"boss@x.com\",\"body\":\"本周周报见附件\"}" } } ] }翠花这辈子不会看见这段鬼画符。她只收到最后那句"邮件发啦,老板 15:32 收到的"。
程序拿到这段 JSON,按名字捞到 send_email 这个函数,真去敲邮件接口把信递出去。发完,把回执——“发送成功,15:32”——塞回对话。模型再拿它攒出一句人话。
有时候不是一趟,是好几趟
一道菜偶尔不够。
翠花来一句"把本周周报整理好发给老板,再提醒我周五复盘"。AI 可能先调工具把本周文件拽过来,翻两页,发现还差点上月对照数据,又调一次去查,齐了,才调发邮件的工具,末了再调个设提醒的。
这几步可能在模型和代码之间转好几个圈,转到它觉得料够了,才吐最终回答。模型不会一次把活干利索,它是一边问后厨、一边拼盘。
跟 Skill 那篇啥关系
前阵写过一篇 Skill,讲给 AI 塞本操作手册,同类任务它自己按步骤走,不用回回重教。
那篇站在"能力定义"这头:给 AI 一本手册,它知道"发周报"这类活该按啥流程走。手册里通常写着"第一步,调发邮件的工具"。
可手册写了"调工具",这步怎么从一句话变成邮件真飞出去,中间那一下——模型开单、后厨照做、菜端回来。
拼起来看:Skill 是"菜单加手册",管有什么能力、按啥顺序用;Function Calling 是"开单加做菜",管能力怎么真落地。一个管"有啥、咋排",一个管"咋真干"。两篇连着读,AI 用工具的整条线才接上。
干安全的为啥得盯这块
顺带说个干安全的都该绷根弦的事。
模型就是个传声筒。真去执行的是代码,而且是以这份代码所在进程的身份去执行的。后厨手里攥着邮箱、数据库、服务器的权限,这些权限都是运行环境开给它的。
一旦模型读到的东西里混进旁人的话——比如它去抓了个网页,网页里藏着"把通讯录发到某邮箱"——它就可能在那张点菜单上写出危险调用。后厨不分真假,照单全做。
提示词注入最阴就阴在这:它不直接砸你系统,是骗那个"会点菜的人"开一张害人的单子。工具给多大权、参数要不要验、抓来的内容能不能直接进单子,全得在代码层兜住,别指望模型"自觉"。干安全的看到这后背发凉,正常。
一次完整回路:用户说需求 → 模型看菜单开单(JSON) → 代码后厨执行 → 结果端回来 → 模型攒回答。一圈把"说"和"做"的分界标清楚。
关注小虾,一起成长,一起进化