June 21, 2023 No Comments

OpenAI Function Calling

OpenAI recently released a new feature called “function calling“, which allows developers to create more interactive and dynamic applications. With the function calling feature, developers can describe functions to OpenAI’s model, and the model will output a JSON object containing arguments to call those functions. Function calling allows developers to get structured data back from the model. Some common use cases of the “Function Calling” feature are as below:

  • To call the external APIs.
  • To convert natural language queries to API calls or database calls
  • Extract structured data from text

In this blog post, we will create a small application that uses OpenAI’s function-calling feature to call external APIs. These APIs will provide us with the current stock price of a company listed in the United States and the current currency exchange rate between the two countries.

To get the current stock price of a company listed in the United States, we will use Finnhub. Finnhub provides a free API key that can be obtained by following the below steps:

It will provide you with the API key, which we will use to fetch stock prices.

To get the current currency exchange rate between the two countries, we will use Alphavantage. Alpha Vantage also provides a free API key that can be obtained by following the below steps:

It will provide you with the API key, which we will use to fetch currency exchange rates between 2 countries.

Now that we have both the API keys of Finnhub and Alpha Vantage, we can start building the application. Below is a step-by-step guide you can follow to create an application: 

Step 1:

To begin, you need to install two packages, openai, and finnhub-python, by using the following commands:

				
					pip install openai
pip install finnhub-python
				
			

Once the installation is complete, you can import the necessary libraries by including the following lines in your code:

				
					import json
import requests
import finnhub
				
			

Step 2:

First, we are creating a utility that facilitates requests to the Chat Completions API. The utility function takes four parameters: messages, functions, function_call, and model. The purpose of each parameter is as follows:

messages: It takes a prompt that will be used when making the ChatGPT API call.

functions: It will take the list of available functions specification, which can be invoked by ChatGPT.

function_call: This parameter allows us to provide either the name of a specific function or set it as “None”. When a function name is provided, the API will be directed to call that particular function. If we want to force the OpenAI model to not use any function, then we need to pass this argument as the None.

model: t will take the name of the model we want to use, here we are using the “gpt-3.5-turbo-0613” model. You can use “gpt-4-0613” also.

This function will call the OpenAI Chat Completion endpoint with appropriate parameters and return the response.

				
					GPT_MODEL = "gpt-3.5-turbo-0613"
def chat_completion_request(messages, functions=None, function_call=None, model=GPT_MODEL):
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + "<your_openai_key>",
    }
    json_data = {"model": model, "messages": messages}
    if functions is not None:
        json_data.update({"functions": functions})
    if function_call is not None:
        json_data.update({"function_call": function_call})
    try:
        response = requests.post(
            "https://api.openai.com/v1/chat/completions",
            headers=headers,
            json=json_data,
        )
        return response
    except Exception as e:
        print("Unable to generate ChatCompletion response")
        print(f"Exception: {e}")
        return e
				
			

Step 3:

Next, we will develop a function for invoking the Finnhub API to retrieve the current stock price of a company listed in the United States. First, you need to create a finnhub client by passing your finnhub API. Then we can write our function like below:

				
					finnhub_client = finnhub.Client(api_key="<Your_finnhub_API_key>")
def get_current_stock_price(arguments):
    try:
        arguments = json.loads(arguments)['ticker_symbol']
        price_data=finnhub_client.quote(arguments)
        stock_price = price_data.get('c', None)
        if stock_price == 0:
            return "This company is not listed within USA, please provide another name."
        else:
            return stock_price
    except:
        return "This company is not listed within USA, please provide another name."
				
			

Step 4:

Next, we will create a function that will call Alpha Vantage API to fetch the currency exchange rate between the 2 countries. You need to add the below lines of code to implement the function.

				
					def currency_exchange_rate(arguments):
    try:
        from_country_currency = json.loads(arguments)['from_country_currency']
        to_country_currency = json.loads(arguments)['to_country_currency']
        url = f'https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency={from_country_currency}&to_currency={to_country_currency}&apikey='<your_Alphavantage_api_key>''
        r = requests.get(url)
        data = r.json()
        return data['Realtime Currency Exchange Rate']['5. Exchange Rate']
    except:
        return "I am unable to parse this, please try something new."
				
			

Step 5:

