# Copilot Agent Integration Patterns

**Last updated:** 2026-02
**Status:** GA
**Category:** Agent Orchestration & Automation

---

## Introduksjon

Integrasjon av agenter med Microsoft Copilot-økosystemet -- Copilot Studio, Microsoft 365 Copilot og Copilot Chat -- gir agenter tilgang til millioner av brukere gjennom kjente grensesnitt i Teams, Outlook, Word og andre Microsoft 365-applikasjoner. Denne integrasjonen utnytter Copilots orkestrator, grunnmodeller og sikkerhetstjenester, slik at agenter arver enterprise-grade compliance, RAI-standarder og governance uten ekstra utviklingsarbeid.

Microsoft tilbyr to hovedveier for agent-integrasjon med Copilot: **Declarative agents** som konfigurerer Copilots innebygde orkestrator med tilpassede instruksjoner, kunnskapskilder og handlinger, og **Custom engine agents** som bruker egne modeller og orkestreringslogikk men eksponeres gjennom Copilots brukergrensesnitt. Valget mellom disse avhenger av behovet for kontroll, fleksibilitet og integrasjonsgrad med Microsoft 365-datakilder.

Copilot Studio fungerer som det primære utviklingsverktøyet for begge agenttyper, med low-code-verktøy for forretningsbrukere og pro-code-muligheter via Microsoft 365 Agents Toolkit for utviklere. Semantic Kernel gir programmatisk integrasjon gjennom `CopilotStudioAgent`-klassen som kobler Copilot Studio-agenter direkte inn i multi-agent orkestreringsflyter.

## Kjernekomponenter

| Komponent | Formål | Teknologi |
|-----------|--------|-----------|
| Copilot Orchestrator | Orkestrer agentforespørsler i M365 | Microsoft 365 Copilot platform |
| Declarative Agent Manifest | Konfigurer agentens kapabiliteter | JSON manifest-filer |
| Copilot Studio | Low-code agentutvikling | Microsoft Copilot Studio |
| Agents Toolkit | Pro-code agentutvikling | VS Code / Visual Studio extension |
| CopilotStudioAgent (SK) | Programmatisk integrasjon | Semantic Kernel Agent Framework |
| Graph Connectors | Tilgang til organisasjonsdata | Microsoft Graph, Copilot connectors |

## Copilot Studio Agent Binding

### Declarative Agent arkitektur

```
┌───────────────────────────────────────────────┐
│              Microsoft 365 Copilot             │
│  ┌─────────────────────────────────────────┐  │
│  │         Copilot Orchestrator            │  │
│  │  - Intent classification                │  │
│  │  - Grounding via Microsoft Graph        │  │
│  │  - RAI filters                          │  │
│  └───────────────┬─────────────────────────┘  │
│                  │                             │
│  ┌───────────────▼─────────────────────────┐  │
│  │       Declarative Agent Config          │  │
│  │  ┌──────────┬──────────┬──────────┐    │  │
│  │  │Custom    │Custom    │Custom    │    │  │
│  │  │Instruc-  │Knowledge │Actions   │    │  │
│  │  │tions     │(SP, Graph│(API      │    │  │
│  │  │          │Connectors│Plugins)  │    │  │
│  │  └──────────┴──────────┴──────────┘    │  │
│  └─────────────────────────────────────────┘  │
│                                               │
│  Surfacing: Teams, Outlook, Word, Excel       │
└───────────────────────────────────────────────┘
```

### Agent manifest-fil

```json
{
    "name": "SaksbehandlingAgent",
    "description": "Hjelper saksbehandlere med å finne relevant regelverk og tidligere vedtak",
    "instructions": "Du er en assistent for saksbehandlere i norsk offentlig sektor. Du hjelper med å finne relevant regelverk, tidligere vedtak og saksbehandlingsrutiner. Svar alltid med kildehenvisning. Følg Forvaltningslovens prinsipper.",
    "capabilities": [
        {
            "name": "WebSearch",
            "disabled": true
        },
        {
            "name": "CodeInterpreter",
            "disabled": true
        },
        {
            "name": "GraphicArt",
            "disabled": true
        }
    ],
    "conversation_starters": [
        {
            "title": "Finn regelverk",
            "text": "Hva sier regelverket om..."
        },
        {
            "title": "Tidligere vedtak",
            "text": "Finn lignende saker der..."
        }
    ],
    "actions": [
        {
            "id": "searchRegulations",
            "file": "regulations-api-plugin.json"
        }
    ]
}
```

