Guide och insikt

Pålitlig LLM API Routing: Timeouts, återförsök och modellfallbacks utan semantiska regressioner

En praktisk arkitektur för att klassificera LLM API-fel, genomdriva en latensbudget, välja kompatibla reservmodeller, skydda biverkningar och validera alla accepterade svar.

En reservbegäran lyckas inte bara för att en annan modell returnerade HTTP 200. Ersättningen kan överskrida den ursprungliga latensbudgeten, utelämna obligatoriska JSON-fält, anropa ett annat verktyg eller producera ett svar med väsentligt annorlunda semantik. Pålitlig LLM API-routing kräver därför mer än en ordnad lista med modeller: den kräver ett kontrakt, en felklassificerare, en policy för begränsat försök och validering innan godkännande.

Den centrala regeln är enkel: försök endast igen när felet troligen är tillfälligt, och fall tillbaka först när nästa rutt fortfarande kan uppfylla det ursprungliga begärandekontraktet.

Definiera routingkontraktet innan du väljer modeller

Börja med att beskriva vad ett framgångsrikt svar måste ge. Detta routingkontrakt bör vara maskinläsbart och bifogas varje arbetsbelastning eller förfrågningsklass.

{
  "workload": "invoice_extraction",
  "modalities": ["text", "bild"],
  "max_input_tokens": 50000,
  "requires_tools": false,
  "structured_output": {
    "required": sant,
    "schema_id": "faktura-v3",
    "strikt": sant
  },
  "allowed_model_classes": ["dokumentutdrag"],
  "max_cost_usd": 0,08,
  "deadline_ms": 8000
}

Kontraktet bör täcka erforderliga modaliteter, kontextkapacitet, verktygsstöd, strukturerad produktion, acceptabla modellklasser, maximal kostnad och deadline från slut till slut. Lägg till applikationsspecifika begränsningar där det är nödvändigt, som tillåtna områden, minsta utdatalängd eller en nödvändig orsak till finish.

Rekommendation: upprätthåll separata, testade ruttgrupper för oformaterad text, schemabegränsad utdata, verktygsanvändning, vision och förfrågningar om långa sammanhang. En modell som är en acceptabel reservtext är inte automatiskt en acceptabel reserv för verktygsanrop eller bildinmatning.

Klassificera felet innan du vidtar åtgärder

Autentiseringsfel, felaktiga förfrågningar, hastighetsgränser och serverfel kräver olika svar. Att behandla varje icke-framgångssvar som ett nytt försök slösar kapacitet och kan dölja defekter.

FelklassExempelStandardåtgärd Permanent begäran misslyckadesOgiltiga referenser, felaktiga parametrar, funktion som inte stödsStoppa och returnera ett tydligt fel RuttinkompatibilitetKontexten är för stor, bildinmatning stöds inte, otillgängligt schemalägeTesta endast en kompatibel rutt Transient transportfelAnslutningsåterställning, DNS-fel, vald timeoutFörsök igen inom den återstående budgeten Kapacitets- eller hastighetsfelHTTP 429, överbelastad tjänst, valda 5xx-svarBeakta tips om försök igen eller använd en sund reserv Ogiltigt lyckat svarFelformat JSON, okänt verktyg, obligatoriskt fält saknasAvvisa, försök sedan igen eller fall tillbaka om policyn tillåter Tvetydig exekveringAnslutning förlorad efter att leverantören kan ha accepterat begäranDeduplicera före uppspelning

Faktum: misslyckade förfrågningar med takstbegränsade förfrågningar kan fortfarande räknas mot leverantörsgränser. Aggressiva omedelbara försök kan därför fördjupa strypningen istället för att lösa det. Omförsök förbrukar också ytterligare kapacitet under ett avbrott, och försök igen vid flera programlager kan multiplicera den resulterande belastningen.

Rekommendation: låt ett lager egna modellgenereringsförsök. I en typisk arkitektur är AI API-gatewayen rätt ägare eftersom den ser ruttens hälsa, försökshistorik, latens och kostnad. Inaktivera automatiska återförsök i klienter på lägre nivå där det är möjligt, eller räkna dem uttryckligen i samma försöksbudget.

Spendera en total latensbudget

Timeouts per försök är otillräckliga. Tre försök med fem sekunders timeout kan förvandla en avsedd operation på fem sekunder till ett svar på femton sekunder, innan backoff och validering ingår.

Spela in en absolut deadline när begäran kommer in i gatewayen. Före varje försök, beräkna den återstående tiden:

resterande = deadline - aktuell_tid
krävs = connect_allowance + generation_allowance + validation_allowance
om återstående < krävs:
    stop_without_launching_another_tempt

För en deadline på åtta sekunder kan en rimlig initial tilldelning reservera 300 ms för gatewayarbete och slutlig validering, tillåta upp till 4,5 sekunder för den primära rutten och behålla cirka 3,2 sekunder för en reserv. Dessa värden är ett exempel, inte ett riktmärke. De måste härledas från uppmätta latensfördelningar för de faktiska leverantörerna, modellerna, regionerna och utdatastorlekarna.

