ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-engineering/references/api-management/circuit-breaker-ai-resilience.md
Kjell Tore Guttormsen 6a7632146e feat(ms-ai-architect): add plugin to open marketplace (v1.5.0 baseline)
Initial addition of ms-ai-architect plugin to the open-source marketplace.
Private content excluded: orchestrator/ (Linear tooling), docs/utredning/
(client investigation), generated test reports and PDF export script.
skill-gen tooling moved from orchestrator/ to scripts/skill-gen/.

Security scan: WARNING (risk 20/100) — no secrets, no injection found.
False positive fixed: added gitleaks:allow to Python variable reference
in output-validation-grounding-verification.md line 109.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 17:17:17 +02:00

18 KiB

Circuit Breaker Patterns for AI Models

Last updated: 2026-02 Status: GA Category: API Management & AI Gateway


Introduksjon

Circuit breaker-mønsteret er en grunnleggende resiliensmekanisme for AI-applikasjoner som kommuniserer med Azure OpenAI og andre LLM-backends. Når en backend-tjeneste blir overbelastet eller utilgjengelig, forhindrer circuit breaker at applikasjonen fortsetter å sende forespørsler som uansett vil feile. I stedet "bryter kretsen" og returnerer en feilmelding umiddelbart, slik at backend-tjenesten får tid til å gjenopprette seg.

For Azure AI-tjenester er circuit breaker spesielt viktig fordi Azure OpenAI returnerer 429 (Too Many Requests) med en Retry-After-header som kan ha verdier opp til 24 timer. Uten circuit breaker vil applikasjoner fortsette å hamre på en throttlet tjeneste, noe som forverrer situasjonen og kaster bort gateway-ressurser. APIMsintegrerte circuit breaker håndterer dette automatisk ved å respektere Retry-After-headeren.

I kombinasjon med backend pools og lastbalansering utgjør circuit breaker selve nervesystemet i en intelligent AI-gateway: den detekterer problemer, isolerer feilende backends, ruter trafikk til friske alternativer, og gjenoppretter normal drift automatisk når backend er tilbake.


Circuit Breaker State Machine

Tre tilstander

Circuit breaker opererer som en tilstandsmaskin med tre tilstander:

                 Feil > threshold
    ┌─────────┐ ───────────────► ┌──────────┐
    │ CLOSED  │                  │  OPEN    │
    │ (normal)│ ◄──────────────  │  (trip)  │
    └─────────┘  Alle OK i       └──────────┘
         │       half-open           │
         │                           │ Trip duration
         │                           │ utløpt
         │       ┌──────────────┐    │
         │       │ HALF-OPEN    │◄───┘
         │       │ (test)       │
         │       └──────────────┘
         │              │
         │    Suksess   │ Feil
         ◄──────────────┘───────────► OPEN
Tilstand Oppførsel Varighet
Closed Normal drift, alle requests videresendes til backend Ubegrenset (til feilbetingelse oppstår)
Open Alle requests avvises umiddelbart med 503 Trip duration (konfigurerbar, eller fra Retry-After)
Half-Open Et begrenset antall test-requests sendes til backend Til nok suksesser ELLER ny feil

APIM-spesifikk oppførsel

APIMcircuit breaker har noen viktige forskjeller fra den generelle circuit breaker-mønsteret:

Egenskap APIM Circuit Breaker
Konfigurasjons-scope Per backend (ikke per API eller policy)
Antall regler Kun én regel per backend (p.t.)
Synkronisering Ingen mellom gateway-instanser (approksimasjon)
Retry-After respekt Ja, dynamisk trip duration basert på backend-respons
Støttede tiers Alle unntatt Consumption
Respons ved Open 503 Service Unavailable

Konfigurasjon

Grunnleggende circuit breaker for Azure OpenAI

resource openaiBackend 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
  parent: apim
  name: 'openai-norwayeast'
  properties: {
    url: 'https://aoai-norwayeast.openai.azure.com/openai'
    protocol: 'http'
    circuitBreaker: {
      rules: [
        {
          name: 'ai-resilience-rule'
          failureCondition: {
            count: 3
            interval: 'PT1M'
            statusCodeRanges: [
              { min: 429, max: 429 }
              { min: 500, max: 599 }
            ]
          }
          tripDuration: 'PT10S'
          acceptRetryAfter: true
        }
      ]
    }
  }
}

Attributter forklart

