前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenAI | Function calling 上手体验

OpenAI | Function calling 上手体验

原创
作者头像
windealli
发布2023-11-22 10:55:26
2.2K1
发布2023-11-22 10:55:26
举报
文章被收录于专栏:windealli

引言

LLM的基本使用方式是 text in -> text out , 输出是 text 。 但是很多时候,我们希望它能以固定的格式输出,以便解析成结构化的数据,传递给后续的处理逻辑。

在 OpenAI 发布 Function calling 之前,我们可能会议文本输入的方式,在Prompt中要求LLM格式化输出,或者通过LangChain框架提供的 Parsers 相关的抽象。现在,OpenAI 提供了 Function calling 用于将LLM的输出格式化成 Function calling 所需要的参数。

Function calling 介绍

简单的说, Function calling 就是基于(自定义)函数调用所需要的参数,输出可识别的格式化的输出。

在 API 调用中,我们可以描述一个函数(函数名、参数等),并使模型智能选择输出一个包含调用一个或多个函数的参数的 JSON 对象。 Chat Completions API 不会直接调用函数;它只会生成 JSON。我们可以在代码中使用该JSON对象调用我们描述的函数。

举个例子:

我们希望构建一个邮件小助手,可以根据用户的输入发送邮件。用户的输入类似”请向xxx@163.com发送邮件,内容是:请明天上午9:00到学校礼堂参加会议“。 发送邮件需要调用外部API,通常会在代码里封装这样的参数 send_email(to: string, body: string)

可以看到,send_email(to: string, body: string) 需要两个参数:收件人 to 和邮件内容 body 。 这两个参数需要用户的输入中提取。

我们描述好send_email(to: string, body: string) 并传递给 Chat Completions API ,它的返回内容会包含以下内容:

代码语言:javascript
复制
function=Function(arguments='{"to": "xxx@163.com", "body": "请明天上午9:00到学校礼堂参加会议"}', name='send_email')

可以看到OpenAI从用户的文本输入中提取出了调用send_email 所需要的参数收件人 to 和邮件内容 body,并以JSON的形式赋值给了 arguments 字段。

Function calling 使用流程

我们以查询指定城市指定日期天气为例,介绍 Function calling 的使用流程,

天气查询使用高德的API。

定义函数

代码语言:javascript
复制
def get_weather(city, date):
    base_url = "<https://restapi.amap.com/v3/weather/weatherInfo>"
    api_key =  os.getenv("AMAP_API_KEY") # 高德API的API-KEY从环境变量获取
    params = {
        'key': api_key,
        'city': city,
        'extensions': 'base',  # 可根据需求选择 'base' 或 'all'
        'output': 'json',
        'date': date  # 指定日期,格式如:2023-01-01
    }
    
    try:
        response = requests.get(base_url, params=params)
        data = response.json()
        logger.info(data) 
        if data['status'] == '1':
            weather_info = data['lives'][0]  # 如果选择了 'base' 扩展,使用 'lives';选择 'all' 扩展,使用 'forecasts'
            # logger.debug(f"城市: {weather_info['city']}")
            # logger.debug(f"日期: {date}")
            # logger.debug(f"天气: {weather_info['weather']}")
            # logger.debug(f"温度: {weather_info['temperature']} ℃")
            # logger.debug(f"风力: {weather_info['windpower']} 级")
            return json.dumps(weather_info)
        else:
            print("查询天气信息失败,错误码:" + data['infocode'])
    except Exception as e:
        print("查询天气信息时发生错误:" + str(e))

为 OpenAI 的API描述函数

Function calling 支持以数组形式传入多个函数描述。

代码语言:javascript
复制
tools = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "查询指定城市,指定日期的天气情况",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "city": {
                            "type": "string",
                            "description": "要查询的城市名称,如:北京",
                        },
                        # "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                        "date": {
                            "type": "string",
                            "description": "要查询的日期,示例:2023-11-23", 
                        }
                    },
                    "required": ["city", "date"],
                },
            },
        }
    ]

completions API 提取JSON格式的参数

代码语言:javascript
复制
client = OpenAI()

## 我们需要将用户的输入一并传递给OpenAI,以便从中提取函数调用所需要的参数。
messages = [
            {
                "role": "user", 
                "content": "深圳11月1号天气怎么样"
            }
        ]

### 第一次调用 Chat Completions API, 提取参数
response = client.chat.completions.create(
        model="gpt-3.5-turbo-1106",
        messages=messages,
        tools=tools,
        tool_choice="auto",  # auto is default, but we'll be explicit
    )

response_message = response.choices[0].message
tool_calls = response_message.tool_calls # 包含了函数调用所需要的信息

response里的tool_calls,包含了我们描述的函数相关信息,以及所需要的参数。

调用自定义函数

从前面的response中提取参数,并调用 get_weather(city, date):

代码语言:javascript
复制
if tool_calls:
        tool_call = tool_calls[0]
        function_args = json.loads(tool_call.function.arguments)
        function_response = get_weather(
            city=function_args.get("city"),
            date=function_args.get("date"),
        )
        return function_response

输出结果:

代码语言:javascript
复制
**(llm) ➜  function_calling python 01_function_calling.py
{"province": "\\u5e7f\\u4e1c", "city": "\\u6df1\\u5733\\u5e02", "adcode": "440300", "weather": "\\u6674", "temperature": "23", "winddirection": "\\u4e1c\\u5317", "windpower": "\\u22643", "humidity": "67", "reporttime": "2023-11-22 10:31:09", "temperature_float": "23.0", "humidity_float": "67.0"}
(llm) ➜  function_calling**

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
    • Function calling 介绍
      • 举个例子:
    • Function calling 使用流程
      • 定义函数
      • 为 OpenAI 的API描述函数
      • completions API 提取JSON格式的参数
      • 调用自定义函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档