Designing Multi-Agent Workflows in Copilot Studio
A single Copilot Studio agent handles one domain well. A multi-agent system handles complex enterprise workflows — routing, handoff, shared context, and orchestration. Here's the architecture and the decisions that matter.
Single-agent architectures have clear limits. One agent covering customer service, order management, account queries, and escalation becomes a complicated mess of topics, conditions, and edge cases that’s hard to maintain and harder to extend.
Multi-agent architectures solve this by decomposing the problem: each agent has a narrow, well-defined domain, and an orchestrating layer routes between them based on intent. The system as a whole handles complex workflows; individual agents remain simple and maintainable.
This is the architecture I use for the enterprise solution I’m building, and today I want to walk through the design decisions.
Orchestration vs. Choreography
Before designing the agents, decide on the coordination model.
Orchestration: a central orchestrator agent receives every request and routes to specialist agents. The orchestrator knows the full workflow and controls execution. Specialists report back to the orchestrator.
Choreography: agents communicate directly with each other. Each agent knows which agents to call for tasks outside its scope. No central controller.
For enterprise Copilot Studio deployments, orchestration is almost always the right choice. Here’s why:
- Easier to debug: all routing decisions happen in one place
- Easier to govern: one agent controls what can happen
- Clearer for users: one entry point, consistent experience
- Easier to monitor: orchestrator logs tell you the full flow
Choreography has advantages in highly distributed systems but introduces coordination complexity that isn’t worth it for most enterprise deployments.
The Orchestrator Agent
The orchestrator’s job is narrow: understand intent and route to the right specialist. It should not handle domain-specific queries itself.
Design principles for the orchestrator:
One job: routing. The orchestrator maps user intent to a specialist agent. It does not answer domain questions directly. If it starts handling content itself, it becomes a monolith.
Explicit intent classification. Don’t rely on implicit LLM routing alone. Define explicit intent triggers and confidence thresholds. When confidence is low, prompt for clarification before routing.
Maintain conversation state. The orchestrator tracks which specialist handled the last turn and whether a multi-turn interaction is in progress. It routes follow-up messages to the same specialist until the interaction completes.
Handle handoff context. When routing to a specialist, pass relevant context: user identity, the original query, any already-extracted entities (order number, account ID). The specialist should not need to re-extract information the orchestrator already has.
1
2
3
4
5
6
7
Orchestrator topic: Route Request
- Trigger: Any new conversation turn
- Extract: intent, entities (order_id, account_id, etc.)
- Classify intent confidence
- If confidence > threshold: route to specialist
- If confidence low: ask clarifying question
- Pass context to specialist on handoff
Specialist Agent Design
Each specialist owns a domain. The design principle: a specialist should be able to handle its domain completely, or know when to escalate.
Scope definition. What does this agent handle? What does it explicitly not handle? Write this down. When topics near the boundary arise, the specialist should either handle them or route back to the orchestrator, not try to improvise.
Self-contained knowledge. Each specialist should have access to the knowledge and data it needs without relying on other specialists. Cross-specialist data dependencies create coupling that’s hard to manage.
Completion signals. The specialist needs to signal to the orchestrator when its interaction is complete (task done, user satisfied) vs. incomplete (needs escalation, needs another specialist). Define these signals explicitly.
Escalation paths. When the specialist can’t handle something — out of scope, requires human intervention, policy exception — it escalates cleanly. The escalation path is defined in the specialist’s design, not improvised at runtime.
Handoff Design
The handoff — transferring a conversation from orchestrator to specialist or between specialists — is where multi-agent systems most commonly break.
The handoff must carry:
- User context: identity, authentication state, previous interactions if relevant
- Conversation context: what was asked, what was extracted, why this specialist was chosen
- Task context: what the user is trying to accomplish (not just the immediate message)
In Copilot Studio, context is passed through conversation variables. Design a standard context schema that all agents in the system understand:
1
2
3
4
5
6
7
ConversationContext:
UserId: string
SessionId: string
OriginalIntent: string
ExtractedEntities: object
PreviousAgent: string
HandoffReason: string
Every agent reads from and writes to this schema. Handoffs are context-preserving, not context-discarding.
Graceful Degradation
Multi-agent systems fail in more ways than single agents. A specialist might be unavailable, a connector might timeout, a knowledge source might return no results.
Design for graceful degradation at every layer:
Specialist unavailable: the orchestrator has a fallback — either a generic agent that handles the domain with less capability, or a graceful message explaining the service is temporarily limited.
Partial data: when a data source returns partial results, the agent communicates that clearly rather than presenting incomplete information as complete.
Confidence thresholds: when the orchestrator isn’t confident in its routing, it asks rather than guessing. A wrong specialist handling a query is worse than an orchestrator that asks a clarifying question.
Escalation to human: define clearly when the system should route to a human agent. Unresolvable queries, frustrated users, policy-sensitive requests — these should not loop indefinitely in the automated system.
A Real Architecture Sketch
The multi-agent solution I’m building for enterprise customer support has this structure:
1
2
3
4
5
6
7
8
9
10
11
12
13
User Request
↓
Orchestrator Agent
├── Intent: Order Query → Order Management Agent
│ ├── Data: Order Management System (connector)
│ └── Actions: Status, Track, Modify (with approval)
├── Intent: Account Query → Account Agent
│ ├── Data: CRM (connector)
│ └── Actions: View, Update (with verification)
├── Intent: Policy/FAQ → Knowledge Agent
│ └── Data: SharePoint knowledge base (generative)
└── Intent: Escalation / Low Confidence → Human Handoff
└── Integration: ServiceNow (create ticket)
Each agent is independently deployable and testable. The orchestrator is the only shared dependency. When the order management system is down, only the order agent is affected — the others continue operating.
The Design Principle
Multi-agent architecture is not more complex than single-agent architecture — it’s complexity distributed in a more manageable way. Each agent is simple. The system is powerful because of composition.
Design each agent to be independently testable, independently deployable, and independently understandable. If you can’t explain what an agent does in one sentence, it’s doing too much.
Day 27 of the 30-Day AI Engineering series. Previous: Microsoft Copilot Studio for Developers.