ms-ai-architect/skills/ms-ai-engineering/references/agent-orchestration/agent-monitoring-observability.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

15 KiB

Agent Monitoring, Observability and Debugging

Last updated: 2026-02 Status: GA / Preview (Agent 365) Category: Agent Orchestration & Automation Type: reference


Innhold

Introduksjon

Observability for agentsystemer går utover tradisjonell applikasjonsovervåking. Agenter opererer probabilistisk, tar dynamiske beslutninger, og produserer ulike outputs for identiske inputs. Denne ikke-deterministiske naturen krever spesialiserte overvåkingsverktøy som fanger ikke bare ytelsesmetrikker, men også beslutningsprosesser, verktøybruk, prompt-respons-par og evalueringskvalitet.

Microsoft tilbyr en komplett observability-stack for agenter gjennom Microsoft Foundry Tracing, Application Insights, Azure Monitor og Microsoft Agent 365. Foundry-plattformen integrerer OpenTelemetry-basert tracing med AI-spesifikke semantiske konvensjoner, slik at hvert LLM-kall, tool-invokasjon og orkestreringsbeslutning fanges som spans i en distribuert trace.

Agent 365 er Microsofts unified plattform for agentobservability på tvers av Copilot Studio, Microsoft Foundry og tredjepartsruntimes. Den gir enterprise-grade governance med sikkerhet, compliance og business impact-metrikker for hele agentflåten.

Kjernekomponenter

Komponent Formål Teknologi
Distributed Tracing Capture full request lifecycle OpenTelemetry, Microsoft Foundry Tracing
Agent Event Logging Logg agentbeslutninger og handlinger Application Insights, Log Analytics
Performance Profiling Identifiser flaskehalser Azure Monitor Metrics, custom spans
Error Categorization Klassifiser og prioriter feil Azure Monitor Alerts, Sentinel
Debugging Tools Interaktiv feilsøking Foundry Portal, Aspire Dashboard
Agent 365 Unified agent governance og observability Microsoft Agent 365 platform

Distributed Tracing for Agents

OpenTelemetry-basert tracing med Microsoft Foundry

from azure.ai.projects import AIProjectClient
from azure.monitor.opentelemetry import configure_azure_monitor
from azure.identity import DefaultAzureCredential
import os

# Aktiver content recording for full prompt/respons-logging
os.environ["AZURE_TRACING_GEN_AI_CONTENT_RECORDING_ENABLED"] = "true"

# Koble til prosjekt
project_client = AIProjectClient(
    credential=DefaultAzureCredential(),
    endpoint=os.environ["PROJECT_ENDPOINT"]
)

# Hent Application Insights connection string fra prosjektet
connection_string = (
    project_client.telemetry
    .get_application_insights_connection_string()
)

# Konfigurer Azure Monitor telemetry
configure_azure_monitor(connection_string=connection_string)

Trace-konsepter

Konsept Beskrivelse Eksempel
Trace Fullstendig reise for en forespørsel gjennom systemet Bruker-spørsmål → routing → RAG → LLM → respons
Span Enkeloperasjon innenfor en trace Ett LLM-kall, ett tool-kall
Attributes Nøkkel-verdi metadata på spans gen_ai.prompt, gen_ai.completion, tool.name
Semantic Conventions Standardiserte attributtnavn OpenTelemetry GenAI semantic conventions

Custom spans for agentorkestrering

from opentelemetry import trace

tracer = trace.get_tracer("agent-orchestrator")

async def orchestrate_agent_request(query: str, user_id: str):
    with tracer.start_as_current_span("agent_orchestration") as root_span:
        root_span.set_attribute("user.id", user_id)
        root_span.set_attribute("query.text", query)

        # Routing span
        with tracer.start_as_current_span("intent_routing") as route_span:
            routing = await classify_intent(query)
            route_span.set_attribute("routing.target", routing.agent)
            route_span.set_attribute("routing.confidence", routing.confidence)
            route_span.set_attribute("routing.intent", routing.intent)

        # RAG retrieval span
        with tracer.start_as_current_span("rag_retrieval") as rag_span:
            documents = await retrieve_context(query, routing.agent)
            rag_span.set_attribute("rag.doc_count", len(documents))
            rag_span.set_attribute("rag.sources",
                [d.source for d in documents])

        # Agent invocation span
        with tracer.start_as_current_span("agent_invocation") as agent_span:
            agent_span.set_attribute("agent.name", routing.agent)
            response = await invoke_agent(routing.agent, query, documents)
            agent_span.set_attribute("response.token_count",
                response.usage.total_tokens)
            agent_span.set_attribute("response.model", response.model)

        root_span.set_attribute("total_tokens", response.usage.total_tokens)
        return response

Agent Event Logging

