Part 3: Orchestrating Agents with OpenAI
Why OpenAI Function Calling Is Perfect for Multi-Agent Work
Prerequisites
pip install openai>=1.14.0 python-dotenv aiosqliteexport OPENAI_API_KEY="sk-..."Replacing _think() with an OpenAI Call
_think() with an OpenAI Call# openai_agent.py
from __future__ import annotations
import json
import os
from openai import AsyncOpenAI
from agent_v2 import AgentV2, Message
from dispatcher import ToolDispatcher
client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"])
class OpenAIAgent(AgentV2):
model: str = "gpt-4o-mini"
def __init__(
self,
name: str,
system_prompt: str,
dispatcher: ToolDispatcher,
model: str = "gpt-4o-mini",
persist: bool = False,
) -> None:
super().__init__(
name=name,
system_prompt=system_prompt,
dispatcher=dispatcher,
persist=persist,
)
self.model = model
async def _think(self) -> str:
"""Call OpenAI with current memory and available tools."""
messages = [{"role": "system", "content": self.system_prompt}]
for msg in self.memory:
if msg.role == "tool":
messages.append({
"role": "tool",
"tool_call_id": msg.metadata.get("tool_call_id", "unknown"),
"content": msg.content,
})
else:
messages.append({"role": msg.role, "content": msg.content})
response = await client.chat.completions.create(
model=self.model,
messages=messages,
tools=[
{"type": "function", "function": schema}
for schema in self.dispatcher.schemas()
],
tool_choice="auto",
)
choice = response.choices[0]
# Model wants to call a tool
if choice.finish_reason == "tool_calls":
tool_call = choice.message.tool_calls[0]
name = tool_call.function.name
args = tool_call.function.arguments # already a JSON string
# Store the assistant message with tool_calls so history is valid
self.memory.append(
Message(
role="assistant",
content="",
metadata={"tool_calls": [tool_call.model_dump()]},
)
)
# Return in the format AgentV2.run() expects
return f"TOOL: {name} {args}"
# Plain response
content = choice.message.content or ""
return f"DONE: {content}"The Supervisor Pattern
Parallel Agent Execution
Handling Errors and Retries
Key Takeaways
Up Next
Last updated