Waarom je AI-Agent Blijft Falen in Productie (En Hoe je het Oplost)
De meeste productieagentstoringen komen voort uit vijf oorzaken: breekbare prompts die randgevallen niet afhandelen, ontbrekende herhaalpoginglogica voor tijdelijke API-fouten, geen observeerbaarheid om te zien wat stuk gaat, ongecontroleerde lussen zonder uitstapconditie en tooldefinities die ambiguïs genoeg zijn dat het model de verkeerde kiest. Alle vijf zijn oplosbaar zonder modellen of frameworks te wijzigen.
Elke woensdag. 28.400+ operators. Geen opvulling.
✓ Controleer je inbox — klik op de bevestigingslink om je aanmelding te voltooien.
✓ Je bent aangemeld!
✓ Je staat al op de lijst.
Inhoudsopgave
Bijgewerkt juni 2026.
TL;DR: De meeste productieagentstoringen komen voort uit vijf oorzaken: breekbare prompts die randgevallen niet afhandelen, ontbrekende herhaalpoginglogica voor tijdelijke API-fouten, geen observeerbaarheid om te zien wat stuk gaat, ongecontroleerde lussen zonder uitstapconditie en tooldefinities die ambiguïs genoeg zijn dat het model de verkeerde kiest. Alle vijf zijn oplosbaar zonder modellen of frameworks te wijzigen.
[Operator’s lezing] Ik run meer dan 30 agenten in productie. Ik heb al deze storingen gehad. De storingen die het meeste tijd kostten waren niet de exotische — het waren de saaie infrastructuurstoringen waarvan ik dacht dat ik ze had afgehandeld.
Storing 1: Breekbare prompts die op randgeval-invoer kapotgaan
Een prompt die werkt op je testgevallen zal falen op invoer die je niet had geanticipeerd. Dat is geen modellimitatie — het is een instructieschrijfprobleem.
Symptomen: De agent produceert zinloze uitvoer, roept het verkeerde tool aan of levert malformateerde JSON bij invoer die enigszins verschilt van wat je hebt getest.
Oorzaak: Je systeemprompt beschrijft alleen het gelukkige pad. Het zegt het model niet wat te doen wanneer gegevens ontbreken, malformateerd of dubbelzinnig zijn.
Oplossing: Voeg expliciete randgeval-afhandeling toe aan je systeemprompt:
If the input data is missing a required field, return:
{ "status": "error", "reason": "missing_field", "field": "<fieldname>" }
Do NOT attempt to infer or hallucinate missing values.
If you are uncertain which tool to call, call no tool and return:
{ "status": "clarification_needed", "question": "..." }Het model volgt expliciete instructies voor randgevallen betrouwbaar. De fout is aannemen dat het de gelukkig-pad instructies zal generaliseren om de rommelige gevallen af te handelen.
Storing 2: Geen herhaalpoginglogica voor tijdelijke API-fouten
Elke externe API die je agent aanroept zal op een gegeven moment falen. De Claude API, de Meta Graph API, je database — ze geven allemaal 5xx-fouten terug, times out, of rate-limiten. Als je agent geen herhaalpoginglogica heeft, doodt één tijdelijke fout de hele run.
Symptomen: Agenten-runs falen willekeurig op verschillende stappen. De logs tonen een 503 of 429 zonder vervolgpoging.
Oplossing: Wikkel elke externe aanroep in een exponentieel-backoff herhalingpoging:
async function withRetry<T>(fn: () => Promise<T>, retries = 3, baseDelayMs = 500): Promise<T> {
for (let attempt = 0; attempt <= retries; attempt++) {
try {
return await fn();
} catch (err: any) {
const isTransient = err.status === 429 || err.status >= 500 || err.code === "ECONNRESET";
if (!isTransient || attempt === retries) throw err;
const delay = baseDelayMs * Math.pow(2, attempt) + Math.random() * 100;
await new Promise((r) => setTimeout(r, delay));
}
}
throw new Error("unreachable");
}
// Usage
const result = await withRetry(() => client.messages.create({ ... }));Drie herhalingspogingen met exponentieel backoff behandelt ~99% van de tijdelijke storingen. Voeg dit toe aan elke externe aanroep en de helft van je willekeurige storingen verdwijnt.
Storing 3: Geen observeerbaarheid — je kunt niet zien wat stuk gaat
Dit is de meest voorkomende storingsmodus in productie en degene die het meeste tijd kost om te debuggen: de agent faalt stil of produceert verkeerde uitvoer, en je hebt geen idee waar in de keten het fout ging.
Symptomen: Je weet dat er iets mis is maar kunt de stap niet identificeren. Je voegt console.log-instructies toe en voert handmatig opnieuw uit om te proberen te reproduceren.
Oplossing: Gestructureerde logging bij elke stap, met een run-ID die de hele uitvoering traceert:
function createLogger(runId: string, agentName: string) {
return {
step: (step: string, data: object) =>
console.log(JSON.stringify({ runId, agent: agentName, step, ts: new Date().toISOString(), ...data })),
error: (step: string, err: unknown) =>
console.error(JSON.stringify({ runId, agent: agentName, step, error: String(err), ts: new Date().toISOString() })),
};
}
const log = createLogger(crypto.randomUUID(), "newsletter-agent");
log.step("fetch_topic", { topicId: topic.id, topic: topic.name });
// ... do work ...
log.step("draft_complete", { subject: draft.subject, wordCount: draft.body.split(" ").length });Als je op Cloudflare Workers bent, gaan deze logs naar Logpush of Workers Tail. Als je lokaal of op een VPS draait, stuur ze naar een logaggregator. De gestructureerde JSON betekent dat je op runId kunt filteren om precies te zien wat er in een enkele run is gebeurd.
Storing 4: Ongecontroleerde lussen zonder uitstapconditie
Agentische lussen — waar het model tools aanroept en itereert totdat een conditie is voldaan — kunnen voor altijd draaien als die conditie nooit wordt voldaan of het model hem verkeerd identificeert.
Symptomen: Agent geeft honderden dollars uit aan API-kosten voor time-out. Of het voert dezelfde toolaanroep steeds opnieuw uit zonder voortgang te boeken.
Oplossing: Heb altijd een harde iteratielimiet en een voortgangscontrole:
const MAX_ITERATIONS = 10;
let iterations = 0;
let lastToolCallName = "";
let sameToolCallCount = 0;
while (true) {
iterations++;
if (iterations > MAX_ITERATIONS) {
log.error("loop", { reason: "exceeded_max_iterations" });
break;
}
const response = await client.messages.create({ ... });
// Detect stuck loops: same tool called 3x in a row
const toolCall = response.content.find(b => b.type === "tool_use");
if (toolCall?.name === lastToolCallName) {
sameToolCallCount++;
if (sameToolCallCount >= 3) {
log.error("loop", { reason: "stuck_loop", tool: toolCall.name });
break;
}
} else {
sameToolCallCount = 0;
lastToolCallName = toolCall?.name ?? "";
}
if (response.stop_reason === "end_turn") break;
}Dit vangt zowel de “te lang gelopen” als de “in de ronde gedraaid” storingsmodi. De limiet moet royaal genoeg zijn voor het gelukkige pad maar strak genoeg om de explosieradius te beperken.
Storing 5: Dubbelzinnige tooldefinities die het model verkeerd oplost
Als je het model twee tools geeft met overlappende beschrijvingen, zal het soms de verkeerde aanroepen. Dit is vooral gebruikelijk met tools zoals search_database vs get_record of send_email vs create_draft.
Symptomen: Het model roept de juiste categorie tool aan maar kiest de verkeerde specifieke. Of het roept een tool in de verkeerde context aan (gebruikt een schrijftool terwijl alleen lezen gepast was).
Oplossing: Maak tooldefinities wederzijds exclusief en voeg expliciet “wanneer NIET te gebruiken” toe:
const tools = [
{
name: "get_subscriber",
description: "Fetch a single subscriber record by email. Use ONLY when you have a specific email address. Do NOT use for searching or listing subscribers.",
input_schema: { ... }
},
{
name: "search_subscribers",
description: "Search subscribers by tag, segment, or status. Use when you need to find subscribers matching a criteria — NOT when you have a specific email address.",
input_schema: { ... }
}
];De “NIET gebruiken wanneer X”-clausule is het deel dat de meeste mensen overslaan. Het is het belangrijkste deel. Modellen zijn beter in het volgen van expliciete negatieve beperkingen dan ze te infereren uit positieve beschrijvingen.
Nog één ding: test je agenten op slechte invoer
De meeste agenten worden alleen getest op schone, gelukkig-pad invoer. Productie heeft vuile invoer: lege strings, null-velden, Unicode-randgevallen, API-antwoorden die 200 teruggeven maar met een onverwacht schema.
Voeg een testsuite toe die expliciet uitoefent:
- Lege of null-invoer
- Invoer bij de maximale lengte die je zou verwachten
- Invoer met speciale tekens of niet-ASCII-tekst
- Externe API’s die onverwachte antwoordvormen retourneren
Als je agent op een van deze kapotgaat, los het dan op voor het live gaat. De productieomgeving zal elke aanname die je hebt gemaakt vinden.
De conclusie van de operator
De meeste agentstoringen in productie zijn infrastructuurproblemen die zich voordoen als modelproblemen. Voeg voor je van model wisselt herhalingspogingen, gestructureerde logging, luslimieten en expliciete randgeval-afhandeling toe aan je prompts. Los de dubbelzinnige tooldefinities op. Test dan op slechte invoer. Doe dat allemaal voor je het model de schuld geeft — in mijn ervaring is het model doorgaans het laatste dat veranderd moet worden.
Elke woensdag. 28.400+ operators. Geen opvulling.
✓ Controleer je inbox — klik op de bevestigingslink om je aanmelding te voltooien.
✓ Je bent aangemeld!
✓ Je staat al op de lijst.
Ontvang het AI-playbook in je inbox
Elke woensdag. 28.400+ operators. Geen opvulling.
Controleer je inbox.
We hebben je een bevestigingsmail gestuurd — klik op de link om je aanmelding te voltooien. Controleer je spam als je hem niet binnen een minuut ziet.
Je bent aangemeld.
Welkom — de volgende editie valt binnenkort in je inbox.
Je staat al op de lijst — kijk er elke woensdag naar uit.