Ordre 20260912T193441Z-7358817909. Steg 1 var ikke transformen, men å rette
roadmapens R13-gate og få den ratifisert. Gaten `grep -rl "Cosmo"
skills/*/references -> 0` var usann på to uavhengige måter:
1. Ordren fanget den første: 451 av forekomstene er Azure Cosmos DB, ekte
produktinnhold. Diskriminatoren er ikke bokstaven «s» — `Cosmos <norsk
substantiv>` er genitiv av personaen (`### Cosmos tonalitet`), mens
`Cosmos DB`/`CosmosClient`/`cosmos_ru` er produkt.
2. Denne økten fant den andre: 132 persona-forekomster ligger i prosa,
tabeller, dialog-replikker og proveniens-linjer. Heading-nøytralisering
kan ikke nå dem, så «0 persona» er uoppnåelig også under den ratifiserte
formen. Operatøren ratifiserte alternativ A: gaten speiler formen, og de
132 bokføres til R13b/R14.
Tre korreksjoner av premisser som sto i ordren og STATE:
«ca 320 produkt» -> 451 (case-sensitivt nett manglet 327 lowercase
TOC-ankre + 99 identifikatorer; sann nevner 1 638)
«169 headinger» -> 401. 169 var `^## For Cosmo`-prefikset (168) og var
internt inkonsistent med sin egen topp-variant (204)
«417 matcher ingen
populasjon» -> 417 er cosmo-headinger utenfor kodefences; briefens
nevner var reell hele tiden
Fence-bevissthet er målt skadelig, ikke nødvendig: begge toggle-regler er
gale på dette korpuset (naiv toggle skjuler en ekte heading i
chain-of-thought-prompting.md, CommonMark-regelen ubalanserer
service-level-documentation-dr.md). Fence-agnostisk deteksjon finner 401
heading-linjer i nøyaktig de samme 40 variantene som fence-bevisst finner
400 i — ingen kodeblokk-linje er byte-identisk til en persona-heading. Derfor
nøkles transformen på 40 enumererte heading-tekster og ignorerer fences. En
ukjent variant kaster; en slug-kollisjon kaster. Ingenting auto-fikses.
TOC-en regenereres ikke, den rettes kirurgisk: alle 327 persona-lenker hadde
lenketekst lik én av de 40 heading-tekstene og anker lik slugify av den
(327/327, 0 avvik), så heading og TOC-entry skrives i samme operasjon og
ingen mellomtilstand etterlater en død lenke.
Ratifisert målform: `For Cosmo`, `For Cosmo Skyberg` og `For arkitekten
(Cosmo)` konvergerer på `For arkitekten`. To filer kolliderte og er adjudisert
ved å lese dem, ikke ved regel.
Verifisering (alle 7 kriterier fra ordren):
G1 persona på heading-linjer 401 -> 0
G2 døde fragmentlenker 1 -> 1 (pre-eksisterende, unntatt)
G3 produkt-forekomster 451 -> 451; `Cosmos DB|Azure Cosmos` 308 = 308
de 3 kun-produkt-filene byte-identiske
nettet validert begge veier injisert persona feller G1; genitiv feller G1;
produkt-heading og de 3 filene passerer
hele diffen 802 heading-linjer + 654 TOC-linjer, ANNET = 0
linjeantall 728 lagt til = 728 slettet
suite 1120/1120 (1097 + 23 nye)
validate-plugin 250 PASS / 0 FAIL
stikkprøve 10 filer, alle 5 skills, inkl. de 3 mest
produkt-tunge (26/20/19) — kun heading+TOC
Utenfor scope, urørt: de 4 SKILL.md, de 23 commands, CLAUDE.md, README.md,
NOTICE.md, docs/ (alt R14).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
20 KiB
Teams Copilot Message Extensions and Plugins
Last updated: 2026-02 Status: GA (Public Preview for agents) Category: Copilot Extensibility & Integration
Introduksjon
Message extensions er en kjernefunksjon i Microsoft Teams og Outlook som lar brukere interagere med eksterne tjenester direkte fra chat-grensesnittet. Med introduksjonen av Microsoft 365 Copilot har message extensions fått en ny rolle som plugins — brukere kan nå bruke naturlig språk for å utløse søk og handlinger, uten å måtte navigere spesifikke UI-kommandoer.
Message extensions som Copilot-plugins representerer et paradigmeskifte: i stedet for å klikke på knapper og fylle ut skjemaer, kan brukeren si "vis produkter på lager" eller "opprett en oppgave i vårt system", og Copilot orkestrerer kallet til riktig plugin basert på kontekst. Svaret leveres som Adaptive Cards, som kan være interaktive og inneholde handlinger.
Arkitektonisk nøkkelegenskap: Message extensions bygges med Bot Framework SDK, som håndterer både Teams-integrasjon og Copilot-orkestrering. Dette gir en konsistent utvikleropplevelse for både bot-baserte applikasjoner og Copilot-plugins.
Kjernekomponenter
Typer message extensions
| Type | Beskrivelse | Bruksområde | Copilot-støtte |
|---|---|---|---|
| Search commands | Søk i eksterne systemer og returner resultater | CRM-søk, dokumentsøk, produktkataloger | ✅ Ja (som agents) |
| Action commands | Utfør handlinger i eksterne systemer | Opprett oppgaver, send data, oppdater poster | ⚠️ Begrenset |
| Link unfurling | Utvid URLer til rike kort automatisk | Forhåndsvis Jira-issues, Figma-design | ❌ Ikke i Copilot |
Arkitektur-komponenter
┌─────────────────────────┐
│ Microsoft 365 Copilot │ ← Bruker: "Vis produkter på lager"
└───────────┬─────────────┘
│ Natural language
↓
┌─────────────────────────┐
│ Message Extension │ ← Plugin (bygget med Bot Framework)
│ (Bot-based) │
└───────────┬─────────────┘
│ Search query
↓
┌─────────────────────────┐
│ Ekstern API │ ← CRM, ERP, Database, etc.
└─────────────────────────┘
│
↓ JSON response
┌─────────────────────────┐
│ Adaptive Card │ ← Resultat rendres i Copilot/Teams
└─────────────────────────┘
Manifest-struktur (app manifest v1.17+)
{
"manifestVersion": "1.17",
"composeExtensions": [
{
"botId": "bot-app-id-guid",
"commands": [
{
"id": "searchProducts",
"type": "query",
"title": "Search products",
"description": "Find products in inventory",
"semanticDescription": "This command searches the company product inventory based on product name, SKU, category, or stock status. Use it when the user wants to find product information or check availability.",
"parameters": [
{
"name": "productName",
"title": "Product name",
"description": "Name or SKU of the product",
"inputType": "text",
"semanticDescription": "The product name, SKU code, or partial match. Supports wildcards."
}
]
}
]
}
]
}
Kritisk: semanticDescription er obligatorisk for Copilot-integrasjon. Den brukes av LLM-en til å matche brukerintensjon mot riktig command.
Adaptive Cards som response
Message extensions returnerer resultater som Adaptive Cards:
// Eksempel: Search command handler (TypeScript)
app.on('message.ext.query', async ({ activity }) => {
const searchQuery = activity.value.parameters[0].value;
const results = await searchProductAPI(searchQuery);
const cards = results.map(product => ({
card: {
type: 'AdaptiveCard',
version: '1.5',
body: [
{ type: 'TextBlock', text: product.name, weight: 'Bolder', size: 'Large' },
{ type: 'TextBlock', text: `SKU: ${product.sku}` },
{ type: 'TextBlock', text: `In stock: ${product.stock}` }
],
actions: [
{ type: 'Action.OpenUrl', title: 'View details', url: product.url }
]
},
preview: {
type: 'ThumbnailCard',
title: product.name,
text: product.sku
}
}));
return {
composeExtension: {
type: 'result',
attachmentLayout: 'list',
attachments: cards.map(c => cardAttachment('adaptive', c.card))
}
};
});
Arkitekturmønstre
1. Search-based plugin (anbefalt for Copilot)
Fordeler:
- Enkleste vei til Copilot-integrasjon
- Krever kun Bot Framework-kompetanse
- Fungerer både i Teams og M365 Copilot (Teams, Word, PowerPoint)
- Støtter SSO og Microsoft Entra-autentisering
Ulemper:
- Begrenset til søk — kan ikke utføre skrive-operasjoner
- Avhengig av god
semanticDescriptionfor intent matching - Kan ikke legges til fra declarative agents (per feb 2026)
Når bruke:
- Readonly data fra eksterne systemer (CRM, ERP, dokumentarkiv)
- Integrasjon med eksisterende REST API
- Raskt proof-of-concept for Copilot-extensibility
2. Action-based plugin med task modules
Fordeler:
- Kan utføre skriveoperasjoner (opprett, oppdater, slett)
- Støtter multi-step forms i dialogs
- Rik UI med Adaptive Cards i task modules
Ulemper:
- Mer kompleks implementasjon
- Begrenset støtte i Copilot (kun som standalone Teams-app)
- Krever mer testing for UX-flyt
Når bruke:
- Opprett oppgaver/tickets i eksterne systemer
- Forms med validering og multi-step flows
- Teams-først, Copilot som nice-to-have
3. Hybrid (Graph Connector + Message Extension)
Fordeler:
- Graph Connector indekserer data til M365-søk
- Message Extension gir real-time data
- Copilot kan bruke begge kilder
Ulemper:
- Dobbel implementasjon (indexing + bot)
- Kostnadsoverhead for Graph Connector
Når bruke:
- Store datamengder som bør indekseres
- Kombinasjon av historiske data (Graph) og real-time (message extension)
- Compliance-krav om datakopier i M365
Beslutningsveiledning
Beslutningstabell: Message Extension vs. andre Copilot-extensibility-veier
| Kriterium | Message Extension | Graph Connector | Copilot Studio | API Plugin (declarative) |
|---|---|---|---|---|
| Real-time data | ✅ Ja | ❌ Nei (indeksert) | ✅ Ja | ✅ Ja |
| Skrive-operasjoner | ⚠️ Action commands | ❌ Nei | ✅ Ja (via flows) | ✅ Ja |
| Krever Azure Bot Service | ✅ Ja | ❌ Nei | ❌ Nei | ❌ Nei |
| Low-code | ❌ Nei (krever kode) | ⚠️ Delvis | ✅ Ja | ⚠️ Delvis |
| SSO-støtte | ✅ Ja (Entra ID) | ✅ Ja | ✅ Ja | ✅ Ja |
| Kostnad (dev-tid) | Middels (2-4 uker) | Lav (1-2 uker) | Lav (dager) | Lav-middels |
| Kostnad (drift) | Azure Bot Service | Graph API calls | Power Platform | Ingen (kun API-host) |
| Tilgjengelig i M365 Copilot | ✅ Ja (preview) | ✅ Ja | ✅ Ja | ✅ Ja |
| Tilgjengelig i Teams | ✅ Ja | ❌ Nei (kun søk) | ✅ Ja | ⚠️ Via agent |
Vanlige feil
| Feil | Konsekvens | Løsning |
|---|---|---|
Manglende semanticDescription |
Copilot finner ikke plugin | Skriv detaljert beskrivelse av når command skal brukes |
| Hardkodet parameter-verdier | Plugin fungerer ikke i Copilot | Bruk dynamic parameters og parameter descriptions |
| For store Adaptive Cards | Rendering-feil i Word/PowerPoint | Bruk single-column layout, unngå fixed widths |
| Manglende SSO-config | Brukeren må logge inn manuelt | Konfigurer Bot SSO med Entra ID app registration |
| Action.Execute i Adaptive Cards | Fungerer ikke i Teams | Bruk Action.Submit i stedet (Action.Execute kun i webChat) |
Røde flagg (når message extensions IKKE passer)
- ❌ Høyfrekvent polling — Graph Connector er bedre for indeksering
- ❌ Komplekse AI-workflows — Copilot Studio med flere actions er bedre
- ❌ Kun intern M365-data — Bruk Graph API direkte
- ❌ Krav om zero-code — Bruk Copilot Studio eller ferdig Graph Connector
Integrasjon med Microsoft-stakken
Bot Framework + Teams SDK
Message extensions bygges med Bot Framework SDK (v4.x) og Teams SDK (tidligere Teams Toolkit):
// Dependencies
import { App } from '@microsoft/teams.apps';
import { cardAttachment } from '@microsoft/teams.api';
import { AdaptiveCard, TextBlock } from '@microsoft/teams.cards';
const app = new App();
app.on('message.ext.query', async ({ activity }) => {
// Håndter søk fra Copilot eller Teams
});
Microsoft 365 Agents Toolkit (tidligere Teams Toolkit)
Utviklingsverktøy for VSCode/Visual Studio:
- Scaffolder message extension-prosjekter
- Automatisk provisjonering i Azure (Bot Service, App Registration)
- Debugging i Teams og Copilot side-by-side
- Publisering til Teams App Store
Azure-infrastruktur
| Tjeneste | Formål | Kostnad |
|---|---|---|
| Azure Bot Service | Hosting av bot-logikk | ~$0.50 per 1000 meldinger (Standard tier) |
| App Service / Functions | REST API for bot | Pay-as-you-go (F1 tier gratis for dev) |
| Application Insights | Telemetri og logging | Gratis tier (5 GB/måned) |
| Entra ID App Registration | SSO og autentisering | Gratis |
Copilot-orkestrering
Når message extension er registrert som plugin i M365 Copilot:
- Bruker sender prompt til Copilot: "Vis siste ordrer fra CRM"
- Copilot analyserer intent og matcher mot plugin
semanticDescription - Copilot ekstraher parametere fra prompt (eks: "siste" → dateFilter)
- Copilot kaller message extension via Bot Framework
- Message extension henter data fra CRM API
- Adaptive Card returneres til Copilot
- Copilot genererer naturlig språk-respons + viser kortet
Viktig: Copilot-orkestrering er ikke-deterministisk. Test med flere prompts for å verifisere plugin-matching.
Offentlig sektor (Norge)
GDPR og databehandling
Message extensions prosesserer data i sanntid — data lagres ikke i Microsoft 365 med mindre det returneres som Adaptive Card i chat-historikk.
Implikasjoner:
- ✅ Mindre GDPR-risiko enn Graph Connectors (som indekserer data)
- ⚠️ Chat-historikk lagres — Adaptive Cards med persondata lagres i Teams/Copilot-samtaler
- ✅ Dataminimering — kun data som returneres i Adaptive Card lagres
Anbefaling: Ikke returner sensitiv personinformasjon (personnummer, helseopplysninger) i Adaptive Cards med mindre det er eksplisitt nødvendig. Bruk Action.OpenUrl for å sende bruker til sikret portal.
Schrems II og data residency
- Azure Bot Service kan provisioneres i West Europe (Amsterdam) for EU-residency
- Bot-kode kan kjøre i Norge (Azure Norway East/West) via App Service
- M365 Copilot-prosessering skjer i EU for europeiske tenants (per Microsoft Data Protection Addendum)
Sjekkliste:
- Azure Bot Service i West Europe region
- App Service i Norway East/West (hvis mulig)
- App Registration i norsk Entra ID tenant
- Verifiser Data Processing Agreement med Microsoft
AI-loven (EU AI Act)
Message extensions som bruker Copilot klassifiseres som AI-system med begrenset risiko (limited risk):
- Krav om transparens — brukeren må kunne se når plugin brukes
- Krav om logging — spor hvilke data som sendes til/fra plugin
Implementasjon:
- Copilot viser automatisk hvilke plugins som brukes i svar (citations)
- Logg alle API-kall i Application Insights for audit trail
- Inkluder versjonsnummer i bot manifest for sporbarhet
Forvaltningsloven og arkivering
Chat-historikk i Teams/Copilot er underlagt arkiveringskrav for offentlig sektor (Arkivlova §6).
Anbefaling:
- Konfigurer retention policies i Microsoft 365 Compliance Center
- Eksporter chat-historikk med eDiscovery ved behov
- Vurder å IKKE inkludere arkivpliktig informasjon i Adaptive Cards (bruk Action.OpenUrl i stedet)
Kostnad og lisensiering
Lisenskrav
| Komponent | Lisenskrav | Kostnad (ca. pris Norge, 2026) |
|---|---|---|
| Teams | Microsoft 365 E3/E5 | Inkludert i E3/E5 |
| Microsoft 365 Copilot | Copilot for M365 license | ~300 NOK/bruker/måned |
| Azure Bot Service | Azure-abonnement | ~0.50 USD per 1000 meldinger (Standard) |
| App Service (F1/B1) | Azure-abonnement | Gratis (F1) / ~70 NOK/måned (B1) |
Total Cost of Ownership (TCO) estimat
Scenario: 100 brukere, 50 søk per bruker per måned
| Kostnadspost | Beregning | Kostnad (NOK/måned) |
|---|---|---|
| M365 Copilot-lisenser | 100 × 300 NOK | 30 000 |
| Azure Bot Service | 5000 meldinger × 0.005 NOK | 25 |
| App Service (B1) | 1 instans | 70 |
| Application Insights | Under 5 GB/måned | 0 (gratis tier) |
| Total | 30 095 NOK/måned |
Optimalisering:
- Bruk Free tier for Bot Service i dev/test (10 000 meldinger gratis)
- Kombiner flere message extensions i samme bot (deler Bot Service-kostnad)
- Bruk Azure Functions Consumption Plan i stedet for App Service for sporadisk bruk
ROI-faktorer
| Gevinst | Estimert tidsbesparelse | Verdi (100 brukere) |
|---|---|---|
| Raskere CRM-søk | 5 min/dag/bruker | ~400 timer/måned |
| Færre kontekstbytter | 10 min/dag/bruker | ~800 timer/måned |
| Self-service uten opplæring | 30 min engangsopplæring | 50 timer |
Breakeven: Hvis tidsbesparelse > 1200 timer/måned (verdi ~600 000 NOK ved 500 NOK/time), er ROI positiv første måned.
For arkitekten
Spørsmål å stille kunden
-
Datakilder og tilgang:
- Hvilke eksterne systemer skal Copilot kunne søke i? (CRM, ERP, dokumentarkiv)
- Har disse systemene REST APIer? Krever de autentisering (OAuth, API-keys)?
- Er dataene sanntids-data, eller kan de indekseres (Graph Connector)?
-
Bruksmønstre:
- Skal brukerne bare søke (read-only), eller også opprette/endre data?
- Hvor mange brukere? Hvor ofte vil de bruke pluginen? (kostnad)
- Skal pluginen brukes i Teams, Copilot, eller begge?
-
Sikkerhet og compliance:
- Inneholder dataene personopplysninger? (GDPR)
- Er det krav om data residency i Norge/EU? (Schrems II)
- Må chat-historikk med plugin-resultater arkiveres? (Forvaltningsloven)
-
Eksisterende infrastruktur:
- Har dere Azure-abonnement? (Bot Service hosting)
- Har dere DevOps-pipeline for CI/CD?
- Hvem skal eie koden og driften? (IT-avdeling, utviklingsteam)
-
Modenhet og kompetanse:
- Har teamet erfaring med Bot Framework / Node.js / C#?
- Har dere tid til å vedlikeholde kode, eller bør dere vurdere Copilot Studio? (low-code)
-
Forventninger til UX:
- Skal resultater vises som rene lister, eller interaktive kort?
- Trenger dere multi-step forms? (task modules)
- Skal brukerne kunne handle direkte fra kortet (Action.OpenUrl)?
-
Testing og utrulling:
- Hvordan skal pluginen testes før produksjon? (pilotgruppe)
- Skal pluginen være tilgjengelig for alle, eller kun spesifikke teams?
-
Fremtidig skalerbarhet:
- Planlegger dere flere plugins? (kan dele samme bot)
- Skal pluginen kunne brukes i andre Copilot-kontekster (Word, PowerPoint)?
Fallgruver å unngå
| Fallgruve | Problem | Løsning |
|---|---|---|
| "Vi trenger AI i Copilot" | Uklar use case | Start med konkret problem: "Saksbehandlere søker i CRM 50 ganger/dag" |
| Overvurdere semanticDescription | Plugin matcher ikke intent | Test med minst 20 ulike prompts før produksjon |
| Ignore adaptive card best practices | Kort renderes dårlig i Word/PowerPoint | Single-column layout, responsive design, test på smaleste viewport |
| Hardkode secrets i bot-kode | Sikkerhetshull | Bruk Azure Key Vault, ikke commit API-nøkler til Git |
| Glemme SSO-konfigurasjon | Brukeren må logge inn hver gang | Konfigurer Bot SSO med Entra ID App Registration fra starten |
| Ikke loggføre API-kall | Umulig å debugge feil i prod | Bruk Application Insights for strukturert logging |
| Anta at Copilot alltid kaller riktig plugin | Brukerfrustrasjon når det feiler | Gi tydelige feilmeldinger i Adaptive Card hvis feil parameter |
Anbefalinger per modenhetsnivå
Nivå 1: "Vi har aldri bygget for Teams/Copilot"
- Start med: Search-based message extension (readonly)
- Verktøy: Microsoft 365 Agents Toolkit i VSCode (scaffolder alt)
- Datakilde: Enkel REST API med offentlig dokumentasjon (eks: produktkatalog)
- Tidsramme: 2-3 uker (inkludert læring)
- Risiko: Lav (ingen skrive-operasjoner)
Nivå 2: "Vi har Teams-apps, men ikke Copilot-plugins"
- Start med: Utvid eksisterende Teams bot til message extension
- Verktøy: Bot Framework SDK (du har allerede bot-logikk)
- Datakilde: Integrer mot eksisterende backend-API med SSO
- Tidsramme: 1-2 uker (gjenbruk av kode)
- Risiko: Middels (må teste Copilot-orkestrering)
Nivå 3: "Vi har Copilot-plugins og vil skalere"
- Start med: Multi-command message extension (flere søk i samme bot)
- Verktøy: Combo av Graph Connector (indeksering) + Message Extension (real-time)
- Datakilde: Flere eksterne systemer (CRM, ERP, dokumentarkiv)
- Tidsramme: 4-6 uker (kompleks orkestrering)
- Risiko: Høy (krever sterk DevOps og testing-pipeline)
Kilder og verifisering
Microsoft Learn (verifisert via MCP, februar 2026)
-
Message extensions for Microsoft 365 Copilot (Verified) https://learn.microsoft.com/en-us/microsoft-365-copilot/extensibility/overview-message-extension-bot
-
Extend bot-based message extension as agent for Microsoft 365 Copilot (Verified) https://learn.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/build-bot-based-agent
-
Adaptive Card response templates for API plugins (Verified) https://learn.microsoft.com/en-us/microsoft-365-copilot/extensibility/api-plugin-adaptive-cards
-
Connect Microsoft 365 Copilot to external data with message extension plugins (Verified) https://learn.microsoft.com/en-us/training/modules/copilot-message-extension-plugins/
-
Adopt, extend and build Copilot experiences across the Microsoft Cloud (Verified) https://learn.microsoft.com/en-us/microsoft-cloud/dev/copilot/overview
-
Teams AI Library - Message Extensions (Verified) https://learn.microsoft.com/en-us/microsoftteams/platform/teams-ai-library/in-depth-guides/message-extensions/
Konfidensnivå per seksjon
| Seksjon | Konfidens | Kilde |
|---|---|---|
| Introduksjon | Verified | MCP microsoft_docs_fetch |
| Kjernekomponenter | Verified | MCP microsoft_docs_fetch + code samples |
| Arkitekturmønstre | Baseline | Modellkunnskap + MCP context |
| Beslutningsveiledning | Baseline | Modellkunnskap (praksis-orientert) |
| Integrasjon med Microsoft-stakken | Verified | MCP microsoft_docs_search |
| Offentlig sektor (Norge) | Baseline | Modellkunnskap (juridisk kontekst) |
| Kostnad og lisensiering | Baseline | Offentlige prislister + erfaring |
| For arkitekten (Cosmo) | Baseline | Best practices fra feltet |
Unike kilder: 6 Microsoft Learn-artikler Dato verifisert: 2026-02-04