做AI这行八年了,见过太多人把ChatGPT当成许愿池,扔个提示词就指望它变出完美代码。说实话,早期我也这么干,直到被生产环境的各种“幻觉”和格式错误折磨得想砸键盘。后来我才明白,想让大模型真正干活,得给它上规矩,这就是所谓的函数调用(Function Calling)。

记得去年给公司做那个智能客服后台,需求很简单:用户问“查下北京天气”,模型得返回结构化数据,好让前端渲染卡片。最开始我没用函数,直接让模型写JSON。结果呢?它偶尔多给个逗号,偶尔把键名拼错成“cityy”,前端解析直接崩盘。那几天我头发掉了一把,调试日志看得眼晕。

后来换了思路,用了chatgpt 函数调用机制。这玩意儿说白了,就是先告诉模型:“我有这几个工具,你判断用户意图,然后按我的格式填空。” 就像给厨师一张标准菜谱,他不能随便发挥,得按步骤来。

具体怎么搞?先定义函数。比如定义一个get_weather函数,参数是city和unit。然后在System Prompt里明确告诉模型,如果用户问天气,必须调用这个函数,参数从对话里提取。这里有个坑,很多新手以为模型会自动推理参数,其实不然。你得在JSON Schema里把类型写死,比如city必须是string,不能让它给你传个整数。

我当时的配置是这样的:

{

"name": "get_weather",

"description": "获取指定城市的天气",

"parameters": {

"type": "object",

"properties": {

"city": {"type": "string"},

"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}

},

"required": ["city"]

}

}

配置好后,测试环节才是重头戏。第一次跑,模型很听话,返回了tool_calls。但第二次,有个用户问“这雨下得真大”,模型居然也调用了天气函数,参数city是“这雨”。我当时就笑了,这逻辑有点跳跃啊。不过好在,通过few-shot examples(少样本提示),我给了几个正确调用的例子,模型很快纠正了行为。

这里分享个数据对比。没用函数前,格式错误率大概在15%-20%,每次都要写正则去清洗,代码臃肿不堪。用了chatgpt 函数调用后,结构化数据的准确率直接飙到95%以上。剩下的5%主要是模型没识别出意图,比如用户问“今天适合洗车吗”,这其实隐含了天气查询,但模型可能直接回复建议,而不是调用函数。这不算bug,算是对业务逻辑的理解偏差,可以通过优化Prompt解决。

还有个细节,关于token消耗。有人担心函数定义太占地方。其实不然,定义一次,后续复用。相比每次让模型生成完整JSON,函数调用的token开销反而更稳定,因为模型不需要每次都“思考”JSON的结构,它只需要填充参数。

当然,也不是所有场景都适合用。如果任务很简单,比如翻译、摘要,直接让模型输出文本就行,别整那些花里胡哨的函数调用,反而增加延迟。只有当需要执行动作、查询数据库、或者获取实时数据时,chatgpt 函数调用才是神器。

最后说点实在的,调试函数调用时,别光看最终结果。去打印中间那个tool_calls对象,看看模型提取的参数对不对。很多时候,参数提取错了,后端逻辑再完美也没用。我见过太多人死磕后端代码,结果发现是模型把“北京”提取成了“北景”,这种低级错误,前端根本没法处理。

总之,把大模型当工具用,就得给它套上枷锁。函数调用就是那根缰绳。刚开始可能觉得麻烦,要写Schema,要处理tool_response,但一旦跑通,那种掌控感,真的爽。别怕报错,报错是常态,解决报错才是本事。我这八年,就是在一堆报错里爬出来的。希望这点经验,能帮你少走点弯路。