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>
15 KiB
API Versioning Strategies for AI Endpoints
Last updated: 2026-06-24 Status: GA Category: API Management & AI Gateway Type: reference Source: https://learn.microsoft.com/azure/api-management/genai-gateway-capabilities Verified: 2026-07-24 Verified by: judge-v3.1
Innhold
- Introduksjon
- Versjoneringsstrategier i APIM
- Avviklingsfrister (Deprecation Timelines)
- Modellversjonsmapping
- Migreringsstrategier
- Revisjonsstyring for ikke-brytende endringer
- Handtering av brytende endringer
- Referanser
- For arkitekten
Introduksjon
API-versjonering er kritisk for AI-tjenester der underliggende modeller endres hyppig, nye kapabiliteter legges til og eldre versjoner fases ut. Azure API Management tilbyr tre versjoneringsstrategier (URL-path, header og query string) samt revisjonsstyring for ikke-brytende endringer. For AI-API-er er dette spesielt utfordrende fordi modellversjoner, API-schemaer og responsformater kan endres uavhengig av hverandre.
For norsk offentlig sektor er kontrollert versjonering essensielt. Offentlige virksomheter har ofte integrerte systemer som er avhengige av stabile API-grensesnitt, og et modellbytte kan gi annerledes output for samme prompt. En robust versjoneringssstrategi sikrer at eksisterende integrasjoner fortsetter a fungere nar nye modeller eller kapabiliteter innfores, og gir forbrukere tid til a migrere kontrollert.
APIM skiller mellom versjoner (for brytende endringer) og revisjoner (for ikke-brytende endringer). Denne referansen dekker begge konseptene i konteksten av AI-API-er, med praktiske monstre for modellversjonsmapping, migrasjon og avvikling.
Versjoneringsstrategier i APIM
Tre tilgjengelige skjemaer
| Skjema | Format | Eksempel |
|---|---|---|
| URL Path | /{api-path}/v1/... |
https://api.virksomhet.no/ai/v1/chat/completions |
| Header | Custom header | Api-Version: 2024-08-01 |
| Query String | URL-parameter | https://api.virksomhet.no/ai/chat/completions?api-version=2024-08-01 |
Anbefaling for AI-API-er
| Strategi | Fordeler | Ulemper | Anbefalt for |
|---|---|---|---|
| URL Path | Tydelig, selvdokumenterende, lett a route | Mer tungvint a migrere | Offentlige API-er med stabile versjoner |
| Header | Ren URL, fleksibelt | Ikke synlig i URL | Interne API-er, programmatisk tilgang |
| Query String | Kompatibelt med Azure OpenAI-konvensjon | Kan bli rotete med mange params | Direkte kompatibilitet med Azure OpenAI |
Anbefaling: For AI gateway som wrapper rundt Azure OpenAI, bruk query string med api-version for a folge Microsofts eksisterende konvensjon. For egne AI-fasade-API-er, bruk URL path for tydelighet.
Konfigurere versjonering i APIM
URL Path-versjonering
resource apiVersionSet 'Microsoft.ApiManagement/service/apiVersionSets@2023-09-01-preview' = {
parent: apiManagement
name: 'ai-gateway-version-set'
properties: {
displayName: 'AI Gateway API'
versioningScheme: 'Segment' // URL path
description: 'AI Gateway API versjonert med URL-path'
}
}
resource aiApiV1 'Microsoft.ApiManagement/service/apis@2023-09-01-preview' = {
parent: apiManagement
name: 'ai-gateway-v1'
properties: {
displayName: 'AI Gateway API v1'
apiVersion: 'v1'
apiVersionSetId: apiVersionSet.id
path: 'ai'
protocols: [ 'https' ]
subscriptionRequired: true
}
}
resource aiApiV2 'Microsoft.ApiManagement/service/apis@2023-09-01-preview' = {
parent: apiManagement
name: 'ai-gateway-v2'
properties: {
displayName: 'AI Gateway API v2'
apiVersion: 'v2'
apiVersionSetId: apiVersionSet.id
path: 'ai'
protocols: [ 'https' ]
subscriptionRequired: true
}
}
Header-basert versjonering
resource apiVersionSetHeader 'Microsoft.ApiManagement/service/apiVersionSets@2023-09-01-preview' = {
parent: apiManagement
name: 'ai-gateway-header-version-set'
properties: {
displayName: 'AI Gateway API (Header Versioned)'
versioningScheme: 'Header'
versionHeaderName: 'Api-Version'
}
}
Query String-versjonering
resource apiVersionSetQuery 'Microsoft.ApiManagement/service/apiVersionSets@2023-09-01-preview' = {
parent: apiManagement
name: 'ai-gateway-query-version-set'
properties: {
displayName: 'AI Gateway API (Query Versioned)'
versioningScheme: 'Query'
versionQueryName: 'api-version'
}
}
Avviklingsfrister (Deprecation Timelines)
Livssyklusmodell for AI-API-versjoner
[Preview] --> [GA] --> [Deprecated] --> [Retired]
| | | |
| 6-12 mnd | 6-12 mnd| 3-6 mnd |
| | | |
Flagg: Flagg: Flagg: Fjernet
beta stable deprecated fra gateway
Fasestyring med policies
<policies>
<outbound>
<base />
<!-- Add deprecation headers based on API version -->
<choose>
<!-- Deprecated version -->
<when condition="@(context.Api.Version == "v1")">
<set-header name="Deprecation" exists-action="override">
<value>true</value>
</set-header>
<set-header name="Sunset" exists-action="override">
<value>Sat, 30 Jun 2026 00:00:00 GMT</value>
</set-header>
<set-header name="Link" exists-action="override">
<value><https://api.virksomhet.no/ai/v2/docs>; rel="successor-version"</value>
</set-header>
<!-- Log deprecation usage for tracking -->
<trace source="api-versioning" severity="warning">
<message>@($"Deprecated API v1 called by {context.Subscription.Name}")</message>
</trace>
</when>
<!-- Preview version -->
<when condition="@(context.Api.Version == "v3-preview")">
<set-header name="x-api-status" exists-action="override">
<value>preview</value>
</set-header>
<set-header name="x-api-warning" exists-action="override">
<value>This API version is in preview and may change without notice.</value>
</set-header>
</when>
</choose>
</outbound>
</policies>
Standard HTTP-headere for versjonsstyring
| Header | Verdi | RFC |
|---|---|---|
Deprecation |
true |
RFC 8594 |
Sunset |
ISO 8601 dato | RFC 8594 |
Link |
URL til ny versjon | RFC 8288 |
x-api-status |
preview / ga / deprecated |
Custom |
Modellversjonsmapping
Utfordringen med AI-modellversjoner
AI-modeller oppdateres uavhengig av API-versjoner:
| API-versjon | Modellnavn | Faktisk modellversjon | Endring |
|---|---|---|---|
| v1 | gpt-4o | 2024-05-13 | Opprinnelig |
| v1 | gpt-4o | 2024-08-06 | Modelloppgradering (transparent) |
| v2 | gpt-4o | 2024-11-20 | Ny API + ny modell |
| v2 | gpt-4o-mini | 2024-07-18 | Ny modelltype i v2 |
Policy: Modellversjonsmapping
<policies>
<inbound>
<base />
<!-- Map API version to specific model deployment -->
<set-variable name="apiVersion" value="@(context.Api.Version)" />
<set-variable name="requestedModel"
value="@(context.Request.Body.As<JObject>(preserveContent: true)?["model"]?.ToString())" />
<choose>
<!-- v1: Map to stable, older model deployments -->
<when condition="@((string)context.Variables["apiVersion"] == "v1")">
<set-variable name="deployment" value="@{
var model = (string)context.Variables["requestedModel"];
return model switch {
"gpt-4o" => "gpt-4o-2024-05-13-stable",
"gpt-4" => "gpt-4-0613-stable",
_ => "gpt-4o-2024-05-13-stable"
};
}" />
</when>
<!-- v2: Map to latest model deployments -->
<when condition="@((string)context.Variables["apiVersion"] == "v2")">
<set-variable name="deployment" value="@{
var model = (string)context.Variables["requestedModel"];
return model switch {
"gpt-4o" => "gpt-4o-2024-11-20-latest",
"gpt-4o-mini" => "gpt-4o-mini-2024-07-18",
_ => "gpt-4o-2024-11-20-latest"
};
}" />
</when>
</choose>
<!-- Route to correct deployment -->
<rewrite-uri template="@($"/openai/deployments/{context.Variables["deployment"]}/chat/completions")" />
</inbound>
</policies>
Migreringsstrategier
Parallellkjoring av versjoner
Kjor gammel og ny versjon side om side med gradvis migrering:
<policies>
<inbound>
<base />
<!-- Canary: Route percentage of v1 traffic to v2 backend -->
<choose>
<when condition="@(context.Api.Version == "v1" && new Random().Next(100) < 10)">
<!-- 10% of v1 traffic gets v2 backend for shadow testing -->
<set-variable name="shadowTest" value="true" />
<set-backend-service backend-id="ai-backend-v2" />
<set-header name="x-shadow-test" exists-action="override">
<value>true</value>
</set-header>
</when>
</choose>
</inbound>
</policies>
Migreringssjekkliste
| Fase | Handling | Varighet |
|---|---|---|
| 1. Announce | Publiser ny versjon, dokumenter endringer | Uke 0 |
| 2. Parallel | Kjor begge versjoner, monitor bruk | Uke 1-12 |
| 3. Deprecate | Merk gammel versjon som deprecated | Uke 8 |
| 4. Notify | Send varsler til aktive brukere | Uke 8, 16, 22 |
| 5. Restrict | Reduser rate limits pa gammel versjon | Uke 20 |
| 6. Sunset | Fjern gammel versjon | Uke 24 |
KQL: Overvak versjonsbruk
ApiManagementGatewayLogs
| where TimeGenerated > ago(30d)
| extend ApiVersion = tostring(split(ApiId, "-")[-1])
| summarize
RequestCount = count(),
UniqueSubscriptions = dcount(SubscriptionId)
by ApiVersion, bin(TimeGenerated, 1d)
| order by TimeGenerated desc, ApiVersion asc
Revisjonsstyring for ikke-brytende endringer
Revisjoner vs. Versjoner
| Egenskap | Revisjon | Versjon |
|---|---|---|
| Type endring | Ikke-brytende | Brytende |
| URL-endring | Nei (;rev=N valgfri) |
Ja (ny versjon i path/header/query) |
| Eksempel | Legge til valgfritt felt | Endre responsstruktur |
| Klientpavirkning | Ingen (bakoverkompatibelt) | Krever klientoppdatering |
| Publisering | Gjor revisjon "current" | Ny API-versjon |
| Change log | Valgfri endringslogg | Egen dokumentasjon |
Bruke revisjoner for modelloppgraderinger
Nar en modell oppdateres uten API-endringer (f.eks. GPT-4o far ny snapshot):
- Opprett ny revisjon av API-et
- Endre backend-deployment i den nye revisjonen
- Test grundig med nye revisjon
- Gjor revisjon "current" nar validert
- Publiser endringslogg
<!-- Revision-specific backend for testing -->
<policies>
<inbound>
<base />
<!-- Non-current revisions can use different backends for testing -->
<choose>
<when condition="@(context.Api.Revision == "3")">
<set-backend-service backend-id="ai-backend-new-model" />
</when>
</choose>
</inbound>
</policies>
Handtering av brytende endringer
Hva er en brytende endring for AI-API-er?
| Endring | Brytende? | Strategi |
|---|---|---|
| Legge til nytt valgfritt felt i response | Nei | Revisjon |
| Endre modellnavn | Ja | Ny versjon |
| Fjerne felt fra response | Ja | Ny versjon |
| Endre feilformat | Ja | Ny versjon |
| Endre token-tellemekanisme | Ja | Ny versjon |
| Legge til ny operasjon | Nei | Revisjon |
| Endre autentiseringsmetode | Ja | Ny versjon |
| Oppdatere underliggende modell (samme API) | Avhenger* | Revisjon eller versjon |
* Modelloppgraderinger som gir vesentlig annerledes output bor behandles som brytende.
Versjonering av OpenAPI-spesifikasjon
openapi: 3.0.3
info:
title: AI Gateway API
version: '2.0'
description: |
## Endringslogg
### v2.0 (2026-02)
- Ny modell: gpt-4o-mini
- Endret responsformat for token_usage
- Fjernet deprecated 'prompt' field (bruk 'messages')
### v1.0 (2025-06) - DEPRECATED
- Opprinnelig versjon
- Sunset: 2026-06-30
contact:
name: AI Platform Team
email: ai-platform@virksomhet.no
Referanser
- Versions in Azure API Management -- versjoneringsguide
- Tutorial: Publish multiple versions of your API -- hands-on tutorial
- Revisions in Azure API Management -- revisjonsstyring
- Tutorial: Use revisions to make nonbreaking changes -- revisjon-tutorial
- API design - Versioning (Azure Architecture) -- designprinsipper
- OWASP: Improper inventory management -- sikkerhetsanbefalinger
- AI gateway in Azure API Management -- AI gateway-oversikt
For arkitekten
- Bruk denne referansen nar kunden planlegger versjonering av sine AI-API-er, trenger a migrere mellom modellversjoner, eller vil etablere en livssyklusmodell for sine API-endepunkter.
- For AI gateway som wrapper rundt Azure OpenAI, anbefal query string-versjonering med
api-versionfor kompatibilitet med Microsofts eksisterende konvensjon. - Skill alltid mellom modellversjoner og API-versjoner -- en modelloppgradering er ikke nodvendigvis en API-versjon. Bruk revisjoner for transparente modelloppgraderinger og versjoner for brytende API-endringer.
- Anbefal minimum 6 maneders deprecation-periode for norsk offentlig sektor, der integrerte systemer ofte har lange endringssykluser.
- Bruk alltid
DeprecationogSunsetHTTP-headere (RFC 8594) for a gi maskinlesbare signaler til klienter om kommende avvikling -- dette lar automatiserte systemer varsle forvaltere.