Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Task 02 - Create a function call for the customer account information API endpoint (40 minutes)

Introduction

Function calling is a feature in OpenAI and the Azure OpenAI Service. It provides the ability to produce structured JSON outputs based on functions you describe in a request. This allows organizations to extract key components needed for API calls from natural language communication and augment native chat capabilities.

Description

In the prior task, you created an endpoint for accessing customer account information from Cosmos DB. In this task, you will show the power of function calling in Azure OpenAI Service by creating a chat completion that enables looking up customer details by name, loyalty tier, or most recent stay.

The key tasks are as follows:

  1. In the Streamlit app’s 1_Chat_with_Data.py file, fill in the functions list with a GPT function definition called “get_customers” that takes two parameters: searchCriterion and searchValue. The searchCriterion parameter should be an enumeration containing three values: CustomerName, LoyaltyTier, and DateOfMostRecentStay.
  2. Add code to the dashboard that converts the GPT function into an Azure OpenAI function definition and executes the customer lookup request. To do this, you will complete the functions named get_customers(), create_chat_completion_with_functions(), and handle_chat_prompt_with_functions().

    For the full_server_url in the get_customers() function, part of the required answer is to provide the IP address and port that your .NET Web API service is running on. This .NET Web API service should be running while you go through this exercise.

  3. After loading the Streamlit app, ensure that you are on the “Chat with Data” page. Then, select the Chat with Data radio button option and ask the following question: “Our family is celebrating my mother’s 90th birthday and we want to have that celebration in Aruba. Do you have a hotel that can accommodate 19 room rentals? And are there any reception rooms at that hotel?”
  4. Continue the chat conversation with this follow-up: “What other amenities does that hotel have?”
  5. Switch the radio button to “Function Calls” and then ask the question, “Which customers are in the Gold tier?” Ensure that Streamlit returns the response as a table.
  6. Continue asking questions to ensure that you can successfully look up customers by name, loyalty tier, and date of most recent stay.

Success Criteria

  • You have filled out the Exercise 03 functions on the Streamlit dashboard.
  • You are able to load customer data by full name, loyalty tier, and date of most recent stay when you select the “Function Calls” radio button.
  • You are also able to chat regarding hotel and resort information when selecting the “Chat with Data” radio button.

Learning Resources

Tips

  • The way to reference response objects in Azure OpenAI has changed with recent versions of the Azure OpenAI API, so if you are looking at older examples online, you might need to make minor changes to your code to be compliant with the new API format. For example, instead of reading response["choices"][0]["message"], you would reference response.choices[0].message.

Solution

Expand this section to view the solution
  • GPT function definitions are JSON objects following a particular pattern, with a combination of name, description, and parameters. The definition for the get_customers function is as follows:

      functions = [
          {
              "name": "get_customers",
              "description": "Get a list of customers based on some search criterion.",
              "parameters": {
                  "type": "object",
                  "properties": {
                      "search_criterion": {"type": "string", "enum": ["CustomerName", "LoyaltyTier", "DateOfMostRecentStay"]},
                      "search_value": {"type": "string"},
                  },
                  "required": ["search_criterion", "search_value"],
              },
          }
      ]
    
  • The handle_chat_prompt_with_functions() function does three things. First, it echoes the user’s prompt to the chat window. After that, it sends the prompt to Azure OpenAI. Finally, it executes the function call that Azure OpenAI returns.
    • The code for the completed handle_chat_prompt_with_functions() function is as follows:

      # Echo the user's prompt to the chat window
      st.session_state.messages.append({"role": "user", "content": prompt})
      with st.chat_message("user"):
          st.markdown(prompt)
      
      # Send the user's prompt to Azure OpenAI and display the response
      # The call to Azure OpenAI is handled in create_chat_completion()
      # This function loops through the responses and displays them as they come in.
      # It also appends the full response to the chat history.
      with st.chat_message("assistant"):
          message_placeholder = st.empty()
          full_response = ""
          response = create_chat_completion_with_functions(deployment_name, st.session_state.messages)
          response_message = response.choices[0].message
      
          # Check if GPT returned a function call
          if response_message.function_call:
              # Get the function name and arguments
              function_name = response_message.function_call.name
              # Verify the function
              if function_name not in available_functions:
                  full_response = f"Sorry, I don't know how to call the function `{function_name}`."
              else:
                  function_to_call = available_functions[function_name]
                  # Verify the function has the correct number of arguments
                  function_args = json.loads(response_message.function_call.arguments)
                  if check_args(function_to_call, function_args) is False:
                      full_response = f"Sorry, I don't know how to call the function `{function_name}` with those arguments."
                  else:
                      # Call the function
                      function_to_call(**function_args)
      st.session_state.messages.append({"role": "assistant", "content": "Table response removed for brevity."})
      
  • The create_chat_completion_with_functions() function reaches out to Azure OpenAI and performs the chat completion, providing it the list of available functions and options.
    • The code for the completed create_chat_completion_with_functions() function is as follows:

      # Create an Azure OpenAI client. We create it in here because each exercise will
      # require at a minimum different base URLs.
      client = openai.AzureOpenAI(
          base_url=f"{aoai_endpoint}/openai/deployments/{deployment_name}/",
          api_key=aoai_api_key,
          api_version="2023-12-01-preview"
      )
      # Create and return a new chat completion request
      # Be sure to include the "functions" parameter and set "function_call"
      return client.chat.completions.create(
          model=deployment_name,
          messages=[
              {"role": m["role"], "content": m["content"]}
              for m in messages
          ],
          functions=functions,
          function_call="auto",
      )
      
  • The get_customers() function reaches out to ASP.NET Web API and performs the lookup call that you created in Exercise 03, Task 01.
    • The code for the completed get_customers() function is as follows. Note that you will want to replace localhost:5292 with the URL and port of the Web API service you ran as part of Exercise 03, Task 01.

      full_server_url = f"http://localhost:5292/Customer/?searchCriterion={search_criterion}&searchValue={search_value}"
      r = requests.get(
          full_server_url,
          headers={"Content-Type": "application/json"}
      )
      if r.status_code == 200:
          return st.write(pd.read_json(r.content.decode("utf-8")))
      else:
          return f"Failure to find any customers with {search_criterion} {search_value}."
      

Additional Challenges

If you would like to take on an additional challenge, perform the following:

  1. Load the contents of Resorts.txt into Cosmos DB in a Resorts collection.
  2. Create a Web API endpoint allowing users to search for resorts by name, nation, or amenities.
  3. Create a new function in the Streamlit application to support this Web API endpoint.
  4. Ask a question of the chat service such as “Which resorts are in Bonaire?”
  5. Ask a question of the chat service such as “Which resorts offer a pool?”