Engineering the Agentic Stack · Deel 5

Langlopende AI agent-runtime: sessies en checkpoints

Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.

Artikelupdate

Oorspronkelijk gepubliceerd op 26 mei 2026. Beoordeeld en bijgewerkt op 6 september 2026. De update behandelt nieuwere runtime-mogelijkheden en deploymentopties, met gecorrigeerde platformvergelijkingen, budgetbeheer en bronlinks.

Een agent-run kan uren duren, maar het worker-proces kan op elk moment opnieuw starten. De runtime bewaart de state van de run, voert de tools uit en herstelt de run als een tool call halverwege stopt. Het model kiest nog steeds de volgende actie. Deel 6 behandelt de harness: de code die context aanlevert, tool calls controleert en bepaalt of het werk voltooid is.

Wat is een AI agent-runtime?

Een AI agent-runtime is de infrastructuur die een agent die tools gebruikt actief houdt nadat een model call is geëindigd. De runtime bewaart session state, voert tools uit, slaat checkpoints op, beheert secrets, schrijft traces, handhaaft cost limits en bepaalt hoe de service wordt gedeployed. Het model kiest de volgende actie. De runtime bepaalt waar die actie wordt uitgevoerd, registreert het resultaat en herstelt de run na een failure. De harness bepaalt of een actie is toegestaan. De harness is geen store, maar staat wel in de tabel omdat de runtime hem ergens moet uitvoeren.

Primitive die je moet plaatsenProductiontaakVeelgebruikte implementatie
SessionDe run log behouden na process restartsAppend-only event log, thread-ID, conversation store
HarnessModel/tool-turns uitvoeren tot de task klaar isLangGraph graph, Agents SDK runner, custom loop
SandboxCode, files, netwerk en tools isolerenHardened container, VM, browser sandbox, managed workspace
CheckpointHervatten zonder de hele run opnieuw af te spelenPostgres, Redis, durable workflow state
TraceLong runs achteraf debuggen en auditenOpenTelemetry spans, LangSmith, vendor traces

Vier van de vijf primitives slaan state op of beperken wat code kan doen: session, sandbox, checkpoint en trace. De harness neemt beslissingen over memory, tool contracts en permissions. Dit artikel legt de services en stores uit die de harness nodig heeft. Deel 6 behandelt de checks, retries en acceptance tests.


Long runs doorbreken stateless-processaannames

Een stateless chat-endpoint kan request state in één process bewaren en na de response weggooien. Een long agent-run gaat over worker restarts, deploys, context resets en approval pauses heen. Het worker-process kan daarom niet langer de source of truth zijn.

Het OpenAI Codex-team beschrijft hoe lang deze runs worden in zijn harness-engineeringartikel:

“We regularly see single Codex runs work on a single task for upwards of six hours (often while the humans are sleeping).”

Het engineeringteam van Anthropic beschrijft het bijbehorende state-probleem in Effectieve harnesses voor langlopende agents:

“The core challenge of long-running agents is that they must work in discrete sessions, and each new session begins with no memory of what came before.”

Beide observaties leiden tot hetzelfde runtime-ontwerp: persist state buiten de worker en maak workers vervangbaar.

De session moet buiten het worker-process bestaan. Een durable store registreert model calls, tool intents en outcomes, en approvals, zodat een andere worker na een crash vanaf het laatste veilige punt kan hervatten. Een pending external effect moet vóór die hervatting worden gereconcilieerd. Checkpoints zorgen er ook voor dat de runtime een nieuwe model session kan starten wanneer het context window vol raakt, zonder de volledige history opnieuw af te spelen. In Anthropics formulering zijn harness-instances disposable en restartable; durable state staat elders.


Plaats vijf primitives voordat je shipt

Anthropics Scaling Managed Agents-artikel biedt een bruikbare vocabulary voor vijf runtimeverantwoordelijkheden. De harness stuurt de agent aan, terwijl de session registreert wat die deed en de sandbox commands uitvoert. Het checkpoint geeft de volgende worker een resume point; de trace bewaart evidence voor latere debugging. Een implementatie kan componenten samenvoegen, maar de verantwoordelijkheden en failure boundaries moeten nog steeds benoemd worden.

De vijf runtime-primitivesDe vijf runtime-primitives

Session. Een afzonderlijk geschreven append-only event log van model calls, aangevraagde en voltooide tool calls, errors en approvals. Een checkpoint database helpt bij recovery, maar graph-state history vervangt dit log niet.

Het woord is overloaded, dus dit artikel gebruikt een application-level naamgevingsschema voor drie spans. Een thread is de conversation van een gebruiker over meerdere dagen. Dit is de langstlevende span en kan veel runs bevatten.

Een model session is het kortst: één ononderbroken periode van modelcontext. Compaction — de stap die het window samenvat zodat het werk kan doorgaan — verlengt een model session in plaats van die te beëindigen. Een restart of een bewuste fresh start beëindigt de session. Deel 6 gebruikt “model session” in die betekenis.

In dit artikel betekent “session” de durable log voor één run. Meerdere model sessions kunnen naar één log schrijven, en één conversation thread kan meerdere run logs bevatten. Om te herstellen, activeer je de run, laad je de session, reconcile je een eventuele pending side effect en hervat je na het laatste event: wake(sessionId) → getSession(id) → reconcile pending effects → resume from last event.

In LangGraph is thread_id de storage- en retrieval-key van de checkpointer voor de graph-state history van een thread (zie LangGraph persistence); deze bepaalt niet de grenzen van de conversation, model session of event log uit dit artikel. Geef het event log een eigen durable run- of session-ID en bepaal expliciet hoe die IDs naar LangGraph-threads worden gemapt. De OpenAI Agents SDK levert tien ingebouwde session-backends, waaronder SQLiteSession, RedisSession, SQLAlchemySession, MongoDBSession en EncryptedSession (zie de Sessions-documentatie). Ze bevatten mutable conversation history, inclusief removal, clearing en compaction; map een SDK session-ID naar de run-event-ID als dat nuttig is, maar behandel SDK history niet als append-only recovery- of auditlog zonder een gelijkwaardige garantie voor immutability.

Harness. De orchestration loop en de enige primitive hier die beslissingen neemt. De harness stelt de prompt samen uit memory, roept het model aan, controleert de voorgestelde tool call tegen zijn permission rules, dispatcht wat is toegestaan, schrijft resultaten terug naar de session, past retry rules toe en bepaalt of de task klaar is. Planning aids en contextmanagement coderen aannames over model capability. Verplichte authorization en isolation implementeren ook requirements die blijven gelden naarmate models beter worden. Anthropic maakt dat punt rechtstreeks — het wordt hieronder geciteerd in de sectie over failure modes, die grotendeels gaat over wat er gebeurt wanneer die aannames stale worden.

Het Codex-team van OpenAI noemt dit harness engineering: software schrijven blijft engineeringwerk, maar steeds meer daarvan gaat naar de scaffolding en minder naar de code zelf. LangGraph CompiledStateGraph, LangChains Deep Agents en zijn create_deep_agent-entrypoint, en Claude Code zelf zijn allemaal harnesses in deze betekenis.

Sandbox. De geïsoleerde execution environment waarin commands daadwerkelijk draaien. De pagina over sandbox concepts van de OpenAI Agents SDK wijst approvals, tracing, handoffs en de state die nodig is om runs te hervatten toe aan de outer runtime. Commands, file changes en environment isolation worden toegewezen aan de sandbox session.

“Outer runtime” betekent daar de harness samen met zijn state stores. In de vocabulary van deze serie zijn approvals en handoffs harness-beslissingen (Deel 4 en Deel 6); tracing en resume bookkeeping zijn de session- en checkpoint-primitives.

Sandboxes verschillen in hoelang ze blijven bestaan en wat ze tussen runs onthouden. De eenvoudigste vorm is fresh ephemeral: start er één voor een enkele task, vernietig hem wanneer de task klaar is en betaal op elke run de cold-startkosten.

Persistent paused sandboxes behouden het filesystem en een memory snapshot tussen runs. De volgende resume kan een volledige boot vermijden. Snapshot or fork maakt een copy-on-write image van een voorbereide parent, zodat veel tasks geïnstalleerde dependencies en warme caches delen zonder hun writable state te delen.

