OpenAI Function Calling 特性有什么用
OpenAI最近发布了一次更新,3.5可以支持16k的token,更新了gpt-3.5-turbo-0613 和 gpt-4-0613两个模型,同时这两个模型在chat completion的api中增加了一个叫 Function Calling 的新功能,本篇文章对其功能进行探究,并分析其作用。
我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
Function Calling 接口说明
chat
接口的messages
数组除了原有的system
、user
、assisant
,新增了role
参数选项function
chat
接口新增functions
参数,格式为数组,意味着可以传入一组函数定义,模型将智能选择用哪个- 每个
function
支持三个参数:name
(函数名)、description
(函数功能说明)和parameters
(模型输出的数据格式说明) chat
接口新增了function_call
参数,默认值为none
,可设置为auto
chat
接口的function_call
用于决定是否启用函数式回答。如果值为none
,则不需要传入functions
参数,如果值为auto
,你需要提供一些函数供模型选择。只有在function_call
为auto
,且functions
包含函数数组,且模型根据你的函数功能说明匹配到函数时,返回的message
中才会包含function_call
- 通过 LLM 调用函数并获取输出后,需要将结果传回给模型以生成自然语言回复(非必须)。此时,应在请求的
messages
中添加一个role
为assisant
的message
,包含function_call
信息(即模型返回的数据),同时需要添加一个role
为function
的数据,包含本地函数执行的结果
Show Me Code
下面通过代码实践的方式进行探索
下面以费用统计应用为例,告诉AI:“今天买了一斤肉,花了多少钱”,正常思路来说,交互流程应该是这样的:
- 用户向LLM输入prompt
- AI进行智能分析
- 返回结构化的数据(每个子项是什么,数量是多少)
- 通过现实生活中的实时物价计算
- 传入LLM获得自然语言解答
1 | import openai |
执行结果解读
- LLM 分析后命中了函数签名描述,就会返回给我们 function_call 这个字段以及函数签名中我们预定义的字段信息:
- category返回给了类目是猪肉
- count返回数量是 1 (斤)
1
2
3
4
5
6
7
8{
"role": "assistant",
"content": null,
"function_call": {
"name": "record_price",
"arguments": "{\n \"category\": \"\u8089\",\n \"count\": 1\n}"
}
}
拿到参数,调用 record_price 进行费用统计的操作即可;如果没有命中函数签名描述,就不会返回function_call字段,也就不需要进行任何操作:
1
2
3
4
5if(message.get("function_call")):
function_name = message["function_call"]["name"]
if function_name == BaseTool.Bookkeeping.value:
arguments = json.loads(message["function_call"]["arguments"])
price = record_price(arguments.get('category'), arguments.get('price'))通过外部实时价格 API 获取到实时物价信息,将其作为
role
为function
的数据,组合成最终的 messages列表,再次传入模型接口:1
2
3
4
5
6
7
8[{'role': 'user', 'content': '今天买了一斤肉,花了多少钱'}, <OpenAIObject at 0x103365540> JSON: {
"role": "assistant",
"content": null,
"function_call": {
"name": "record_price",
"arguments": "{\n \"category\": \"\u8089\",\n \"count\": 1\n}"
}
}, {'role': 'function', 'name': 'record_price', 'content': '12'}]最后返回预期可控的结果
今天买了一斤肉,花了12元。
存在问题
- 函数描述是会被计入 token 的
- 潜在的风险:分析不准确,出现无法命中函数的情况
参考
OpenAI Function Calling 特性有什么用