## Message Format Adaptation

### Adaptive Cards for rike svar

```json
{
    "type": "AdaptiveCard",
    "version": "1.5",
    "body": [
        {
            "type": "TextBlock",
            "text": "Saksbehandlingsresultat",
            "weight": "Bolder",
            "size": "Large"
        },
        {
            "type": "FactSet",
            "facts": [
                {"title": "Saksnummer", "value": "${saksnummer}"},
                {"title": "Status", "value": "${status}"},
                {"title": "Regelverk", "value": "${regelverk}"}
            ]
        },
        {
            "type": "ActionSet",
            "actions": [
                {
                    "type": "Action.OpenUrl",
                    "title": "Se fullstendig sak",
                    "url": "${sakUrl}"
                },
                {
                    "type": "Action.Submit",
                    "title": "Send til godkjenning",
                    "data": {"action": "approve", "sakId": "${sakId}"}
                }
            ]
        }
    ]
}
```

### Copilot-kompatibelt responsformat

```python
# Formater agentrespons for Copilot-kontekst
class CopilotResponseFormatter:
    def format_for_copilot(self, agent_response: dict) -> dict:
        """Tilpass agentrespons til Copilot-forventninger"""
        return {
            "text": agent_response["content"],
            "citations": [
                {
                    "title": ref["title"],
                    "url": ref["url"],
                    "content": ref["snippet"]
                }
                for ref in agent_response.get("references", [])
            ],
            "followup_prompts": agent_response.get("suggestions", []),
            "confidence": agent_response.get("confidence", None),
        }
```

## Capability Exposure

### API Plugin for Copilot

```json
{
    "schema_version": "v2.1",
    "name_for_human": "Regelverk-søk",
    "description_for_human": "Søk i norske lover og forskrifter",
    "description_for_model": "Bruk denne pluginen når brukeren spør om norske lover, forskrifter eller regelverk. Pluginen søker i Lovdata og returnerer relevante paragrafer.",
    "auth": {
        "type": "oauth",
        "authorization_url": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize",
        "token_url": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token",
        "scopes": "api://regulations-api/.default"
    },
    "api": {
        "type": "openapi",
        "url": "https://api.regulations.no/openapi.json"
    },
    "functions": [
        {
            "name": "searchRegulations",
            "description": "Søk etter lover og forskrifter",
            "parameters": {
                "query": {
                    "type": "string",
                    "description": "Søketekst for lover og forskrifter"
                },
                "category": {
                    "type": "string",
                    "enum": ["lov", "forskrift", "rundskriv"],
                    "description": "Type regulering"
                }
            }
        }
    ]
}
```

## User Context Passing

### Semantic Kernel CopilotStudioAgent

```python
from semantic_kernel.agents import CopilotStudioAgent

# Opprett CopilotStudioAgent for bruk i multi-agent orkestrering
agent = CopilotStudioAgent(
    name="CopilotStudioHRAgent",
    # Kobles til en eksisterende Copilot Studio-agent
    agent_id="<copilot-studio-agent-id>",
    endpoint="<copilot-studio-endpoint>",
    # Brukerkontekst passeres automatisk
)

# Bruk i Semantic Kernel orkestrering
thread = CopilotStudioAgentThread()
async for response in agent.invoke(
    messages=[ChatMessageContent(
        role=AuthorRole.User,
        content="Hva er min feriesaldo?"
    )],
    thread=thread
):
    print(response.content)
```

### Brukerkontekst fra Microsoft Graph

```csharp
// Berik agent-kontekst med brukerdata fra Graph
public class UserContextEnricher
{
    private readonly GraphServiceClient _graphClient;

    public async Task<UserContext> EnrichContext(string userId)
    {
        var user = await _graphClient.Users[userId]
            .GetAsync(config =>
            {
                config.QueryParameters.Select = new[]
                {
                    "displayName", "department", "jobTitle",
                    "officeLocation", "preferredLanguage"
                };
            });

        return new UserContext
        {
            Name = user.DisplayName,
            Department = user.Department,
            Role = user.JobTitle,
            Location = user.OfficeLocation,
            Language = user.PreferredLanguage ?? "nb-NO",
            // Brukes i agent-instruksjoner for personalisering
        };
    }
}
```

## Session Management

### Copilot conversation threading