Per-worktree workspaces geven tasks afzonderlijke checkouts; Git worktrees delen repository-infrastructuur en zijn geen OS-sandboxes. Beperk execution afzonderlijk met een container, VM of process policy. Een application per task kan ook een eigen observability stack hebben. Afzonderlijke logs, metrics en traces maken het mogelijk één run te debuggen zonder dat state naar een andere run lekt. De providertabel verderop in dit artikel vergelijkt isolation- en persistence-contracten.

Checkpoint. De state die nodig is om te hervatten: welke graph node draaide, de nieuwste values en wat hierna moet draaien. Een event log beantwoordt de vraag wat er is gebeurd: de aangevraagde acties en hun outcomes. Een checkpoint kan events die de harness nooit heeft gelogd niet reconstrueren.

LangGraphs PostgresSaver schrijft op elke super-step boundary een Checkpoint. Een super-step is één ronde van de graph, bestaande uit één node of een batch die parallel draaide. Per-task writes gaan naar checkpoint_writes, zodat succesvolle node outputs niet opnieuw worden berekend wanneer een sibling faalt.

Een checkpoint is een gewone dict (v, id, ts, channel_values, channel_versions, versions_seen, updated_channels). LangGraph serialiseert die met zijn op msgpack gebaseerde JsonPlusSerializer in plaats van JSON. datetime, set, Decimal en dataclasses worden round-tripped. Het format is gedocumenteerd op de langgraph-checkpoint-postgres-PyPI-pagina en in de LangGraph checkpoints reference.

StateSnapshot is de afzonderlijke, rijkere view die graph.get_state() boven op een checkpoint bouwt. Een debug bundle kan de .values exporteren als de laatst bekende graph state; eventdetails die de harness nooit heeft gelogd kunnen niet worden gereconstrueerd.

Trace. Het debug- en auditsurface. Elke model call, tool call en sub-agent step moet timing, status, model en provider, correlation IDs, token counts en cost uitsturen. Prompts, completions, tool arguments en tool results zijn optionele content: de GenAI-richtlijnen van OpenTelemetry gebruiken standaard metadata omdat deze velden gevoelige data kunnen bevatten. Leg ze alleen vast nadat je hebt bepaald welke redaction of filtering, access controls en retention van toepassing zijn. Wanneer een run van zes uur faalt, is de trace wat je leest om te achterhalen wat er misging. Een trace kan een investigation ondersteunen, maar het event log en de checkpoint state, met idempotency handling, maken een veilige resume of replay mogelijk. De terminaloutput van de run is dan al lang verdwenen. De GenAI semantic conventions van OpenTelemetry standaardiseren de attributenamen (welk model, welke provider, hoeveel tokens, welke conversation, welke workflow). Voor een OTLP-compatibele destination die deze conventions ondersteunt, kan dezelfde instrumentation de trace exporteren naar systemen zoals Tempo, Jaeger, Honeycomb of LangSmith, hoewel backend adapters of destination-specifieke configuratie nog steeds nodig kunnen zijn.

Policy en secrets lopen dwars door de primitives heen

Twee grenzen lopen dwars door alle vijf primitives heen. Ze zijn de runtimeversie van het securityargument uit Deel 4. De permission decision zelf hoort bij de harness; hieronder gaat het om waar de mechanismen die deze decision afdwingen en voeden fysiek staan.

Permission enforcement

De permission ladder uit Deel 4 moet ergens draaien. De check wordt vóór elke tool call uitgevoerd en beslist of die doorgaat. In production zijn twee patronen gebruikelijk. De filesystem-permission middleware van Deep Agents kan de ingebouwde filesystem tools beperken tot gedeclareerde paths. Deze middleware beheert geen sandbox shell commands, custom tools of MCP calls; dwing die af in de sandbox policy of achter hun eigen tool proxy. Anthropic Managed Agents routeert custom MCP tool calls via een proxy die credentials beheert. Sandbox command execution en Git-authentication gebruiken afzonderlijke paden; de MCP proxy is geen universele interceptor voor elke actie. Wanneer voor een gevoelige call human approval nodig is, pauzeren LangGraphs interrupt() en de approval hook van Deep Agents de graph totdat iemand toestemming geeft.

Secret broker

Het model mag geen long-lived secrets zien, en de sandbox meestal evenmin. Het Managed Agents-patroon is het patroon om over te nemen:

“For Git, we use each repository’s access token to clone the repo during sandbox initialization and wire it into the local git remote. Git push and pull work from inside the sandbox without the agent ever handling the token itself. For custom tools, we support MCP and store OAuth tokens in a secure vault. Claude calls MCP tools via a dedicated proxy; this proxy takes in a token associated with the session. … The harness is never made aware of any credentials.”

In de market-analyst-agent-referentiestack — een kleine LangGraph-agent die market data ophaalt en een analyst report schrijft, gebouwd in deze serie — roept de worker zijn market-data tools lokaal aan. De optionele MCP-server exporteert een tool surface; hij is geen geïmplementeerde credential broker tussen die worker en zijn providers. Beide containers kunnen de gedeelde development .env lezen. Een production broker vereist dat provider credentials worden verplaatst naar een store die de worker niet kan lezen en dat elke relevante call via de broker wordt gerouteerd.

Controleer de plaatsing

Een praktische sanity check is om elk component op te schrijven en te bepalen welke van de vijf primitives het implementeert. Postgres kan session en checkpoint afdekken. De worker-container is de harness. Een service zoals Daytona, Modal of E2B levert de sandbox, terwijl Tempo of LangSmith de trace opslaat.

Onderzoek vervolgens gekoppelde failures. Als twee primitives in hetzelfde process leven, haalt één crash beide neer. Als ze een credential delen, overschrijdt één leak beide boundaries. Veelvoorkomende voorbeelden zijn een worker die ook trace durability bezit, of een sidecar-token dat ook de checkpoint database ontsluit.


Failure modes van een production AI agent-runtime

De runtime beheert retries, herstelt eerder werk, isoleert workspaces en handhaaft budgets. Naarmate runs zich over workers en context windows uitstrekken, verschuiven failures richting state, duplicate side effects, sandbox drift en budgetoverschrijdingen.

De failures vallen in vier groepen:

  • Failures in output quality: de agent verklaart de task klaar voordat het werk echt af is, vergeet wat hij deed na een context-window reset, of vertrouwt op zijn eigen self-evaluation en shipt broken output.
  • Failures in cost control: de agent raakt vast in een retry loop, of verbruikt een token- of tool-call budget zonder iets nuttigs te produceren.
  • Failures in state en crashes: workspaces driften omdat één run files aanraakt die een andere run bezit, tool calls worden meer dan één keer uitgevoerd omdat retries ze opnieuw afspelen, of werk gaat verloren wanneer een worker tussen events sterft.
  • Failures van het context window: het model vat samen en stopt vroeg omdat het denkt dat de ruimte opraakt, zelfs wanneer het window nog ruimte heeft.

De tabel koppelt elke failure aan een mitigation, de basis voor de aanbeveling en de runtime hook die deze afdwingt. Model-specifiek gedrag kan veranderen, dus behandel vendorobservaties als aanleiding om de aanname opnieuw te testen, niet als permanente regels.

Failure modes en hun mitigationsFailure modes en hun mitigations

