Skip to main content
Multi-agent systems enable specialized agents to work together on complex tasks. Each agent focuses on a specific domain and coordinates through orchestration patterns.

Multi-Agent System Design Patterns

There are many ways to design multi‑agent systems, but we commonly see two broadly applicable patterns:
  • Manager (agents as tools): A central manager/orchestrator invokes specialized sub‑agents as tools and retains control of the conversation.
  • Handoffs: Peer agents hand off control to a specialized agent that takes over the conversation. This is decentralized.
This guide focuses on the Manager pattern (agents as tools), which is the most common and straightforward approach.

Installation

npm install @ag-kit/agents @ag-kit/tools zod

Manager Pattern (Agents as Tools)

In the Manager pattern, a central orchestrator invokes specialized agents as tools. The orchestrator retains control throughout the conversation and decides when to call each specialized agent.

Creating Specialized Agents

Each specialized agent focuses on a specific task:
import { Agent, OpenAIProvider } from '@ag-kit/agents';

const pageProcessorAgent = new Agent({
  name: 'PageProcessorAgent',
  description: 'Process single page: crawl, translate, summarize',
  model: new OpenAIProvider({
    apiKey: process.env.OPENAI_API_KEY!,
    defaultModel: process.env.OPENAI_MODEL || 'gpt-4o-mini'
  }),
  instructions: `You are PageProcessorAgent. Process a single page:
1. Crawl the page content
2. Translate if needed to target language
3. Extract key points and entities
4. Return structured data for report generation`
});

const reportGeneratorAgent = new Agent({
  name: 'ReportGeneratorAgent',
  description: 'Generate comprehensive report from multiple page results',
  model: new OpenAIProvider({
    apiKey: process.env.OPENAI_API_KEY!,
    defaultModel: process.env.OPENAI_MODEL || 'gpt-4o'
  }),
  instructions: `You are ReportGeneratorAgent. Generate comprehensive reports:
1. Integrate results from multiple pages
2. Create structured summary with key insights
3. Generate mind map (mermaid format)
4. Provide quality assessment`
});

Creating the Orchestrator

The orchestrator coordinates the workflow by delegating to specialized agents. It wraps specialized agents as tools:
import { tool } from '@ag-kit/tools';
import { z } from 'zod';

// Wrap agent as tool
function createAgentTool(agent: Agent, toolName: string) {
  return tool(
    async ({ url, content, targetLanguage, pageResults }) => {
      let prompt = '';
      switch (toolName) {
        case 'process_page':
          prompt = `Process this page: ${url}\n\nTarget language: ${targetLanguage || 'en'}`;
          break;
        case 'generate_report':
          prompt = `Generate comprehensive report from these page results:\n\n${JSON.stringify(pageResults)}\n\nTarget language: ${targetLanguage || 'en'}`;
          break;
        default:
          prompt = content || url;
      }
      const result = await agent.run(prompt);
      return result.data;
    },
    {
      name: toolName,
      description: agent.config.description || `Agent: ${agent.config.name}`,
      schema: z.object({
        url: z.string().optional(),
        content: z.string().optional(),
        targetLanguage: z.string().optional(),
        pageResults: z.array(z.any()).optional()
      })
    }
  );
}

const orchestrator = new Agent({
  name: 'multi-agent-orchestrator',
  description: 'Orchestrates multi-page web reading and summarization workflow',
  model: new OpenAIProvider({
    apiKey: process.env.OPENAI_API_KEY!,
    defaultModel: process.env.OPENAI_MODEL || 'gpt-4o'
  }),
  instructions: `You are the orchestrator for multi-page web reading. When given URLs:
1. Use todo_write to plan tasks for each page
2. Coordinate page processing using process_page
3. Coordinate report generation using generate_report
4. Generate comprehensive report in user's language`,
  tools: [
    createAgentTool(pageProcessorAgent, 'process_page'),
    createAgentTool(reportGeneratorAgent, 'generate_report')
  ]
});

Best Practices

  1. Clear Boundaries: Each agent should have a specific, focused responsibility
  2. Efficient Communication: Minimize overhead between agents using appropriate patterns
  3. Structured State: Use typed state classes when agents need to share data
// Good: Specific purpose
const billingAgent = new Agent({
  name: 'billing-specialist',
  description: 'Handles billing inquiries only'
});

// Avoid: Too general
const generalAgent = new Agent({
  name: 'general-agent',
  description: 'Handles everything'
});

Next Steps