Skip to main content

Supervisor Agent

When building complex AI applications, you often need multiple specialized agents to collaborate on different aspects of a task. A supervisor agent enables one agent to act as a supervisor, coordinating the work of other agents, each focused on their own area of expertise. This structure allows agents to delegate, collaborate, and produce more advanced outputs than any single agent alone.

In this example, this system consists of three agents:

  • A Copywriter agent that writes the initial content.
  • An Editor agent that refines the content.
  • A Publisher agent that supervises and coordinates the other agents.

Prerequisites

This example uses the openai model. Make sure to add OPENAI_API_KEY to your .env file.

.env
OPENAI_API_KEY=your_api_key_here

Copywriter agent

This copywriter_agent is responsible for writing the initial blog post content based on a given topic.

from timbal.core import Agent
copywriter_agent = Agent(
name="copywriter-agent",
system_prompt="You are a copywriter agent that writes blog post copy.",
model="openai/gpt-4o"
)

Copywriter tool

The copywriter_tool provides an interface to call the copywriter_agent and passes in the topic.

from timbal.core import Tool
async def copywriter_tool(topic: str) -> dict[str, str]:
"""Calls the copywriter agent to write blog post copy."""
# Call the copywriter agent
result = await copywriter_agent(prompt=f"Create a blog post about {topic}").collect()
return {
"copy": result.output.content[0].text
}
# Create the Tool instance
copywriter_tool_instance = Tool(
name="copywriter_tool",
description="Calls the copywriter agent to write blog post copy.",
handler=copywriter_tool
)

Editor agent

This editor_agent takes the initial copy and refines it to improve quality and readability.

from timbal.core import Agent
editor_agent = Agent(
name="editor-agent",
system_prompt="You are an editor agent that edits blog post copy.",
model="openai/gpt-4o-mini"
)

Editor tool

The editor_tool provides an interface to call the editor_agent and passes in the copy.

from timbal.core import Tool
async def editor_tool(copy: str) -> dict[str, str]:
"""Calls the editor agent to edit blog post copy."""
# Call the editor agent
result = await editor_agent(prompt=f"Edit the following blog post only returning the edited copy: {copy}").collect()
return {
"copy": result.output.content[0].text
}
# Create the Tool instance
editor_tool_instance = Tool(
name="editor_tool",
description="Calls the editor agent to edit blog post copy.",
handler=editor_tool
)

Publisher agent

This publisher_agent coordinates the entire process by calling the copywriter_tool first, then the editor_tool.

from timbal.core import Agent
from timbal.tools.example_copywriter_tool import copywriter_tool_instance
from timbal.tools.example_editor_tool import editor_tool_instance
publisher_agent = Agent(
name="publisher-agent",
system_prompt="""You are a publisher agent that first calls the copywriter agent to write blog post copy about a specific topic and then calls the editor agent to edit the copy. Just return the final edited copy.""",
model="openai/gpt-4.1-mini",
tools=[copywriter_tool_instance, editor_tool_instance]
)

Registering the agents

All three agents are created and available for use in the workflow. In Timbal, agents are used directly without needing a central registry.

# All agents are already created and available
# No central registration needed - use them directly
# Available agents:
# - copywriter_agent
# - editor_agent
# - publisher_agent
# Available tools:
# - copywriter_tool_instance
# - editor_tool_instance
# The publisher_agent already has access to both tools
# and can coordinate the entire workflow

Example usage

Use the publisher agent directly by calling it with a prompt message.

import asyncio
async def main():
response = await publisher_agent(prompt="Write a blog post about React JavaScript frameworks. Only return the final edited copy.").collect()
response_text = response.output.content[0].text
print(response_text)
if __name__ == "__main__":
asyncio.run(main())