Failure modeMitigationEvidence noteRuntime hook
Premature completion: agent verklaart de task te vroeg klaarGenerator/evaluator split: een evaluator in een fresh context — een tweede model session die zonder history van de run start — leest files (niet chat) en stemt “done” of “not done”. Fail closed bij elke acceptance check.Anthropics cwc-long-running-agents quick-start bevat een evaluator subagent; valideer het patroon op je task suite.Sub-agent zonder Write/Edit-tools en met een eigen context window
Feature amnesia across context windowsInitializer-agent schrijft PROGRESS.md, feature-list.json, init.sh. De coding agent leest ze bij elke cold boot.Harness-design requirement; meet cold-boot task completion vóór en na het toevoegen van de artifacts.Boot hook vóór de eerste model call van elke session
Duplicated work after session resetAppend-only event log plus een structured handoff file. Elke nieuwe session start met pwd → read PROGRESS.md → review tests.Requirement voor durable-log- en checkpointdesign; test door dezelfde session handoff opnieuw af te spelen.Afzonderlijk geschreven event store plus LangGraph PostgresSaver checkpoint en PROGRESS.md artifact
Context anxiety: model vat samen en stopt vroegBegrens de actieve session en bouw opnieuw op vanuit een handoff wanneer het model de resterende context niet effectief gebruikt. Cognitions workaround voor Sonnet 4.5 schakelde een groter window in, maar beperkte effectief gebruik tot 200k.Vendorobservaties verschillen tussen Sonnet 4.5 en latere generaties. Test opnieuw voordat je de workaround naar een ander model of andere harness overzet.De harness begrenst de sessieduur, start de volgende en hervat vanaf het checkpoint
Self-evaluation optimism: model keurt zijn werk goedFresh-context evaluator plus Playwright/MCP-grounding in de echte DOM, niet in screenshots. Anthropics harness design frontend-rubric bestraft “AI-style” defaults.Anthropic frontend-harness pattern; valideer met task-level acceptance tests op de gerenderde applicatie.Evaluator draait in een afzonderlijke sandbox session zonder write tools
Stuck loops en retry stormsIteration cap per turn, exponential backoff, circuit breaker bij tool error rate. Hard budget op tool calls.Runtime-control requirement; injecteer herhaalde tool failures en controleer de cap, backoff en circuit breaker.Decorator op de tool-execution node; RetryPolicy op Temporal Activities (zie Temporal OpenAI Agents SDK contrib)
Workspace drift: agent bewerkt niet-gerelateerde filesGit commits als checkpoints, per-session workspace mount en Deep Agents filesystem permissions voor zijn ingebouwde filesystem tools. Plaats shell-, custom-tool- en MCP-enforcement in de sandbox policy of een tool proxy.Isolation requirement; voer gelijktijdige sessions uit tegen fixtures en inspecteer file changes tussen runs.Deep Agents FilesystemPermission voor ingebouwde filesystem tools; sandbox policy of MCP proxy voor andere operaties; Daytona/Runloop per-task fork
Runaway token- of toolkostenReserveer vóór dispatch atomair een conservatief budget per call, inclusief in-flight calls; begrens output en tool use en reconcile vervolgens het werkelijke gebruik.Cost-control recommendation; Addy Osmani’s verslag over langlopende agents illustreert het risico, terwijl de werkelijke spend afhangt van model- en toolprijzen.Budget ledger in het dispatch path; Prometheus en Alertmanager als aanvullende monitoring- en stopsignalen
Non-idempotent tool callsPersist een pending-intent en idempotency key vóór dispatch; persist de outcome nadat die terugkomt. Query of retry bij resume met dezelfde key en registreer daarna de recovered outcome of needs_human.At-least-once retry property; valideer een crash nadat de provider commit maar vóór de lokale outcome is geschreven.Durable event store plus provider idempotency lookup, naast de tool-execution node
Lost work after process of sandbox crashDurable event log buiten het process; checkpoint na elke super-step; reconcile pending effects voordat je doorgaat. wake(sessionId) → getSession(id) → reconcile → resume.Recovery requirement; injecteer een crash tussen provider success en outcome persistence en vergelijk daarna het gereconcilieerde event log met het external effect.PostgresSaver voor graph state plus een afzonderlijke event store, of een Temporal Workflow

Twee ideeën liggen aan de basis van de meeste rijen. Anthropic over harness staleness in Harness design for long-running application development:

“Every component in a harness encodes an assumption about what the model can’t do on its own, and those assumptions are worth stress testing, both because they may be incorrect, and because they can quickly go stale as models improve.”

Vercel over het verwante probleem van te veel tools die te veel aannames coderen, in We removed 80% of our agent’s tools:

“We deleted most of it and stripped the agent down to a single tool: execute arbitrary bash commands. We call this a file system agent.”

Het citaat beschrijft de bash-core; de agent die Vercel shipte behield twee tools, ExecuteCommand en ExecuteSQL, ter vervanging van een oud codevoorbeeld dat zeventien tools benoemt. Deel 3 behandelt het volledige before-and-after. Hun gerapporteerde resultaat over vijf representatieve queries: success steeg van 4/5 naar 5/5, en het worst case daalde van 724 s / 100 steps / 145,463 tokens (failed) naar 141 s / 19 steps / 67,483 tokens (succeeded). Die worst-case row is de spectaculaire; gemiddeld over de vijf queries bedroeg de tokenbesparing 37%. De les is niet “delete your tools.” Optionele assistance kan redundant worden naarmate modelgedrag verandert. Test de aanname opnieuw wanneer het model verandert.

Cognition zag met Sonnet 4.5 dezelfde moving target bij session length. In Rebuilding Devin for Claude Sonnet 4.5 beschrijven ze een model dat proactief SUMMARY.md / CHANGELOG.md schrijft zodra het context exhaustion aanvoelt, maar onderschat hoeveel tokens het nog over heeft. Hun oplossing was de context van 1M tokens in te schakelen en het gebruik te beperken tot 200k, zodat het model nog steeds denkt dat het headroom heeft. Dat was een beta flag toen zij dit schreven.

Anthropics context-window documentation, gecontroleerd op 6 september 2026, vermeldt Sonnet 5 en Opus 5 standaard met 1M tokens; Sonnet 4.5 blijft op 200k. Huidige Sonnet-modellen ontvangen resterende-contextupdates automatisch, en server-side compaction is in beta beschikbaar voor Claude 4.6 en latere models. Test het geselecteerde model met de ondersteunde context controls voordat je Cognitions historische cap overneemt. Een groter window of een budget counter garandeert geen betrouwbare recall, en geen van beide vervangt durable progress buiten het model.

Het harness-team van OpenAI vat het samen in één regel: “Humans steer. Agents execute.” Wanneer iets faalt, is de nuttige vraag welke capability ontbreekt en hoe je die capability voor de agent zowel legible als enforceable maakt.


De gezonde run-lifecycle

Een goed functionerende run is saai. Het is een keten van kleine, herstelbare steps, waarbij elke voltooide step durable state schrijft voordat de volgende start.

Door elk resultaat te schrijven voordat de volgende step start, beperk je de schade door crashes. Een in-flight external effect is de uitzondering: een worker kan crashen nadat de provider het effect heeft committed maar voordat de harness de outcome registreert. De volgende worker moet dat pending effect reconciliëren voordat hij vanaf de laatste voltooide step hervat.

De lifecycle van een gedeployde agent-runDe lifecycle van een gedeployde agent-run

  1. Boot vanaf een nieuwe session of een hervatte session. Mount bij resume de workspace vanuit de laatst bekende state, lees progress files die de vorige poging heeft achtergelaten (PROGRESS.md, feature-list.json), laad het laatste checkpoint en controleer het event log op pending tool intents. Reconcile elk pending external effect voordat je een nieuwe model- of tool call maakt.
  2. Plan voordat tool calls worden uitgevoerd. Leg vast wat “done” betekent, hoeveel de run mag uitgeven, welke tools de agent kan aanroepen en wat de run vroegtijdig moet stoppen. Deze plan values worden runtime checks; zonder die checks heeft execution niets om weerstand aan te bieden.
  3. Serialiseer side-effecting tool calls of coördineer ze expliciet. De permission check van de harness bepaalt of elke call wordt toegestaan. Voeg vóór dispatch een pending-intent met zijn idempotency key toe; voeg de outcome toe nadat de provider terugkeert. Onafhankelijke read-only of idempotent calls kunnen parallel draaien wanneer elke call een eigen durable intent/result record heeft en de resultaten deterministisch worden geaggregeerd. Als de worker sterft tussen een side effect en het schrijven van de outcome, hervat dan door de provider met dezelfde key te queryen of te retrien en voeg vervolgens de recovered outcome of needs_human toe. Stripe retourneert bijvoorbeeld het opgeslagen resultaat van de eerste request bij een herhaalde idempotency key; een andere provider heeft een equivalente lookup- of retry-contract nodig.
  4. Maak checkpoints op super-step boundaries, of na elk event in een eenvoudigere harness. Persist de graph state, workspace diff en references naar geproduceerde artifacts. Dit checkpoint leest step 1 bij de volgende resume. Als het checkpoint ontbreekt of stale is, kan recovery het event log nodig hebben om de state opnieuw op te bouwen, wat veel trager is.
  5. Evalueer artifacts wanneer de agent denkt dat hij klaar is: tests, een fresh-context evaluator, schema validation en browser checks. Als de check slaagt, eindigt de run succesvol. Als de check faalt, hervat de run vanaf het laatste schone checkpoint, met de failure message toegevoegd aan de context, en probeer opnieuw.

