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 do not have to write the function-calling loop by hand.
ToyAIKit pieces
ToyAIKit is an educational library I use across workshops. It is not the
production framework choice for serious systems, but 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:
Toolsstores Python callables and their tool descriptions.IPythonChatInterfacegives us a small chat UI inside Jupyter.OpenAIClientwraps the OpenAI SDK client.OpenAIResponsesRunnerruns 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
Jupyter is not required for agents. It is useful for this workshop because we can run one cell, look at the result, change a small piece, and run again. A coding agent is built through iteration, so the feedback loop matters.
The same runner pattern can be moved into a web application later. For today, the notebook gives us the chat interface for free.
Read the runner later
You do not need to understand all of ToyAIKit before continuing, but it is
worth reading the runner code after the workshop. 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
A useful exercise is to paste the runner class into ChatGPT and ask it to explain why there are two loops. That is a good way to understand what the educational wrapper is hiding.
Continue with Part 3: Django template.