Attributt Type Beskrivelse Anbefalt verdi for AI
failureCondition.count int Antall feil som trigger trip 3-5
failureCondition.interval duration Tidsvindu for feil-telling PT1M (1 minutt)
failureCondition.statusCodeRanges array HTTP-koder som teller som feil 429 + 500-599
tripDuration duration Hvor lenge circuit er åpent PT10S - PT1M
acceptRetryAfter bool Bruk Retry-After header som trip duration true (alltid for AI)

Prosentbasert vs. count-basert triggering

APIM støtter to modeller for feil-deteksjon:

Count-basert (anbefalt for AI):

{
  "failureCondition": {
    "count": 3,
    "interval": "PT1M",
    "statusCodeRanges": [{"min": 429, "max": 429}]
  }
}

Trigger: 3 eller flere 429-responser innen 1 minutt.

Prosentbasert:

{
  "failureCondition": {
    "percentage": 50,
    "interval": "PT1M",
    "statusCodeRanges": [{"min": 429, "max": 429}]
  }
}

Trigger: 50% eller mer av requests feiler innen 1 minutt.

Anbefaling: Count-basert er mer forutsigbar for AI-workloads. Prosentbasert kan gi falske positiver ved lav trafikk (2 av 3 requests feiler = 66%).


Failure Threshold Tuning

Faktorene som påvirker threshold

Faktor Lav threshold (1-2) Høy threshold (5-10)
Reaksjonstid Rask, reagerer umiddelbart Tregere, tolererer noen feil
Falske positiver Høy risiko Lav risiko
Backend-beskyttelse Sterk, minimal ekstra belastning Svakere, flere feil-requests
Anbefalt for Kritiske, kapasitetsbegrensede backends Robuste backends med transiente feil

Anbefalte innstillinger per scenario

Scenario count interval tripDuration acceptRetryAfter
PTU-instans (high priority) 3 PT1M PT10S true
PAYGO-instans (fallback) 5 PT2M PT30S true
Dev/test 2 PT30S PT5S true
Business-critical 3 PT1M PT10S true
Batch processing 10 PT5M PT1M true

Dynamisk trip duration med Retry-After

Når acceptRetryAfter: true er satt, overstyrer Azure OpenAIs Retry-After-header den konfigurerte tripDuration:

Scenario: OpenAI returnerer 429 med Retry-After: 30
  → Circuit breaker åpner i 30 sekunder (ikke konfiguert tripDuration)
  → Etter 30 sekunder: half-open → test request
  → Suksess: circuit lukkes
  → Feil: circuit åpner igjen med ny Retry-After

Scenario: OpenAI returnerer 429 med Retry-After: 86400 (1 dag!)
  → Circuit breaker åpner i 24 timer
  → All trafikk rutes til andre backends i poolen

Viktig advarsel: Azure OpenAI kan returnere Retry-After verdier opp til 1 dag (86400 sekunder). Med acceptRetryAfter: true vil dette bety at backend er utilgjengelig i 24 timer. Sørg for at backend-poolen har nok kapasitet i andre backends til å håndtere dette.


Fallback-policies

Mønster 1: Backend Pool med automatisk failover

Den enkleste og mest robuste tilnærmingen:

<policies>
    <inbound>
        <!-- Backend pool håndterer failover automatisk -->
        <set-backend-service backend-id="openai-pool-priority" />
        <authentication-managed-identity
            resource="https://cognitiveservices.azure.com/" />
    </inbound>
</policies>

Når circuit breaker utløses på Priority 1-backends, ruter APIM automatisk til Priority 2, osv.

Mønster 2: Retry med backend-bytte

Eksplisitt retry-logikk som bytter backend ved 429:

<policies>
    <backend>
        <retry condition="@(context.Response.StatusCode == 429)"
               count="3"
               interval="0"
               first-fast-retry="true">
            <set-backend-service backend-id="openai-pool-priority" />
        </retry>
    </backend>
</policies>

Viktig: interval="0" betyr umiddelbar retry til neste backend, IKKE ventetid. Server-side retries bør aldri ha delay — det holder opp klienten og bruker gateway-ressurser.

Mønster 3: Graceful Degradation med cache-fallback

