Three-tier AI fallback
Stel je product calls een LLM-API en die call faalt. Wat ziet de gebruiker? "Service temporarily unavailable" is het slechte antwoord. Het goede antwoord: een stilletjes gedegradeerde response die nog steeds doet wat het moet doen, en die de gebruiker niet eens opmerkt.
Het patroon is drie tiers gestapeld: API → rule-based → hardcoded. Elke tier kan dezelfde request afhandelen, met dalende kwaliteit maar stijgende betrouwbaarheid.

Whiteboard-schets · de cascade
De dispatch
async def generate_response(context: dict) -> str:
# Tier 1: LLM API (primair)
try:
return await _call_api(context, timeout=5.0)
except (httpx.HTTPError, APIError) as e:
log.info("tier-1 failed (%s), falling through", type(e).__name__)
# Tier 2: rule-based reasoning
try:
result = _rules_engine(context)
if result:
return result
except Exception as e:
log.warning("tier-2 failed (%s), falling through", e)
# Tier 3: hardcoded fallback
return _hardcoded_for_context(context)
De dispatch is bewust dom. Elke tier geeft óf een bruikbare response, óf niks; en als het niks is, draait de volgende. Geen coördinatie, geen retry-logica op dit niveau, geen slimme circuit breakers.
Wat elke tier doet
Tier 1 — LLM API is de default. Beste output-kwaliteit. Maar ook de tier die faalt als het netwerk eruit ligt, als je rate-limits raakt, als de provider een incident heeft, als je key zonder waarschuwing roteert, of als een model waar je op leunt deprecated wordt. Plan voor al die gevallen.
Tier 2 — rule-based reasoning draait dezelfde logica, lokaal, in gewone Python. Voor een AI-coach die input-verbeteringen voorstelt: een handgeschreven rules-engine met grofweg 60 if/else-takken dekt de meest voorkomende feedback-patronen. Minder elegant, maar 80% van de tijd goed en direct.
Tier 3 — hardcoded is het absolute minimum. Een klein dictionary met context-gekoppelde standaard-antwoorden. Saai, repetitief, maar betrouwbaar. Als tier 1 én 2 falen krijgt de gebruiker tenminste iets, en iets is altijd beter dan een error-toast.
Wanneer wel of geen tier 2
Tier 2 is paradoxaal genoeg de duurste tier om te bouwen — het is code, en code schrijven kost meer tijd dan een API-call. Je bouwt 'm als:
- De feature in een kritieke user-flow zit (elke sessie raakt 'm)
- "Geen response" een zichtbare breuk in het product is
- De rules-ruimte klein genoeg is om uit te schrijven
Je slaat 'm over als:
- De feature zelden gebruikt wordt of niet-kritiek is
- Een failure gracieus opgelost kan worden ("probeer opnieuw" knop)
- De rules-ruimte echt open-eindig is (creatief schrijven bijvoorbeeld)
Voor de meeste features is tier 1 + tier 3 genoeg. De middelste tier is voor producten waar reliability onderdeel is van het merk.
Cache is bijna een eigen tier
Net onder tier 1, vóór elke call, kan een cache-laag de API helemaal
overslaan. Cache-keys zijn meestal (context-hash, mood, last-action) of
iets vergelijkbaars. Hit-rate van 40-60% is realistisch voor een chat-agent
met herhalende patronen.
Cache-TTLs zijn wel een tuning-probleem. Te lang en de agent "herhaalt zichzelf" — gebruikers zien hetzelfde antwoord twee keer in een sessie en de illusie breekt. Te kort en je betaalt API-kosten die je niet hoeft te maken. Begin op 30 minuten en pas aan op basis van klachten over herhaling.
Observability per tier
Log welke tier elke request heeft afgehandeld. Na een week zie je de echte distributie. Als tier 1 99% serveert en tier 2 + 3 samen 1%, dan kun je waarschijnlijk tier 2 droppen. Als tier 2 op 15% komt: die trekt z'n gewicht, en je API is minder betrouwbaar dan je dacht.
De cijfers verrassen je meestal in minstens één richting.
Wat het je merk oplevert
De grootste onzichtbare winst van dit patroon: als andere AI-producten zichtbaar faillen (toast-errors, kapotte loading-states, "AI is currently unavailable" banners), draait jouw product gewoon door. Iets minder slim, iets saaier, maar nog steeds functioneel.
Een gebruiker die al een paar keer is afgeknapt op een AI-product-down gaat jouw AI-product vertrouwen — ook als die ook tien keer down is geweest en ze gewoon tier-3 responses kregen zonder het te merken.