Geen enkele step in deze lijst vereist dat de agent tussen runs iets onthoudt. De state staat in de session en het checkpoint, en de agent leest die bij elke resume opnieuw in.

Persist vóór dispatch een application-owned operation ID en bind die aan de goedgekeurde arguments. Hergebruik die ID voor recovery van dezelfde business intent, zelfs wanneer replanning een nieuwe model tool-call-ID oplevert. Registreer die model IDs afzonderlijk voor correlation. Natuurlijk idempotente updates hebben mogelijk in plaats daarvan een version precondition nodig. AWS retry guidance legt uit waarom request identity intent representeert. Definieer wanneer een action echt nieuw is en hoe lang deduplication duurt: Stripe staat toe keys na minstens 24 uur te verwijderen. Reconcile gewijzigde payloads en verlopen keys vóór een nieuwe poging.

Kies één active writer of een lease per thread. Voor input die tijdens een run binnenkomt, moet je expliciet rejecten, enqueuen, interrupten of rollbacken; Deep Agents’ runtime account beschrijft deze keuzes. Cancellation moet nieuwe dispatch stoppen, de request registreren en in-flight effects reconciliëren; de worker killen maakt een provider call niet ongedaan.

Budget enforcement hoort naast dispatch. Concurrent calls mogen niet dezelfde resterende allowance uitgeven. Prometheus is een monitoringsysteem, geen authoritative spending ledger per request. Reserveer conservatief en reconcile actual usage; vertraagde provider accounting en cancellation kunnen nog steeds tot overschrijding leiden.

Nieuwe model controls helpen het tempo van de run te regelen, maar beheren de spending limit niet. Anthropics beta task budgets geven ondersteunde Messages API-modellen een advisory budget over een agentic loop. Dit budget kan worden overschreden; max_tokens begrenst één response, niet de hele run. Support is model-specifiek: Opus 5 ondersteunt task budgets, Sonnet 5 niet. Behoud de dispatch ledger en cancellation path, ook wanneer het model een budget hint ontvangt.

Safety stops van de provider hebben een eigen terminal path nodig. Voor OpenAI’s misalignment_policy_violation stop je dispatch, behoud je correlated records en vraag je om operator review in plaats van opnieuw te retrien. Handel stream errors na gedeeltelijke output af en reconcile eerdere effects; Deel 4 legt de monitoring boundary uit.

Evaluation moet evidence buiten de producerende context omvatten. Een fresh-context evaluator vermindert shared-context bias, terwijl tests, lints, browser checks en schema validation deterministische evidence bieden. De check kan pass, fail of needs_human retourneren. Voor code agents kan de reviewer een andere model session zijn met read-only tools. Combineer voor data- en report-agents deterministic validation met een reviewer model wanneer judgment nog vereist is.


Elf AI agent-deploymentpatronen en wat de keuze bepaalt

Zodra de vijf primitives benoemd zijn, is de vraag welke deploymentvorm ze uitvoert. Met “vorm” bedoel ik een arrangement van die primitives: waar de harness leeft, waar state persistent wordt gemaakt en welk type sandbox het werk uitvoert. Een vorm is een wiring-beslissing, geen vendor-keuze. De chart hieronder toont waar elke vorm comfortabel is op de run-length-as. De tekst daarna behandelt wat de keuze bepaalt.

Als je maar één van de elf leest, lees dan vorm 2: queue + worker + checkpoint DB. Dit is de default die ik voor de meeste teams aanbeveel, de vorm die de reference repo gebruikt en het skelet waarvan de meeste andere vormen varianten zijn: queue → worker → durable state, waarbij de sandbox source, harness owner of state engine wordt verwisseld. Door eerst vorm 2 te lezen, kun je de rest sneller scannen.

Deploymentvormen en hun sweet spots voor run lengthDeploymentvormen en hun sweet spots voor run length

De chart vergelijkt vormen op run length. De matrix hieronder vergelijkt ze op ownership: elke omlijnde cel benoemt het component dat die primitive levert.

Waar elke primitive leeft in elke deploymentvormWaar elke primitive leeft in elke deploymentvorm

1. SDK in een app server (synchroon, request scoped)

De oorspronkelijke vorm. De agent SDK draait in een request handler. Goed voor tasks onder 30 seconden, demos en internal tools. Slecht voor alles waarvan een HTTP-client kan disconnecten. Cloud Runs HTTP-timeout loopt op tot maximaal 60 minuten, en elke panic in de web tier stopt de run. De SDK is de harness. Untrusted tool execution heeft een afzonderlijke sandbox nodig, en state staat meestal in process memory tenzij je die expliciet elders opslaat. Gebruik dit niet voor werk van meerdere uren.

2. Queue + worker + checkpoint DB

De default die ik voor de meeste teams aanbeveel en de production-shaped demo-implementatie in market-analyst-agent: een Python-worker met een PostgreSQL-checkpointer, Redis Streams (of RabbitMQ) voor de inbound queue en een MCP-sidecar voor tools. Goed voor runs van 10 minuten tot meerdere uren met idempotent steps. De local runner kan de queue omzeilen voor synchrone development, maar de queue maakt deel uit van de productionvorm zodra je asynchronous submission en backpressure nodig hebt.

In het production pattern accepteert de app een request, maakt een session row aan, pusht een job en retourneert een run-ID. De worker haalt de job op, voert de harness uit, schrijft session events en checkpoints, streamt status en slaat artifacts op tijdens de uitvoering. Postgres blijft beschikbaar, workers zijn cattle en queue depth geeft backpressure. Spot/Preemptible compute werkt zolang de durable event- en checkpoint-writes zijn voltooid voordat de worker success rapporteert. De gelinkte repository demonstreert de vorm, maar geen geverifieerde durable recovery. De consumer leest nieuwe messages zonder pending jobs te reclaimen, ACKt exceptions en levert werk opnieuw af met nieuwe initial state in plaats van een gedefinieerd resume-contract. Production vereist claim/lease/reclaim/ACK-gedrag en fault tests voordat deze topology recoverable kan worden genoemd.

In deze vorm is de worker de harness. Zijn container en per-thread workspace leveren een execution boundary, maar untrusted code heeft nog steeds een hardened sandbox of VM nodig. De event store bezit session history; PostgresSaver bezit checkpoint state. Ze kunnen alleen een database delen wanneer de harness beide schemas expliciet schrijft. Traces gaan via OpenTelemetry naar de observability stack die je gebruikt.

3. Durable workflow engine (Temporal-stijl)

Agent orchestration code draait binnen een Temporal Workflow; model calls en tool calls draaien als Activities. Workflow state leeft in een event-history log, ondersteund door Cassandra, MySQL of Postgres, zodat replay over failures heen mogelijk is. Deployments van workflow-code die een execution overlappen hebben replay-safe Worker Versioning of patches nodig; code vervangen zonder die discipline kan replay breken. De Temporal × OpenAI Agents SDK-integratie, algemeen beschikbaar sinds maart 2026, levert een OpenAIAgentsPlugin en een activity_as_tool-helper, en de agentic sandboxes write-up beschrijft hoe je een draaiende agent halverwege een conversation naar een andere sandbox provider forkt. Idle workflows verbruiken geen compute. De caveats zijn reëel: realtime agents worden niet ondersteund, streaming staat nog als experimental gemarkeerd en LocalShellTool en ComputerTool zijn disabled omdat ze niet passen bij een distributed model.

