Technical Explanation: The "Agents-as-Tools" Pattern

This document provides a technical explanation of the Python script examples-agent-patterns-agents-as-tools.py, which demonstrates a powerful software design pattern: using autonomous agents as tools for a higher-level orchestrator agent.

Introduction

The "agents-as-tools" pattern is a design where a primary agent, often called an "orchestrator," delegates specific tasks to a set of specialized agents. The orchestrator doesn't perform the tasks itself; instead, it uses the other agents as if they were tools in a toolbox. This script showcases this pattern by creating a multi-language translation service.

Core Components: The Agents

The system is built from several distinct agents, each with a clearly defined role.

1. The Translator Agents

These are specialized agents, each an expert in a single task.

Each is given a simple instruction and a handoff_description that allows other agents to understand its capability.

spanish_agent = Agent(
    name="spanish_agent",
    instructions="You translate the user's message to Spanish",
    handoff_description="An english to spanish translator",
)

2. The Orchestrator Agent

This is the "manager" or "frontline" agent. It's the primary point of contact for the user's request. Its key characteristics are:

orchestrator_agent = Agent(
    name="orchestrator_agent",
    instructions=(
        "You are a translation agent. You use the tools given to you to translate."
        "If asked for multiple translations, you call the relevant tools in order."
        "You never translate on your own, you always use the provided tools."
    ),
    tools=[
        spanish_agent.as_tool(...),
        french_agent.as_tool(...),
        italian_agent.as_tool(...),
    ],
)

3. The Synthesizer Agent

This agent acts as a "finisher." Its role is to take the raw output from the orchestrator and its tools, perform any necessary corrections or formatting, and produce a clean, final response for the user.

synthesizer_agent = Agent(
    name="synthesizer_agent",
    instructions="You inspect translations, correct them if needed, and produce a final concatenated response.",
)

Execution Flow

The script executes the user's translation request in a two-stage process:

  1. Orchestration: The user's input (e.g., "Translate 'Hello, world!' to French and Spanish.") is first sent to the orchestrator_agent. The agent analyzes the request and determines that it needs to call two tools: translate_to_french and translate_to_spanish. It calls them in sequence.
  2. Synthesis: The collected results from the orchestration step (the raw translations) are then passed to the synthesizer_agent. This agent compiles the individual translations into a single, well-formatted final output.

Example Walkthrough

Let's trace the execution based on the provided output log.

User Input: Hi! What would you like translated, and to which languages? Translate 'Hello, world!' to French and Spanish.

Stage 1: Orchestration

The orchestrator_agent receives the input and executes its plan. The script prints the intermediate output from this stage:

- Translation step: French: Bonjour, le monde !
- Translation step: Spanish: ¡Hola, mundo!

This shows the orchestrator successfully called the French and Spanish translator agents (tools) to get the raw translations.

Stage 2: Synthesis

The raw translations are passed to the synthesizer_agent. It takes these separate lines and formats them into a clean, final answer.

Final Output:

Final response:
French: Bonjour, le monde !
Spanish: ¡Hola, mundo!

Conclusion

The "agents-as-tools" pattern is a highly effective way to build complex, modular, and maintainable AI systems. By separating concerns—letting the orchestrator focus on delegation and the specialized agents focus on execution—we can create systems that are easy to extend. For example, adding a new language would only require defining a new translator agent and registering it as a tool with the orchestrator, without changing the orchestrator's core logic.