Defining Copilot Agent Scenarios in TypeSpec - Why This Small Feature Matters More Than It Looks
If you have built a Microsoft 365 Copilot agent and been disappointed, there is a decent chance the problem was not the model, the knowledge sources, or your instructions. It was that Copilot never worked out your agent existed for the question the user asked. The user typed something perfectly reasonable, the orchestrator looked at every available agent, and yours did not win the routing decision. So the built-in Copilot answered instead, or worse, said it could not help, while your carefully built agent sat there unused.
This is one of the least understood parts of building agents for Microsoft 365, and it is where scenarios come in. Microsoft's documentation on scenarios in TypeSpec covers the syntax. I want to explain why this feature exists, because once you understand the routing problem it solves, you build agents differently, and they work noticeably better.
The problem scenarios actually solve
Microsoft 365 Copilot is not one agent. It is an orchestrator sitting in front of many agents, and its job is to look at what a user typed and decide which agent should handle it. Your custom agent is one of potentially dozens the orchestrator could pick. If you have built an agent for, say, checking stock levels in a warehouse system, that agent only helps if the orchestrator routes a "how many pallets of X do we have in the Brisbane DC" question to it rather than trying to answer generically.
The orchestrator makes that decision based on what it knows about your agent: its description, its instructions, and its declared scenarios. Get those wrong and your agent is invisible. It does not matter how good the logic behind it is if it never gets called.
Scenarios are how you tell the orchestrator, in structured terms, "here are the situations this agent is the right choice for". They are not marketing copy for humans. They are routing signals for a machine that has to make a fast decision about where a query goes. That reframing is the whole point. A lot of people write agent descriptions like a product blurb. The orchestrator does not care about your blurb. It cares about matching intent to capability.
Why do this in TypeSpec
You can define an agent's manifest in raw JSON, and plenty of people do. TypeSpec is Microsoft's typed, code-first way to author the same thing, and for anything beyond a toy agent it is the better path. You describe your agent, its capabilities, its actions, and its scenarios in TypeSpec, and it compiles down to the manifest and schemas the platform needs.
The reason we default to TypeSpec on client builds is not novelty. It is that agents are software, and software belongs in source control, in a form you can diff, review, and reason about. Hand-editing a growing JSON manifest is how you end up with a subtle typo that breaks routing and takes an afternoon to find. TypeSpec gives you a compiler that catches structural mistakes before they ship, and a definition that a second engineer can actually read. When you are maintaining a fleet of agents rather than one, that discipline pays for itself quickly. Our Microsoft AI agent framework consultants work this way as a matter of course, because the alternative does not scale past the first demo.
Writing scenarios that actually route well
Here is what we have learned about making scenarios work, which is a bit more opinionated than the docs.
Be specific about the situations, not the features. A weak scenario says the agent "helps with inventory". A strong one describes the actual user moments: a warehouse supervisor checking whether there is enough stock to fulfil a large order, a purchasing officer deciding whether to reorder, an account manager confirming availability before promising a delivery date. The orchestrator matches user intent, and users express intent as situations, not as feature names. The closer your scenarios sit to how a real person phrases a real need, the better the routing.
Cover the phrasings people actually use, including the messy ones. Real users do not speak like documentation. They type "have we got any of the blue widgets left" not "query current inventory quantity for SKU". Your scenarios and the surrounding instructions need to reflect the vocabulary of the people who will use the agent, including regional and industry language. This is one of those areas where knowing the client's actual business matters more than knowing the platform.
Mind the boundaries between agents. If you have several agents in one tenant, badly drawn scenarios cause them to fight over the same queries, and the orchestrator's picks become unpredictable. Scenarios should carve out clear territory. The inventory agent handles stock questions, the logistics agent handles delivery and routing, and their scenarios should not blur into each other. When they do, you get an agent answering questions it is bad at because it won a routing contest it should have lost.
Do not try to be everything. There is a temptation to write broad scenarios so the agent gets called more often. Resist it. An agent that wins routing for questions it cannot answer well is worse than one with a tight, honest scope, because it produces confident bad answers and erodes trust. A narrow agent that nails its lane is far more valuable than a broad one that is mediocre everywhere.
The honest assessment
The part that is genuinely good: scenarios give you real, declarative control over a routing decision that used to feel like a black box. Before this was well supported, getting an agent to reliably trigger involved a lot of guesswork and reverse-engineering. Being able to state the situations your agent is for, in a typed and version-controlled way, is a real improvement and it makes agent behaviour more predictable.
The part that is still rough: it is iterative, and you will not get it right on the first pass. Routing is a live system reacting to real phrasing, and the only way to tune scenarios properly is to watch how actual users trigger, or fail to trigger, your agent and adjust. Budget for that. An agent is not "done" when it compiles and deploys. It is done when you have observed real usage and closed the gap between what users ask and what your scenarios anticipated. Teams that skip that tuning phase ship agents that work in the demo and disappoint in production, and then blame the technology.
The other thing worth saying plainly: this is fiddly platform work that rewards experience. The difference between an agent that routes reliably and one that sits idle often comes down to how well someone understood both the orchestrator's behaviour and the client's real language. It is not hard in the sense of being technically deep. It is hard in the sense that small wording choices have outsized effects and the feedback loop is slow. That is exactly the kind of thing worth getting right early rather than discovering after a failed rollout.
Where this fits
Scenarios are a small feature with a large effect, and they sit inside a bigger truth about building Copilot agents: most of the value is in the design decisions around the model, not the model itself. Which situations the agent claims, how tightly it scopes them, how it plays with the other agents in the tenant. Get those right and a modest agent feels sharp. Get them wrong and a sophisticated one feels broken.
If you are building agents for Microsoft 365 Copilot and finding they do not trigger when they should, or you are planning a rollout and want it done in a way that survives contact with real users, that is the work our AI agent builders do day to day. And if you are earlier than that, still working out which processes are even worth an agent, our AI strategy consultants can help you pick the ones that will actually pay off rather than the ones that demo well.
Microsoft's scenarios documentation has the current syntax and the TypeSpec decorators you will need. The judgement about what to put in them is the bit that comes with experience, and it is worth the investment, because an agent that never gets called is just expensive shelfware.