Använd begränsad exponentiell backoff med jitter för övergående försök:

delay = random(0, min(cap, base * 2^retry_index))

Tips från leverantören om försök, till exempel ett nytt försök efter-värde, bör ha företräde när de passar inom den återstående tidsfristen. Stoppa efter ett litet antal försök. En vanlig policy är ett primärt försök plus en reserv, med ett valfritt försök på samma rutt endast för ett tidigt anslutningsfel som inte kunde ha genererat fakturerbar utdata.

Avvägning: sekventiell reserv förbättrar tillgängligheten men ökar svansfördröjningen. Parallella eller säkrade förfrågningar kan minska latensen under avmattningar, men de förbrukar mer kapacitet och kan medföra avgifter för flera framgångsrika generationer. Säkring bör begränsas till fördröjningskritiska, biverkningsfria arbetsbelastningar med avbokning och kostnadskontroll.

Välj fallbacks efter förmåga, inte rang

En reservtabell bör koda kompatibilitet snarare än en global preferensordning. Filtrera kandidatvägar mot kontraktet innan du överväger hälsa, latens eller pris.

kandidater = rutter
  .filter(supports_required_modalities)
  .filter(context_limit >= estimated_input_size)
  .filter(supports_required_tools)
  .filter(supports_requested_schema_mode)
  .filter(modellklass i tillåtna_modellklasser)
  .filter(estimated_cost <= resterande_kostnadsbudget)
  .filter(inte_temporarily_suppressed)
vald = rank(kandidater, hälsa, latens, kostnad)

Stöd för strukturerad utdata förtjänar explicit testning. Även när två rutter annonserar om schemabegränsad generering kan de stödja olika JSON Schema-underuppsättningar eller tolka kantfall på olika sätt. Verktygskompatibla modeller kan också skilja sig åt i verktygsval, argumentkonstruktion och parallellanropsbeteende.

Fakta: Att byta modellfamiljer kan bevara transporttillgängligheten samtidigt som man ändrar stil, resonemangskvalitet, säkerhetsbeteende, tokenisering och verktygsval. HTTP-framgång är inte bevis på semantisk likvärdighet.

Förutsägelse: när modellkatalogerna expanderar, kommer produktionsdirigeringspolicyer i ökad grad att använda versionsbaserade kapacitetsprofiler och arbetsbelastningsspecifika acceptanstester istället för statiska modelllistor. Behandla detta som en designriktning, inte en garanti om leverantörens beteende.

Verifiera svaret innan du accepterar det

Kör varje svar, inklusive det primära svaret, genom samma acceptanspipeline. Validering bör ske innan resultatet cachelagras, faktureras internt som framgångsrikt eller skickas till en verktygsexekutor.

  1. Bekräfta att transporten har slutförts och svarskuvertet kan tolkas.
  2. Kontrollera slutorsaken och avvisa trunkering när fullständig utdata krävs.
  3. Validera strukturerad utdata mot det ursprungliga schemat.
  4. Verifiera obligatoriska fält, uppräkningsvärden och applikationsinvarianter.
  5. Tillåt endast registrerade verktygsnamn och validera argument mot varje verktygsschema.
  6. Tillämpa arbetsbelastningsspecifika semantiska kontroller där falsk acceptans skulle bli kostsamt.

För fakturaextraktion kan semantiska kontroller kräva en icke-negativ summa, en valutakod som stöds och radsummor inom en explicit definierad tolerans. För klassificering krävs en etikett från den tillåtna uppsättningen. För kodgenerering kan parsning eller kompilering vara lämpligt. Dessa kontroller bevisar inte kvalitet, men de förhindrar att förutsägbara kontraktsbrott behandlas som framgångar.

Reparera inte alla felaktiga svar i tysthet. Deterministisk normalisering, som att ta bort ofarliga omgivande blanksteg, kan vara acceptabelt. Att gissa saknade ekonomiska fält eller omskrivningsverktygsargument ändrar modellens innebörd och bör utlösa avslag eller mänsklig granskning.

Separat generationsförsök från biverkningar

LLM-förfrågningar använder vanligtvis HTTP POST, vilket inte är i sig idempotent. Ännu viktigare är att ett modellsvar kan initiera en extern åtgärd som att debitera en betalningsmetod, skicka ett meddelande, skapa en biljett eller ändra infrastruktur. Att försöka generera igen och spela upp den handlingen är separata beslut.

Tilldela ett operations-ID vid applikationsgränsen och ett försöks-ID till varje modellanrop. Behåll verktygskörningstillstånd mot en deterministisk nyckel, såsom:

execution_key = operation_id + tool_name + canonical_arguments_hash

Innan du kör ett verktyg, kontrollera om nyckeln är väntande, slutförd eller misslyckad. Returnera det lagrade resultatet för en slutförd körning istället för att köra det igen. För operationer vars argument kan ändras legitimt, kräver godkännande på applikationsnivå eller ett nytt operations-ID.