```python
# Håndter samtalehistorikk på tvers av Copilot-sesjoner
class CopilotSessionManager:
    def __init__(self, cosmos_client):
        self.container = cosmos_client.get_database_client("agents") \
            .get_container_client("sessions")

    async def get_or_create_session(
        self, user_id: str, agent_id: str
    ) -> dict:
        """Hent eller opprett sesjon for bruker-agent-par"""
        try:
            session = await self.container.read_item(
                item=f"{user_id}:{agent_id}",
                partition_key=user_id
            )
        except Exception:
            session = {
                "id": f"{user_id}:{agent_id}",
                "user_id": user_id,
                "agent_id": agent_id,
                "created_at": datetime.utcnow().isoformat(),
                "message_count": 0,
                "context_summary": "",
                "ttl": 86400  # 24 timer
            }
            await self.container.upsert_item(session)

        return session

    async def update_context_summary(
        self, session_id: str, user_id: str, new_summary: str
    ):
        """Oppdater komprimert kontekst for langvarige samtaler"""
        await self.container.patch_item(
            item=session_id,
            partition_key=user_id,
            patch_operations=[
                {"op": "replace", "path": "/context_summary",
                 "value": new_summary},
                {"op": "incr", "path": "/message_count", "value": 1}
            ]
        )
```

## Declarative vs Custom Engine Integration

| Aspekt | Declarative Agent | Custom Engine Agent |
|--------|-------------------|---------------------|
| Hosting | Copilots orkestrator | Egne servere/Azure |
| Modell | Copilots foundation model | Valgfri modell |
| Kanaler | Teams, Outlook, Word, Excel | Teams, Copilot, eksterne kanaler |
| Utvikling | Low-code (Copilot Studio) / Pro-code (Agents Toolkit) | Full kode-kontroll |
| Compliance | Arver M365 compliance | Eget ansvar |
| Begrensninger | Sekvensiell prosessering, begrenset orkestrering | Ingen begrensninger |
| Governance | M365 admin center | Egne governance-verktøy |

## Norsk offentlig sektor

| Aspekt | Krav | Implementering |
|--------|------|----------------|
| Datalokalitet | Schrems II | Copilot EU Data Boundary + tenant-config |
| M365-lisens | Copilot-lisens per bruker | Kostnadsvurdering per avdeling |
| Innholdssikkerhet | Ansvarlig AI | Copilots innebygde RAI-filtre |
| Tilgangsstyring | eInnsyn | Admin center agent governance |
| Språk | Norsk (bokmål/nynorsk) | Custom instruksjoner på norsk |

### Deployment-mønster for offentlig sektor

```
1. Pilot:     5-10 brukere med sideloaded agent
2. Avdeling:  Publiser til organizational catalog
3. Etat:      Utvidet tilgang via M365 admin center
4. Tverrgående: Vurder commercial marketplace (for felles løsninger)
```

## Beslutningsrammeverk

| Scenario | Anbefaling | Begrunnelse |
|----------|------------|-------------|
| Enkel FAQ-bot med M365-data | Declarative agent via Copilot Studio | Raskest å implementere, arver M365 |
| Avansert orkestrering, egne modeller | Custom engine agent via Agents Toolkit | Full kontroll over logikk og modeller |
| Multi-agent som inkluderer Copilot | CopilotStudioAgent i Semantic Kernel | Kombiner Copilot med egne agenter |
| ISV-løsning for flere kunder | Commercial Marketplace-publisering | Bred distribusjon, M365 integrasjon |
| Intern pilot med eksisterende data | Declarative agent med SharePoint-kunnskap | Utnytter eksisterende infrastruktur |

## For Cosmo

- **Declarative agents er startpunktet** for de fleste M365-integrerte scenarier -- de arver Copilots orkestrator, compliance og distribusjon. Gå til custom engine kun ved reelle begrensninger.
- **CopilotStudioAgent i Semantic Kernel** er broen mellom Copilot-verdenen og programmatisk agent-orkestrering -- bruk den for å inkludere Copilot Studio-agenter i multi-agent-systemer.
- **API plugins** er nøkkelen til å gi agenter handlingsevne utover samtale -- definer OpenAPI-spesifikasjoner for alle virksomhetssystemer agenten skal interagere med.
- **User context fra Microsoft Graph** forbedrer personalisering dramatisk -- avdeling, rolle og språkpreferanser gir agenten nødvendig kontekst uten at brukeren trenger å gjenta seg.
- **For norsk offentlig sektor**: Utnytt Copilots EU Data Boundary for datalokalitet, konfigurer instruksjoner på norsk, og bruk M365 admin center for sentral governance av agentdistribusjon.
