OpenAI
Connect Riza’s Python code interpreter to OpenAI
In this guide, we’ll show you how to use function calling and Riza’s Code Interpreter API to safely execute Python code generated by an OpenAI model, such as gpt-4o.
Background
OpenAI’s function calling feature allows you to connect gpt-4o and other OpenAI models with external tools. A common function calling use case is to execute Python code generated by an LLM. However, unreviewed code generated by an LLM should be treated as untrusted and should only be run in a safe environment.
Riza’s Code Interpreter provides a safe environment for executing untrusted code via a simple API call.
The complete script
This script uses OpenAI’s gpt-4o and function calling to write and execute Python code. Below is the full script, in case you want to copy and paste it into your own project.
In the rest of this guide we’ll explain each of its components.
Running this script will output something like this:
Let’s take a look at how to set up the script, and how it works.
Set up your environment and run the script
Create and activate a virtual environment:
Install the openai
and rizaio
Python libraries.
We’ll need API keys from both OpenAI and Riza.
- Get an OpenAI API key from the OpenAI Console.
- Get a Riza API key from the Riza Dashboard.
Set these API keys as environment variables in your terminal:
Copy and paste the above script into a file named coder.py
and run it:
How the script works
Let’s look at the key components of our script:
Import libraries and initialize clients
First we import our helper libraries and initalize the OpenAI and Riza clients.
Use Riza to execute the code and return the result
Our exec_python
function uses Riza to safely execute any untrusted code in an isolated environment.
This function accepts a single parameter: a string of code to execute. We assume the code is Python since we’re prompting the LLM to produce Python.
We use the Riza client to execute the code. Riza returns an object with three properties: exit_code
, stdout
, and stderr
. If execution completes successfully, exit_code
will be 0 and stdout
will contain the output. If execution results in an error, exit_code
will be greater than 0 and stderr
will contain the error message.
We return the result from execution (either stdout
or stderr
) which we’ll pass back to the LLM.
Occasionally, the code will run successfully (exit_code == 0
) with no output (stdout == ""
). This happens when the LLM generates code that does not print anything to stdout
. In this case we raise an exception to avoid silent failure. Aggressive and specific prompting will usually prevent this.
Describe the function for the LLM
OpenAI’s function calling syntax requires a list of dictionaries describing your functions and their parameters.
A list of tools containing only our exec_python
description would look like this:
Notice that we tell the LLM it must write code that prints output to stdout.
Make the call to the Chat Completion API
The general pattern for using function calling with OpenAI is to:
-
Make an initial call to the Chat Completion API, including a list of tools it can use to generate a response.
-
Check the initial response for a
tool_calls
field to see if the model decided to use a tool. If so, extract the function arguments from the response, run the function, and append the result as a message to the conversation. In our case, the function arguments will be a string of Python code, and the tool will beexec_python
. -
Make another call to the Chat Completion API endpoint with the appended message including the function result.
-
Return the final completion to the user.
For the sake of this guide we’ve hardcoded a simple system message and user message.
We make our first API call to OpenAI, providing the model, list of messages, and available tools.
Handle function calls
If the model decides to use a function, we will see a tool_calls
field in completion.choices[0].message.tool_calls
.
In this example, we have only equipped the model with a single function, exec_python
, but to support multiple tools in the future we iterate over each function call in the tool_calls
list.
When we find the exec_python
function name in the tool_calls
list we extract the arguments returned from the model, execute the code using Riza, and append the result to the list of messages.
We make a final call to the Chat Completion API endpoint with the updated list of messages.
And finally, we print the final completion.
Next steps
If you modify the user prompt message enough times and ask a wide variety of questions you’ll surely notice that the model will try to make HTTP requests within the Python code it writes. By default Riza’s isolated Python runtime environment doesn’t allow access to network I/O. Read about how to allow network access here.
Conclusion
The script in thie guide demonstrates how to use OpenAI’s function calling feature with Riza’s Code Interpreter API to safely execute Python code generated by an LLM. By leveraging these tools you can create powerful applications that write and run code dynamically, while maintaining a secure execution environment.
Remember to always treat LLM-generated code as untrusted and use appropriate safeguards, such as Riza’s sandboxed environment, when executing it.