<policies>
    <inbound>
        <!-- Prøv semantic cache først -->
        <azure-openai-semantic-cache-lookup
            score-threshold="0.20"
            embeddings-backend-id="embeddings-backend"
            embeddings-backend-auth="system-assigned" />

        <set-backend-service backend-id="openai-pool-priority" />
    </inbound>

    <on-error>
        <choose>
            <!-- Alle backends utilgjengelige -->
            <when condition="@(context.Response.StatusCode == 503)">
                <return-response>
                    <set-status code="503" reason="AI Service Temporarily Unavailable" />
                    <set-header name="Retry-After" exists-action="override">
                        <value>60</value>
                    </set-header>
                    <set-body>@{
                        return new JObject(
                            new JProperty("error", new JObject(
                                new JProperty("code", "service_unavailable"),
                                new JProperty("message", "AI-tjenesten er midlertidig utilgjengelig. Prøv igjen om 60 sekunder."),
                                new JProperty("type", "circuit_breaker_open")
                            ))
                        ).ToString();
                    }</set-body>
                </return-response>
            </when>
        </choose>
    </on-error>
</policies>

Mønster 4: Fallback til enklere modell

<policies>
    <backend>
        <retry condition="@(context.Response.StatusCode == 429 || context.Response.StatusCode == 503)"
               count="1"
               interval="0"
               first-fast-retry="true">
            <!-- Fallback til mindre modell -->
            <set-backend-service backend-id="openai-gpt4o-mini-backend" />
            <rewrite-uri template="/deployments/gpt-4o-mini/chat/completions" />
        </retry>
    </backend>
</policies>

Recovery-mekanismer

Automatisk recovery

Circuit breaker håndterer recovery automatisk:

1. Trip: Circuit åpner (503 til klienter)
2. Wait: tripDuration utløper (eller Retry-After)
3. Half-Open: Test-request sendes til backend
4. Success: Circuit lukkes, normal drift gjenopptas
5. Failure: Circuit åpner igjen, ny tripDuration starter

Recovery-timing

Kilde Prioritet Typisk verdi
Retry-After header (når acceptRetryAfter: true) Høyest 1-86400 sekunder
Konfigurert tripDuration Fallback PT10S - PT1M
Default (uten konfigurasjon) Lavest PT1M

Overvåking av circuit breaker-tilstand

<outbound>
    <!-- Log circuit breaker state -->
    <trace source="circuit-breaker" severity="information">
        <message>@{
            var backendId = context.Backend?.Id ?? "unknown";
            var statusCode = context.Response.StatusCode;
            return $"Backend: {backendId}, Status: {statusCode}";
        }</message>
    </trace>
</outbound>

KQL for circuit breaker-hendelser:

ApiManagementGatewayLogs
| where ResponseCode == 503
| extend backendId = tostring(parse_json(BackendResponseBody).backendId)
| summarize CircuitBreakerTrips = count() by backendId, bin(TimeGenerated, 5m)
| render timechart

Timeout-konfigurasjon

Forward-request timeout

Kontroller hvor lenge APIM venter på backend-respons:

<policies>
    <backend>
        <forward-request timeout="120" />
    </backend>
</policies>

Anbefalte timeouts for AI-workloads:

Operasjon Anbefalt timeout Begrunnelse
Chat Completion (standard) 60-120 sek GPT-4o kan bruke tid på komplekse prompts
Chat Completion (streaming) 120-180 sek Streaming starter raskt, men kan vare lenge
Embeddings 30-60 sek Raskere operasjon, typisk < 10 sek
Image Generation (DALL-E) 120-180 sek Bildegenerering er CPU-intensivt
Assistants API 180-300 sek Multi-step agent workflows
Batch API 300-600 sek Store batch-operasjoner

Timeout + Circuit Breaker interaksjon

Timeout utløper (120 sek)
  → APIM registrerer det som feil
  → Teller mot circuit breaker threshold
  → Etter N timeouts → Circuit breaker trip
  → Backend fjernes fra pool → Trafikk til alternativer

Best practice: Sett timeout lavere enn det du tror er nødvendig. Bedre å få rask feil og retry til annen backend enn å vente 120 sekunder på en hengende request.


Avanserte mønstre

Mønster: Cascading Circuit Breakers

For multi-tier arkitekturer der APIM ruter til mellomtjenester som igjen kaller Azure OpenAI:

Client → APIM [CB-1] → Custom Service [CB-2] → Azure OpenAI
// CB-1: APIM → Custom Service
resource customServiceBackend 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
  properties: {
    circuitBreaker: {
      rules: [{
        failureCondition: {
          count: 5
          interval: 'PT2M'
          statusCodeRanges: [
            { min: 502, max: 504 }
          ]
        }
        tripDuration: 'PT30S'
      }]
    }
  }
}

Applikasjons-nivå CB-2 implementeres med Polly (.NET), resilience4j (Java), eller tilsvarende.

Mønster: Health Endpoint Monitoring

Kombiner circuit breaker med aktiv health checking:

