Code Interpreter
How to build an AI capable of generating and running code
Last updated
How to build an AI capable of generating and running code
Last updated
You can retrieve the full example of this recipe here
It was also inspired by this tutorial made by E2B.
In this recipe, we will build a simple version of ChatGPT Code Interpreter using OpenAI GPT-4 and E2B.
Here's the final result:
Building a code interpreter is pretty straightforward; we'll proceed as follows:
We'll use the AgentLabs SDK to listen for user's input in the Chat.
We'll send the request to GPT-4 and ask it to generate some code snippets if asked by the user.
GPT is returning some code to run; then, we'll use E2B to run the code in a sandboxed cloud environment.
We'll use the AgentLabs SDK again to display the result to the user
Using E2B is not mandatory, but it's a great solution to run code safely in a sandboxed environment, so we highly recommend you check this out.
In this tutorial, we'll need many environment variables. If you look at our example, you'll see we verify every variable is present before running the app, but you're free to manage your environment variables as you want.
We'll need the following variables:
AgentLabs Project ID, Agent ID, URL and Secret (that you can find on your console)
Open AI Api Key
E2B Api Key
Once our variables are ready, we'll import and init the AgentLabs SDK.
Here, we instantiate the project and the agent.
We start listening for user messages using the .onChatMessage()
method, we'll complete it later in this recipe.
We don't forget to use the .connect()
method to open the socket connection.
Whenever a user sends a message, we'll forward it to GPT-4 using the ChatCompletionAPI. We expect GPT-4 to send us a response with potentially the code to execute.
We'll provide GPT with two kinds of information:
The context: a list of fake history messages so GPT understands what we expect, plus in the end the message sent by the user.
The function calling config: we leverage the function call API so ChatGPT will hopefully output some code we can directly execute in the sandbox.
Don't forget the OpenAI SDK needs an environment variable named OPENAI_API_KEY
to be set.
If you look at the chatCompletion result, you will see it contains something like this:
From this result we want to:
Know if the choices[0].function_call.name
equals exec_code.
If yes, it means we have to execute the code.
Parse the arguments of choices[0].function_call.arguments
in order to extract the value of the code to execute.
Now we have extracted the code to run; we can use E2B to execute it safely in a sandboxed environment.
We will use their process API
to start a new process that will run our code.
Here's the plan:
Initiate an E2B session using Session.create()
method.
Write the code we want to execute in a file named index.js
in the sandbox.
Create a new process, running the node index.js
command to run our code remotely.
We'll keep the onStdout
and onStderr
callbacks empty for now but we'll use them later.
We'll wait for the process execution to be completed.
The code above will run our code until the execution is completed. Every output in Stdout or Stderr will trigger a call of one of the given callbacks.
So far we're able to listen for messages, ask completions to OpenAI, and eventually execute the code.
We still need to implement some real-time feedback to the users so they know what's going on, and they will view the output generated by the code interpreter.
To do so, we'll leverage the agent.createSteam()
method provided by AgentLabs.
We can add some feedback whenever we want.
Let's create a stream if the ChatCompletion contains a function_call.
Here, we open a stream channel, and we indicate we'll send some Markdown, so the Chat UI knows how to display the code output.
Now we can use stream.write
to write on the chat every time we need to.
For example, we can indicate we received some code to execute.
Note we stream in markdown format, so we use ``` in front of the code so it's shown in a code block.
Then, we want to notify the user we'll start executing the code, and crucially we want to output the result of the code interpreter in real time. To do so, we'll write to our stream before executing the code, and every time the onStdout
or onStderr
callbacks are called.
And once we're done, we'll end
the stream.
Congrats, you just rebuilt your own code interpreter!
Feel free to check out the full example here.