Copilot Studio Cheat Sheet
Build agents that actually ship — grounded, governed, and able to act. Topics and nodes, generative vs classic orchestration, Power Fx in the conversation, variables and entities, knowledge sources and grounding, tools and actions, authentication, channels, ALM, and the analytics that tell you whether it works.
Fundamentals
Copilot Studio is the low-code tool for building agents — conversational and autonomous AI assistants grounded in your data and able to act on it. An agent combines instructions, knowledge (what it can answer from), tools (what it can do), and topics (authored conversation paths). It builds on Power Platform, so agents live in environments, ship in solutions, and obey DLP. (Copilot Studio is the successor to Power Virtual Agents; older bots are now labelled classic and don’t support the generative features.)
- Agent — the top-level thing you build and publish. New agents default to generative orchestration.
- Topic — an authored slice of conversation on a canvas, made of nodes (message, question, condition, tool call…).
- Knowledge — sources the agent searches to answer (SharePoint, Dataverse, files, public websites, web search…).
- Tool — an action the agent can call (connector, agent flow, prompt, REST API, MCP server, computer use).
- Orchestration — how the agent decides what to do next: generative (the model chooses) or classic (trigger phrases pick one topic).
Author the business-critical parts; let AI do the rest
The modern design pattern is *not* hundreds of rigid topics. Author topics for the flows that must be exact (auth, payments, consent, regulated wording), ground everything else in trusted knowledge, and let generative orchestration combine topics, tools, and knowledge for the long tail.
Orchestration: generative vs classic
Orchestration decides who controls the next step — the model or the author. Generative orchestration (default for new agents) lets the agent pick the best mix of topics, tools, knowledge, and other agents from their descriptions, auto-ask for missing inputs, and compose the reply. Classic orchestration matches the user’s message to one topic’s trigger phrases and runs exactly what you authored. Toggle it on the agent’s Overview page under Orchestration.
| Behaviour | Generative orchestration | Classic orchestration |
|---|---|---|
| Topic selection | By each topic’s description | By matching trigger phrases |
| Tools / actions | Agent calls them by name + description | Only when explicitly called from a topic |
| Knowledge | Proactively searched to answer | Fallback when no topic matches (or called in a topic) |
| Multiple sources | Combines topics + tools + knowledge | Tries to pick one topic, falls back to knowledge |
| Asking for input | Auto-generates questions for missing inputs | You add Question nodes for every input |
| Responding | Auto-composes the response | You author Message nodes (or call a tool) |
| Other agents | Can route to child / connected agents | Not applicable |
Descriptions are the new trigger phrases
In generative mode a topic’s Trigger node becomes The agent chooses and selection rides entirely on the topic, tool, and knowledge descriptions. Write them like you’re briefing a colleague: what it does, when to use it, what it needs. Turning generative on for a classic agent auto-generates descriptions from trigger phrases — review them, don’t trust them blindly.
Pick classic when the path must be exact
- Authentication and identity verification, consent capture, PCI / payment collection.
- Regulatory or legal wording that must be delivered verbatim, in a fixed order.
- DTMF menu flows and any journey where exact steps matter more than flexibility.
- You can still use generative answers inside a classic agent as a fallback for unmatched questions.
Known limits before you flip to generative
With generative orchestration the Conversational boosting and Multiple Topics Matched system topics aren’t used, custom entities (closed-list / regex) aren’t yet supported as topic or tool *input* parameters (use a Question node), conversation history fed to the model is limited, and hyperlinks from knowledge render as plain text. Test thoroughly before turning it on for an existing agent.
Topics & nodes
A topic is a portion of a conversation defined on the authoring canvas as a graph of nodes. Agents start with system topics (essential behaviours you can customise but not create) and a few predefined custom topics (greeting, end of conversation…). Every topic you add is a custom topic. Under the hood a topic is an AdaptiveDialog you can also edit as YAML in the code editor or the VS Code extension.
| Node | What it does | Notes |
|---|---|---|
| Send a message | Show text / rich content to the user | Supports variables, Markdown, Adaptive Cards |
| Ask a question | Prompt the user and capture the answer | Identifies an entity → fills a variable (slot filling) |
| Add a condition | Branch the conversation | Switch to a Power Fx formula for complex logic |
| Set a variable value | Assign a variable | Use a literal or a Power Fx formula |
| Add a tool | Call a connector / flow / prompt / REST / MCP | Inputs + outputs map to variables |
| Create generative answers | Search & summarise knowledge | Topic-level grounding with citations |
| Ask with Adaptive Card | Collect input via a card | JSON or a Power Fx formula |
| Topic management | Redirect / Go to another topic | Reuse bite-size topics; pass inputs/outputs |
| Send HTTP request | Call a REST endpoint directly | Parse the response into a variable |
| Parse value | Coerce a value to a type / schema | Turn JSON into a typed record/table |
| End / Transfer conversation | Close out or hand off | Transfer escalates to a live agent |
Key system topics
| System topic | Purpose |
|---|---|
| Conversation Start | Begins the conversation automatically (on by default) |
| Greeting / Thank you / Goodbye | Social niceties; Goodbye ends the conversation |
| Escalate | Hand off to a live agent |
| Fallback | No topic matched the user — try generative answers, then escalate |
| Conversational boosting | Generative answers over knowledge before fallback (classic mode) |
| Multiple Topics Matched | Disambiguation — the “did you mean?” prompt |
| End of Conversation | Triggers the CSAT survey; mark resolution here |
| On Error / Reset Conversation | Error handling and full reset of variables |
Bite-size, reusable topics beat a few giants
Break logic into small topics and call them with Redirect so one fix updates every caller. Topics don’t all need trigger phrases — a redirect-only topic with input/output variables is the conversational equivalent of a function.
Never put a period in a topic name
You can’t export a solution containing an agent whose topic name has a period (.). It silently breaks ALM — keep names clean from day one.
Triggering topics
A topic can start four ways: from the user’s utterance (intent recognition via trigger phrases, classic), because the agent chooses it from its description (generative), from a Redirect in another topic, or from an event (conversation start, inactivity, custom event, an error, an autonomous trigger).
| Trigger | Mode | When it fires |
|---|---|---|
| Trigger phrases (intent) | Classic | User utterance matches the NLU model |
| The agent chooses (description) | Generative | Model selects the topic by its description |
| Redirect / Go to topic | Both | Another topic explicitly calls this one |
| Conversation Start | Both | A new conversation begins |
| Inactivity | Both | User idle past the configured time |
| Activity received / Custom event | Both | A channel event or custom signal arrives |
| On Error | Both | An unhandled error occurs in the agent |
Trigger-phrase hygiene (classic)
Give each topic 5–10 short, varied trigger phrases — keywords and questions, not long sentences. The match is fuzzy: “see store opening hours” still hits a topic trained on “check store hours.” You can bulk upload/replace phrases from a text file. For generic words like “request” or “issue,” split into more specific topics so triggering stays sharp.
Variables & scope
Variables store user responses and carry state. They live at four scopes. Question nodes auto-create an output variable of the right type; you can promote a topic variable to global, and pass variables in and out of topics and Power Automate (whole records and tables, not just primitives).
| Scope | Visibility | Power Fx prefix |
|---|---|---|
| Topic | Only the topic that created it (default) | Topic. |
| Global | Every topic in the agent | Global. |
| System | Built-in context, all topics | System. |
| Environment | Power Platform env var, read-only | Environment. |
Useful system variables
| Variable | Type | What it holds |
|---|---|---|
| Activity.Text | string | The most recent message from the user |
| Activity.Channel / ChannelId | choice / string | The channel the conversation is on |
| Activity.From.Name | string | Channel display name of the sender |
| Conversation.Id | string | Unique ID of the current conversation |
| Conversation.InTestMode | boolean | True when running in the test canvas |
| Conversation.LocalTimeZone | string | User’s IANA time zone |
| Bot.Name / Bot.Id / Bot.EnvironmentId | string | Identity of the agent and its environment |
| LastMessage.Text | string | The previous user message |
| FallbackCount | number | Times no topic matched (On Unknown Intent) |
| Error.Code / Error.Message | string | Current error detail (On Error trigger only) |
| User.DisplayName / User.Id | string | The signed-in user (when authenticated) |
Some system variables are hidden — reach them with Power Fx
The variable picker doesn’t list every system variable. To use a hidden one, write a Power Fx formula and prefix it with System. — e.g. System.Conversation.Id or System.Activity.ChannelId.
Entities & slot filling
An entity is a type of information the NLU model extracts from a message (an email, a date, money, a person). Slot filling stores that extracted value into a variable — and lets the agent *skip* questions whose answers were already in the user’s opening line. “I’d like 3 large blue t-shirts” can fill quantity, size, and colour at once.
| Prebuilt entity | Base type | Example |
|---|---|---|
| String | ada@contoso.com | |
| Date and time | DateTime | next Friday at 3pm |
| Number / Integer | Number | 3, forty-two |
| Money | Number | $100, a hundred dollars |
| Person name | String | Ada Lovelace |
| Phone number | String | +1 555 0100 |
| City / State / Country or region | String | Seattle |
| Boolean | Boolean | yes / no |
| Percentage | Number | 20% |
| URL | String | https://flowlibs.com |
| Multiple-choice options | Choice | a button selection |
Custom entities
- Closed list — a fixed set of values with optional synonyms (e.g. *Hiking* ← “trekking”, “mountaineering”).
- Regular expression — values in a fixed format, ideal for IDs like
INC000001(^INC[0-9]{6}$). - Dynamic (open list) entity — values supplied at runtime from a table variable (≤ 100 entries); great for per-user lists like payees or accounts.
- One of multiple entities — accept any of up to five entities at one turn; the answer is a *record* (
Identifier.account,Identifier.phone…).
Proactive slot filling makes agents feel smart
Use entities in your Question nodes and the agent fills what it already heard and only asks for what’s missing. Need to force a prompt anyway? Set the Question node’s Skip question behaviour to Ask every time. Note: in generative orchestration, custom entities can’t be topic/tool inputs yet — collect them with a Question node.
Power Fx in agents
Power Fx is the Excel-like formula language for logic inside an agent — set a variable, evaluate a condition, parse a string, shape a table, or build a dynamic Adaptive Card. It’s the *data* layer of the conversation: there are no UI/behaviour functions here (no Navigate, SubmitForm, screens). You set state with the Set a variable value node, not a Set() call, and reference variables with their scope prefix.
| Where | How | Example |
|---|---|---|
| Set a variable value | Formula tab → fx | Upper(Text(Topic.customerName)) |
| Condition node | “Change to formula” | Topic.bookingDate > DateAdd(Now(), 14) |
| Message / question text | Inline variable + functions | Concatenate("Hi ", Topic.name) |
| Adaptive Card | Switch JSON → Formula | Bind Topic.Title into the card body |
| Knowledge / generative URL | Dynamic data source | Build a URL from a lookup table |
Reference variables by scope
System.Conversation.Id // system variable
Global.gblUserName // global variable
Topic.customerName // topic variable
Environment.ApiBaseUrl // Power Platform environment variableSet a variable with a formula
Upper(Text(Topic.customerName))A condition as a formula
Topic.bookingDate > DateAdd(Now(), 14)US number formatting — commas separate arguments
Power Fx in Copilot Studio uses US-style numbers (the dot is the decimal point, as in 1,234.50), so the argument separator is a comma. Named formulas and user-defined functions can’t be generated by the in-product Copilot, and the Copilot helper only reuses variables that already exist.
Knowledge & grounding
Knowledge sources ground the agent’s answers in trusted content instead of the model’s general training. Add them on the Knowledge page (agent-wide) or in a Create generative answers node (topic-level). Internal files are chunked, vector-indexed, and stored in Dataverse; web and SharePoint use Bing/Graph search. Source limits differ by orchestration mode — and a generative-answers *node* always uses classic processing, so its public-site cap is 4 even when the agent is generative.
| Source | Generative limit | Classic limit | Auth |
|---|---|---|---|
| Public website (Bing) | 25 sites | 4 sites | None |
| File upload / Documents | All documents | Dataverse storage | None |
| SharePoint (Graph) | 25 URLs | 4 URLs / node | User Entra ID |
| Dataverse tables | Unlimited | 2 sources (≤15 tables each) | Authenticate with Microsoft |
| Enterprise data (Graph connectors) | Unlimited | 2 per agent | User Entra ID |
| Web search (real-time Bing) | On/off | Not available | None |
| Real-time structured (Salesforce, ServiceNow, Azure SQL, Zendesk) | Supported | — | Connector |
- Public website URLs allow up to two path levels (
contoso.com/engines/rotary); sites that need auth or aren’t Bing-indexed (wikis, SharePoint) don’t work as public sources. - Generative answers supported content: SharePoint modern pages, Word (
.docx), PowerPoint (.pptx), and PDF. - Dataverse knowledge needs Dataverse search enabled and Authenticate with Microsoft; add synonyms and a glossary so the model maps business terms.
- Citations are returned automatically; if you customise the answer (store it in a variable for a card) you must render citations yourself, especially in Teams.
Content moderation trades coverage for safety
Each generative-answers node has a moderation level from Lowest to Highest (default High). Lower levels return more answers but loosen the harmful-content filter; higher levels return fewer, stricter answers. If a node returns nothing, moderation is a prime suspect.
Descriptions drive knowledge selection too
In generative orchestration the agent decides *which* knowledge source to search from its description. Give each source a specific, jargon-aware description — it’s the difference between the model reaching for the right corpus and guessing.
Tools & actions
Tools let an agent *do* things, not just answer. In generative orchestration the agent calls tools automatically based on their name and description; in classic mode you call them from a node inside a topic. The same underlying tool (a flow, a connector) can be added to many agents, each with its own input/output wrapper.
| Tool type | Use it for | Notes |
|---|---|---|
| Connector (prebuilt) | Thousands of Microsoft / third-party APIs | Pick a specific action; create a connection |
| Custom connector | Your own API via an OpenAPI definition | Needs org view + share permission |
| Agent flow | Multi-step automation in Power Automate | Returns data / performs actions |
| Prompt | Single-turn model call with instructions | Can reference knowledge; bring your own model |
| REST API | Call API endpoints directly | Select methods to expose as tools |
| Model Context Protocol (MCP) | Connect to an MCP server’s tools/resources | Discoverable tool + resource list |
| Computer use | Drive a GUI app with no API | Needs a provisioned machine |
End-user vs maker credentials
Tools run in the user context and need authentication. End-user credentials mean each user only touches data they’re allowed to (best for personalised access). Maker-provided credentials use the author’s connection for shared resources. Anonymous (No authentication) agents can’t run tools that need user credentials.
A good description is most of the work
For a tool the agent might auto-call, the description is how it decides when and how. State plainly what the tool does and the questions that should trigger it. Let Copilot fill obvious inputs, but mark anything sensitive or ambiguous to be filled at authoring time.
Authentication
Set authentication under Settings → Security → Authentication. It controls who can chat, which variables you get, and which channels are available — and changes only take effect after you publish.
| Option | Behaviour | Auth variables |
|---|---|---|
| No authentication | Anyone with the link; public knowledge only; no user-credential tools | None |
| Authenticate with Microsoft | Entra SSO; auto-config for Teams / M365 / Power Apps | User.DisplayName, User.Id (+Email, names) |
| Authenticate manually | Entra V2 (federated / cert / secret) or Generic OAuth 2 | User.DisplayName, User.Id, User.IsLoggedIn, User.AccessToken |
- Teams and all Microsoft channels require authentication — they can’t be anonymous. Use Microsoft auth, or manual auth if you also need other channels.
- User.AccessToken / User.IsLoggedIn only exist with manual auth — pick it when a topic needs a token for a downstream API.
- Federated credentials (secret-less, short-lived OIDC tokens) are the recommended manual setup over stored client secrets.
- A Power Platform data policy can *require* authentication, which removes the No-authentication option entirely.
Don’t disable auth if tools depend on it
If any tool is configured to require user credentials, turning auth off at the agent level breaks it. Switching auth modes can also leave User.AccessToken / User.IsLoggedIn as Unknown variables — fix the topic errors before publishing.
Channels & publishing
You must publish before anyone can use the agent, and a single publish updates every connected channel — make a change, publish again, or users stay on the old version. Add channels after the first publish.
| Channel | Notes |
|---|---|
| Teams + Microsoft 365 Copilot | Org users; requires authentication |
| SharePoint | Microsoft channel; requires authentication |
| Demo website | Prebuilt page for stakeholder testing — not production |
| Custom website | Embed on your live site (Web Chat / React) |
| Mobile app / custom app | Via the Direct Line API |
| WhatsApp / Facebook | Messaging channels |
| Azure Bot Service channels | Slack, Telegram, Twilio, Line, Email, and more |
Test chat vs demo website
Use the Test agent panel while building to watch the flow and variables (turn on tracking between topics). Share the demo website with teammates and stakeholders for feedback — but never with customers; it isn’t for production. Publishing to the org catalog (Teams / M365) can require admin approval in the Microsoft 365 admin center.
ALM & environments
Copilot Studio brings Power Platform ALM into the app. Every agent belongs to a solution; author unmanaged in DEV and import managed to TEST/PROD, or deploy with pipelines in one click. Keep config out of the agent so it travels cleanly between environments.
- Solutions — set a preferred/default solution so new agents and components land in the right place; export/import or use pipelines from inside Copilot Studio.
- Environment variables — store URLs, list names, and thresholds; reference them in Power Fx with
Environment.so values rebind per environment. - Connection references — one per connector/purpose so credentials rotate in a single place across all flows and tools.
- Environment strategy — at least DEV/TEST/PROD, governed with DLP and Managed Environments; lock down the Default environment.
- Avoid hardcoding — no inline site URLs, keys, or emails; secrets belong in Key Vault via environment variables.
Build solution-aware from day one
Authoring inside a solution from the start makes the agent portable and reviewable. Retrofitting a finished agent into ALM later is painful — and a topic name with a period will block the very first export.
Analytics
Every published agent emits analytics from the first conversation. The unit is the session: a continuous interaction addressing the user’s questions within a 60-minute window (and ≤ 100 turns). Review these monthly and act on the gaps.
| Metric | What it measures |
|---|---|
| Total sessions | Analytics sessions in the period (one chat can be several) |
| Engagement rate | % of sessions that triggered a custom topic, Escalate, Fallback, or Conversational Boosting |
| Resolution rate | % of engaged sessions resolved (confirmed at End of Conversation, or implied) |
| Escalation rate | % of engaged sessions handed off (Escalate / Transfer) |
| Abandon rate | % of engaged sessions idle 60 min with no resolution/escalation |
| Deflection rate | % of requests self-served instead of escalated |
| CSAT | Average End-of-Conversation survey score (1–5) |
| Reactions / Sentiment / Themes | Thumbs (28 days), AI sentiment, AI-grouped question themes |
Design conversations to end at End of Conversation
Resolution and CSAT are measured at the End of Conversation topic. Redirect successful paths there so the agent asks “Did that answer your question?” — otherwise good outcomes show up as *implied* or *abandoned* and your numbers understate the agent. Mine unrecognised utterances and themes to find topic-coverage gaps.
Design best practices
- Lead with knowledge, author the exceptions. Ground broad Q&A in trusted sources; reserve topics for flows that must be exact.
- Write descriptions like briefs. In generative mode, topic/tool/knowledge descriptions *are* the routing logic — be specific about what and when.
- Keep topics bite-size and reusable. Redirect into shared topics; pass inputs/outputs; one fix propagates everywhere.
- Use entities and slot filling so the agent asks only for what’s missing — fewer turns, happier users.
- Centralise config in environment variables and connection references; never hardcode URLs, list names, or secrets.
- Authenticate by default, apply least-privilege scopes on tools, and prefer federated credentials over stored secrets.
- Test before you widen. Use the test canvas and demo website, validate negative paths, and re-check after flipping to generative orchestration.
- Publish deliberately — every publish hits all channels; review, then ship.
Every cheat table above is searchable
Use the filter box on each table to jump straight to a node, variable, entity, or limit. This whole guide is generated from one structured dataset, so it stays in sync with the FlowLibs MCP reference.