Orchestration: Sequential
Key Points
- Sequential pattern: Agent A → Agent B → Agent C. Output of one feeds the next.
- Use when steps have a clear linear order: research → draft → polish; or extract → transform → summarize.
- Output of each agent enriches the conversation passed to the next.
- More predictable than free-form multi-agent; easier to debug.
Concept
[User input]
│
▼
[Researcher Agent] — finds relevant docs
│ context+findings
▼
[Writer Agent] — drafts based on findings
│ draft
▼
[Editor Agent] — polishes
│
▼
[Final output]
Each agent has a focused role.
Code
var researcher = new ChatClientAgent(chat)
{
Name = "Researcher",
Instructions = "Find relevant documents for the user's question. List 3-5 sources.",
Tools = [AIFunctionFactory.Create(SearchDocs)]
};
var writer = new ChatClientAgent(chat)
{
Name = "Writer",
Instructions = "Write a concise answer based on the researcher's sources. Cite each fact.",
};
var editor = new ChatClientAgent(chat)
{
Name = "Editor",
Instructions = "Polish for clarity and grammar. Keep citations intact."
};
// Sequential orchestration
var orchestration = new SequentialOrchestration([researcher, writer, editor]);
var response = await orchestration.InvokeAsync("Explain quantum tunneling");
SequentialOrchestration runs each agent in turn; appends output to messages; passes to next.
Implementation pattern
If not using a built-in helper:
public class SequentialOrchestration(IList<Agent> agents)
{
public async Task<AgentResponse> InvokeAsync(string input, CancellationToken ct = default)
{
var messages = new List<ChatMessage> { new(ChatRole.User, input) };
AgentResponse? final = null;
foreach (var agent in agents)
{
var resp = await agent.InvokeAsync(messages, ct);
messages.AddRange(resp.Messages);
final = resp;
}
return final!;
}
}
With handoff messages
For agents to know context:
messages.Insert(0, new ChatMessage(ChatRole.System,
$"This is a multi-step pipeline. Current stage: {agent.Name}. Previous outputs are in conversation."));
Streaming
await foreach (var update in orchestration.InvokeStreamingAsync(input))
{
Console.WriteLine($"[{update.AgentName}] {update.Text}");
}
Caller can show "Researcher is searching..." → "Writer is drafting..." → etc.
Use cases
- Content generation: research → draft → polish.
- Code review: linter → test runner → semantic review.
- Data pipeline: extract → transform → summarize.
- Customer issue: classifier → router → resolver.
Trade-offs
| Aspect | Pros | Cons |
|---|---|---|
| Predictable | Easy to debug | Less flexible than free-form |
| Linear | Clear contract | Can't skip; can't loop |
| Cost | Each step adds tokens | Multiplies model calls |
When NOT sequential
- Steps are independent → parallel/concurrent.
- Steps depend on dynamic decisions → handoff or group chat.
- Steps loop with conditions → workflow engine.
Token cost
Researcher: ~3K input + 1K output = $0.005 (gpt-4o-mini)
Writer: ~5K input + 1K output = $0.008
Editor: ~6K input + 800 output = $0.009
Total: ~$0.022 per request
Cumulative input grows with each stage.
Optimization
- Have early stages output structured summaries rather than dumping everything.
- Use cheaper model for early stages.
- Cache early-stage outputs if input deterministic.
Senior considerations
- Each agent should have a CRISP role.
- Test stages independently before composing.
- Limit total iterations (no infinite chains).
- Trace per-stage with OTel.