Multi-Agent Patterns

Coordinate multiple agents for complex workflows

Overview

Aegeantic provides built-in patterns for coordinating multiple agents. These patterns handle common multi-agent workflows while leveraging the existing Agent/AgentRunner infrastructure.

Agent Chain

Sequential execution where each agent's output becomes the next agent's input:

from agentic import AgentChain, AgentChainConfig

# Create specialized agents
researcher = Agent(research_config, context, patterns, tools, llm)
analyzer = Agent(analysis_config, context, patterns, tools, llm)
summarizer = Agent(summary_config, context, patterns, tools, llm)

# Build chain
chain = AgentChain(
    agents=[
        ("researcher", researcher),
        ("analyzer", analyzer),
        ("summarizer", summarizer)
    ],
    config=AgentChainConfig(
        pass_mode="response",  # Pass response text to next
        prepend_context=True      # Include context about previous agent
    )
)

# Execute chain
async for event in chain.execute("Research quantum computing"):
    if event.type == "step_complete":
        print(f"Agent completed: {event.result.segments.response}")

Chain Configuration

Supervisor-Worker Pattern

One supervisor delegates tasks to specialized workers:

from agentic import SupervisorPattern, SupervisorConfig

# Create supervisor and workers
supervisor = Agent(supervisor_config, context, patterns, tools, llm)
workers = {
    "search_agent": Agent(search_config, context, patterns, tools, llm),
    "data_agent": Agent(data_config, context, patterns, tools, llm),
    "code_agent": Agent(code_config, context, patterns, tools, llm)
}

pattern = SupervisorPattern(
    supervisor=supervisor,
    workers=workers,
    config=SupervisorConfig(
        delegation_pattern_name="delegate",  # Pattern for delegation
        worker_key="to",                       # Key to extract worker name
        task_key="task",                      # Key to extract task
        max_delegation_rounds=10             # Prevent infinite loops
    )
)

# Execute
async for event in pattern.execute("Build a web scraper"):
    if event.type == "status":
        print(event.message)

Delegation Format

Supervisor uses the delegation pattern in its output:

<delegate>
{
  "to": "search_agent",
  "task": "Search for Python web scraping libraries"
}
</delegate>

Parallel Pattern

Multiple agents analyze the same input in parallel, results merged:

from agentic import ParallelPattern, ParallelConfig

# Create agents with different perspectives
agents = {
    "technical": Agent(tech_config, context, patterns, tools, llm),
    "business": Agent(biz_config, context, patterns, tools, llm),
    "security": Agent(sec_config, context, patterns, tools, llm)
}

# Optional merger agent
merger = Agent(merger_config, context, patterns, tools, llm)

parallel = ParallelPattern(
    agents=agents,
    merger=merger,
    config=ParallelConfig(
        merge_strategy="agent",  # Use merger agent
        timeout_seconds=60.0
    )
)

async for event in parallel.execute_and_merge("Analyze this API design"):
    if event.type == "step_complete":
        print(event.result.segments.response)

Merge Strategies

Debate Pattern

Agents debate a topic until consensus:

from agentic import DebatePattern, DebateConfig

# Create debating agents
agents = {
    "advocate": Agent(advocate_config, context, patterns, tools, llm),
    "critic": Agent(critic_config, context, patterns, tools, llm),
    "mediator": Agent(mediator_config, context, patterns, tools, llm)
}

# Optional moderator for final summary
moderator = Agent(mod_config, context, patterns, tools, llm)

debate = DebatePattern(
    agents=agents,
    moderator=moderator,
    config=DebateConfig(
        max_rounds=5,
        consensus_detector=lambda responses: check_consensus(responses)
    )
)

async for event in debate.converge("Should we use microservices?"):
    if event.type == "status":
        print(event.message)

Shared Context

All agents in a pattern can share the same context manager:

# Shared context for all agents
shared_context = ContextManager(storage, iteration_mgr)

# Create agents with shared context
agent1 = Agent(config1, shared_context, patterns1, tools1, llm)
agent2 = Agent(config2, shared_context, patterns2, tools2, llm)

# Agents can read each other's outputs
# via context keys

Custom Multi-Agent Patterns

Build your own coordination patterns:

class CustomPattern:
    def __init__(self, agents):
        self._runners = {
            name: AgentRunner(agent)
            for name, agent in agents.items()
        }

    async def execute(self, input_text):
        # Custom coordination logic
        for name, runner in self._runners.items():
            async for event in runner.step_stream(input_text):
                yield event

                # Custom decision logic
                if event.type == "step_complete":
                    if event.result.status == AgentStatus.DONE:
                        return  # Stop on first completion

Best Practices

Performance: Parallel patterns execute agents concurrently but still require LLM API calls for each agent. Monitor costs and latency carefully.

Next Steps