Skip to content

Copilot Agent Evidence

Sam Betts edited this page Nov 4, 2026 · 5 revisions

Copilot → Copilot Agent Evidence

Credit Estimation

Calculation fix shipped in 1852; no historical estimate backfill. A stored zero from an older build is not evidence that Microsoft billed nothing. This estimate is a model over audit fields, separate from actual consumption and Azure currency.

For interactions with a custom-engine agent, the engine estimates the number of Copilot Credits consumed based on the Microsoft Copilot Studio billing model. This is an estimate from the audit log, not a bill: the Agent costs page shows what Microsoft actually charged.

Billing Category Credits How Detected
Generative answer 2 per response Response messages that are not prompts.
Tenant Graph grounding 10 per grounded answer Accessed resources from SharePoint, OneDrive, Email, or Teams.
Agent action (e.g. deep reasoning) 5 per action DEEP_LEO model detected in ModelTransparencyDetails.

The credit estimate is stored both as a total (copilot_chats.copilot_credit_estimate_total) and as a JSON breakdown per event (copilot_credit_estimate_json).

Which interactions are priced. Whether an interaction is priced at all depends on the agent's type, and the JSON records the reason in AgentCreditBasis, so a genuine 0 can be told apart from one that was never assessed:

AgentCreditBasis Meaning Credits
CustomEngine A custom-engine agent, such as a Copilot Studio agent. Priced as above. As above
NoMessages A custom-engine agent, but the record carries no messages, so there is nothing to price. Copilot Studio writes its own record for every turn like this. In Microsoft 365 Copilot the same turn is logged again, with its messages, and that record carries the estimate — so a turn is never priced twice. Turns in Teams and the Copilot Studio test pane have only this record, so they are not priced. 0
Declarative A declarative agent, such as a Copilot Studio declarative agent or a SharePoint agent. The model does not price declarative agents. 0
MicrosoftAgent One of Microsoft's own agents, such as Cowork. The model does not price them — which is not the same as saying they use no credits. 0
NotAssessed The audit record does not say what kind of agent it is, so it was not assessed. Count these to see how much agent use the estimate cannot cover. 0
NoAgent Ordinary Microsoft 365 Copilot use, with no agent. Not billed in Copilot Credits. 0

Declarative agents used by people without a Microsoft 365 Copilot licence are not priced. Whether they should be is a billing question the estimate does not try to answer.

Estimates were 0 from Stable build 1552 until the fix for #639. In those builds the importer never worked out what kind of agent an interaction used, so every agent interaction was stored with an estimate of 0. Estimates already stored are not recomputed. Rows written after the fix carry "CostModelVersion": "1.2.0.0" and an AgentCreditBasis; older rows carry an earlier CostModelVersion and no AgentCreditBasis, which is how to tell them apart.

Reference: https://learn.microsoft.com/en-us/microsoft-copilot-studio/requirements-messages-management

App Hosts

The AppHost value indicates which Copilot surface the user was interacting with. Known values include:

Assist365, Bing, BashTool, DevUI, Excel, Loop, M365AdminCenter, M365App, Office, OneNote, Outlook, Planner, PowerPoint, SharePoint, Stream, Teams, VivaCopilot, VivaEngage, VivaGoals, Whiteboard, Word.

A Copilot Studio agent's own runtime logs its channel instead: m365copilot (Microsoft 365 Copilot), Microsoft Teams and Copilot Studio (the maker's test pane). See how a Copilot Studio agent's turns are counted.

Agent type: who made it and what kind it is

Each agent is described by two separate answers, because one yes/no flag cannot hold both: an agent built in Copilot Studio as a declarative agent is customer-built but not custom-engine, and Cowork is Microsoft's but not declarative.

  • Origin — who made the agent: customer-built (your organisation), Microsoft, or unknown. This is what the Copilot Adoption Agents tab and its Excel export show in the Type column, and what is_custom_agent stores.
  • Kind — declarative, custom-engine, or unknown. This decides whether the credit estimate prices an interaction.

The importer works both out from the shape of the identifiers on each audit record. Anything it does not recognise is unknown — it never guesses, so a new kind of identifier from Microsoft shows up as an unknown count rather than as agents filed under the wrong heading.

