Agentic AIC#verifiedVerified
Multi-Agent Orchestration Pattern in C#
Coordinate a network of specialised AI agents under an orchestrator, where each agent owns a distinct capability or domain and agents communicate through structured messages.
How to Implement the Multi-Agent Orchestration Pattern in C#
1Step 1: Define the agent interface
public record AgentMessage(string From, string Content);
public interface IAgent
{
string Name { get; }
Task<string> ProcessAsync(string input, IReadOnlyList<AgentMessage> history);
}2Step 2: Coordinator routes messages between agents
public class Coordinator
{
private readonly List<IAgent> _agents = [];
private readonly List<AgentMessage> _history = [];
public void Register(IAgent agent) => _agents.Add(agent);3Step 3: Run a round-robin conversation until consensus
public async Task<string> RunAsync(string task, int maxRounds = 5)
{
_history.Add(new AgentMessage("user", task));
for (var round = 0; round < maxRounds; round++)
{
foreach (var agent in _agents)
{
var response = await agent.ProcessAsync(task, _history);
_history.Add(new AgentMessage(agent.Name, response));
if (response.Contains("[DONE]"))
return response;
}
}
return _history[^1].Content;
}
}using System.Threading.Channels;
using Microsoft.Extensions.Logging;
// [step] Define agent message types and roles
public enum AgentRole { Planner, Researcher, Writer, Reviewer }
public record AgentMessage(
string From, AgentRole Role, string Content,
DateTime Timestamp, string? ReplyTo = null);
public interface IAgent
{
string Name { get; }
AgentRole Role { get; }
Task<AgentMessage> ProcessAsync(
AgentMessage input, IReadOnlyList<AgentMessage> history,
CancellationToken ct = default);
}
public record OrchestratorConfig(
int MaxRounds = 10,
TimeSpan Timeout = default,
bool ParallelExecution = false);
public record ConversationResult(
string FinalOutput, IReadOnlyList<AgentMessage> FullHistory,
int Rounds, TimeSpan Duration);
// [step] Production multi-agent orchestrator with channels and logging
public sealed class MultiAgentOrchestrator(
OrchestratorConfig config, ILogger<MultiAgentOrchestrator> logger)
{
private readonly List<IAgent> _agents = [];
private readonly List<AgentMessage> _history = [];
public MultiAgentOrchestrator Register(IAgent agent)
{
_agents.Add(agent);
logger.LogInformation("Registered agent: {Name} ({Role})",
agent.Name, agent.Role);
return this;
}
public async Task<ConversationResult> RunAsync(
string task, CancellationToken ct = default)
{
var sw = System.Diagnostics.Stopwatch.StartNew();
var timeout = config.Timeout == default
? TimeSpan.FromMinutes(5) : config.Timeout;
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
cts.CancelAfter(timeout);
_history.Clear();
_history.Add(new AgentMessage("user", AgentRole.Planner, task, DateTime.UtcNow));
for (var round = 0; round < config.MaxRounds; round++)
{
cts.Token.ThrowIfCancellationRequested();
logger.LogDebug("Starting round {Round}", round + 1);
if (config.ParallelExecution)
{
var tasks = _agents.Select(a =>
a.ProcessAsync(_history[^1], _history, cts.Token));
var results = await Task.WhenAll(tasks);
_history.AddRange(results);
}
else
{
foreach (var agent in _agents)
{
var response = await agent.ProcessAsync(
_history[^1], _history, cts.Token);
_history.Add(response);
logger.LogDebug("{Agent}: {Content}",
agent.Name, response.Content[..Math.Min(100, response.Content.Length)]);
if (response.Content.Contains("[DONE]"))
{
return new ConversationResult(
response.Content, _history.AsReadOnly(),
round + 1, sw.Elapsed);
}
}
}
}
logger.LogWarning("Max rounds reached without consensus");
return new ConversationResult(
_history[^1].Content, _history.AsReadOnly(),
config.MaxRounds, sw.Elapsed);
}
}Multi-Agent Orchestration Pattern Architecture
hourglass_empty
Rendering diagram...
lightbulb
Multi-Agent Orchestration Pattern in the Real World
“A film director (Orchestrator) does not personally operate the camera, compose the score, or design costumes. Instead they delegate to specialist department heads — cinematographer, composer, costume designer — each expert in their domain. The director collects their work, gives feedback, and integrates it into a coherent film.”