Gebruik deze vorm wanneer de run echte waiting points heeft: human approvals, external callbacks, lange sleeps, retries met business rules en deploy windows — en het team replay-safe workflow versioning kan beheren. Een human approval wordt een durable sleep die geen compute verbruikt, geen polling loop.

De Workflow-code is de harness. De sandbox leeft meestal buiten Temporal en wordt vanuit Activities aangeroepen. Session- en checkpoint state vallen samen in het event-history log van Temporal, terwijl trace visibility afkomstig is van de Temporal UI plus OpenTelemetry spans op elke Activity.

4. Sandbox provider per session

Een nieuwere vorm. Elke agent-run krijgt een eigen microVM of container van een sandbox-as-a-service provider. De harness leeft ergens durable; de sandbox is de disposable execution environment.

ProviderIsolation / execution contractSession- en persistence-limieten, gecontroleerd in september 2026
E2BFirecracker microVM1 uur Hobby / 24 uur Pro voor continuous sessions; pause/resume is een afzonderlijke lifecycle
Vercel SandboxFirecracker microVM45 min Hobby / 24 uur Pro en Enterprise; snapshot expiry is standaard 30 dagen na het laatste gebruik en configureerbaar
DaytonaDoor administrator/provider geconfigureerde sandboxConfigureerbare stop/archive-lifecycle; fork support
ModalgVisor5 min default / 24 uur maximum; volumes en ondersteunde snapshotmechanismen hebben afzonderlijke persistence-contracten
RunloopMarketplace-listing beschrijft microVMsSuspend/resume en disk snapshot/branch; concurrency op platformniveau is geen account quota

Provider startup figures meten verschillende intervallen en vormen geen snelheidsranglijst. Meet API request tot de eerste succesvolle command en application-ready latency afzonderlijk, inclusief image/cache state, region, concurrency en p95/p99. Modal’s boot van een container in ongeveer één seconde sluit bijvoorbeeld application initialization uit. Controleer account concurrency limits vóór load testing.

Daytona registreert voor elke onafhankelijke fork een parent-child link, waarmee de lineage van afgeleide sandboxes behouden blijft. De Codex-harness van OpenAI gebruikt de per-worktreevariant: “Codex works on a fully isolated version of that app, including its logs and metrics, which get torn down once that task is complete.”

Kies deze vorm wanneer de agent untrusted code, browser automation, tests of package installs uitvoert. De trade-off is hogere cost en sterkere provider coupling dan bij shared workers.

De provider bezit de sandbox en niets anders. Harness, session, checkpoint en trace blijven aan jouw kant, meestal aangesloten volgens de queue + worker-vorm uit #2.

5. Anthropic Managed Agents (hosted harness)

Anthropic lanceerde Managed Agents op 8 april 2026 in public beta, achter de managed-agents-2026-04-01 beta header. De service levert een hosted session, harness, sandbox en vault-backed MCP proxy. wake(sessionId) kan de harness op een nieuwe worker initialiseren zonder durable session state te verliezen.

Anthropic rekent Managed Agents af tegen standaard token rates plus $0.08 per session-hour. Billing gebeurt op millisecondeniveau en geldt alleen wanneer de sessionstatus “running” is; idle time is gratis. Een runaway retry loop voegt dus session-hour cost toe boven op de token cost.

Lees de caveats. De Batch API discount geldt niet (“Sessions are stateful and interactive. There is no batch mode.”). Managed Agents is niet beschikbaar via AWS Bedrock of Google Vertex AI. Binnen de beta vallen MCP tunnels en agent “dreaming” achter een extra research preview waarvoor je toegang moet aanvragen; multi-agent coordination en rubric-graded self-evaluation zijn gedocumenteerde onderdelen van de beta. Lock-in is hoog: je ruilt harness freedom in voor het niet zelf draaien van de loop.

De default cloudconfiguratie plaatst alle vijf primitives bij Anthropic. Met self-hosted sandboxes beheer je execution, filesystems en network egress, terwijl Anthropic de orchestration en het model draait. Tool inputs en results bereiken nog steeds het control plane; attached skills en memory worden daar opgeslagen en gesynchroniseerd. Execution bezitten maakt het gehele systeem niet self-hosted.

Claude Platform on AWS ondersteunt Managed Agents en self-hosted sandboxes ook; dit staat los van Bedrock. Daar heeft een autonomous session na zes uur een user-role event nodig om opnieuw te authenticeren, en self-hosted sessions kunnen geen memory stores koppelen. First-party Managed Agents heeft deze twee beperkingen niet. Controleer naast het model ook het platform voordat je een session design overneemt.

6. LangChain Deep Agents Deploy (managed open harness)

deepagents deploy verpakt een deepagents.toml in een LangSmith Deployment met durable execution, memory, multi-tenancy, human-in-the-loop, observability, sandboxed code execution en scheduled runs. Cloud-, hybrid- en self-hosted deployment modes worden ondersteund. Sandbox providers (LangSmith Sandboxes, Daytona, Modal, Runloop of custom) zijn via één config value verwisselbaar. Agent files en memory leven in een virtual filesystem met pluggable backends; checkpoint persistence is afzonderlijk en memory is gescoped naar user, assistant of beide. Lock-in is lager dan bij Managed Agents: de harness heeft een MIT-licentie, instructions gebruiken de open AGENTS.md-standard en agents worden beschikbaar gesteld via MCP, het A2A (Agent2Agent)-protocol en Agent Protocol. Zie LangChains runtime-behind-production-deep-agents-artikel.

Alle vijf primitives worden standaard hosted aangeboden, maar elk component is via configuratie verwisselbaar. De sandbox staat achter één config value. Het memory filesystem staat los van thread- en checkpoint persistence. Trace gaat naar LangSmith.

7. Google Cloud Run service of job

Cloud Run heeft twee verschillende runtime modes, en welke past hangt af van hoe de agent wordt aangeroepen. Services zijn HTTP-bound en schalen naar nul tussen requests; de harness draait als request handler die terugkeert wanneer de run klaar is. Jobs draaien tot completion zonder HTTP-entrypoint; de harness draait als een one-shot worker die stopt wanneer de task klaar is. Beide kunnen de harness hosten, maar geen van beide houdt state tussen runs vast. Sessions en checkpoints moeten in Postgres, Spanner of een vergelijkbare external store leven.

De harde limieten verschillen sterk. Cloud Run service request timeout: standaard 300 s, maximum 3.600 s (60 min). WebSockets krijgen dezelfde timeout. Cloud Run jobs: standaard 10 min per task, maximum 168 uur (7 dagen); voor tasks met GPUs is het maximum 1 uur. Instance-based billing (always-allocated CPU) staat nog steeds scale-to-zero toe; minimum instances is een afzonderlijke setting; jobs hebben geen HTTP en autoscalen niet.

Gebruik een service voor synchrone runs tot 60 minuten. Gebruik een job voor langer one-shot- of async werk. Cloud Run Jobs kan een task dagenlang actief houden, maar levert geen durable replay over deploys, version changes of worker replacement heen. Een langere workflow kan meerdere executions omvatten wanneer een external orchestrator durable progress bezit.

Cloud Run host de harness. Session- en checkpoint state staan in Postgres, Spanner of een andere external store, en traces kunnen via Cloud Logging en OpenTelemetry stromen. De service-container is een execution environment; voeg een afzonderlijke sandbox toe wanneer de agent untrusted code uitvoert.

8. AWS Lambda: begrensde invocations en durable workflows

Lambdas maximale function timeout is 900 s (15 minuten) en hard. Wanneer API Gateway vóór de function staat, hangt de integration limit af van het API-type. HTTP APIs staan 30 seconden toe; REST integrations hebben standaard 29 seconden, terwijl Regional en private REST APIs een langere timeout kunnen configureren. Lambda durable functions, gelanceerd in december 2025, voegen managed checkpoints, steps en waits toe over executions die maximaal één jaar duren. De actieve invocation blijft begrensd, terwijl de durable workflow langer kan leven. Vergelijk ondersteunde runtimes, regions, replay rules en activity idempotency met je requirements.

