ms-ai-architect/skills/ms-ai-engineering/references/agent-orchestration/agent-routing-and-specialization.md
Kjell Tore Guttormsen ddce43d8b2 feat(ms-ai-architect): Spor 1 — Port-1-substrat migrert på 4 ikke-advisor-skills (243 Source + 327 Type + 325 TOC + stale-verified poison fjernet) [skip-docs]
Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/
infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk
(fra første ## seksjon), advisor urørt (0 endringer).

To applier-fixes oppdaget under kjøring (TDD, RED→GREEN):
- insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer
  500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor
  scan-vinduet, applierens post-write-assertion fanget + restaurerte).
- normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i
  500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var
  ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent
  utvidelse av carve-out; kun stray metadata-linjer, aldri prosa.

test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet
(fila bærer nå Source). Suite 728/728 grønn.
2026-07-04 10:19:11 +02:00

16 KiB

Agent Routing and Task Specialization

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


Innhold

Introduksjon

Intelligent routing mellom spesialiserte agenter er en av de mest kritiske arkitekturbeslutningene i multi-agent-systemer. Istedenfor å bygge en "god nok til alt"-agent, deler man ansvarsområder mellom spesialiserte agenter som hver mestrer sitt domene. En router-agent eller orkestrator analyserer innkommende forespørsler og dirigerer dem til riktig spesialist basert på intent-klassifisering, kontekstuell matching og kapabilitets-deklarasjoner.

Microsoft Agent Framework og Semantic Kernel tilbyr flere routing-mekanismer gjennom orkestreringsmønstrene Handoff, Group Chat og Magentic. Handoff-mønsteret er spesielt designet for agent-til-agent delegering, der en agent kan overføre en samtale til en mer kvalifisert agent basert på brukerens behov. Group Chat bruker en manager-agent til å dirigere samtaler, mens Magentic bruker en planbasert tilnærming med dynamisk oppgavefordeling.

For komplekse enterprise-scenarier er routing-strategien avgjørende for brukeropplevelse, kostnadseffektivitet og systemets evne til å skalere. Feil routing betyr enten at brukeren møter en agent som ikke kan svare godt nok, eller at en dyr premium-modell brukes på enkle oppgaver. Riktig routing balanserer kvalitet, kostnad og responstid.

Kjernekomponenter

Komponent Formål Teknologi
Intent Classifier Klassifiser brukerens hensikt Azure AI Language, LLM-basert klassifisering
Capability Registry Registrer agent-kapabiliteter Agent manifest, Semantic Kernel plugins
Router Agent Dirigér forespørsler til rett agent Handoff orchestration, custom routing logic
Load Balancer Fordel last mellom agentinstanser Azure APIM, Azure Load Balancer
Fallback Handler Håndtér situasjoner der ingen agent matcher Default agent, human escalation
Skill Matcher Match oppgave-krav til agent-ferdigheter Semantic matching, capability scoring

Intent Classification Routing

LLM-basert intent-klassifisering

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion

# Router-agent som klassifiserer intent og velger spesialist
ROUTER_PROMPT = """
Du er en routing-agent. Analyser brukerens forespørsel og klassifiser den.

Tilgjengelige agenter:
1. HR-Agent: Spørsmål om ansettelse, ferie, lønn, personalhåndbok
2. IT-Support-Agent: Tekniske problemer, tilganger, programvare
3. Økonomi-Agent: Faktura, budsjett, reiseregning, innkjøp
4. Juridisk-Agent: Kontrakter, personvern, compliance, anskaffelser
5. General-Agent: Alt annet

Svar med JSON:
{
    "intent": "<kort beskrivelse>",
    "target_agent": "<agent-navn>",
    "confidence": <0.0-1.0>,
    "reasoning": "<kort begrunnelse>"
}

Brukerforespørsel: {{$query}}
"""

async def route_query(kernel: Kernel, query: str) -> dict:
    result = await kernel.invoke_prompt(
        ROUTER_PROMPT,
        input_vars={"query": query}
    )
    routing = json.loads(str(result))

    # Fallback hvis confidence er lav
    if routing["confidence"] < 0.6:
        routing["target_agent"] = "General-Agent"
        routing["needs_clarification"] = True

    return routing

Azure AI Language for intent-klassifisering

# CLU (Conversational Language Understanding) for deterministisk routing
from azure.ai.language.conversations import ConversationAnalysisClient
from azure.core.credentials import AzureKeyCredential

client = ConversationAnalysisClient(
    endpoint=os.environ["LANGUAGE_ENDPOINT"],
    credential=AzureKeyCredential(os.environ["LANGUAGE_KEY"])
)

def classify_intent(query: str) -> dict:
    result = client.analyze_conversation(
        task={
            "kind": "Conversation",
            "analysisInput": {
                "conversationItem": {
                    "id": "1",
                    "participantId": "user",
                    "text": query
                }
            },
            "parameters": {
                "projectName": "agent-routing",
                "deploymentName": "production"
            }
        }
    )

    prediction = result["result"]["prediction"]
    return {
        "intent": prediction["topIntent"],
        "confidence": prediction["intents"][0]["confidenceScore"],
        "entities": prediction.get("entities", [])
    }

