Published on

How to Use Functions with the OpenAI Assistants API

Authors

How to Use Functions with the OpenAI Assistants API

For general information on how to use the Assistants API, check out my guide on getting set up here: https://www.jimmymills.io/blog/openai-assistants-api

This is probably the most complicated tool for the Assistants API to use effectively, but is one of the most powerful, as it can allow your assistant to take basically any action you can put into code, even fetching information from the internet or your own databases.

Setting Up Functions

To use functions, you will need a tool entry for each function you want to be able to use. When the assistant wants to use one of these functions, instead of just handling the action itself like the previous tools, the run will be placed into a 'requires_action' status and it will be up to you to read the run and respond to each of the functions that the assistant is waiting for (yes, it can be multiple at once!).

Use Cases

Some good use cases of functions would be:

  • Anything requiring live data from the internet
  • Allowing the assistant to access your API for information
  • Needing the assistant to stop and ask for permission prior to taking certain actions

Example: FDA API

Here's an example of an assistant that has a function for reading FDA label data for incoming medication queries:

from openai import OpenAI

client = OpenAI()

assistant = client.beta.assistants.create(
  name="FDA Assistant",
  instructions="You are a helpful health assistant. When asked a question about medication, you will provide answers with the label data of the medication.",
  model="gpt-4-1106-preview",
  tools=[{
      "type": "function",
      "function": {
          "name": "medication_label_data",
          "description": "Gives the FDA label data for a given medication",
          "parameters": {
              "type": "object",
              "properties": {
                  "medicine": {"type": "string", "description": "The medicine to look up."},
              },
              "required": ["medicine"]
          }
      }
  }],
)

def medication_label_data(medicine):
  return requests.get("https://api.fda.gov/drug/label.json?search=openfda.brand_name:" + medicine).text

# Handle any required actions for a given run
def complete_tool_calls(run):
  tool_calls = run.required_action.submit_tool_outputs.tool_calls
  outputs = []
  # Be sure to loop since there can be multiple tool_calls in a batch
  for tool_call in tool_calls:
    function_name = tool_call.function_name
    args = json.loads(tool_call.function.arguments)
    if function_name == 'medication_label_data':
      response = medication_label_data(medicine=args['medicine'])
      outputs.append({"tool_call_id": tool_call.id, "output": results})
    else: # Make sure you catch any erroneous tool calls
      raise Error('Unsupported function called')
  run = client.beta.threads.runs.submit_tool_outputs(
    thread_id=thread.id,
    run_id=run.id,
    tool_outputs=outputs,
  )
  return run

# Create a thread
thread = client.beta.threads.create()

# Add your message to the thread
client.beta.threads.messages.create(
  thread_id=thread.id,
  role="user",
  content="Is there any reason I can't take Omeprazole when I'm lactose intolerant?",
)

# Create a run
run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id,
)

# Wait for the run to complete
while run.status != 'completed':
  time.sleep(5) # Sleep for 5 seconds between checks to limit calls
  # The 'requires_action' status requires submitting tool calls to continue
  if run.status == 'requires_action':
    run = complete_tool_actions(run)
  else:
    run = client.beta.threads.retrieve(
      thread_id=thread.id,
      run_id=run.id,
    )


# Print out the response
messages = client.beta.threads.messages.list(thread_id=thread.id)
print(messages[0].content[0].text.value)

While this example only has a single function passed in, you can pass in an array of "function" type tools to give your assistant a number of different useful abilities.

Conclusion

Functions allow your assistant to take any number of useful actions, interacting with your systems and/or the internet as needed. Understanding how to use functions can signifigantly increase the possibilities for useful OpenAI powered tools.