Lambda kan een begrensde harness binnen de cap van 15 minuten bevatten. Session- en checkpoint state hebben nog steeds expliciete external homes nodig; voeg voor untrusted code een afzonderlijke sandbox toe en exporteer traces naar external telemetry. Een durable Lambda workflow kan werk van meerdere uren orchestreren over begrensde invocations heen.

9. AWS ECS / Fargate task per run

Fargate documenteert geen harde cap op task runtime, anders dan een gewone Lambda invocation. Fargate ondersteunt geen GPU tasks; ECS GPU workloads hebben geschikte EC2-instances of een external GPU service nodig. Fargate levert virtualization-based task isolation, hoewel credentials en toegestane network access nog steeds een threat model vereisen. Fargate throttling quotas staan een launch burst van 100 toe en vullen aan met 20 per seconde, met afzonderlijke on-demand- en spot-budgets. ECS service quotas beperken services die AWS Cloud Map discovery gebruiken tot 1.000 tasks per service en EC2-backed clusters tot 5.000 container instances.

Fargate vereist de awsvpc-mode, waardoor elke task een network interface en private IP krijgt. Deze vorm past bij VPC-internal data access. Fargate Spot voegt interruption risk toe, en durability blijft jouw verantwoordelijkheid omdat het platform geen Temporal-style replay heeft.

Fargate host de harness en geeft elke run zijn eigen task. Dat scheidt workspaces en task credentials, maar is op zichzelf geen volledige sandbox voor hostile code. Session, checkpoint en trace gaan naar external services zoals RDS of DynamoDB plus CloudWatch/X-Ray.

Vergelijk ook Amazon Bedrock AgentCore Runtime voordat je zelf de AWS session layer bouwt. Deze runtime host jouw agent code met managed session lifecycle en keuze uit compute. AWS documenteert maximaal 8 uur op serverless microVMs, of 14 dagen op het compute type Instances, dat ook GPU workloads ondersteunt. Instances gebruiken AWS-managed EC2-resources in jouw account, met een ander security model dan de serverless optie. Selecteer en test dat compute-contract expliciet; een langer levende instance geeft nog steeds geen exactly-once execution van een external side effect.

10. Kubernetes Job of namespace per session

Goed wanneer je al Kubernetes beheert en per-session sandboxing met clusterbrede controls wilt. Slecht wanneer je sub-second startup nodig hebt, omdat het pullen van de container image en het initialiseren van de pod te lang duurt bij een cold start. Het patroon is één Job per agent-run, met activeDeadlineSeconds, een PersistentVolumeClaim voor de workspace en een sidecar voor de MCP-server. Crash recovery moet je zelf bouwen. Kubernetes adopteren om alleen agents te hosten is duur door configuration overhead en operationele belasting. Het is alleen de moeite waard als je K8s al om andere redenen draait.

Kubernetes host de harness en de per-run execution environment, meestal als één Job en soms met een dedicated namespace. Sterke isolation hangt nog steeds af van runtime class, network policy, pod security en de onderliggende container- of VM-boundary. Session- en checkpoint state staan in een external database of op een PersistentVolumeClaim.

11. Local Docker Compose (alleen dev)

De referentie voor de volgende sectie. Het doel van deze vorm is dat hij de production topology één-op-één weerspiegelt (dezelfde primitives, dezelfde network shape) terwijl hij op één machine draait. Wat hij niet weerspiegelt, is de isolation: één gedeelde workspace mount, één Postgres, geen hardened sandbox en geen afzonderlijke failure domains tussen de worker en zijn state. Ship niets dat deze vorm heeft.

Compose weerspiegelt vorm #2 op één host. In de reference stack bevat Postgres de checkpoint state en is de worker-container de harness. Een production-shaped session heeft een eigen afzonderlijk geschreven event store nodig; PostgresSaver history levert op zichzelf geen event store. De gedeelde workspace mount is handig voor development maar isoleert untrusted runs niet. De optionele OpenTelemetry-stack registreert traces.


Reference stack: Docker Compose

De referentietopologie, gebruikt in slavadubrov/market-analyst-agent, bestaat uit een LangGraph-worker, een Postgres-checkpointer, Qdrant voor retrieval, een MCP-sidecar, een Redis-queue voor async production-like runs en een optionele Prometheus / Grafana / Loki / Tempo / OTel observability stack. In local compose is Redis alleen optioneel omdat de synchrone runner de worker direct kan aanroepen. docker compose up brengt de core topology lokaal omhoog; de MCP-sidecar en observability stack zijn opt-in profiles (--profile mcp, --profile observability).

De reference Docker Compose-topologieDe reference Docker Compose-topologie

Het diagram toont de PostgresSaver van de local demo. Een production-shaped session voegt een afzonderlijk geschreven event schema toe voor tool intents en outcomes; PostgresSaver blijft uitsluitend checkpoint state.

Het enige onderdeel dat de moeite waard is om inline te tonen, is de canonical LangGraph-wiring. Dit is een illustratief fragment, geen repository-runnable voorbeeld. Om het uit te voeren heb je langgraph, langgraph-checkpoint-postgres en psycopg[binary,pool] nodig, een bereikbare PostgreSQL-database met toestemming om de checkpointer tables aan te maken, POSTGRES_PASSWORD en een eerder gebouwde StateGraph in builder; zie LangGraphs Postgres checkpointer setup.

import os
from urllib.parse import quote

from langgraph.checkpoint.postgres import PostgresSaver

password = quote(os.environ["POSTGRES_PASSWORD"], safe="")
DB_URI = f"postgresql://agent:{password}@postgres:5432/agent"
# `builder` is your StateGraph, already built
session_id = "session-123"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
    checkpointer.setup()  # creates tables on first run
    graph = builder.compile(checkpointer=checkpointer)
    result = graph.invoke(
        {"messages": [{"role": "user", "content": "Continue the task"}]},
        {"configurable": {"thread_id": session_id}},
    )

Observability die de run overleeft

Korte request handlers zijn eenvoudig te debuggen: als er iets faalt, lees je de response en de live log. Long-running agents hebben die luxe niet. Tegen de tijd dat een run van zes uur faalt, gebeurde het interessante event vijf uur geleden, is de live terminaloutput verdwenen en is de worker die het produceerde vervangen. Niemand gaat de run reconstrueren vanuit memory. Je debugt dus met durable artifacts die tijdens de actieve run zijn geschreven.

Production stacks dekken doorgaans vier soorten artifacts in twee groepen. Twee daarvan lees je na afloop van de run, voor postmortems en replay: een queryable event log van elke step en OpenTelemetry-traces van waar tijd en tokens naartoe gingen. Twee lees je tijdens de run. Eén is een live tail van wat de agent in de workspace produceert. De andere is een observability stack per worktree die de agent zelf kan queryen terwijl hij nog werkt.

Structured event log (na de run lezen)

Elke model call, tool call, result, error en approval wordt naar durable storage geschreven, keyed by session ID en timestamp. Na afloop van de run query je het log als een normale database table. Addy Osmani legt de lat duidelijk in Long-running Agents: “If you can’t reconstruct what the agent did in the last 24 hours from durable storage, what you have is a long-running shell script that happens to call an LLM, not a long-running agent.”

OpenTelemetry GenAI-traces (na de run lezen)

Dezelfde stapsgewijze data wordt als spans geëmitteerd met de standard attributes uit de gen_ai.* semantic conventions: model name, provider, input- en output-token counts, conversation ID en workflow name. De conventions hebben nog steeds Development stability.

In 2026 zijn ze uit OpenTelemetrys belangrijkste semantic-conventionsrepository verhuisd naar hun eigen GenAI semantic conventions repo. De attributenamen zijn bruikbaar voor instrumentation, maar pin de revision die je hebt gevalideerd in plaats van een version number uit de main repo. Provider-specific fields leven in subnamespaces (anthropic.*, openai.*) die keyed zijn op gen_ai.provider.name. De reden om de standaard te gebruiken is portability: op OTLP-compatibele destinations die deze conventions ondersteunen, hoef je bij het wisselen van backend mogelijk niet opnieuw te instrumenteren, hoewel backend adapters of destination-specific configuration nog steeds nodig kunnen zijn.