Identifier on the audit record Kind Origin Why
AgentId starts CopilotStudio.Declarative. Declarative Customer-built Documented by Purview
AgentId starts CopilotStudio.CustomEngine. Custom-engine Customer-built Documented by Purview
AppIdentity (or an agent keyed on it) is Copilot.Studio.{environment}-{schema name}, in the default environment or any other Custom-engine Customer-built Copilot Studio's own record of a turn
AgentPlatform is CopilotStudio, or AppIdentity starts Copilot.Studio.CustomEngine.T_ Custom-engine Customer-built The two records Copilot Studio and Microsoft 365 Copilot write for a Copilot Studio agent
TargetAgentName is present Custom-engine Customer-built Except on the identifiers in the last row, which have also been seen on Microsoft's own agents
Any other Copilot.Studio.* AppIdentity, or CopilotStudio.* agent ID Unknown Customer-built Purview documents both prefixes as agents created through Copilot Studio
SPO_… or SharePointAgents.Declarative.SPO_… Declarative Unknown A SharePoint agent. One a user built and a site's ready-made agent can share the prefix
Copilot.M365Copilot.… (for example Cowork) Unknown Microsoft A vetted list of Microsoft's own agent identifiers
BuiltIn_…, T_…, P_…, a single word, or a bare GUID with nothing else to go on Unknown Unknown Not enough evidence either way

What copilot_agents.is_custom_agent means

Value Meaning
1 Customer-built.
0 Microsoft's own agent.
NULL Not known. The importer could not tell from the audit records it has seen for this agent.

A later record that has nothing to go on (NULL) never overwrites a value that is already known.