Agent Capability Matching

Capability Registry Pattern

// Definer agent-kapabiliteter som et registrer
public class AgentCapabilityRegistry
{
    private readonly List<AgentCapability> _capabilities = new();

    public void Register(AgentCapability capability)
    {
        _capabilities.Add(capability);
    }

    public AgentCapability FindBestMatch(
        string intent,
        Dictionary<string, string> context)
    {
        return _capabilities
            .Where(c => c.CanHandle(intent))
            .OrderByDescending(c => c.CalculateScore(intent, context))
            .FirstOrDefault();
    }
}

public class AgentCapability
{
    public string AgentName { get; set; }
    public string[] SupportedIntents { get; set; }
    public string[] RequiredEntities { get; set; }
    public string[] SupportedLanguages { get; set; }
    public int MaxComplexity { get; set; }  // 1-5
    public decimal CostPerRequest { get; set; }

    public bool CanHandle(string intent)
        => SupportedIntents.Any(i =>
            intent.Contains(i, StringComparison.OrdinalIgnoreCase));

    public double CalculateScore(
        string intent, Dictionary<string, string> context)
    {
        double score = 0;
        // Eksakt intent-match gir høy score
        if (SupportedIntents.Contains(intent)) score += 10;
        // Språkmatch
        if (SupportedLanguages.Contains(context.GetValueOrDefault("lang", "no")))
            score += 5;
        // Lavere kostnad gir bonus (for like-kapable agenter)
        score += (1.0 / (double)(CostPerRequest + 0.01));
        return score;
    }
}

// Registrering
var registry = new AgentCapabilityRegistry();
registry.Register(new AgentCapability
{
    AgentName = "HR-Specialist",
    SupportedIntents = new[] { "ferie", "lønn", "ansettelse", "permisjon" },
    RequiredEntities = new[] { "ansatt-id" },
    SupportedLanguages = new[] { "no", "en" },
    MaxComplexity = 3,
    CostPerRequest = 0.02m
});

Semantic Kernel Handoff Pattern

Handoff-mønsteret i Semantic Kernel er designet for agent-til-agent delegering:

from semantic_kernel.agents import ChatCompletionAgent, HandoffOrchestration
from semantic_kernel.agents.orchestration.handoffs import HandoffBuilder

# Definer spesialiserte agenter
triage_agent = ChatCompletionAgent(
    name="Triage",
    instructions="""
    Du er en triage-agent. Analyser brukerens forespørsel og
    overfør til riktig spesialist:
    - HR-spørsmål → transfer_to_hr
    - IT-problemer → transfer_to_it_support
    - Økonomi → transfer_to_finance
    """,
    kernel=kernel
)

hr_agent = ChatCompletionAgent(
    name="HR-Specialist",
    instructions="Du er en HR-ekspert. Svar på HR-relaterte spørsmål.",
    kernel=kernel
)

it_agent = ChatCompletionAgent(
    name="IT-Support",
    instructions="Du er IT-support. Hjelp med tekniske problemer.",
    kernel=kernel
)

# Konfigurer handoff-regler
handoffs = (
    HandoffBuilder()
    .add(source=triage_agent, target=hr_agent, description="HR-spørsmål")
    .add(source=triage_agent, target=it_agent, description="IT-problemer")
    .add(source=hr_agent, target=triage_agent, description="Ikke HR-relatert")
    .add(source=it_agent, target=triage_agent, description="Ikke IT-relatert")
    .build()
)

# Opprett orkestrering
orchestration = HandoffOrchestration(
    members=[triage_agent, hr_agent, it_agent],
    handoffs=handoffs
)

# Kjør
result = await orchestration.invoke(
    task="Hvordan søker jeg om foreldrepermisjon?",
    runtime=runtime
)

Load Balancing Strategies

Multi-instans agent routing via APIM

<!-- APIM policy for intelligent agent routing -->
<policies>
    <inbound>
        <!-- Klassifiser intent basert på header eller body -->
        <set-variable name="agentType"
            value="@{
                var body = context.Request.Body.As<JObject>();
                var query = body["query"]?.ToString() ?? "";
                if (query.Contains("HR") || query.Contains("ferie"))
                    return "hr-agent";
                if (query.Contains("IT") || query.Contains("tilgang"))
                    return "it-agent";
                return "general-agent";
            }" />

        <!-- Route til riktig backend basert på agent-type -->
        <choose>
            <when condition="@(context.Variables.GetValueOrDefault<string>("agentType") == "hr-agent")">
                <set-backend-service
                    backend-id="hr-agent-pool" />
            </when>
            <when condition="@(context.Variables.GetValueOrDefault<string>("agentType") == "it-agent")">
                <set-backend-service
                    backend-id="it-agent-pool" />
            </when>
            <otherwise>
                <set-backend-service
                    backend-id="general-agent-pool" />
            </otherwise>
        </choose>
    </inbound>
</policies>

Fallback Routing

Graceful degradation ved routing-feil