Strukturert hendelseslogging

import logging
import json
from datetime import datetime

class AgentEventLogger:
    """Strukturert logging for agent-hendelser"""

    def __init__(self, app_insights_handler):
        self.logger = logging.getLogger("agent-events")
        self.logger.addHandler(app_insights_handler)

    def log_agent_decision(self, event: dict):
        """Logg en agentbeslutning med full kontekst"""
        self.logger.info(json.dumps({
            "event_type": "agent_decision",
            "timestamp": datetime.utcnow().isoformat(),
            "agent_name": event["agent"],
            "decision_type": event["type"],  # routing, tool_selection, response
            "input_summary": event.get("input_summary", ""),
            "decision": event["decision"],
            "confidence": event.get("confidence", None),
            "reasoning": event.get("reasoning", ""),
            "tokens_used": event.get("tokens", 0),
            "latency_ms": event.get("latency_ms", 0),
            "metadata": event.get("metadata", {})
        }))

    def log_tool_invocation(self, tool_name: str, input_params: dict,
                            output: str, duration_ms: float, success: bool):
        self.logger.info(json.dumps({
            "event_type": "tool_invocation",
            "timestamp": datetime.utcnow().isoformat(),
            "tool_name": tool_name,
            "input_params": input_params,
            "output_preview": output[:200],
            "duration_ms": duration_ms,
            "success": success
        }))

Performance Profiling

KQL-spørringer for agentytelse

// Latency-breakdown per agent-komponent
traces
| where timestamp > ago(24h)
| where customDimensions.event_type == "agent_decision"
| extend
    agent = tostring(customDimensions.agent_name),
    decision_type = tostring(customDimensions.decision_type),
    latency = todouble(customDimensions.latency_ms),
    tokens = toint(customDimensions.tokens_used)
| summarize
    p50_latency = percentile(latency, 50),
    p95_latency = percentile(latency, 95),
    p99_latency = percentile(latency, 99),
    avg_tokens = avg(tokens),
    request_count = count()
    by agent, decision_type
| order by p95_latency desc
// Identifiser trege tool calls
traces
| where timestamp > ago(7d)
| where customDimensions.event_type == "tool_invocation"
| extend
    tool = tostring(customDimensions.tool_name),
    duration = todouble(customDimensions.duration_ms),
    success = tobool(customDimensions.success)
| summarize
    avg_duration = avg(duration),
    p95_duration = percentile(duration, 95),
    failure_rate = countif(success == false) * 100.0 / count(),
    total_calls = count()
    by tool
| where p95_duration > 2000 or failure_rate > 5
| order by p95_duration desc

Azure Monitor dashboards

// Agent health dashboard - hoveddatakilder
let agent_health = traces
| where timestamp > ago(1h)
| where customDimensions.event_type in
    ("agent_decision", "tool_invocation")
| extend agent = tostring(customDimensions.agent_name)
| summarize
    requests = count(),
    errors = countif(customDimensions.success == "false"),
    avg_latency = avg(todouble(customDimensions.latency_ms)),
    avg_tokens = avg(todouble(customDimensions.tokens_used))
    by agent, bin(timestamp, 5m);

agent_health
| render timechart

Error Categorization

Feilkategorisering for agentsystemer

Kategori Eksempler Alvorlighet Handling
Model Errors Rate limit, timeout, content filter Medium Retry med backoff
Tool Failures API-feil, timeout, ugyldige params Medium Fallback til alternativt verktøy
Routing Errors Feil agent valgt, lav confidence Lav Logg + iterér på router-prompt
Hallucination Agent fabrikkerer fakta Høy Groundedness-evaluering + alert
Safety Violations Upassende innhold generert Kritisk Umiddelbar blokkering + varsling
Data Quality RAG returnerer irrelevante dokumenter Medium Indeks-kvalitetsjekk
# Automatisk feilkategorisering
class AgentErrorClassifier:
    ERROR_CATEGORIES = {
        "rate_limit": {"severity": "medium", "retry": True},
        "timeout": {"severity": "medium", "retry": True},
        "content_filter": {"severity": "high", "retry": False},
        "tool_failure": {"severity": "medium", "retry": True},
        "hallucination": {"severity": "high", "retry": False},
        "routing_error": {"severity": "low", "retry": True},
    }

    def classify(self, error: Exception, context: dict) -> dict:
        if "429" in str(error):
            return {**self.ERROR_CATEGORIES["rate_limit"],
                    "wait_seconds": self._extract_retry_after(error)}
        if "timeout" in str(error).lower():
            return self.ERROR_CATEGORIES["timeout"]
        if "content_filter" in str(error).lower():
            return self.ERROR_CATEGORIES["content_filter"]
        # Default
        return {"severity": "unknown", "retry": False}