En tvetydig timeout kräver speciell hantering. Om anslutningen misslyckas efter att en begäran har överförts kanske gatewayen inte vet om generering inträffade. En leverantörsstödd idempotensnyckel kan hjälpa när den är tillgänglig. Annars loggar du resultatet som okänt och tillämpar en arbetsbelastningsspecifik uppspelningspolicy istället för att anta att ingenting har hänt.

Undertryck ohälsosamma vägar och avslöja varje försök

En strömbrytare eller tillfälligt hälsoskydd förhindrar att varje ny begäran återupptäcker samma misslyckade rutt. Öppna kretsen efter en definierad felfrekvens eller tröskelvärde för konsekutivt fel, släpp sedan in begränsade sonder i halvöppet tillstånd. Justera trösklar efter rutt och felklass så att en felaktig klientförfrågan inte kan få en hälsosam modell att verka otillgänglig.

Spela in en händelse på begäran och en händelse per försök. Användbara fält inkluderar operations-ID, försöks-ID, vald leverantör och modell, felklass, statuskod, latens, tokenantal, uppskattad kostnad, reservorsak, valideringsresultat, kretsstatus och slutligt resultat. Redigera eller hasha uppmaningar, utdata och verktygsargument enligt deras krav på känslighet och lagring.

Användbara operativa mätvärden inkluderar reservfrekvens, försök per slutförd begäran, utmattningsfrekvens för deadline, avvisningsfrekvens för validering, tvetydiga resultat, kostnad per accepterat svar och fördröjning genom slutlig väg. En stigande HTTP-framgångsfrekvens tillsammans med en stigande valideringsavvisningsfrekvens är en varning om att transporttillgänglighet döljer kontraktsfel.

Checklista för utbyggnad av produktion

  • Definiera ett versionerat routingkontrakt för varje arbetsbelastningsklass.
  • Kapta leverantörsfel till permanenta, övergående, inkompatibla, ogiltigt svar och tvetydiga kategorier.
  • Välj ett nytt försök ägare och begränsa det totala antalet försök.
  • Skapa en absolut deadline genom gateway, leverantörsklient, validering och verktygsexekvering.
  • Bygg kapacitetstestade reservgrupper snarare än en global modellkedja.
  • Validera scheman, verktygsanrop, slutskäl och domäninvarianter.
  • Deduplicera biverkningar med drift- och körningsnycklar.
  • Lägg till ruttundertryckning med avgränsade halvöppna sonder.
  • Loggförsöksfördröjning, tokens, kostnader, misslyckanden och acceptansresultat.
  • Injicera timeouts, 429s, valda 5xx-fel, felaktigt format JSON, kontextspill och långsamma framgångar i iscensättningen.

Börja med en primär rutt och en kompatibel reserv för en enda arbetsbelastning med låg risk. Jämför accepterade svarskvalitet, latens och kostnad innan du utökar policyn. Målet är inte högsta möjliga reservfrekvens. Det är ett avgränsat system som antingen returnerar ett svar som uppfyller det ursprungliga kontraktet eller misslyckas tydligt innan det orsakar dubbelarbete eller semantisk skada.

Relaterad läsning

FAQ

Vanliga frågor

Vilka LLM API-fel bör utlösa ett nytt försök?
Försök endast igen fel som klassificeras som övergående, såsom valda anslutningsfel, timeouts, hastighetsgränser och leverantörsserverfel. Försök inte automatiskt igen ogiltiga autentiseringsuppgifter, felaktiga förfrågningar, funktioner som inte stöds eller kontextbegränsningsfel. Ett fel med kontextbegränsning kan motivera en kompatibel reserv med långa sammanhang, men att upprepa samma begäran på samma rutt kommer inte att åtgärda det.
Hur många fallback-försök bör en gateway tillåta?
Det finns inget universellt nummer, men gränsen bör vara liten och styras av en deadline från början till slut. En praktisk utgångspunkt är ett primärt försök och en kompatibel reserv. Lägg till ytterligare ett försök endast när uppmätta tillförlitlighetsvinster motiverar den extra latensen, kapaciteten och kostnaden.
Är förfrågningar om verktygsanrop säkra att försöka igen?
Modellgenerering kan försökas igen under en begränsad policy, men exekvering av externa verktyg måste dedupliceras separat. Använd ett operations-ID och en deterministisk exekveringsnyckel, behåll verktygsresultatet och undvik att spela upp betalningar, meddelanden eller andra biverkningar bara för att genereringen upprepades.
Kan en billigare modell användas som automatisk reserv?
Endast när den uppfyller samma routingkontrakt och klarar arbetsbelastningsspecifika acceptanstest. Pris ensamt etablerar inte kompatibilitet. Kontrollera modalitet, sammanhang, strukturerad utdata, verktyg, latens och kvalitetskrav innan du placerar någon modell i en reservgrupp.