工具使用与函数调用(tool use / function calling)
/ TOOL yooss and FUNK-shun KAWL-ing /
语言模型本身只会产生文字。它没法真的去查今天的天气,没法对大数做可靠的算术,也查不到它从没记住过的事实。工具使用,就是让它伸手到自身之外的窍门:模型不再凭记忆硬答,而是写出一条请求——「调用 get_weather,城市=东京」——再由外面的程序去运行那个真实函数,把答案递回来。就像给一位才华横溢却足不出户的专家一部电话和一套仪器:现在他能去问世界,而不必靠猜。
函数调用,是把这件事接通的那种具体而规整的方式。开发者描述每一个可用工具——它叫什么、做什么、需要什么输入——而模型一旦判断某个工具有用,就吐出一条整洁的结构化请求(通常是JSON),点名要调用的函数并填好参数。关键在于:模型自己什么都不运行,它只是用固定格式提出这个调用。是应用程序去校验并执行它,再把结果喂回对话,模型才能接着用。这就是几乎每一个现代AI智能体底下的「管路」。
最大的好处,是对「模型做不到什么」保持诚实:算术交给计算器,时事交给搜索工具,私有数据交给你的数据库。但决定何时、如何调用工具的,仍然是模型,而它可能决定得很糟——编造参数、选错工具、或漏掉本该发出的调用。所以外层代码必须把模型提出的每一个调用都当作不可信的输入来对待:校验它、限制工具能做的事,绝不能让一团判断失误的JSON,比如说,把整个数据库抹掉。
你问「4891×2733 等于多少?」模型不去猜,而是吐出:{"tool": "calculator", "args": {"expression": "4891*2733"}}。应用运行真正的计算器,得到13,367,103,再喂回去。模型于是用大白话回答:「答案是13,367,103。」之所以精确,是因为算这道题的是一台真计算器,而不是模型那模糊的记忆。
模型提出一个结构化的调用;应用运行真正的工具,再返回结果。
一个常见误解:以为模型「运行」了工具。它并没有——它只写下请求。从请求到结果之间的一切,都是你掌控的普通软件,而那里正是你必须放安全检查的地方。模型可能被骗(比如被一个动了手脚的网页),从而请求一个危险的调用,所以真正的安全边界,在工具那一层,而不在模型身上。