<policies>
    <inbound>
        <!-- Sjekk health endpoint før ruting -->
        <send-request mode="new"
                      response-variable-name="healthCheck"
                      timeout="5"
                      ignore-error="true">
            <set-url>@("https://aoai-norwayeast.openai.azure.com/openai/models?api-version=2024-10-21")</set-url>
            <set-method>GET</set-method>
            <authentication-managed-identity
                resource="https://cognitiveservices.azure.com/" />
        </send-request>

        <choose>
            <when condition="@(((IResponse)context.Variables["healthCheck"]).StatusCode != 200)">
                <!-- Backend er nede, bruk fallback direkte -->
                <set-backend-service backend-id="openai-fallback-pool" />
            </when>
            <otherwise>
                <set-backend-service backend-id="openai-primary-pool" />
            </otherwise>
        </choose>
    </inbound>
</policies>

Merk: Health endpoint monitoring legger til latens og backend-belastning. Bruk det kun for scenarier der circuit breaker alene ikke gir rask nok failover.


Anti-mønstre

Anti-mønster Problem Løsning
Ingen circuit breaker Backend overbelastes, cascading failure Aktiver circuit breaker på alle AI-backends
For lav threshold (count=1) Falske positiver ved transiente feil Bruk count=3-5 for produksjon
For lang tripDuration Backend er unødvendig utilgjengelig Bruk acceptRetryAfter: true
Ignorere Retry-After Hammer backend som eksplisitt ber om pause Sett acceptRetryAfter: true alltid
Server-side delay Retry med sleep/delay holder opp klienter Bruk interval="0" med backend pool failover
Timeout for lang Gateway-ressurser brukt opp på hengende requests Sett realistiske timeouts per operasjonstype
Mangle monitoring Ingen innsikt i circuit breaker-oppførsel Emit metrikk + KQL dashboards

Komplett resiliens-policy

<policies>
    <inbound>
        <!-- 1. Token rate limiting -->
        <llm-token-limit
            counter-key="@(context.Subscription.Id)"
            tokens-per-minute="50000"
            estimate-prompt-tokens="true" />

        <!-- 2. Backend pool med circuit breaker -->
        <set-backend-service backend-id="openai-pool-priority" />

        <!-- 3. Managed Identity auth -->
        <authentication-managed-identity
            resource="https://cognitiveservices.azure.com/" />
    </inbound>

    <backend>
        <!-- 4. Retry til annen backend ved 429 -->
        <retry condition="@(context.Response.StatusCode == 429)"
               count="3"
               interval="0"
               first-fast-retry="true">
            <set-backend-service backend-id="openai-pool-priority" />
        </retry>

        <!-- 5. Timeout -->
        <forward-request timeout="120" />
    </backend>

    <outbound>
        <!-- 6. Token metrikk -->
        <llm-emit-token-metric namespace="ai-gateway">
            <dimension name="Backend" value="@(context.Backend?.Id ?? "unknown")" />
            <dimension name="StatusCode" value="@(context.Response.StatusCode.ToString())" />
        </llm-emit-token-metric>
    </outbound>

    <on-error>
        <!-- 7. Graceful degradation -->
        <choose>
            <when condition="@(context.Response.StatusCode == 503)">
                <return-response>
                    <set-status code="503" reason="AI Service Unavailable" />
                    <set-header name="Retry-After" exists-action="override">
                        <value>60</value>
                    </set-header>
                    <set-body>{"error":{"code":"all_backends_unavailable","message":"Alle AI-backends er midlertidig utilgjengelige"}}</set-body>
                </return-response>
            </when>
        </choose>
    </on-error>
</policies>

For Cosmo

  • Circuit breaker er obligatorisk for alle Azure OpenAI backends i produksjon -- uten det risikerer du cascading failures og bortkastet gateway-kapasitet mot throttlede backends.
  • Sett ALLTID acceptRetryAfter: true for Azure OpenAI backends. Azure OpenAI returnerer presise Retry-After verdier som gir optimal recovery-timing. Uten dette bruker du den statiske tripDuration som kan være for kort eller for lang.
  • Anbefalt baseline: count: 3, interval: PT1M, tripDuration: PT10S, acceptRetryAfter: true. Juster count opp for PAYGO-backends med mer toleranse.
  • Kombiner circuit breaker med backend pools for automatisk failover: når PTU-backend tripper, ruter APIM automatisk til PAYGO-backends uten klient-endringer.
  • Advarsler: Azure OpenAI kan returnere Retry-After opp til 86400 sekunder (1 dag). Sørg for at arkitekturen har nok alternative backends til å håndtere langvarige circuit breaks.