Part 2: ToyAIKit runner

We have a Python function and its OpenAI tool schema. Now we put the same example behind a small chat runner, so we don't have to write the function-calling loop by hand.

ToyAIKit pieces

ToyAIKit is an educational library I use across workshops. It's not the framework you'd reach for in a serious production system. It keeps the notebook short and makes the tool calls visible enough for learning.

Import the pieces we need:

from toyaikit.tools import Tools
from toyaikit.chat import IPythonChatInterface
from toyaikit.llm import OpenAIClient
from toyaikit.chat.runners import OpenAIResponsesRunner

The four pieces each have one job:

  • Tools stores Python callables and their tool descriptions.
  • IPythonChatInterface gives us a small chat UI inside Jupyter.
  • OpenAIClient wraps the OpenAI SDK client.
  • OpenAIResponsesRunner runs the Responses API tool loop.

Register the joke tool

Create a Tools object and add the function with the schema from the previous step:

tools_obj = Tools()
tools_obj.add_tool(make_joke, make_joke_description)

The schema is still useful here because we already wrote it by hand. Later, when we add methods from an object, ToyAIKit can infer schemas from type hints and docstrings.

Create the runner

The chat interface handles input and output in the notebook:

chat_interface = IPythonChatInterface()
openai_client = OpenAIClient(client=OpenAI())

Pass the tools, developer prompt, chat interface, and client into the runner:

runner = OpenAIResponsesRunner(
    tools=tools_obj,
    developer_prompt=system_prompt,
    chat_interface=chat_interface,
    llm_client=openai_client,
)

Now run it.

runner.run()

Try a message like this in the notebook chat:

Tell me a personalized joke. My name is Alex.

You should see a function call to make_joke, the arguments the model chose, the function output, and the final assistant message.

Jupyter is useful here

Agents don't require Jupyter, but it helps here. We can run one cell, look at the result, then change a small piece and run again. You build a coding agent through iteration, so a fast feedback loop matters.

We can move the same runner pattern into a web application later. For today, we get the chat interface for free in the notebook.

Read the runner later

You don't need to understand all of ToyAIKit before continuing, but read through the runner code once we wrap up.

The code shows the tool loop that the OpenAI API requires:

  • send messages and tool definitions to the model
  • receive model output
  • execute requested tool calls
  • append tool results to the conversation
  • continue until the assistant returns text

As an exercise, paste the runner class into ChatGPT and ask why there are two loops. That's a good way to see what the educational wrapper is hiding.

Continue with Part 3: Django template.

Questions & Answers

Sign up to ask questions, track your progress, and get access to other workshops · Already have an account? Sign in