Getting Started with OpenAI Function Calling

The basic usage of LLM is text in -> text out, where the output is in text format. However, there are often cases where we want it to output in a fixed format for parsing into structured data and passing it to subsequent processing logic.

Before the release of Function calling by OpenAI, we may have used text prompts to request LLM to format the output, or used the Parsers provided by the LangChain framework. Now, OpenAI provides Function calling to format the output of LLM into the required parameters for function calling.

Introduction to Function calling: Simply put, Function calling is about generating formatted output that is recognizable based on the parameters required for (custom) function calls.

In API calls, we can describe a function (function name, parameters, etc.) and have the model intelligently generate a JSON object that contains the parameters for calling one or more functions. The Chat Completions API does not directly call the functions; it only generates the JSON. We can use this JSON object in our code to call the functions we have described.

Here’s an example:

Let’s say we want to build an email assistant that can send emails based on user input. The user input might be something like “Please send an email to xxx@gmail.com with the following content: Please attend the meeting in the school auditorium tomorrow morning at 9:00 AM.”

Sending an email requires calling an external API, and typically we would encapsulate the parameters like this in our code: send_email(to: string, body: string).

As we can see, send_email(to: string, body: string) requires two parameters: the recipient “to” and the email content “body”. These parameters need to be extracted from the user’s input.

We can describe send_email(to: string, body: string) and pass it to the Chat Completions API. The response from the API will include the following content:

 function=Function(arguments='{"to": "xxx@gmail.com", "body": "Please attend the meeting in the school auditorium tomorrow morning at 9:00 AM."}', name='send_email') 

We can see that OpenAI has extracted the required parameters, the recipient “to” and the email content “body”, from the user’s text input and assigned them to the “arguments” field in JSON format.

Workflow of Function calling: Let’s take the example of querying the weather for a specific city on a specific date to explain the workflow of Function calling.

For weather queries, we will use the API provided by AMap.

def get_weather(city, date):
    base_url = "<https://restapi.amap.com/v3/weather/weatherInfo>"
    api_key =  os.getenv("AMAP_API_KEY")
    params = {
        'key': api_key,
        'city': city,
        'extensions': 'base',
        'output': 'json',
        'date': date
    }
    try:
        response = requests.get(base_url, params=params)
        data = response.json()
        logger.info(data) 
        if data['status'] == '1':
            weather_info = data['lives'][0] 
            # logger.debug(f"city: {weather_info['city']}")
            # logger.debug(f"date: {date}")
            # logger.debug(f"weather: {weather_info['weather']}")
            # logger.debug(f"temperature: {weather_info['temperature']} ℃")
            # logger.debug(f"windpower: {weather_info['windpower']}")
            return json.dumps(weather_info)
        else:
            print("query fail, error code:" + data['infocode'])
    except Exception as e:
        print("query exception:" + str(e))

The Function calling feature of OpenAI’s API supports passing multiple function descriptions in the form of an array.

tools = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "Querying the weather conditions for a specific city and date.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "city": {
                            "type": "string",
                            "description": "The name of the city you want to query, for example: Beijing.",
                        },
                        # "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                        "date": {
                            "type": "string",
                            "description": "The date you want to query, for example: 2023-11-21.", 
                        }
                    },
                    "required": ["city", "date"],
                },
            },
        }
    ]

The Completions API can extract parameters in JSON format.

client = OpenAI()
messages = [
            {
                "role": "user", 
                "content": "What is the weather like in Shanghai on November 1st?"
            }
        ]
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

The “tool_calls” field in the response contains the relevant information about the functions we described, including the required parameters.

To call the custom function get_weather(city, date) using the extracted parameters from the previous response, you can use the following code:

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

Output:

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**

已发布

分类

标签:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注