Since Stable 1856 (PR #768): the importer commits Copilot activity newest-first, in batches, so on earlier builds an older batch committed after a newer one could put an agent's older display name or is_custom_agent value back. From Stable 1856, migration 202610221500001_CopilotAgentNameAndFlagRecency records how recent the stored name and flag are, and an older batch no longer replaces them. A stored Copilot Studio schema name (such as cr123_contosoHelpdesk) is still replaced by any agreed display name. See Upgrade to Build 1856.

Older rows are not reliable, so don't read them on their own. Before Stable build 1552 the flag was set only for agents keyed on their AppIdentity; from 1552 until the fix for #639 it was never set, so every agent first seen in those builds has NULL, and a 0 from any older build does not mean "Microsoft's". An agent that is used again after the upgrade gets whatever value its new records support. The Copilot Adoption area does not depend on the stored value: it works out each agent's origin from its agent_id when the report runs, and only uses a stored 1 to settle an ID it cannot place by itself. So every agent with a recognisable ID is labelled as soon as you upgrade, with no data migration, and the rest show as Unknown until a new record identifies them.

Power BI. The Copilot Activity Dashboard and Copilot Agent Interactions templates (reports/Copilot/*.pbit) read is_custom_agent directly, so they inherit the meaning above: 1 is customer-built, 0 is Microsoft's, and NULL — which these templates may show as (Blank) — is unknown, not Microsoft's. Agents first seen between Stable build 1552 and the fix stay NULL until a new record identifies them; the Copilot Adoption area is the better source for an agent's origin. Copilot Agent Interactions also reads the credit estimate columns; see the note under Credit estimation about estimates stored before the fix.

To see how your own agents break down (please don't post the results anywhere public):

SELECT CASE is_custom_agent WHEN 1 THEN 'Customer-built' WHEN 0 THEN 'Microsoft' ELSE 'Not known' END AS stored_origin,
       COUNT(*) AS agents
FROM dbo.copilot_agents
GROUP BY is_custom_agent;

How a Copilot Studio agent's turns are counted

Turn pairing shipped in 1852. Stable 1854 removes unsupported same-host timing suppression and adds optional retained-evidence repair. #699's remaining operational acceptance is still open: released code is not proof of a completed historical repair or Power BI refresh.

One turn with a Copilot Studio agent can produce more than one audit record. The importer keeps every record, then lists the extra ones in copilot_chat_duplicates, so that every figure counts the turn once.

Where the agent was used Audit records per turn What is counted
Microsoft 365 Copilot Two. The Copilot Studio runtime logs one (AppHost m365copilot, no messages), and Microsoft 365 Copilot logs another a few seconds later (AppHost Office, with the agent's name, the messages and the credit estimate). The Microsoft 365 Copilot record. The runtime record is listed as its twin. The turn appears under Office, like every other Microsoft 365 Copilot turn, and not under m365copilot as well.
Teams One runtime record (AppHost Microsoft Teams), occasionally followed by an extra one a few seconds later (cause unknown). Each runtime record. A second record a few seconds later, in the same conversation with the same agent and user, is not merged on timing alone, because a quick, genuine second prompt looks the same in the audit data. An actual repeat can therefore count twice.
Copilot Studio test pane One runtime record (AppHost Copilot Studio), and one each time the maker opens or reloads the agent's overview or Channels page. Maker testing — see below.

How the two Microsoft 365 Copilot records are matched. They share only the conversation id (CopilotEventData.ConversationId); their thread ids differ. A runtime record and a Microsoft 365 Copilot record are a pair when they have the same agent, the same user and the same conversation, and the Microsoft 365 Copilot record was logged within 2 minutes after the runtime record (or up to 5 seconds before it, for clock skew). Microsoft 365 Copilot's record has been seen 3–8 seconds after its twin, so 2 minutes leaves room for a slow answer. Pairs are one-to-one, and each record pairs with the nearest candidate, so several quick prompts in one conversation pair turn for turn. It doesn't matter whether the two records arrive in the same import cycle or in different ones, in either order, or are re-imported: whichever arrives second completes the pair, and nothing already paired is paired again.

What still counts in full. An unpaired runtime record remains a turn in overall Copilot-use measures. Agent measures still exclude maker testing as described below. If a Microsoft 365 Copilot twin arrives later, its turn moves from m365copilot to Office, rather than becoming a second turn.

Accessed resources and DLP blocks are counted once per turn too. Both records of a pair can list the same resource (a web-search result has been seen on both), and both can carry the same Copilot DLP block. A resource or block that only one record lists still counts.

Repair of stored DLP copies is bounded. When an import batch revisits a turn, the importer also removes identical stored Copilot DLP copies across its counted record and duplicate constituents, including existing Teams echoes and already-mapped pairs. Identity includes policy, rule, action, resource name/type, sensitivity label and blocked state; different or previously unique evidence survives. Re-importing converges without deleting unrelated turns or other workloads' DLP events. It is not a whole-history purge/backfill: old copies outside the affected batch neighbourhood remain until those turns are re-read. This repair is separate from the additive schema migration and adds no new migration or setting.

Maker testing. Chats in the Copilot Studio test pane (AppHost Copilot Studio) are kept, but they are left out of every agent figure — agent users, interactions, active days, apps used, the Keep / Review / Retire verdict, Top agents, agents used per person — and out of the "by app" charts and licence activity. Copilot Studio's own Monitor page leaves test-panel activity out of its analytics for the same reason. A maker's test chats still count as Copilot use in their own interactions and active days. An agent that has only ever been tested is not in the agent inventory.

Interactions imported before this change are not paired. Their conversation id was not stored, so a Microsoft 365 Copilot turn imported earlier still counts twice. The importer fills in the conversation id of any event it re-reads within its look-back window (DaysBeforeNowToDownload), so the last few days before the upgrade are paired as well.

Changed in 1854: 1852 could suppress a genuine second prompt sent within ten seconds in the same Teams conversation, by listing it in copilot_chat_duplicates with reason = 2. Timing alone does not prove an echo, so 1854 stopped writing those rows. The importer also removes the old ones itself, up to 50,000 per import cycle, so those records count again without any chats or resources being deleted; a large backlog takes a few cycles to clear. Some actual same-host repeats may remain counted; do not claim perfect historical turn reconstruction.

To see how much this affects your own tenant, run against your database (don't post the results publicly):

-- Extra audit records, by reason: 1 = runtime twin of a Microsoft 365 Copilot record;
-- 2 = time-only match written by Stable 1852, no longer created and removed by the importer each cycle
SELECT reason, COUNT_BIG(*) AS records
FROM dbo.copilot_chat_duplicates
GROUP BY reason;

-- Maker testing in the Copilot Studio test pane
SELECT COUNT_BIG(*) AS test_pane_interactions
FROM dbo.copilot_chats
WHERE app_host = N'Copilot Studio';

Return to Copilot · All topics in this guide

Previous: Copilot Backfill Recovery · Next: Copilot Historical Evidence Repair

Start here

Copilot analytics

Using the portal

Install & configure

Beyond Copilot

Operate

Upgrading from an older build

Reference

Project

Clone this wiki locally