Tool-call timeline plus workspace diffs (tijdens de run lezen)

De snelste manier om te weten wat een agent nu doet, is de output in de workspace tailen, niet door in een session log te greppen. Anthropics Harness Primitives for Long-Running Claude Agents quick-start levert hiervoor een two-pane watch loop: watch -n 5 'git log --oneline -8' toont de nieuwste commits die de agent heeft gemaakt en watch -n 5 'find screenshots -name "*.png" | tail -5' toont de nieuwste screenshots die hij heeft genomen. Twee terminalpanes die elke vijf seconden refreshen zijn voldoende om te zien of een run echte progress maakt of blijft ronddraaien.

Ephemeral stack per worktree (door de agent zelf gelezen, tijdens de run)

Volgens OpenAI’s harness post: “Logs, metrics, and traces are exposed to Codex via a local observability stack that’s ephemeral for any given worktree.” Elke agent-worktree krijgt zijn eigen short-lived Loki + Prometheus + Tempo, uitsluitend gescoped naar die run. De agent queryt de stack tijdens het werk. Daardoor kan een prompt als “no span in these four user journeys exceeds two seconds” iets worden dat de agent rechtstreeks kan verifiëren, in plaats van iets dat hij moet gokken.

(De fresh-context evaluator uit de failure-modes-tabel leest deze artifacts om “done” te bepalen. Dit hoort bij evaluation, niet bij observability; zie § gezonde run-lifecycle. De evaluator is afhankelijk van elk van de bovenstaande surfaces.)

Een minimale self-hosted observability stack

Voor iets als market-analyst-agent:

  1. OpenTelemetry Collector met de GenAI Normalizer Processor (contrib, alpha) voor ondersteunde GenAI attributes. Gebruik de generieke Attributes- of Transform-processors om gen_ai.*-fields te filteren of te herschrijven.
  2. Tempo (of Jaeger) voor traces, keyed by gen_ai.conversation.id / thread_id.
  3. Loki voor structured event-log entries.
  4. Prometheus voor gen_ai.client.token.usage, gen_ai.client.operation.duration en gen_ai.client.operation.time_to_first_chunk — de gen_ai.server.* metrics komen van de model server, dus je krijgt ze alleen als je de weights host (zie de GenAI metrics conventions).
  5. Grafana dashboards keyed on gen_ai.agent.name en gen_ai.request.model.

Hosted alternatives (kies er één, geen drie):

  • LangSmith: native LangGraph integration; ook het deployment target voor Deep Agents Deploy.
  • Braintrust: beste fit als eval-first regression suites prioriteit hebben.
  • Arize Phoenix: OSS, native to OTLP (het OpenTelemetry wire protocol), gecombineerd met OpenInference instrumentation.
  • OpenAI’s tracing dashboard: automatisch wanneer je de OpenAI Agents SDK of de Temporal-integratie gebruikt.
  • Anthropics Claude tracing: voor sessions die binnen Managed Agents draaien.

Instrumenteer de LangGraph-node

Dit is een illustratief fragment en wordt overgeslagen door de repository’s example runner. Het gaat ervan uit dat de LangGraph-node al een actieve OpenTelemetry span, de huidige thread_id en een provider response usage-object met input_tokens en output_tokens heeft; tracer setup, export configuration en provider-specific usage mapping vallen buiten het fragment.

# In the LangGraph node, around the model call:
span.set_attribute("gen_ai.operation.name", "chat")
span.set_attribute("gen_ai.provider.name", "anthropic")
span.set_attribute("gen_ai.request.model", "<your-model-id>")
span.set_attribute("gen_ai.response.model", "<your-model-id>")
span.set_attribute("gen_ai.conversation.id", thread_id)
span.set_attribute("gen_ai.agent.name", "market-analyst")
span.set_attribute("gen_ai.workflow.name", "research_then_write")
span.set_attribute("gen_ai.usage.input_tokens", usage.input_tokens)
span.set_attribute("gen_ai.usage.output_tokens", usage.output_tokens)

Attributenamen zijn letterlijk overgenomen uit de OpenTelemetry GenAI semantic conventions registry.

Drie queries die op een dashboard horen

# Loki: output tokens per agent in the last hour (one completion event per call)
sum by (gen_ai_agent_name) (
    sum_over_time({service_name="market-analyst-agent"} | json | event = "model_call_completed" | unwrap gen_ai_usage_output_tokens | __error__="" [1h])
)
# PromQL: p95 model latency per model
histogram_quantile(0.95,
    sum by (le, gen_ai_request_model) (
        rate(gen_ai_client_operation_duration_bucket[5m])
    )
)
# TraceQL: long-running tool calls
{ span.gen_ai.operation.name = "execute_tool" && duration > 30s }

De LogQL aggregation gaat uit van precies één gelogde completion event per model call. Deduplicate die events vóór ingestion; rate zou tokens per seconde rapporteren in plaats van dit totaal over één uur. Valideer de field mapping tegen je gedeployde Loki stream.

Het debug-bundlepatroon

