Wat een AI-agent is: vijf klassieke types, twee rivaliserende definities
De vacuumwereld vier keer gebroken; elke breuk levert één van vijf klassieke agent-types op. Eén tool maakt 39 input tokens 420.
Op deze pagina
Hier is dezelfde vraag, twee keer gesteld aan hetzelfde model, met dezelfde weights en greedy decoding. Het enige verschil is dat er de tweede keer één tool in de catalogus stond.
no tools in the catalogue
turn 1 prompt= 39 out= 8 finish=stop TEXT "The capital of France is Paris."
=> model calls=1 prompt tokens=39 output=8 wall=974 ms
one tool in the catalogue: get_temperature(city)
turn 1 prompt= 185 out= 20 finish=tool_calls CALL get_temperature({"city": "Paris"})
tool get_temperature -> {"city":"Paris","celsius":11}
turn 2 prompt= 235 out= 18 finish=stop TEXT "The capital of France is Paris. It is
currently at 11 degrees Celsius."
=> model calls=2 prompt tokens=420 output=38 wall=6,685 msEén call werd er twee. Negenendertig input tokens werden er 420, een factor 10,8. Minder dan een seconde werd bijna zeven. En het antwoord kreeg er een feit bij waar niemand om had gevraagd, uit een tool die het model zelf koos aan te roepen voor een vraag waarin het weer nooit werd genoemd.
Het tweede systeem is wat het grootste deel van de industrie in 2026 een agent noemt. Of juist niet, afhankelijk van welke van de twee meest gelezen definities je opent — en die twee zeggen niet hetzelfde. Eén is het zelfs niet met zichzelf eens.
Die onenigheid is dit hoofdstuk. Het is geen woordenruzie: de twee definities trekken de grens langs verschillende assen, en de as die je kiest bepaalt wat je bouwt en waarvoor je betaalt. Beide rusten op een oudere taxonomie, en de goedkoopste manier om die te verdienen is de slechtste agent ter wereld bouwen.
Details tonen
Wat dit hoofdstuk nodig heeft uit de eerdere hoofdstukken.
- Hoofdstuk 13 mat wat één call kost in tijd; dit hoofdstuk vermenigvuldigt dat met het aantal beurten.
- Hoofdstuk 15: de prompt is de volledige state van het model, omdat niets de call overleeft.
- Hoofdstuk 16: input tokens groeien met het kwadraat van het gesprek.
- Hoofdstuk 18: de toolcatalogus, en de rondreis waarin het model iets vraagt en jouw code uitvoert.
Geen tensors hier. Het hoofdstuk is TypeScript, waar de taalregel van Hoofdstuk 14 het plaatst, en de loop is de directe voorouder van die van Hoofdstuk 23.
Een robot met twee kamers
Link naar de sectie: Een robot met twee kamersHet oudste voorbeeld in het vakgebied is een stofzuiger in een wereld van twee vakken, A en B, elk schoon of vies.1 Het overleeft in elk tekstboek omdat het de kleinste wereld is waarin een agent gelijk of ongelijk kan hebben.
De percept is een paar — waar ik ben, en of het hier vies is — en de acties zijn SUCK, LEFT en RIGHT. Het hele programma is één regel.
type Percept = { dirty: boolean; where?: "A" | "B" };
type Action = "SUCK" | "LEFT" | "RIGHT";
const textbook = (p: Percept): Action =>
p.dirty ? "SUCK" : p.where === "A" ? "RIGHT" : "LEFT"; Draai het tegen elke startconfiguratie van de wereld met twee vakken:
A dirty, B dirty, start A -> steps=3 clean=true
A clean, B dirty, start A -> steps=2 clean=true
A dirty, B clean, start B -> steps=2 clean=trueDat is een simple reflex agent: hij handelt alleen op basis van de huidige percept, zonder herinnering aan wat eraan voorafging. Geen speelgoedcategorie — een thermostaat is er één, en een enkele call naar een taalmodel zonder gesprek eraan vast ook.
Breek hem nu zoals de werkelijkheid dat doet. Een echte stofzuigrobot heeft een vuilsensor en een bumper, geen vak met label A onder het tapijt. Haal de locatie uit de percept en verander verder niets:
const dirtOnly = (p: Percept): Action => (p.dirty ? "SUCK" : "RIGHT");A dirty, B dirty, start A -> steps=3 clean=true still dirty=0
t=0 at=A percept={dirty:true} -> SUCK
t=1 at=A percept={dirty:false} -> RIGHT
t=2 at=B percept={dirty:true} -> SUCK
A dirty, B clean, start B -> steps=500 clean=false still dirty=1
t=0 at=B percept={dirty:false} -> RIGHT
t=1 at=B percept={dirty:false} -> RIGHT
t=2 at=B percept={dirty:false} -> RIGHT
t=3 at=B percept={dirty:false} -> RIGHTHetzelfde programma, twee vakken. Vanuit één starttoestand is het in drie stappen klaar; vanuit een andere rijdt het vijfhonderd keer tegen de rechtermuur en zou het doorgaan tot de batterij leeg was. Het kan het verschil tussen de twee situaties niet waarnemen, dus het kan er niet anders in handelen. Russell en Norvig formuleren het algemene resultaat in één regel: oneindige loops zijn vaak onvermijdelijk voor simple reflex agents in gedeeltelijk observeerbare omgevingen.1
Er is een fix die één regel kost en geen geheugen, de moeite waard om te meten voordat we naar iets slimmers grijpen.
let seed = 12345;
const rnd = () => ((seed = (seed * 1103515245 + 12345) & 0x7fffffff) / 0x7fffffff);
const coin = (p: Percept): Action => (p.dirty ? "SUCK" : rnd() < 0.5 ? "LEFT" : "RIGHT"); Tweeduizend runs van een volledig vieze gang in drie groottes, met één seeded generator voor alles:
| kamers | gemiddelde stappen | mediaan | slechtste van 2.000 | nooit klaar |
|---|---|---|---|---|
| 2 | 4,0 | 4 | 13 | 0 |
| 4 | 16,6 | 14 | 81 | 0 |
| 8 | 68,7 | 52 | 306 | 0 |
Randomisatie verwijdert de loop volledig. Het kost ook iets: acht kamers vragen vijftien zetten als je weet wat je doet, en deze agent haalt gemiddeld 68,7 en deed er één keer 306 over. Dat is het hele hoofdstuk in het klein. Elke capability die we toevoegen koopt correctness in een geval dat de vorige agent niet aankon, en rekent daarvoor af in een valuta die je eerst een naam moet geven.
De onderdelen benoemen, nu ze nodig zijn
Link naar de sectie: De onderdelen benoemen, nu ze nodig zijnEen agent neemt zijn omgeving waar via sensors en handelt via actuators. Het agent program is de functie van percepts naar acties — elke listing hierboven is er één. De percept sequence is alles wat tot nu toe is waargenomen, en een simple reflex agent negeert alles behalve het laatste item.
Rationaliteit is het woord dat de meeste artikelen verkeerd gebruiken, en als je het goed gebruikt wordt de rest van dit hoofdstuk bruikbaar. Een agent is op zichzelf niet rationeel of irrationeel. Russell en Norvig definiëren een rationele agent als één die, voor elke mogelijke percept sequence, de actie selecteert waarvan wordt verwacht dat die zijn performance measure maximaliseert, gegeven het bewijs uit die sequence en alle ingebouwde kennis die hij heeft.1 De performance measure zit niet in de agent: die hoort bij de ontwerper, en rationaliteit wordt alleen relatief daaraan gedefinieerd.
De specificatie wordt traditioneel geschreven als vier dingen, PEAS: performance measure, environment, actuators, sensors.
| de stofzuigrobot | een support-agent in productie | |
|---|---|---|
| Performance measure | schone vakken, per batterijeenheid | opgeloste tickets, per dollar, zonder escalatie |
| Environment | de vloer, het vuil, het meubilair, het tapijt | de ticketwachtrij, je database, de klant |
| Actuators | wielen, zuigkracht | tool calls |
| Sensors | vuilsensor, bumper | het bericht van de gebruiker, toolresultaten |
Let op welke rij uit de toon valt. Bijna elk team dat in 2026 agents bouwt, schrijft E, A en S op — de toolschema’s, de integrations, het berichtformaat — omdat de code zonder die dingen niet draait. Bijna niemand schrijft P op. Zonder P betekent „onze agent doet het goed” niets wat iemand kan controleren, en „rationeel” kan helemaal niet op het systeem worden toegepast, alleen op een demo. Hoofdstuk 29 gaat over P in een getal veranderen, en dit is waarom het bestaat.
┌───────────────────────── the environment ─────────────────────────┐
│ │
│ ┌──────────────────────── the agent ─────────────────────┐ │
│ │ │ │
───┼──►│ sensors ──► the agent program ──► actuators ─────┼──────┼──►
percept │ │ action
│ └────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
▲
the performance measure lives out here, in the head of
whoever built the thing, and the agent cannot change itTaakomgevingen worden verder geclassificeerd langs zeven assen, waarvan er vijf hier het grootste deel van de moeilijkheid bepalen: volledig of gedeeltelijk observeerbaar, deterministisch of niet, episodisch of sequentieel, statisch of dynamisch, bekend of onbekend.1 Een agent die met echte tools over een echt netwerk praat zit in de moeilijke hoek van alle vijf — niet-deterministisch zelfs bij temperature zero (Hoofdstuk 17), en, de onderschatte, onbekend, omdat je geen betrouwbaar model hebt van wat je eigen tools met de wereld doen. Daarom heeft de loop van Hoofdstuk 23 meer error handling nodig dan planning.
Geheugen toevoegen, en de volgende muur vinden
Link naar de sectie: Geheugen toevoegen, en de volgende muur vindenEchte vloeren zijn niet eendimensionaal, dus promoveer de wereld naar een plattegrond. Hekjes zijn muren, sterretjes zijn vuil, en de robot begint in de middelste kamer:
col 0 1 2 3 4 5 6
row 0 * . . # . . *
row 1 . # . # . # .
row 2 . # . S . # . S = the robot starts here
row 3 . # . # . # .
row 4 * . . # . . *De voor de hand liggende upgrade is geheugen. De agent houdt een kaart bij: elk vak waar hij heeft gestaan en elk vak waar de bumper afging. Zijn regel is een aangrenzend vak inlopen waar hij nog niet is geweest — rechts, dan omlaag, dan links, dan omhoog — en terugdeinzen wanneer alles om hem heen bekend is. Dit is een model-based reflex agent: hij onderhoudt interne state uit de percept history, zodat hij kan handelen op basis van wat hij op dit moment niet kan zien.
Het is een echte verbetering, en nog steeds niet genoeg:
5,000 steps allowed -> steps=5,000 distinct squares visited=13/25 still dirty=2/4Vijfduizend zetten, de helft van de vloer nooit gezien. De kaart klopt en de regels kloppen. Wat de agent niet kan, is de kaart gebruiken om ergens naartoe te gaan: zijn regels beantwoorden alleen ooit „naar welke van mijn vier buren moet ik stappen”, dus zodra er naast hem geen onbezochte vakken meer zijn, heeft hij geen manier om de gedachte uit te drukken er is een onbezocht vak acht zetten verderop en ik zou daar graag staan. Hij weet waar hij is. Hij weet niet waar hij wil zijn.
Een doel, en daarna een reden om de ene route boven de andere te verkiezen
Link naar de sectie: Een doel, en daarna een reden om de ene route boven de andere te verkiezenEen goal-based agent houdt, boven op zijn model van de wereld, een beschrijving bij van de situatie die hij wil laten ontstaan, en kiest acties door reeksen ervan te doorzoeken totdat hij er één vindt die daar eindigt. Doelen veranderen actieselectie van een lookup in een search.
Het doel is „er blijft geen vies vak over”. De search is een breadth-first wandeling naar het dichtstbijzijnde vieze vak, en het pad dat die oplevert is het plan.
goal-based (fewest moves) -> moves=27 battery=52 still dirty=0
from 2,3 -> 4,6 via 5 moves: 2,3 2,4 3,4 4,4 4,5 4,6
from 4,6 -> 0,6 via 4 moves: 4,6 3,6 2,6 1,6 0,6
from 0,6 -> 4,0 via 10 moves: 0,6 0,5 0,4 1,4 2,4 2,3 2,2 3,2 4,2 4,1 4,0
from 4,0 -> 0,0 via 4 moves: 4,0 3,0 2,0 1,0 0,0Zevenentwintig zetten, vloer schoon. Maar kijk naar de batterijkolom en het laatste been van het plan. Kolom 0 heeft tapijt: een vak met tapijt oversteken kost zes batterijeenheden, een betegeld vak één. De agent ging via kolom 0 naar huis omdat dat vier zetten zijn in plaats van acht, en die vier tapijtzetten kostten 24 waar de omweg van acht zetten 13 had gekost.
Hij kan niet anders. Een doel is een binaire test: de vloer is schoon of niet. Elk plan dat eindigt met een schone vloer voldoet er even goed aan, dus wanneer meerdere plannen slagen heeft de agent niets om ertussen te kiezen. De ene succesvolle uitkomst boven de andere verkiezen vraagt om een getal over outcomes, en dat getal is een utility function. Een agent die die maximaliseert is een utility-based agent.
De wijziging in de code is één term binnen de search. Breadth-first search telt zetten; laat hem in plaats daarvan kosten tellen en je hebt Dijkstra’s algoritme en een andere agent:
const nd = dist.get(k)! + (byCost ? cell.cost : 1); // <- the entire differencegoal-based (fewest moves) -> moves=27 battery=52 still dirty=0
utility-based (cheapest route) -> moves=31 battery=41 still dirty=0
from 4,0 -> 0,0 via 8 moves: 4,0 4,1 4,2 3,2 2,2 1,2 0,2 0,1 0,0Vier extra zetten, elf batterijeenheden minder: eenentwintig procent goedkoper. Zelfde doel, zelfde kaart, zelfde code op één term na. De twee agents verschillen alleen in waar ze goed in proberen te zijn, en ze nemen verschillende routes naar huis.
Dit is ook het eerste punt waarop de agent iets nodig heeft dat hij niet kan produceren. Iemand moet beslissen wat een batterijeenheid waard is ten opzichte van een zet. Utility is de performance measure geschreven in een vorm waarmee de agent kan rekenen, en het schrijven ervan is de taak van de ontwerper. Wanneer mensen zeggen dat een agent „het verkeerde optimaliseerde”, bedoelen ze bijna nooit een bug. Ze bedoelen dat deze regel slordig is geschreven.
Het vijfde type, en hoe het misgaat
Link naar de sectie: Het vijfde type, en hoe het misgaatLaat vuil nu terugkomen. Vier kamers worden opnieuw vies met vier verschillende snelheden, en de agent krijgt die nooit te horen. Hij bezoekt één kamer per tick en ziet alleen die kamer. De performance measure is room-ticks die vies worden doorgebracht over 4.000 ticks — lager is beter.
Een learning agent is, in de ontleding van het tekstboek, een van de bovenstaande plus drie onderdelen: een learning element dat de agent verandert, een critic die vertelt hoe de agent het doet ten opzichte van een vaste prestatienorm, en een problem generator die acties voorstelt die het proberen waard zijn vanwege wat ze zouden leren.1 Drie policies in dezelfde omgeving. De eerste leert niet; de tweede en derde leren hetzelfde en gebruiken het anders.
| policy | vieze room-ticks over 4.000 | versus de patrouille |
|---|---|---|
| vaste round-robin-patrouille, geen learning | 2.290 | — |
| learner A: schat de vuilsnelheid van elke kamer, ga dan waar vuil het waarschijnlijkst is | 11.820 | 5,2× slechter |
| learner B: dezelfde schattingen, gewogen met hoe lang sinds het laatste bezoek | 1.576 | 31 % beter |
De verborgen snelheden waren 0,35 voor de keuken, 0,05 voor de hal, 0,02 voor de werkkamer en 0,01 voor de zolder — en learner A vond ze. Hij identificeerde de keuken correct als de vieste kamer in het huis, ging daarna elke tick voor de rest van de simulatie naar de keuken terwijl de andere drie voor altijd vies bleven. Hij is vijf keer slechter dan helemaal niet leren, en hij is niet stuk.
De les is die van de sectie over utility. Learner A maximaliseerde „kans dat de kamer die ik ga bezoeken vies is”. De performance measure was „room-ticks die vies worden doorgebracht”. Verschillende getallen; het tweede is wat de critic beoordeelde, en niemand vertelde het de agent. Learner B vermenigvuldigt dezelfde geleerde snelheid met de tijd sinds het laatste bezoek — het vuil dat hij verwacht te vinden in plaats van de kans om überhaupt iets te vinden — en verslaat de patrouille waar hij mee begon.
Eén implementatiedetail bepaalde het resultaat. In de eerste versie van learner B kreeg een kamer waar in drie bezoeken geen vuil was opgedoken een snelheid van precies nul — en nul keer wat dan ook is nul, dus die werd nooit meer bezocht en de schatting kon nooit worden gecorrigeerd. De fractie smoothen, successen plus één gedeeld door pogingen plus twee, veranderde 11.895 in 1.576. „Nog niet waargenomen” en „gemeten en kwam uit op nul” zijn verschillende claims, en een systeem dat ze in hetzelfde veld opslaat neemt beslissingen die het niet ongedaan kan maken.
De vijf types, en wat ze zijn in 2026
Link naar de sectie: De vijf types, en wat ze zijn in 2026 1 simple reflex percept ────────────────────────────────► rules ────► action
2 model-based percept ──► [state] ──────────────────► rules ────► action
3 goal-based percept ──► [state] ──► [goal] ──────► search ───► action
4 utility-based percept ──► [state] ──► [goal] ──► [U] ──► argmax ► action
5 learning all of the above, plus [critic] ──► changes the parts aboveElk van de vijf staat vandaag in productie onder een andere naam.
| klassiek type | wat het tussen percepts meedraagt | zijn vorm in 2026 | wat het niet kan |
|---|---|---|---|
| simple reflex | niets | één model call zonder history: een classifier, een extractie-endpoint, een single-turn completion | alles wat afhangt van de vorige beurt |
| model-based reflex | interne state opgebouwd uit de percept history | een chat: het transcript, volledig opnieuw meegestuurd bij elke call | kiezen waar het gesprek moet eindigen |
| goal-based | state plus een beschrijving van de gewenste situatie | een reason-and-act-loop met een stopvoorwaarde2 | de ene succesvolle plan boven de andere verkiezen |
| utility-based | state, doel en een getal over outcomes | evaluator–optimiser-loops, en kandidaat-antwoorden ranken op basis van een geschreven criterium (Hoofdstuk 25) | het criterium uitvinden |
| learning | alles ervan, plus een critic en een problem generator | Reflexion, dat zijn eigen lessen in een episodic buffer schrijft in plaats van weights bij te werken;3 persistent user memory (Hoofdstuk 24) | de norm kiezen waartegen de critic scoort |
Twee rijen zijn meer dan een analogie, op een manier die geld kost.
De chat is een model-based reflex agent waarvan het model niet intern is. In het tekstboek is de state een variabele binnen het agent program. In een chat is het het transcript: het leeft aan jouw kant, wordt bij elke call volledig opnieuw meegestuurd en wordt elke keer vanaf nul opnieuw opgebouwd binnen het model. Dat is de kwadratische rekening van Hoofdstuk 16, en het is hetzelfde object dat het tekstboek tekende als een box met label „state”. Hier is het verschil, gemeten op één follow-upvraag met en zonder de twee berichten ervoor:
with the transcript prompt=67 "The current temperature in Lisbon, Portugal is 15°C."
without the transcript prompt=29 "Lisbon is the capital of Portugal, not a city in Portugal."Hetzelfde model, dezelfde drie woorden user input, en de tweede is de gangrobot die tegen de muur rijdt. Er waren geen tools in die run, dus de 15 is verzonnen — maar de state is wat de follow-up überhaupt iets laat betekenen. Je bouwt die elke keer opnieuw op en betaalt er 2,3× de input tokens voor op een gesprek van twee beurten. Hoofdstuk 16 mat waar die multiplier bij beurt veertig uitkomt.
Reflexion is een learning agent die zijn input verandert in plaats van zijn programma. In de ontleding van het tekstboek past het learning element het performance element aan. Reflexion laat de weights met rust en schrijft reflectieve tekst naar een episodic buffer die de volgende poging leest.3 Het learning element is een prompt, het geheugen een databaserij, het performance element een frozen model — en het diagram is dat van het tekstboek, onveranderd.
En hier is de eerlijke grens van de mapping. De vijf types classificeren het agent program. In 2026 is dat programma doormidden gesplitst: een deel zit in jouw code, een deel zit in weights die jij niet hebt getraind. Wanneer een model uit zichzelf besluit een tool aan te roepen, zit de goal test dan in jouw programma of in het model? De taxonomie heeft geen antwoord, omdat er toen ze werd geschreven nergens anders plaats voor was — en precies die vraag is waar de twee moderne definities uit elkaar gaan.
Antwoorden, aanroepen en stoppen, in één trace
Link naar de sectie: Antwoorden, aanroepen en stoppen, in één traceDe definities zijn discussies over gedrag, en veel makkelijker te beoordelen met een trace voor je.
De loop hieronder stuurt het gesprek naar een model; als het antwoord een tool call bevat, voert hij de tool uit, voegt het resultaat toe en stuurt het geheel opnieuw. Hij draait tegen een lokale Qwen2.5-0.5B-Instruct achter een OpenAI-vormig endpoint op deze machine — de naad uit Hoofdstuk 14, dus de loop weet niet en geeft er niet om wat er achter de poort zit.
const BASE = process.env.LLM_BASE_URL ?? "http://127.0.0.1:8799/v1";
async function loop(question: string, maxTurns = 6) {
const messages: Msg[] = [
{ role: "system", content: SYSTEM },
{ role: "user", content: question },
];
for (let turn = 1; turn <= maxTurns; turn++) {
const reply = await call(messages, TOOLS);
const calls = reply.choices[0].message.tool_calls ?? [];
messages.push(reply.choices[0].message);
if (!calls.length) return messages;
for (const c of calls) {
const out = runTool(c.function.name, JSON.parse(c.function.arguments));
messages.push({ role: "tool", name: c.function.name, content: out });
}
}
throw new Error("turn cap reached");
}Twee regels dragen het hele idee, en beide zijn gemarkeerd; de rest is boekhouding. Alle drie gedragingen zijn zichtbaar in één run. Vraag je iets wat het zelf kan doen, dan antwoordt het model. Vraag je iets wat het niet kan, dan roept het aan:
=== a question the model cannot answer, one tool available
turn 1 prompt= 187 out= 21 finish=tool_calls CALL get_temperature({"city": "Oslo"})
tool get_temperature -> {"city":"Oslo","celsius":4}
turn 2 prompt= 238 out= 12 finish=stop TEXT "The current temperature in Oslo is 4
degrees Celsius."
=> model calls=2 prompt tokens=425 output=33 wall=6,257 ms
=> stopped by: the model produced text instead of a callEn het stopt — het derde gedrag, en het makkelijkst te missen, omdat het eruitziet alsof er niets gebeurt. De loop eindigt omdat beurt 2 terugkwam zonder tool call. Niemand besloot dat; het model deed dat, door proza uit te stoten. De termination condition van dit programma is het teken van een afwezigheid.
Nog twee runs zijn de ruimte waard. Gevraagd om twee steden te vergelijken, doet het model beide tool calls in één beurt, krijgt beide metingen terug, en heeft de vergelijking fout:
turn 1 prompt= 188 out= 43 finish=tool_calls CALL get_temperature({"city": "Oslo"}),
get_temperature({"city": "Lisbon"})
tool get_temperature -> {"city":"Oslo","celsius":4}
tool get_temperature -> {"city":"Lisbon","celsius":19}
turn 2 prompt= 284 out= 13 finish=stop TEXT "Oslo is currently warmer than Lisbon
at 4°C."De tools werkten. De parallelle call werkte. De loop werkte. Het antwoord is onwaar, met beide juiste getallen in het transcript. Een model in een loop wikkelen laat het niet redeneren; het geeft een model dat fout zit het vermogen te handelen op basis van fout zitten — dat is Hoofdstuk 30 vooruitgeschoven, en de helft van Hoofdstuk 29.
Verwijder nu de gemarkeerde return en laat de loop in plaats daarvan tot zijn limiet draaien. Zelfde vraag, zelfde model:
turn 1 prompt= 187 out= 21 CALL get_temperature({"city": "Oslo"})
turn 2 prompt= 238 out= 12 TEXT "The current temperature in Oslo is 4 degrees Celsius."
turn 3 prompt= 261 out= 30 TEXT "Could you please specify the exact location you're..."
turn 4 prompt= 302 out= 14 TEXT "Sure! Could you tell me which city you're interested in?"
turn 5 prompt= 327 out= 35 TEXT "I'm sorry, but I need more details to provide an..."
turn 6 prompt= 373 out= 12 TEXT "Which city would you like to know the temperature for?"
=> model calls=6 prompt tokens=1,688 output=124 wall=25,261 ms stopped by: turn capVier keer zoveel input tokens, vier keer zoveel wall clock, en een einde waarin de agent is vergeten wat hem werd gevraagd en de gebruiker ondervraagt over een vraag die die op beurt één al had beantwoord. Het juiste antwoord stond bij beurt 2 op het scherm, en elke beurt daarna maakte het transcript slechter.
Een agent is dus geen loop. Het is een loop plus een regel om die te verlaten, en deze heeft precies één zo’n regel. Hoofdstuk 23 vindt er vijf, en laat zien wat breekt wanneer elk ontbreekt.
De twee definities, naast elkaar
Link naar de sectie: De twee definities, naast elkaarBeide geciteerd in plaats van geparafraseerd, omdat de parafrases de verwarring produceren.
Definitie één legt de grens bij wie de flow controleert. Anthropic’s Building effective agents benoemt de ambiguïteit en doet er uitspraak over:
„Bij Anthropic categoriseren we al deze variaties als agentic systems, maar trekken we een belangrijk architectonisch onderscheid tussen workflows en agents: workflows zijn systemen waarin LLMs en tools worden georkestreerd via vooraf gedefinieerde codepaden. Agents daarentegen zijn systemen waarin LLMs dynamisch hun eigen processen en toolgebruik aansturen, waarbij ze controle houden over hoe ze taken uitvoeren.”4
De test is een vraag over je source code: wie koos de volgende stap? Een switch in je programma: workflow. Het model: agent. Hetzelfde document zegt dat agents „typically just LLMs using tools based on environmental feedback in a loop” zijn — wat precies de listing hierboven is.
Definitie twee legt de grens bij onafhankelijkheid van de gebruiker. OpenAI’s A practical guide to building agents opent zijn definitiepagina zo:
„Terwijl conventionele software gebruikers helpt workflows te stroomlijnen en te automatiseren, kunnen agents dezelfde workflows namens gebruikers uitvoeren met een hoge mate van onafhankelijkheid. Agents zijn systemen die zelfstandig taken namens je volbrengen.”5
Twee zinnen later, op dezelfde pagina, sluit het uit:
„Applicaties die LLMs integreren maar ze niet gebruiken om workflow execution te controleren — denk aan eenvoudige chatbots, single-turn LLMs of sentiment classifiers — zijn geen agents.”5
Lees die citaten op volgorde. De openingszinnen trekken de lijn bij onafhankelijkheid: gaat dit ding ervandoor en maakt het de klus af zonder mij? De vierde trekt hem bij controle over execution, wat exact de lijn van Anthropic is. Verschillende tests, dezelfde pagina, en er zijn echte systemen waarover ze het oneens zijn.
Daaronder zit een botsing van vocabulaire, en die veroorzaakt discussies in echte meetings. In het eerste document is een workflow een architectuur, en het is het ding dat geen agent is. In het tweede is een workflow „een sequence of steps die moet worden uitgevoerd om het doel van de gebruiker te bereiken” — de taak zelf, waarvan elke agent er één heeft. „We hebben de workflow vervangen door een agent” is coherent onder de eerste definitie en bijna betekenisloos onder de tweede.
Drie systemen, twee keer geclassificeerd
Link naar de sectie: Drie systemen, twee keer geclassificeerdDrie systemen die in 2026 bestaan, onder beide definities.
Een coding agent in een terminal
Link naar de sectie: Een coding agent in een terminalJe beschrijft een taak; hij leest bestanden, draait de test suite, bewerkt, draait ze opnieuw, en stopt wanneer ze slagen of wanneer hij opgeeft. Niets in jouw code beslist dat de volgende stap „de tests draaien” is — het model doet dat, op basis van wat de laatste tool teruggaf.
Definitie één: agent, omdat het model zijn eigen proces aanstuurt. Definitie twee: agent, omdat het de taak zelfstandig volbrengt, voltooiing herkent en de controle teruggeeft. Beide documenten noemen deze vorm als hun centrale voorbeeld.
Een nachtelijke pipeline voor tickettriage
Link naar de sectie: Een nachtelijke pipeline voor tickettriageVoor elk nieuw supportticket drie model calls in een vaste volgorde — classificeren, de velden extraheren, het antwoord opstellen — en dan versturen. Geen model kiest ooit wat er daarna gebeurt; een for loop doet dat. Hij draait om 03:00 en niemand kijkt mee.
Definitie één: geen agent. Het is prompt chaining, expliciet als workflow genoemd. Definitie twee: beide antwoorden. Volgens de openingszinnen volbrengt het zelfstandig taken namens je; volgens de vierde gebruikt het het model niet om workflow execution te controleren, en is het uitgesloten. Dit systeem is waarom je de hele pagina leest in plaats van het pull quote.
Een chat assistant met een search-tool
Link naar de sectie: Een chat assistant met een search-toolEén user turn. Het model beslist zelf of het moet zoeken voordat het antwoordt, antwoordt daarna en wacht op je.
Definitie één: agent, omdat het model zijn eigen toolgebruik dynamisch aanstuurt op resultaten uit de environment, wat de genoemde test is. Definitie twee: geen agent, omdat er geen onafhankelijkheid is — één beurt, dan geeft hij terug — en „simple chatbots” expliciet op de uitsluitingslijst staan.
Twee van de drie wisselen van kant. Dat is geen falen van een van beide documenten. Het is een waarschuwing voor een soort meeting waarin twee mensen die het volledig eens zijn over wat een systeem doet een uur besteden aan onenigheid over hoe je het moet noemen.
De uitweg is twee assen, niet één
Link naar de sectie: De uitweg is twee assen, niet éénDe definities botsen omdat elk twee onafhankelijke vragen samenperst in één woord. Haal ze uit elkaar en de onenigheid wordt een tabel, wat nuttiger is dan een oordeel.
| jouw code kiest de volgende stap | het model kiest de volgende stap | |
|---|---|---|
| een persoon kijkt elke beurt mee | een formulier met een model erin: classifiers, extractie, single-turn completion | een chat met tools — definitie één zegt agent, definitie twee zegt nee |
| niemand kijkt mee tot het klaar is | een pipeline — de opening van definitie twee zegt agent, de vierde zin zegt nee | iedereen is het eens: een agent |
Elke definitie betwist een andere cel, en de andere twee staan niet ter discussie. Dus wanneer het label ertoe doet — in een contract, een risk review, een postmortem — zijn de twee zinnen die het waard zijn om op te schrijven niet „is het een agent”, maar wie koos de volgende stap en wie keek mee. Beide zijn te beantwoorden door code te lezen, geen van beide heeft iemands definitie nodig, en samen dragen ze elke consequentie waarvoor het label inviel.
Niets hiervan is nieuw. Wooldridge en Jennings onderzochten de concurrerende betekenissen van „agent” in 1995;6 Franklin en Graesser stelden de vraag van dit hoofdstuk in 1996, verzamelden de definities die in omloop waren en ontdekten dat ze elkaar tegenspraken.7 Een survey uit 2023 definieert agents nog steeds vanaf de eerste principes — „artificial entities that sense their environment, make decisions, and take actions”8 — omdat er niets gevestigds bestond om te citeren, en CoALA beschrijft onderdelen in plaats van überhaupt een grens te trekken.9 Dertig jaar weigering om het eens te worden zegt dat het woord meer dan één taak uitvoert.
Een agent is N calls, niet één
Link naar de sectie: Een agent is N calls, niet éénNu de consequentie die vóór de filosofie arriveert: de rekening.
Elke meting hier heeft dezelfde vorm. De single call kostte 39 input tokens; dezelfde vraag met één tool kostte 420 over twee calls; de loop zonder stopregel kostte 1.688 over zes. De groei is erger dan lineair, omdat beurt n elke vorige beurt meedraagt: de prompt-kolom van die run met zes beurten leest 187, 238, 261, 302, 327, 373. Hoofdstuk 16 leidde af dat het totaal is en fit de curve op een echt gesprek. Een agent verandert elke taak in dat gesprek, of een mens het nu ooit ziet of niet.
Als die gemeten token counts naar een commercieel endpoint waren gegaan tegen de tarieven die Hoofdstuk 16 op 6 september 2026 las — $2.00 per miljoen input tokens en $12.00 per miljoen output — dan komen de vier runs zo uit:
| run | model calls | input tokens | output tokens | kosten |
|---|---|---|---|---|
| de vraag, geen tools | 1 | 39 | 8 | $0.000174 |
| dezelfde vraag, één tool in de catalogus | 2 | 420 | 38 | $0.001296 |
| een vraag die de tool nodig heeft | 2 | 425 | 33 | $0.001246 |
| dezelfde, met de stopregel verwijderd | 6 | 1.688 | 124 | $0.004864 |
Rij twee tegenover rij één is het getal om te onthouden. Zeven en een half keer de kosten, voor een slechter antwoord op een vraag die het model al wist. Niets was verkeerd geconfigureerd: er bestond een tool, dus het model gebruikte die — en de bevinding van Hoofdstuk 18, dat de prijs van een catalogus en niet de nauwkeurigheid ervan pijn doet, heeft hier zijn goedkoopste demonstratie met een catalogus van één.
Daarom is de nuttige helft van beide documenten de helft over dit niet bouwen. Anthropic is bot: zoek de eenvoudigst mogelijke oplossing en voeg complexiteit alleen toe wanneer dat nodig is, wat „might mean not building agentic systems at all”, omdat agentic systems „trade latency and cost for better task performance” en „for many applications, optimizing single LLM calls with retrieval and in-context examples is usually enough”.4 Zijn case voor een agent is smal: open problemen waarbij je het aantal stappen niet kunt voorspellen en geen pad kunt hardcoden, in een environment die je vertrouwt, waarbij je „higher costs, and the potential for compounding errors” accepteert.4 OpenAI’s scherm is het spiegelbeeld — complex judgement, ononderhoudbare regelsets, ongestructureerde data — en eindigt hetzelfde: „otherwise, a deterministic solution may suffice”.5
Dus, in de taxonomie van dit hoofdstuk: een vast aantal stappen in een vaste volgorde is een pipeline, en die een agent noemen maakt hem niet sneller. Als het aantal stappen afhangt van wat je onderweg vindt, wil je een loop — en die flexibiliteit koop je met N calls, een kwadratisch transcript en een systeem dat N keer fout kan zijn in plaats van één keer.
Waar dit hierna naartoe gaat
Link naar de sectie: Waar dit hierna naartoe gaatJe hebt nu de taxonomie, beide moderne definities, de twee assen die ze compatibel maken, en een korte loop die antwoordt, aanroept en stopt.
Die loop heeft één manier om te eindigen: het model stopt met om tools vragen. Hoofdstuk 23 breekt hem expres, zeven keer, en elke breuk voegt een stuk toe. Een onmogelijke taak, en hij eindigt nooit — een turn cap. Een nacht draaien, en de rekening komt — een budget in dollars. Een tool die faalt — een error waarop het model kan handelen. Dezelfde call twee keer — een idempotency key. Een bestand dat het niet had mogen aanraken — menselijke goedkeuring. Een restart halverwege — session persistence. Een tool die drie minuten stil is — voortgang en annulering. Wat eruit komt is een harness, het bestand waarop de rest van deze cursus draait.
Daarmee blijft de vraag over waar de betwiste diagonaal van dit hoofdstuk echt over ging. Een loop die zijn eigen volgende stap beslist moet beslissen wanneer hij stopt, en we hebben net gezien wat er gebeurt wanneer hij dat niet kan: zes beurten, vier keer de rekening, en een agent die de gebruiker ondervraagt over een vraag die hij al had beantwoord. Stoppen is niet één voorwaarde. Hoeveel zijn er, en welke gaat als eerste af?
Bronnen en methode
Link naar de sectie: Bronnen en methodeLilian Wengs LLM Powered Autonomous Agents (2023) is de bekendste ontleding van een language agent in planning, memory en tool use, en is de juiste volgende tekst naast de twee vendordocumenten; de drie componenten zijn Hoofdstuk 23, 24 en 18 van deze cursus, in die volgorde.
Elk getal in dit hoofdstuk is op deze machine geproduceerd en niets is geschat. De gang, de plattegrond, de vier agents die erop lopen en de drie patrol policies zijn de TypeScript hierboven, gedraaid op Node 22; de cijfers van de gerandomiseerde agent zijn gemiddelden over 2.000 seeded runs elk en de patrol figures zijn enkele seeded runs van 4.000 ticks. De model traces komen van Qwen2.5-0.5B-Instruct in float32 op CPU met greedy decoding, geserveerd over loopback door een klein lokaal Python-endpoint dat de weights laadt en de OpenAI chat-completions-vorm spreekt — opnieuw de naad, met de tensors aan de Python-kant en de loop aan de TypeScript-kant — dus de token counts zijn die van de tokenizer van dat model en de latencies die van die machine. De enige cijfers die elders vandaan komen zijn de twee prijzen in de kostentabel, de tarieven die Hoofdstuk 16 op 6 september 2026 las van OpenAI’s pricing page, hier toegepast op lokaal gemeten token counts als illustratie en niet als waargenomen factuur.
Referenties
Link naar de sectie: Referenties-
Russell, S. en Norvig, P. Artificial Intelligence: A Modern Approach, 4e editie, hoofdstuk 2, Intelligent Agents. Bron van de vacuum world, de PEAS-specificatie, de definitie van rationaliteit relatief aan een performance measure, de zeven eigenschappen van task environments, de vijf agent-types die hier worden gebruikt, en de observatie dat oneindige loops vaak onvermijdelijk zijn voor simple reflex agents in gedeeltelijk observeerbare omgevingen. De companion code bij het boek is
aimacode/aima-pythonop GitHub (8.806 stars, laatst gepusht op 30 juni 2026, gelezen op 7 september 2026) — de moeite waard om precies te benoemen voor wat het is. Het is een begeleidende repository bij een boek, geen reference implementation waarop andere projecten bouwen zoalskarpathy/micrograd(17.412) enkarpathy/nanoGPT(62.852) dat zijn. Daarom citeert en linkt dit hoofdstuk die in plaats van hem te vertalen, en daarom geldt het ecosysteemargument dat Hoofdstuk 5 in Python hield hier niet: niets in dit hoofdstuk raakt een tensor, en de loop hierboven is de directe voorouder van die van Hoofdstuk 23. ↩ ↩2 ↩3 ↩4 ↩5 -
Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K. en Cao, Y. ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629 (2022). De afwisseling van reasoning traces en acties waar de goal-based rij van de mappingtabel naar verwijst. ↩
-
Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. en Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). De eigen samenvatting van het paper over het mechanisme is de reden dat het op de learning agent mapt: het versterkt agents „not by updating weights, but instead through linguistic feedback”, met agents die „verbally reflect on task feedback signals, then maintain their own reflective text in an episodic memory buffer to induce better decision-making in subsequent trials”. ↩ ↩2
-
Anthropic, Building effective agents, 19 december 2024,
anthropic.com/engineering/building-effective-agents, gelezen op 7 september 2026. Bron van het hierboven geciteerde onderscheid tussen workflow en agent, van de overkoepelende term „agentic systems”, van de beschrijving van agents als „typically just LLMs using tools based on environmental feedback in a loop”, van de richtlijn om de eenvoudigst mogelijke oplossing te vinden en dat dit „might mean not building agentic systems at all”, en van de case voor en tegen agents, inclusief „higher costs, and the potential for compounding errors” en de aanbeveling van stopping conditions „such as a maximum number of iterations” om controle te behouden. ↩ ↩2 ↩3 -
OpenAI, A practical guide to building agents, pagina’s 4 tot 7, gelezen op 7 september 2026. Bron van „Agents are systems that independently accomplish tasks on your behalf”, van de uitsluiting van „simple chatbots, single-turn LLMs, or sentiment classifiers”, van de definitie van een workflow als „a sequence of steps that must be executed to meet the user's goal”, van de twee kernkenmerken van een agent, van de drie componenten — model, tools, instructions — en van de screeningcriteria voor wanneer je er één moet bouwen, eindigend in „otherwise, a deterministic solution may suffice”. ↩ ↩2 ↩3
-
Wooldridge, M. en Jennings, N. R. Intelligent Agents: Theory and Practice. The Knowledge Engineering Review, volume 10, nummer 2 (1995). De survey die het gebruik in het veld opsplitste in een zwakke notie van agency — autonomy, social ability, reactivity, pro-activeness — en sterkere noties die mentale vocabulaire lenen. Vandaag gelezen is het een verslag van hetzelfde argument dat de twee documenten van dit hoofdstuk nog steeds voeren. ↩
-
Franklin, S. en Graesser, A. Is It an Agent, or Just a Program? A Taxonomy for Autonomous Agents. Proceedings of the Third International Workshop on Agent Theories, Architectures, and Languages, Springer (1996). Hier geciteerd om wat het is in plaats van om een citaat: een survey die de definities van „agent” verzamelde die toen in omloop waren, constateerde dat ze elkaar tegenspraken, en een taxonomie voorstelde om het argument te vervangen. Dertig jaar later staat het argument in beter ontworpen documentatie en is het verder onveranderd. ↩
-
Xi, Z. et al. The Rise and Potential of Large Language Model Based Agents: A Survey. arXiv:2309.07864 (2023). Hierboven geciteerd voor de openingsdefinitie, „AI agents are artificial entities that sense their environment, make decisions, and take actions”, wat de tekstboekdefinitie opnieuw geformuleerd in 2023 is omdat er geen overeengekomen moderne definitie bestond om te citeren. ↩
-
Sumers, T. R., Yao, S., Narasimhan, K. en Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Organiseert language agents als „modular memory components, a structured action space to interact with internal memory and external environments, and a generalized decision-making process to choose actions”, en plaatst ze expliciet in de geschiedenis van symbolische AI en cognitive science. De memory-taxonomie keert terug in Hoofdstuk 24, waar de tabel met drie stores zijn praktische schaduw is. ↩