Debugging Tools

Microsoft Foundry Portal

Foundry-portalen gir visuell trace-inspeksjon:

  1. Traces-visning: Filter traces etter tidsrom, agent, bruker eller status
  2. Span-detaljer: Se inputs, outputs og attributter for hver operasjon
  3. Call tree: Visualiser hierarkisk relasjon mellom spans
  4. Evaluering: Se evalueringsresultater direkte på traces

Aspire Dashboard for lokal debugging

# Lokal debugging med Aspire Dashboard
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
    OTLPSpanExporter
)

# Eksporter til Aspire Dashboard (localhost:4317)
exporter = OTLPSpanExporter(endpoint="http://localhost:4317")
tracer_provider = TracerProvider()
tracer_provider.add_span_processor(SimpleSpanProcessor(exporter))
trace.set_tracer_provider(tracer_provider)

# Alle agent-operasjoner vises nå i Aspire Dashboard
# Start med: docker run --rm -p 18888:18888 -p 4317:18889 \
#   mcr.microsoft.com/dotnet/aspire-dashboard:latest

Debugging-strategi for agenter

1. Reprodusér → Finn den spesifikke tracen i Foundry/AppInsights
2. Isolér    → Identifiser hvilken span som forårsaket problemet
3. Inspiser  → Se prompt, kontekst og respons for den spannen
4. Hypotese  → Er det routing? RAG? Modell? Verktøy?
5. Test      → Kjør isolert test med samme input
6. Fiks      → Oppdater prompt/config/verktøy
7. Verifiser → Sammenlign metrikker før/etter

Observability SDK Integration

Agent Framework observability

// Microsoft Agent Framework med full observability
var builder = WebApplication.CreateBuilder(args);

// Aktiver agent observability
builder.Services.AddAgentObservability(options =>
{
    options.EnableSensitiveData = true; // Full prompt logging
    options.ServiceName = "customer-support-agent";
    options.ExportToApplicationInsights(
        connectionString: builder.Configuration["AppInsights:ConnectionString"]
    );
});

Norsk offentlig sektor

Aspekt Krav Implementering
Logging av AI-beslutninger EU AI Act Art. 12 Full trace med decision reasoning
Personvern i logger GDPR Art. 5 Redact PII fra traces, eller disable content recording
Arkivering Arkivloven Retensjon av agent-traces minimum 5 år
Innsyn Offentlighetsloven Tilgjengeliggjør agent-beslutningslogger for innsyn
Sikkerhetshendelser NSM Grunnprinsipper Azure Sentinel-integrasjon for anomali-deteksjon

Personvern i observability

# Sensitive data redaction for offentlig sektor
import re

class PIIRedactor:
    PATTERNS = {
        "fnr": r"\b\d{11}\b",  # Fødselsnummer
        "email": r"\b[\w.-]+@[\w.-]+\.\w+\b",
        "phone": r"\b(?:\+47|0047)?\s*\d{8}\b",
    }

    def redact(self, text: str) -> str:
        for pii_type, pattern in self.PATTERNS.items():
            text = re.sub(pattern, f"[REDACTED_{pii_type.upper()}]", text)
        return text

# Bruk i tracing
redactor = PIIRedactor()
span.set_attribute("query.text", redactor.redact(query))

Beslutningsrammeverk

Scenario Anbefaling Begrunnelse
Utvikling/testing Aspire Dashboard + full content recording Maksimal synlighet for debugging
Pre-produksjon Foundry Tracing + evaluatorer Kvalitetssikring før lansering
Produksjon standard Application Insights + 10% sampling Balanse mellom synlighet og kostnad
Produksjon høy-risiko 100% tracing + Sentinel + Agent 365 Full compliance og sikkerhet
Multi-team organisasjon Agent 365 + sentralisert Log Analytics Unified governance på tvers av team

For Cosmo

  • OpenTelemetry-basert tracing er fundamentet -- all agent-observability bygger på traces med spans. Implementer fra dag 1, ikke legg til etterpå.
  • Agent 365 er veien fremover for enterprise-scale agent governance -- det gir unified synlighet på tvers av Copilot Studio, Foundry og tredjepartsagenter.
  • Redact PII i traces for offentlig sektor -- bruk AZURE_TRACING_GEN_AI_CONTENT_RECORDING_ENABLED=false i produksjon med persondata, eller implementer custom redaction.
  • KQL er ditt viktigste verktøy for å analysere agent-atferd i produksjon -- bygg dashboards for latency, feilrater, token-bruk og kvalitetsmetrikker per agent.
  • Debugging-workflow: Start alltid med å finne tracen, deretter isolér den problematiske spannen -- 90% av agent-feil kan diagnostiseres ved å inspisere prompt, kontekst og respons.