Battalion Orchestration (Many Agents, One Runtime)
When several agents should collaborate on one task — rather than serve independent
requests — use a Battalion. It runs many Paladins in a single tokio runtime with a
coordination pattern built in, so you express the relationship between agents instead of
hand-rolling the concurrency.
The example below is compiled code pulled from the
paladin-doc-examplescrate via mdBook{{#include}}, so it matches the current API.
When to choose it
- Choose it when the agents form a workflow: a pipeline, a fan-out/fan-in, a DAG, or a lead delegating to specialists. The Battalion owns ordering, concurrency limits, and error strategy for you.
- Look elsewhere when the agents are independent request handlers — a plain agent registry (optionally behind an HTTP host) fits better than an orchestration pattern.
This is still a single-process topology — it composes naturally with the others: a worker or an HTTP host can run a Battalion as the unit of work it executes.
Example: parallel agents (Phalanx)
A Phalanx fans the same input out to several Paladins concurrently and aggregates the
results — the most direct "many agents, one runtime" pattern. Note the with_max_concurrency
cap and the BattalionConfig:
#![allow(unused)] fn main() { use paladin_battalion::phalanx_service::PhalanxExecutionService; use paladin_core::platform::container::battalion::phalanx::{AggregationStrategy, Phalanx}; /// Fan the same input out to several Paladins concurrently, then aggregate. pub async fn run_phalanx() -> Result<(), Box<dyn std::error::Error>> { let paladin_port = mock_paladin_port(); let security = create_paladin("SecurityAuditor"); let perf = create_paladin("PerformanceAnalyst"); let style = create_paladin("StyleChecker"); let phalanx = Phalanx::new(vec![security, perf, style], BattalionConfig::default())? .with_aggregation(AggregationStrategy::CollectAll) .with_max_concurrency(4); // cap concurrent Paladins let service = PhalanxExecutionService::new(paladin_port); let result = service .execute(&phalanx, "Review this Rust module...") .await?; println!("Aggregated: {}", result.final_output); Ok(()) } }
Picking a pattern
| Your agents should… | Pattern | Service type |
|---|---|---|
| Run in a fixed order, each feeding the next | Formation (sequential) | FormationExecutionService |
| Run together on the same input, then aggregate | Phalanx (parallel) | PhalanxExecutionService |
| Follow explicit dependencies / branches | Campaign (DAG) | CampaignExecutionService |
| Have a lead delegate to specialists | Chain of Command | ChainOfCommandExecutionService |
| Use a pattern chosen per-request | Commander (auto-route) | CommanderBuilder |
The full guides cover every pattern with a worked, compiled example, plus Conclave, Council, Grove, and the Maneuver flow DSL:
- Orchestration Patterns — the comprehensive reference.
- Battalion Orchestration Patterns — pattern-by-pattern walkthrough.
← Back to Choosing a topology