AI agents
LangGraph-audit: de checklist vóór een reliability-retrofit
Om 03:30 valt een LangSmith-regio uit en je facturatie-agent zwijgt. Wij auditen retry-drift, prompt-pinning en regio-failover vóór we offerte uitbrengen.

Het is 03:30 op een dinsdag. Een oprichter in Eindhoven krijgt een Slack-ping van haar on-call engineer: de customer-success-agent geeft geen antwoord meer. De LangSmith-statuspagina staat geel op us-east-1. De agent zelf draait prima, op haar eigen infrastructuur in Frankfurt, maar elke retry die get_order_status had moeten aanroepen, loopt nu stil rondjes tegen een tracing-endpoint dat geen writes meer accepteert. Om 04:10 staan er 8.000 berichten in de queue, klaar voor de ochtenddienst.
Dit is het faalpatroon waar we als eerste naar zoeken wanneer een Nederlands mkb-bedrijf onder de €20M ons vraagt hun agent-stack betrouwbaarder te maken. Voordat we beginnen met retrofit-werk, draaien we dezelfde audit van vijf pagina's op de LangGraph- en LangSmith-opzet die al in productie staat. Hieronder staat wat erop staat, waarom elk punt erop staat, en wat de scores eigenlijk betekenen wanneer de pdf eind van de week binnenkomt.
Wat de audit meet
Drie dingen. Meer niet. Een reliability-retrofit die alles tegelijk probeert op te lossen, lost meestal niets op. De meeste teams die we binnenstappen, hebben al een backlog van dat moeten we opruimen-tickets ter dikte van een telefoonboek. Wij kiezen de drie faalpatronen die, over de veertien agents die we momenteel in productie hebben, verantwoordelijk zijn voor het overgrote deel van de weekend-verwoestende incidenten.
- Tool-call retry-drift over de top 30 nodes op basis van call-volume.
- Prompt-version pinning op de top 12 sub-agents op basis van traffic-aandeel.
- Regio-failover-overleven voor de drie workflows die de business 's nachts echt niet kan missen.
De grenzen zijn niet willekeurig. Op een Pareto-grafiek van LangSmith-trace-aantallen voor vrijwel elke mkb-stack die we hebben geaudit, vlakt de staart af rond node dertig en sub-agent twaalf. Boven die grens stapelt drift snel op, omdat dezelfde nodes door de helft van de graph worden aangeroepen. Daaronder is de blast radius van een enkele storing klein genoeg dat het dit kwartaal oplossen zonde van het budget zou zijn.
Tool-call retry-drift, met cijfers
Een node heeft drift wanneer dezelfde input, opnieuw geprobeerd, een andere tool-call oplevert. Dit is bijna nooit de schuld van het model. Meestal is het een van vier oorzaken: een niet-gepinde tool-schema die tussen calls is gemuteerd, een sampling-temperatuur boven nul op een node die de auteur deterministisch waande, een retry-policy die de hele LLM-call opnieuw draait in plaats van alleen de tool, of een structured-output-validator die op poging twee stilletjes een veld coerceert en daarna nooit meer.
We trekken de laatste 30 dagen aan traces voor de top 30 nodes uit LangSmith en bucketen elke span op (node_id, input_hash, retry_index). Elk (node, input)-paar dat over retries heen meer dan één unieke tool-call-signatuur opleverde, krijgt een drift-punt. We wegen op traffic, normaliseren naar een 100-puntsschaal en noemen alles boven de 12 een harde buis. Tussen 5 en 12 is een zachte buis, met een regeltje erbij over welke nodes het zwaarst wegen.
De fix op een gezakte node is bijna altijd een van drie dingen, in deze volgorde toegepast: pin de tool-schema, zet de temperatuur op nul waar de node aan classificatie of routing doet, en versmal de retry-scope zodat hij om de tool-call heen ligt en niet om de LLM-stap die hem produceerde.
from langgraph.graph import StateGraph
from langgraph.pregel import RetryPolicy
# Retry the tool call, not the LLM that produced it.
graph.add_node(
"lookup_invoice",
lookup_invoice_tool,
retry=RetryPolicy(
max_attempts=4,
retry_on=(TransientError,), # never on ValueError
initial_interval=0.5,
backoff_factor=2.0,
jitter=True,
),
)
Als je retry-policy om de model-call heen ligt, doe je geen retry op dezelfde tool-call. Je sampelt een nieuwe. Dat is drift by construction, en het is het patroon dat we op dag één het vaakst tegenkomen. Het LangGraph-team legt het verschil uit in hun node retries guide, maar de meeste teams die we auditen hebben een tutorial gekopieerd die de hele node omwikkelt en er daarna nooit meer naar gekeken.
Prompt-version pinning, de matrix
De prompt-hub van LangSmith is uitstekend en gevaarlijk in gelijke mate. Uitstekend omdat een niet-engineer een system-prompt van een sub-agent kan aanpassen zonder te deployen. Gevaarlijk omdat een niet-engineer een system-prompt van een sub-agent kan aanpassen zonder te deployen.
Voor elk van de top 12 sub-agents stellen we één vraag: wordt de prompt opgehaald op naam (latest) of op commit-hash (gepind)? Wat op naam binnenkomt, zakt voor de audit. Het maakt ons niet uit hoe gedisciplineerd het team op dit moment is. Het gaat erom dat het rollback-pad bij een incident om 03:30 git revert is, en niet weet iemand nog hoe de prompt er gistermiddag uitzag?
from langsmith import Client
client = Client()
# Fails the audit: silently follows whoever last clicked Save.
prompt = client.pull_prompt("invoice-chaser/system")
# Passes the audit: pinned to a commit, behaviour is reproducible.
prompt = client.pull_prompt("invoice-chaser/system:6f3a91b")
Als jouw CI niet faalt wanneer een sub-agent naar een ongepinde prompt verwijst, doet onze audit dat wel. We grepen de repo op pull_prompt(-aanroepen zonder dubbele punt in het eerste argument en sommen elke overtreder op met bestand en regelnummer.
De matrix die we teruggeven, heeft één rij per sub-agent en vier kolommen: prompt-naam, momenteel gepinde commit, laatste commit op de hub, en aantal ongepinde productie-calls in de laatste 7 dagen. Alles wat in de laatste kolom niet nul is, wordt als eerste opgelost. De kosten zijn bijna altijd een paar uur code-werk en een CI-regel. De winst is dat een middernachtelijk prompt-experiment van een welwillende collega geen P1-incident meer is.
Drie workflows die een regio-failover moeten overleven
LangSmith draait in twee regio's: us-east-1 en eu-west-1, waarbij de EU-regio wordt aangeprezen voor AVG-relevant verkeer. Voor Nederlandse mkb-bedrijven die persoonsgegevens verwerken, is de EU-regio geen optie. Het is de enige configuratie die trace-payloads binnen de EER houdt, zonder dat je een transfer-impact-assessment moet schrijven dat de meeste operations-teams niet uit hun mouw schudden.
De vraag is dus niet zitten we op de EU-regio? Dat is het minimum. De vraag is: als eu-west-1 zelf om 03:30 degradeert, welke workflows kunnen dan hun huidige job afmaken, hun traces lokaal bufferen en die afspelen zodra de regio terug is, zonder ook maar een snipper geschiedenis te verliezen die de AVG en je DPO maandagochtend zullen opvragen?
We kiezen drie workflows voor survival-certificering. Drie, niet allemaal. De selectiecriteria, in volgorde:
- De workflow draait onbeheerd buiten kantooruren.
- Een stille storing kost het bedrijf dezelfde nacht geld of vertrouwen.
- De trace moet wettelijk minstens 30 dagen opvraagbaar blijven.
Bij de meeste klanten zit op die shortlist de facturatie-agent, de inbox-triage-agent en welke klantgerichte chat-agent dan ook die 24/7 draait. Voor een logistieke klant vorig jaar was het de route-herplan-agent, de SLA-bewaker en de overdracht naar de nachtdispatcher. De vorm van de werklast verandert; het principe niet.
Het overlevingspatroon is voor alle drie hetzelfde: een lokale trace-buffer op disk, een strakke client-side timeout op de LangSmith-call en een expliciete replay-job. Teruggebracht tot het strikt noodzakelijke:
import os, json, pathlib
from langsmith import Client
BUFFER = pathlib.Path("/var/lib/agent/trace-buffer")
BUFFER.mkdir(parents=True, exist_ok=True)
client = Client(
api_url=os.environ["LANGSMITH_ENDPOINT_EU"], # https://eu.api.smith.langchain.com
api_key=os.environ["LANGSMITH_API_KEY"],
timeout_ms=750, # fail fast; tracing must never stall the agent
)
def safe_emit(run: dict) -> None:
try:
client.create_run(**run)
except Exception:
# AVG-safe: persist locally, replay later, never drop.
(BUFFER / f"{run['id']}.json").write_text(json.dumps(run))
De replay-job draait elke vijf minuten en loopt de buffer in schrijfvolgorde af. We benchmarken hem op de hardware van de klant zelf voordat we tekenen: op een typische mkb-werklast leegt hij een storing van zes uur in minder dan twaalf minuten zodra de regio weer gezond is. Het draait niet om de doorvoer. Het draait erom dat geen enkele trace ooit verloren gaat, en dat is precies wat artikel 30 van de AVG en een toekomstige auditor willen horen.
Als je agent zijn werk niet kan afmaken wanneer LangSmith plat ligt, is LangSmith niet je tracing-backend. Dan is het je single point of failure, en je betaalt voor het privilege.
Wat bewust niet op de checklist staat
We auditen geen modelkeuze. We auditen geen kosten per run. We scoren de system-prompt niet op kwaliteit. Dat zijn interessante vragen waar we bij een koffie graag over willen kibbelen, maar het is geen betrouwbaarheid. Het zijn productbeslissingen, en die horen in een ander gesprek thuis, met andere mensen aan tafel.
We benchmarken in deze fase ook geen eval-dekking. Evals doen ertoe, maar een team waarvan de retries driften en de prompts ongepind zijn, krijgt ruizige eval-uitkomsten die iedereen in het kanaal stilletjes leert te negeren. Repareer eerst het fundament. Dan beginnen de evals weer iets waars te zeggen, en gaat het team ze weer vertrouwen.
Toen we deze audit vorig kwartaal op een B2B-SaaS-werklast in Utrecht draaiden, kwam de retry-drift-score uit op 38 van de 100, op een systeem waarvan het team overtuigd was dat het rotsvast stond: één node met veel verkeer had een volledig deterministische SQL-tool ingepakt in een generieke LLM-retry-decorator uit een tutorial, en één commit dichtte het gat. Dat soort onspectaculaire fix is waar ons werk aan AI-agents de score het hardst op verzet.
Wil je al iets doen voor je iemand spreekt: trek de laatste 30 dagen aan LangSmith-traces voor je drie nodes met het meeste verkeer, groepeer op input-hash en tel hoeveel unieke tool-call-signaturen elke input heeft opgeleverd. Is het antwoord meer dan één voor meer dan 5% van de inputs? Dan heb je drift. Dat is ticket nummer één.
Kern
Audit retry-drift, prompt-pinning en regio-failover voordat je betaalt voor een reliability-retrofit op je agents — de rest is product, geen betrouwbaarheid.
FAQ
Hoe lang duurt de audit van kick-off tot opgeleverde pdf?
Vier werkdagen voor een stack tot ~80 nodes en een dozijn sub-agents. Grotere graphs schalen ongeveer lineair, maar dat melden we op de intake-call voordat de teller gaat lopen.
Hebben jullie directe toegang nodig tot onze productie-LangSmith-workspace?
Lees-toegang tot traces van de laatste 30 dagen, plus lees-toegang tot de prompt-hub. We hebben geen keys nodig voor de onderliggende modellen of jullie applicatie-database om de audit te draaien.
En als we nog op de us-east-1-regio van LangSmith zitten?
Verhuizen naar eu-west-1 wordt punt één van de retrofit. We kunnen de audit prima draaien op de US-regio, maar geen Nederlands mkb-bedrijf dat persoonsgegevens verwerkt, zou daar mogen blijven zitten zodra de audit klaar is.
Kunnen onze eigen engineers deze checklist zonder jullie draaien?
Ja. De drie metingen hierboven zijn de hele methode. De meeste teams die het proberen, melden dat de prompt-pinning-controle een ochtend kost en het scoren van retry-drift een dag aan zorgvuldige trace-analyse.