Wanneer een run faalt, moet de worker een /workspaces/${THREAD_ID}/_debug/ aanmaken met de artifacts die je in een postmortem zou opvragen:

  • events.jsonl: export uit de afzonderlijk geschreven append-only event store van de harness, inclusief tool intents, outcomes, approvals en errors.
  • checkpoints.jsonl: graph-state history uit checkpointer.list({"configurable": {"thread_id": ...}}), gelabeld als checkpoints en niet als event log.
  • last_state.json: StateSnapshot.values van de laatste succesvolle super-step.
  • trace.json: OTLP-exported spans voor de run; metadata is de baseline en eventueel vastgelegde content volgt de trace policy.
  • tool_calls.csv: (ts, tool, input_hash, latency_ms, status, error).
  • workspace.tar.zst: de workspace directory plus git diff tegen de initializer commit.
  • screenshots/*.png: wat de agent zag.
  • PROGRESS.md, feature-list.json en andere door de agent geschreven progress files.
  • env.txt: image tags, model version, harness commit SHA.

Samen kunnen deze artifacts een human of reviewer agent voldoende evidence geven om de failure te reconstrueren, op voorwaarde dat de harness het event store schreef terwijl de run actief was. “The agent got stuck” is vaag. Een illustratief report is concreet: session s_123 besteedde 71 procent van zijn tokens aan het herhalen van drie commands nadat npm install faalde.


De juiste vorm kiezen: een decision guide

Het grootste deel van de vergelijking hierboven komt neer op een handvol beslissingen.

Begin met run length

Gebruik run length als eerste filter:

  • Onder 30 seconden, idempotent: request-lifecycle SDK in een app server.
  • 30 s tot 60 min: queue + worker + checkpoint DB.
  • 60 min tot 24 uur: dezelfde queue + worker, of een Cloud Run Job voor one-shot werk. Gebruik een durable workflow engine als je ook versioning en replay nodig hebt.
  • Meer dan 24 uur, moet deploys overleven: durable workflow engine (Temporal-style). Cloud Run Jobs kunnen long work uitvoeren tot hun task limit, maar bieden geen replay semantics.
  • Multi-day reinforcement-learning training loops: K8s Job + volume + Temporal.

Controleer na deze grove filter side effects, recovery, replay, isolation, data location en het team dat het systeem gaat beheren.

Platform fit per use case

Platform fit per use casePlatform fit per use case

De matrix is dense, en geen enkele groene cel bepaalt de architecture; meestal zijn het de conditional cells — waar een platform iets alleen met een caveat ondersteunt — die de beslissing bepalen. Brede workload coverage is nuttig, maar toont geen data residency, replay semantics, provider dependence, operational maturity of de cost van state later verplaatsen.

De conditional cells gebruiken voor elk platform dezelfde regel. De AWS/VPC- en GPU-opties van Deep Agents hangen af van hybrid deployment of een sandbox provider; Managed Agents kan customer-operated execution gebruiken terwijl de orchestration hosted blijft. De sandbox-choice row bevat een external-provider integration die je op een owned runtime bouwt of in een managed harness configureert. Dit belooft geen snapshot van draaiende state. Een Kubernetes Job heeft ook een API- of queue-layer nodig voor een interactive request; snel afronden maakt het nog geen HTTP-service. Vergelijk network access, hardware, recovery en state-export path van de geselecteerde deployment voordat je kiest. De harness-code row gaat over toegang tot de loop-implementatie, niet over portability van een managed deployment of zijn state. Kubernetes GPU execution vereist bovendien GPU nodes, drivers en een device plugin.

Managed Agents vereist Claude en Anthropic-operated orchestration. De optionele self-hosted sandbox kan passen bij private-network execution, maar een requirement om inference of het control plane zelf te hosten sluit deze optie nog steeds uit. Bekijk welke tool inputs, results, skills en memory die boundary mogen passeren. Internal coding work kan passen wanneer die dataflows acceptabel zijn en het team de operationele verantwoordelijkheid voor de harness wil uitbesteden.

Modelleer de pricing voordat je je vastlegt, niet erna. De session-hourregel is $0.08/uur boven op standaard token costs. Als één session continu draaide, is dat ongeveer $58/maand per session. Bij 100 continu draaiende sessions is dat ongeveer $5.800/maand vóór tokens. Vermenigvuldig $0.08 met je verwachte uren met concurrent sessions, tel dat op bij je token bill en vergelijk het met de kosten van een queue + worker stack op je eigen infra. Later migreren van Managed Agents is een re-platforming exercise, geen config change.

Hosted harness versus owned harness

Het onderscheid gaat hier over wie de harness beheert, niet over wie de code ervan heeft geschreven. Hosted betekent dat de vendor de harness loop in zijn infrastructuur draait en jij een API aanroept. Owned betekent dat je de loop op je eigen infrastructuur draait, zelfs als de harness-code zelf van een vendor afkomstig is.

LangChain komt aan beide kanten van deze grens voor, wat voor verwarring zorgt. Ze leveren LangGraph, een MIT-gelicentieerde library die je self-host (owned), en Deep Agents Deploy, een managed product dat standaard in de cloudmode een Deep Agents harness op LangSmith Deployment draait (hosted). Zelfde bedrijf, twee verschillende operational models. Je kiest wie de loop draait, niet wiens logo op de library staat. (Deep Agents Deploy heeft ook een self-hosted mode voor teams die de harness ergonomics zonder cloudcomponent willen; die mode valt in de owned-categorie.)

Kies een hosted harness wanneer model support, data boundary, recovery behavior en extension points al passen. Kies een owned harness wanneer die constraints requirements zijn waarvan je verwacht dat ze veranderen. Migratie tussen beide verandert state, observability en execution boundaries, dus test de exit path voordat production data ervan afhankelijk wordt.

Hosted sandbox versus een owned execution environment

Kies een hosted sandbox wanneer isolation, pause/resume- of fork-semantics van de provider passen bij het threat model en startup budget. Docker of Fargate kan passen bij trusted internal workloads die VPC access of strikte data residency nodig hebben, maar een standaardcontainer is geen voldoende boundary voor hostile code. Deel 4 behandelt in dat geval het isolationaanbod.

State stores: Git, DB en object storage naast elkaar

Long-running agents gebruiken meestal drie state stores tegelijk omdat elke store een ander artifact bezit.

Git bewaart workspace state: de code, documents en progress files die de agent wijzigt. Elke commit geeft de harness een stabiel recovery point en de volgende session een compacte history.

De checkpoint database bewaart graph state: wat is besloten, welke nodes draaiden, welke results terugkwamen en wat hierna moet draaien. De artifact store bevat grote final outputs zoals PDFs, Parquet-files en screenshots. Die artifacts horen niet in Git of in de checkpoint database.

Wanneer git als state gebruiken

Gebruik git wanneer de workload code-shaped is (multi-file edits, refactors, app generation) of document-shaped genoeg dat file history belangrijk is. Het patroon is eenvoudig: maak een run branch aan, maak een initializer commit en commit daarna op betekenisvolle boundaries: na setup, na elke feature, nadat tests slagen en na de laatste cleanup. Bewaar de laatste workspace commit SHA naast de checkpoint row. Bij resume checkt de volgende worker de branch uit, leest git log --oneline -8, inspecteert git status en de laatste diff en leest vervolgens PROGRESS.md of het handoff file dat de vorige session heeft geschreven.

Daarmee is git een recovery surface voor het artifact waaraan wordt gewerkt, geen replacement voor de checkpoint DB. Git kan twee vragen beantwoorden: wat veranderde er en welke versie slaagde voor de tests. Git kan de harness niet vertellen welke graph node hierna moet draaien, welke tool call op approval wacht of welke retry zijn idempotency key al gebruikte. De harness van Anthropic gebruikt initializer commits plus per-feature commits als source of truth voor workspace recovery; het model leest git log --oneline -8 om state te herstellen. Sla git over wanneer het work product uit één conversational answer bestaat. De overhead loont dan niet.

Wanneer DB-checkpointing gebruiken

Gebruik PostgresSaver-style checkpointing wanneer de agent een graph structure heeft met meerdere nodes waarvan de intermediate state van belang is (planner → researcher → writer → verifier). De reference repo gebruikt dit precies om die reden. Plaats terabyte-scale workspace artifacts niet in het checkpoint; die horen in object storage.

Wanneer een artifact store gebruiken (S3 / GCS)

Gebruik object storage wanneer:

  • de output groter is dan de checkpoint database zou moeten dragen;
  • downstream consumers een URL-addressable artifact nodig hebben zonder via de agent te gaan; of
  • het deliverable en de run state verschillende retention windows hebben.

Je kunt bijvoorbeeld de session log na 30 dagen verwijderen maar het final report jarenlang bewaren. Key de layout op (thread_id, checkpoint_id, artifact_name) zodat de producing run reconstructable blijft.

Wanneer om human approval vragen

Stel approval requirements vast op basis van action risk, reeds verleende authority en deployment policy. Een reversible draft database write verschilt van een customer charge of een destructive production change. Wanneer approval nodig is, toon je de daadwerkelijke action, arguments en destination, persist je die decision en controleer je die opnieuw als de voorgestelde call verandert; voer een rejected call niet uit. LangGraphs interrupt() en de approval middleware van Deep Agents kunnen de run voor die decision pauzeren. Deel 4 legt uit waarom dit een permission decision is en geen prompt instruction.


Een praktische production checklist

Beantwoord deze vragen in concrete infrastructure-termen voordat een long-running agent wordt geshipt.

  1. Welke store bezit session events en checkpoints?
  2. Wat gebeurt er als de worker halverwege een tool call sterft?
  3. Kan één run de workspace van een andere run corrumperen?
  4. Welke actions vereisen approval?
  5. Kan het model of de sandbox raw credentials lezen?
  6. Welke tool calls kunnen veilig worden geretried?
  7. Waar wordt de cost cap per run afgedwongen?
  8. Welke deterministic evidence bepaalt completion, en welke resterende criteria vereisen een reviewer?
  9. Waar staan final outputs nadat de sandbox is verdwenen?
  10. Kunnen we morgen een failed run uitleggen zonder die opnieuw te draaien?

Als het antwoord op een van deze vragen “de prompt zegt dat de agent voorzichtig moet zijn” is, is het systeem nog niet gedeployed. Het is nog steeds een demo.

De volgende laag is de harness loop

Deze runtime kan een run actief en recoverable houden, maar durability bewijst niet dat het werk correct is. Deel 6, Harness Engineering for AI Agents, opent de harness primitive uit de tabel hierboven: hoe een trace je vertelt welke van meerdere failures je werkelijk hebt, waar retry- en stop rules staan, wat een handoff moet bewaren en hoe een external acceptance check bepaalt dat een run klaar is. Dit is ook het laatste bericht in de serie.

References

Engineering write-ups

LangGraph en Deep Agents

OpenAI Agents SDK

Temporal

Anthropic-platform

Sandbox providers

Timeouts en quota’s van cloudplatforms

Observability


De code van de Market Analyst Agent (LangGraph-worker, Postgres-checkpointer, Qdrant memory, MCP-sidecar en de hierboven beschreven Docker Compose-topologie) staat op GitHub.