Now, we need to create function specifications for interacting with the Finnhub API and Alpha Vantage API. We’ll pass these function specifications to the Chat Completions API in order to generate function arguments that adhere to the specification. In this function specification, you need to provide the name and description of the function and its parameters. You can describe the functional specification as below:

				
					functions = [
    {
        "name": "get_current_stock_price",
        "description": "It will get the current stock price of the US company.",
        "parameters": {
            "type": "object",
            "properties": {
                "ticker_symbol": {
                    "type": "string",
                    "description": "This is the symbol of the company.",
                }
            },
            "required": ["ticker_symbol"],
        },
    },
    {
        "name": "currency_exchange_rate",
        "description": "It will get the currency exchange rate between 2 countries.",
        "parameters": {
            "type": "object",
            "properties": {
                "from_country_currency": {
                    "type": "string",
                    "description": "This is the currency of the country whose we need to map.",
                },
                "to_country_currency": {
                    "type": "string",
                    "description": "This is the currency of the country to which we need to map.",
                }
            },
            "required": ["from_country_currency","to_country_currency"],
        },
    }]
				
			

Step 6:

Now, we can utilize the function-calling capability of OpenAI. We need to call chat completion API with prompt and function specifications. It will call ChatGPT and generate JSON that we can use to call the function in our code. You can use the below code to generate JSON which will be used further to call a local function.

				
					user_input = input("Please enter your question here: ")

# prompt
messages = [{"role": "system", "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous."}]
messages.append({"role": "user", "content": user_input})

# calling chat_completion_request to call ChatGPT completion endpoint
chat_response = chat_completion_request(
    messages, functions=functions
)

# fetch response of ChatGPT and call the function
assistant_message = chat_response.json()["choices"][0]["message"]
print(assistant_message)
				
			
Output:

We asked, “What is the stock price of Apple?”, ChatGPT recognized the need to invoke the ‘get_current_stock_price’ function with the parameter ‘AAPL’ in order to access the Finnhub API. So, it produced a JSON response containing the function name and the corresponding parameter required to execute the local function.

				
					Please enter your question here: What is the stock price of Apple?
{'role': 'assistant', 'content': None, 'function_call': {'name': 'get_current_stock_price', 'arguments': '{\n  "ticker_symbol": "AAPL"\n}'}}
				
			

Step 7:​

Now, we can call the local function ‘get_current_stock_price’, using the JSON generated by ChatGPT as below:

				
					if assistant_message['content']:
    print("Response is: ", assistant_message['content'])
else:
    fn_name = assistant_message["function_call"]["name"]
    arguments = assistant_message["function_call"]["arguments"]
    function = locals()[fn_name]
    result = function(arguments)
    print("Response is: ", result)
				
			
Output:
				
					Please enter your question here: What is the stock price of Apple?
{'role': 'assistant', 'content': None, 'function_call': {'name': 'get_current_stock_price', 'arguments': '{\n  "ticker_symbol": "AAPL"\n}'}}
Response is:  184.92
				
			
Step 8:

Now, we can merge the above 2 steps, to generate JSON using ChatGPT and call a local function using generated JSON and put them into the loop like below:

				
					user_input = input("Please enter your question here: (if you want to exit then write 'exit' or 'bye'.) ")

while user_input.strip().lower() != "exit" and user_input.strip().lower() != "bye":
    # prompt
    messages = [{"role": "system", "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous."}]
    messages.append({"role": "user", "content": user_input})

    # calling chat_completion_request to call ChatGPT completion endpoint
    chat_response = chat_completion_request(
        messages, functions=functions
    )

    # fetch response of ChatGPT and call the function
    assistant_message = chat_response.json()["choices"][0]["message"]

    if assistant_message['content']:
        print("Response is: ", assistant_message['content'])
    else:
        fn_name = assistant_message["function_call"]["name"]
        arguments = assistant_message["function_call"]["arguments"]
        function = locals()[fn_name]
        result = function(arguments)
        print("Response is: ", result)

    user_input = input("Please enter your question here: ")
				
			
Results:
				
					Please enter your question here: (if you want to exit then write 'exit' or 'bye'.) 1 dollar is equal to what rs?    
Response is:  81.94000000
Please enter your question here: What is the current stock price of Amazon?
Response is:  125.4902
Please enter your question here: Currency exchange rate between india and canada?
Response is:  0.01606000
Please enter your question here: Stock price of Tesla?
Response is:  260.54
				
			

Write a comment

Your email address will not be published. Required fields are marked *

Want to talk to an Expert Developer?

Our experts in Generative AI, Python Programming, and Chatbot Development can help you build innovative solutions and scale your business faster.