class FallbackRouter:
    """Router med multi-level fallback"""

    def __init__(self, agents: dict, default_agent: str):
        self.agents = agents
        self.default = default_agent
        self.escalation_threshold = 2  # Maks antall re-routes

    async def route(self, query: str, context: dict) -> AgentResponse:
        attempts = 0
        current_agent = self._classify_and_select(query)

        while attempts < self.escalation_threshold:
            try:
                response = await self.agents[current_agent].invoke(query)

                # Sjekk om agenten selv indikerer at den ikke kan svare
                if response.confidence < 0.4:
                    attempts += 1
                    current_agent = self._get_fallback(current_agent)
                    continue

                return response

            except AgentUnavailableError:
                attempts += 1
                current_agent = self._get_fallback(current_agent)

        # Ultimat fallback: default agent eller menneskelig eskalering
        return await self.agents[self.default].invoke(query)

    def _get_fallback(self, current: str) -> str:
        fallback_chain = {
            "HR-Specialist": "General-Agent",
            "IT-Support": "General-Agent",
            "Økonomi-Agent": "General-Agent",
            "General-Agent": "Human-Escalation"
        }
        return fallback_chain.get(current, self.default)

Specialization Hierarchies

Tre-nivå spesialiseringshierarki

                    ┌──────────────┐
                    │   Triage     │  L0: Intent classification
                    │   Router     │
                    └──────┬───────┘
                           │
            ┌──────────────┼──────────────┐
            │              │              │
    ┌───────▼──────┐ ┌────▼────┐ ┌──────▼───────┐
    │  HR Domain   │ │   IT    │ │   Finance    │  L1: Domain
    │  Agent       │ │  Agent  │ │   Agent      │
    └───────┬──────┘ └────┬────┘ └──────┬───────┘
            │              │              │
    ┌───────▼──────┐      │       ┌──────▼───────┐
    │ Rekruttering │      │       │   Faktura    │  L2: Specialist
    │ Onboarding   │      │       │   Budsjett   │
    │ Permisjon    │      │       │   Innkjøp    │
    └──────────────┘      │       └──────────────┘
                          │
                   ┌──────▼───────┐
                   │ Nettverks-   │  L2: Specialist
                   │ Applikasjons-│
                   │ Tilgangs-    │
                   └──────────────┘

Norsk offentlig sektor

Routing-hensyn for offentlig sektor

Aspekt Krav Implementering
Sakstype-basert routing Ulike sakstyper krever ulik behandling Map sakstyper til agent-spesialister
Sikkerhetsnivå Gradert informasjon krever spesielle agenter Rout gradert info til isolerte agenter
Språk Bokmål, nynorsk, samisk Språkdeteksjon i router + dedikerte agenter
Arkivering Alle agent-interaksjoner skal journalføres Logging av routing-beslutninger
Innsynsrett Borgere har rett til innsyn i saksbehandling Dokumentér hvilken agent som behandlet saken

Eksempel: Norsk kommune agent-routing

KOMMUNE_AGENT_MAP = {
    "byggesak": {
        "agent": "byggesak-agent",
        "model": "gpt-4o",  # Kompleks regulering
        "knowledge": ["plan-og-bygningsloven", "kommuneplan"],
        "requires_human_review": True
    },
    "barnehageplass": {
        "agent": "barnehage-agent",
        "model": "gpt-4o-mini",  # Enklere forespørsler
        "knowledge": ["barnehageloven", "lokale-vedtekter"],
        "requires_human_review": False
    },
    "sosialtjenester": {
        "agent": "sosial-agent",
        "model": "gpt-4o",  # Sensitive opplysninger
        "knowledge": ["sosialtjenesteloven", "NAV-retningslinjer"],
        "requires_human_review": True,
        "data_classification": "fortrolig"
    }
}

Beslutningsrammeverk

Scenario Anbefaling Begrunnelse
< 5 agenttyper, lavt volum Enkel LLM-basert router Lav kompleksitet, rask å implementere
5-20 agenttyper, middels volum CLU + capability registry Deterministisk + skalerbar
> 20 agenttyper, høyt volum APIM-basert routing + hierarkisk Ytelse + kostnadseffektivitet
Sensitive domener med compliance Handoff med human-in-the-loop Sikkerhet + etterprøvbarhet
Dynamisk agentøkosystem Capability advertisement + discovery Agenter kan registreres/fjernes uten kodeendring

For Cosmo

  • Handoff-mønsteret i Semantic Kernel er den mest naturlige routing-mekanismen for multi-agent-systemer -- triage-agenten klassifiserer og delegerer, spesialistene behandler.
  • Kombiner LLM-basert og deterministisk routing for best resultat: Bruk CLU for kjente intenter med høy volum, LLM for edge cases og nye scenarier.
  • Capability Registry er nøkkelen til skalerbar arkitektur -- nye agenter registrerer sine kapabiliteter, og routeren oppdager dem automatisk uten kodeendringer.
  • Fallback er like viktig som routing -- design alltid en graceful degradation-kjede fra spesialist via generalist til menneskelig eskalering.
  • For norsk offentlig sektor: Map sakstyper til agenter, respekter sikkerhetsnivåer i routing, og sørg for at alle routing-beslutninger logges for etterprøvbarhet.