Traduction automatique
Cet article a été traduit automatiquement depuis la version originale en anglais.
Runtime d’agents IA longue durée en 2026 : sessions, sandboxes, checkpoints et harnesses
Partie 5 de la série Engineering the Agentic Stack
Les quatre articles précédents couvraient l’intérieur de l’agent : boucles de raisonnement, architecture mémoire, utilisation des outils, sécurité. Celui-ci parle de l’extérieur : le runtime de production autour des agents IA longue durée.
En 2026, les agents IA de production ont cessé d’être des gestionnaires de requêtes pour devenir des workers d’arrière-plan. Une exécution peut durer plusieurs heures. Le worker qui l’héberge peut ne pas survivre aussi longtemps. L’ingénierie intéressante s’est déplacée hors de l’agent, vers le runtime qui l’entoure. Le modèle choisit le prochain mouvement. Le runtime décide ce qu’il advient de ce mouvement quand le worker meurt au milieu d’un appel.
TL;DR : Les agents IA longue durée ont besoin d’un runtime en dehors du modèle : journaux de session, logique de harness, isolation sandbox, checkpoints, traces, contrôles de policy, secrets et limites de coût. Queue + worker + base de checkpoints est le choix par défaut quand vous possédez la stack ; les harnesses hébergés conviennent quand les contraintes du fournisseur sont acceptables. Choisissez d’abord selon la durée d’exécution, puis selon la sémantique de reprise, les besoins de replay, l’isolation sandbox et la responsabilité opérationnelle.
C’est un long article. Voici ce que vous y trouverez :
La première moitié parcourt les cinq primitives du runtime et les modes de défaillance que chacune est là pour gérer. La seconde moitié compare onze formes de déploiement — SDK dans un serveur d’application, queue + worker, Temporal, Anthropic Managed Agents, Deep Agents Deploy, Cloud Run, Lambda, ECS, Kubernetes Job par session, plus deux autres — et se termine par un guide de décision pour en choisir une.
Ce qui change quand les sessions d’agents longue durée dépassent la durée de vie des processus
Il y a un an, « déployer un agent » signifiait envelopper un endpoint de chat dans un conteneur et pointer un load balancer dessus. Le travail était indiscernable de celui de n’importe quel autre service web Python. Cela a cessé d’être vrai au moment où les agents ont commencé à tourner pendant des heures au lieu de quelques secondes.
L’équipe OpenAI Codex a chiffré cette nouvelle base dans son retour d’expérience sur l’ingénierie de harness :
« We regularly see single Codex runs work on a single task for upwards of six hours (often while the humans are sleeping). »
L’équipe d’ingénierie d’Anthropic a formulé le problème structurel tout aussi clairement dans Effective harnesses for long-running 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. »
Prenez cette phrase au sérieux et toute la stack runtime change de forme. Trois conséquences découlent de « sessions discrètes sans mémoire partagée », et chacune impose un élément d’infrastructure précis dans le design.
Si les sessions sont discrètes, la session doit vivre hors du processus. L’état en mémoire disparaît dès que le worker s’arrête, donc la session doit être écrite dans un store durable que le worker suivant peut relire. Si une session peut reprendre après un crash, l’enregistrement durable doit contenir tout ce qui s’est passé jusque-là, pas seulement la réponse finale. Cela permet au worker suivant de reprendre au bon endroit au lieu de rejouer l’exécution depuis zéro. Si le modèle remplit sa fenêtre de contexte avant que le travail soit terminé, quelque chose doit checkpoint l’avancement, fermer la session courante et en démarrer une nouvelle qui charge le checkpoint au lieu de rejouer tout l’historique. Dans la formulation d’Anthropic, le harness devient du « bétail » : des instances jetables, redémarrables, identiques. L’état vit ailleurs.
Le modèle décide quoi faire ensuite. Le runtime décide si ce mouvement est autorisé, où il s’exécute, comment il est enregistré, et comment l’exécution reprend après un crash. Le reste de cet article porte sur ce runtime.
Les cinq primitives runtime dont tout agent IA longue durée a besoin
Le retour d’expérience Scaling Managed Agents d’Anthropic a donné à l’industrie un vocabulaire de travail, et l’essentiel du domaine s’y est aligné. Cinq composants font l’essentiel du travail runtime. Le harness fait avancer l’agent étape par étape ; la session enregistre ce qu’il a fait ; le sandbox est l’endroit où les commandes s’exécutent ; le checkpoint est ce que lit le worker suivant à la reprise ; la trace est ce que vous lisez plusieurs jours plus tard quand vous devez comprendre ce qui a mal tourné. Chaque composant est interchangeable tant que sa responsabilité reste intacte.
Session. Un journal append-only de tout ce qui s’est passé : appels modèle, appels outils, résultats, erreurs, approbations. La reprise est wake(sessionId) → getSession(id) → resume from last event. Dans LangGraph, c’est un thread_id plus un checkpointer Postgres (voir LangGraph persistence). Le OpenAI Agents SDK fournit dix backends de session intégrés, dont SQLiteSession, RedisSession, SQLAlchemySession, MongoDBSession et EncryptedSession (voir la documentation Sessions).
Harness. La boucle d’orchestration. Elle appelle le modèle, parse les appels outils, les exécute, réécrit les résultats dans la session et applique les règles de retry. Anthropic l’exprime sans détour :
« every component in a harness encodes an assumption about what the model can't do on its own. »
L’équipe Codex d’OpenAI appelle cette discipline harness engineering : écrire du logiciel demande toujours de la discipline, mais une plus grande part passe maintenant dans l’échafaudage que dans le code lui-même. Le CompiledStateGraph de LangGraph, le create_deep_agent de Deep Agents, et Claude Code lui-même sont tous des harnesses dans ce sens.
Sandbox. L’environnement d’exécution isolé dans lequel les commandes s’exécutent réellement. La page sandbox concepts du OpenAI Agents SDK trace une frontière nette :
« The outer runtime still owns approvals, tracing, handoffs, and resume bookkeeping. The sandbox session owns commands, file changes, and environment isolation. »
Les sandboxes diffèrent par leur durée de vie et par ce qu’ils mémorisent entre les exécutions. La forme la plus simple est fresh ephemeral : on en démarre un pour une seule tâche, on le détruit quand la tâche se termine, et on paie le coût de cold start à chaque exécution. Les sandboxes persistent paused restent vivants entre les exécutions, dans un état mis en pause ; le système de fichiers et un snapshot mémoire persistent, donc la reprise suivante se fait en moins d’une seconde au lieu d’un boot complet. Le mode snapshot or fork va plus loin : chaque tâche branche une image copy-on-write depuis un parent qui a déjà ses dépendances installées et ses caches chauds, de sorte que le setup coûteux n’a lieu qu’une fois et que N tâches partagent l’image de base. Les sandboxes per-worktree donnent à chaque tâche son propre workspace et sa propre stack d’observabilité : logs, métriques et traces séparés. Cela permet de déboguer l’exécution d’un agent sans qu’elle se mélange avec celle d’un autre. Des chiffres concrets de cold start et de persistance par fournisseur figurent dans le tableau plus bas dans cette section.
Checkpoint. L’état reprenable. Le PostgresSaver de LangGraph écrit un StateSnapshot à chaque frontière de super-step, avec des écritures par tâche dans checkpoint_writes pour que les sorties des nœuds réussis ne soient pas recalculées lorsqu’un sibling échoue. Le snapshot est un dict sérialisable en JSON (v, ts, id, channel_values, channel_versions, versions_seen, pending_sends) documenté sur la page PyPI langgraph-checkpoint-postgres et dans la référence LangGraph checkpoints.
Trace. La surface de replay et de debug. Chaque appel modèle, appel outil et étape de sous-agent devient un span avec timing, entrées, sorties, volumes de tokens et coût. Quand une exécution de six heures échoue, la trace est ce que vous lisez pour comprendre ce qui s’est passé. La sortie terminal de l’exécution a disparu depuis longtemps. Les conventions sémantiques GenAI d’OpenTelemetry standardisent les noms d’attributs (quel modèle, quel provider, combien de tokens, quelle conversation, quel workflow), de sorte qu’une même trace s’affiche proprement dans Tempo, Jaeger, Honeycomb ou LangSmith sans réinstrumenter.
Policy et secrets sont des frontières runtime distinctes
Deux frontières traversent ces cinq primitives et sont plus simples à penser comme des préoccupations séparées. C’est la version runtime de l’argument de sécurité de la Partie 4.
Moteur de policy
Un contrôle de permission s’exécute avant chaque appel outil et décide s’il passe. Deux patterns sont fréquents en production. Deep Agents laisse chaque sous-agent déclarer quels chemins de fichiers il peut lire ou écrire, et le middleware bloque tout ce qui sort de cette déclaration. Anthropic Managed Agents fait passer chaque appel outil par un proxy MCP, de sorte que le proxy applique les permissions au lieu du code agent. Lorsqu’un appel sensible nécessite une approbation humaine, le interrupt() de LangGraph et le hook d’approbation de Deep Agents mettent le graphe en pause jusqu’à ce qu’une personne dise oui.
Broker de secrets
Le modèle ne devrait pas voir les secrets longue durée, et le sandbox ne devrait généralement pas les voir non plus. Le pattern Managed Agents est celui à reproduire :
« 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
pushandpullwork 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. »
Dans la stack de référence market-analyst-agent, le sidecar MCP lit les tokens OAuth depuis un secret Docker (en production, HashiCorp Vault) et n’expose que la surface outil au worker LangGraph. Le worker ne voit jamais le token. git push fonctionne. cat ~/.ssh/id_rsa ne fonctionne pas.
Une vérification de bon sens sur votre propre stack : notez chaque composant que vous exécutez et quelle primitive parmi les cinq il implémente. Postgres peut couvrir session et checkpoint. Le conteneur worker est le harness. Un service de sandbox hébergé comme Daytona, Modal ou E2B est le sandbox. Tempo ou LangSmith est la trace. Si vous constatez que deux primitives vivent dans le même processus, un seul crash les fait tomber toutes les deux. Si deux partagent un même credential, une seule fuite les compromet toutes les deux. Ces deux situations s’introduisent facilement par accident quand vous allez vite : un worker qui écrit aussi les traces, un token sidecar qui ouvre aussi la base de checkpoints.
Modes de défaillance du runtime d’un agent IA en production
Le runtime existe pour les choses que le modèle ne peut pas faire seul : gérer les retries, se souvenir de ce qu’il a fait il y a trois heures, isoler le système de fichiers d’une exécution de celui d’une autre, s’arrêter avant de dépasser le budget. Nous en avons maintenant nommé sept éléments : harness, journal de session, sandbox, checkpointer, tracer, moteur de policy, broker de secrets. Dès qu’une seule exécution d’agent dépasse environ 30 minutes de temps mur, un ensemble reconnaissable d’échecs commence à apparaître. La plupart n’ont rien à voir avec la qualité du raisonnement ; ce sont des problèmes d’état, de retries, de sandboxes et de budgets.
Les défaillances se répartissent en quatre groupes souples :
- Défaillances de qualité de sortie : l’agent déclare victoire avant que le travail soit réellement terminé, oublie ce qu’il a fait lors d’un reset de fenêtre de contexte, ou fait confiance à sa propre auto-évaluation et livre une sortie cassée.
- Défaillances de contrôle des coûts : l’agent se bloque dans une boucle de retry, ou consomme un budget de tokens ou d’appels outils sans rien produire d’utile.
- Défaillances d’état et de crash : les workspaces dérivent parce qu’une exécution touche des fichiers appartenant à une autre, les appels outils partent plus d’une fois parce que les retries les rejouent, ou du travail est perdu lorsqu’un worker meurt entre deux événements.
- Défaillances de fenêtre de contexte : le modèle résume et s’arrête trop tôt parce qu’il pense manquer d’espace, même quand la fenêtre a encore de la marge.
Le tableau ci-dessous associe chaque défaillance à son pattern de mitigation, au hook runtime où la mitigation vit, et à la question de savoir si la mitigation est encore nécessaire avec la génération actuelle de modèles. Certaines ne sont plus nécessaires. Plus votre harness est ancien, plus il contient probablement de mitigations obsolètes.

| Mode de défaillance | Mitigation | Toujours nécessaire ? | Hook runtime |
|---|---|---|---|
| Achèvement prématuré : l’agent déclare victoire trop tôt | Séparation générateur/évaluateur : un évaluateur en contexte frais lit les fichiers (pas le chat) et vote « done » ou « not done ». FAIL par défaut sur chaque contrôle d’acceptation. | Oui ; le quick-start cwc-long-running-agents d’Anthropic embarque toujours un sous-agent évaluateur. |
Sous-agent sans outils Write/Edit et avec sa propre fenêtre de contexte |
| Amnésie fonctionnelle entre fenêtres de contexte | Un agent d’initialisation écrit claude-progress.txt, feature-list.json, init.sh. L’agent de coding les lit à chaque cold boot. |
Oui ; la compaction seule ne comble pas l’écart. | Hook de boot avant le premier appel modèle de chaque session |
| Travail dupliqué après reset de session | Journal d’événements append-only plus fichier de handoff structuré. Chaque nouvelle session démarre avec pwd → read PROGRESS.md → review tests. |
Oui | Checkpoint PostgresSaver de LangGraph plus artéfact progress.md |
| Anxiété de contexte : le modèle résume et s’arrête tôt | (a) Activer la bêta 1M tokens mais plafonner l’usage effectif à 200k (correctif Sonnet 4.5 de Cognition). (b) Fermer la session et la reconstruire depuis un handoff. | Non sur Opus 4.5 ; Anthropic indique que « the behavior was gone » et que les resets « had become dead weight. » Oui sur Sonnet 4.5 et GPT-5/Codex. | Le driver externe plafonne la longueur de session, démarre la suivante, reprend depuis le checkpoint |
| Optimisme d’auto-évaluation : le modèle juge son travail correct | Évaluateur séparé plus grounding Playwright/MCP dans le vrai DOM, pas dans des captures d’écran. La conception de harness d’Anthropic pour le frontend pénalise les défauts « AI-style ». | Oui | L’évaluateur s’exécute dans une session sandbox séparée sans outils d’écriture |
| Boucles bloquées et tempêtes de retry | Plafond d’itérations par tour, backoff exponentiel, circuit breaker sur le taux d’erreur des outils. Budget dur sur les appels outils. | Oui | Décorateur sur le nœud d’exécution des outils ; RetryPolicy sur les Temporal Activities (voir Temporal OpenAI Agents SDK contrib) |
| Dérive du workspace : l’agent modifie des fichiers sans rapport | Commits Git comme checkpoints, middleware de permissions sur les fichiers, montage de workspace par session. Le middleware Deep Agents permet de déclarer les chemins en lecture/écriture. | Oui | Middleware de permissions de fichiers LangGraph ou fork par tâche Daytona/Runloop |
| Dérive du coût tokens ou outils | Budget de tokens par exécution, budget par outil, kill switch lié à un compteur Prometheus. | Oui ; une session Opus de 24 heures avec une mauvaise budgétisation peut dépenser le budget API d’une semaine en un après-midi (Addy Osmani sur les agents longue durée). | Attributs de span d’attribution des coûts plus règle Alertmanager |
| Appels outils non idempotents | Clé d’idempotence par appel outil. Dans les workflows durables, les retries peuvent déclencher le même appel outil plus d’une fois, donc une clé de déduplication bloque le doublon. | Oui | Temporal Activity avec start_to_close_timeout et clé d’idempotence |
| Travail perdu après crash du processus ou du sandbox | Journal de session durable hors du processus ; checkpoint après chaque super-step. wake(sessionId) → getSession(id) → resume. |
Oui | PostgresSaver à chaque super-step, ou envelopper dans un Temporal Workflow |
Deux idées reviennent dans chaque ligne. Anthropic, sur l’obsolescence des harnesses dans 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, sur le problème connexe d’un trop grand nombre d’outils encodant trop d’hypothèses, dans 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. »
Résultat rapporté par Vercel sur une requête représentative : le taux de succès est passé de 80 % à 100 %, et le pire cas est passé de 724 s / 100 étapes / 145,463 tokens (échec) à 141 s / 19 étapes / 67,483 tokens (succès). La leçon n’est pas « supprimez vos outils ». C’est que chaque primitive de votre runtime, y compris la surface outil, a une demi-vie. Re-testez l’hypothèse quand le modèle change.
Cognition a constaté la même cible mouvante sur la longueur de session avec Sonnet 4.5. Dans Rebuilding Devin for Claude Sonnet 4.5, ils décrivent un modèle qui écrit de manière proactive SUMMARY.md / CHANGELOG.md lorsqu’il sent l’épuisement du contexte, mais sous-estime le nombre de tokens qu’il lui reste. Leur correctif consiste à activer la bêta 1M tokens et à plafonner l’usage à 200k pour que le modèle croie encore disposer de marge. Cette mitigation aussi finira par devenir du poids mort.
L’équipe harness d’OpenAI résume la discipline en une ligne : « Humans steer. Agents execute. » Quand quelque chose échoue, la question n’est pas « essaie plus fort ». C’est « quelle capacité manque, et comment la rendre à la fois lisible et imposable pour l’agent ? »
Le cycle de vie d’une exécution saine
Une exécution qui se comporte bien est ennuyeuse. C’est une chaîne de petites étapes récupérables, chacune écrivant son résultat dans un stockage durable avant que la suivante ne démarre, plutôt qu’une seule énorme requête qui doit réussir de bout en bout. Découper une exécution en étapes de cette façon est ce qui lui permet de survivre aux crashes : quand quelque chose échoue, seule l’étape en cours est perdue, et le worker suivant reprend depuis la dernière étape terminée au lieu de recommencer.
- Démarrer soit depuis une session fraîche, soit depuis une session reprise. À la reprise, monter le workspace dans son dernier état connu, lire les éventuels fichiers de progression laissés par la tentative précédente (
PROGRESS.md,feature-list.json) et charger le dernier checkpoint depuis la base. C’est là que le harness redonne à l’agent tout ce que le worker précédent avait en mémoire avant de mourir. - Planifier avant que le moindre appel outil ne parte. Écrire ce à quoi ressemble « done », combien l’exécution a le droit de dépenser, quels outils l’agent peut invoquer, et ce qui doit arrêter l’exécution plus tôt. Ces valeurs de plan deviennent des contrôles runtime ; sans elles, l’exécution n’a rien contre quoi buter.
- Exécuter un appel outil à la fois. La couche de policy décide si l’appel est autorisé. Le harness l’exécute, capture le résultat et écrit un événement dans le journal de session. Une étape, un événement. Un crash entre deux événements est récupérable parce que le journal, et non la mémoire du worker, est la source de vérité.
- Checkpoint aux frontières de super-step, ou après chaque événement dans un harness plus simple. Persister l’état du graphe, le diff du workspace et les références vers les éventuels artéfacts produits. C’est ce checkpoint que lit l’étape 1 à la prochaine reprise. S’il manque ou est périmé, la reprise se dégrade en replay complet du journal de session depuis zéro, ce qui est bien plus lent.
- Évaluer les artéfacts quand l’agent pense avoir terminé : tests, reviewer en contexte frais, validation de schéma, vérifications navigateur. Si le contrôle passe, l’exécution se termine avec succès. S’il échoue, l’exécution reprend depuis le dernier checkpoint propre avec le message d’échec ajouté au contexte et réessaie.
Il n’y a aucune étape dans cette liste qui exige que l’agent se souvienne de quoi que ce soit entre deux exécutions. L’état vit dans la session et le checkpoint, et l’agent le relit à chaque reprise.
Les outils à effets de bord ont besoin d’idempotence. Tout outil avec effets de bord doit avoir une clé d’idempotence dérivée du session ID et du tool-call ID, stockée avant que l’effet de bord ne parte. send_email(session_id, tool_call_id, message_hash). create_pr(session_id, tool_call_id, branch_name). charge_customer(session_id, tool_call_id, invoice_id). L’exécution au moins une fois est la valeur par défaut dans les queues et les moteurs de workflow. Si répéter un appel outil peut provoquer un vrai dommage, l’outil n’est pas prêt pour les agents.
L’évaluation doit s’exécuter hors du contexte producteur. Le même contexte qui a produit la réponse ne peut pas juger de façon fiable si la réponse est correcte. Un évaluateur frais lit les fichiers et artéfacts, exécute tests, lints, vérifications navigateur ou validation de schéma, et renvoie pass, fail ou needs_human. Pour les agents de code, c’est une autre session modèle avec outils en lecture seule. Pour les agents de données et de reporting, c’est un validateur déterministe plus un modèle reviewer.
Onze patterns de déploiement d’agents IA et ce qui les départage
Une fois les cinq primitives nommées, la question devient : quelle forme de déploiement les exécute ? Par « forme », j’entends un arrangement de ces primitives : où vit le harness, où l’état persiste, et quel type de sandbox exécute le travail. Ce n’est pas seulement un choix de fournisseur. Le graphique ci-dessous montre sur quel axe de durée d’exécution chaque forme est à l’aise. Le texte qui suit détaille ce qui les départage.
Si vous ne lisez qu’une des onze, lisez la forme 2 : queue + worker + base de checkpoints. C’est le choix par défaut que je recommande à la plupart des équipes, la forme utilisée par le dépôt de référence, et le squelette dont la plupart des autres variantes ne changent qu’un élément : queue → worker → état durable, avec permutation de la source du sandbox, du propriétaire du harness ou du moteur d’état. Lire la forme 2 en premier rend le reste plus rapide à parcourir.
Le graphique compare les formes par durée d’exécution. La matrice ci-dessous les compare par responsabilité : où chacune des cinq primitives vit physiquement. Les cellules vertes indiquent où la forme fournit la primitive ; les grises indiquent là où vous l’intégrez vous-même.
1. SDK dans un serveur d’application (synchrone, scope requête)
La forme d’origine. Le SDK agent s’exécute dans un gestionnaire de requêtes. Bien pour des tâches de moins de 30 secondes, des démos et des outils internes. Mauvais pour tout ce dont un client HTTP pourrait se déconnecter. Le timeout HTTP de Cloud Run culmine à 60 minutes, et toute panique dans la couche web tue l’exécution. Le SDK est le harness, le processus web fait aussi office de sandbox, et l’état vit généralement en mémoire du processus sauf si vous le poussez explicitement ailleurs. N’utilisez pas cela pour du travail de plusieurs heures.
2. Queue + worker + base de checkpoints
Le choix par défaut que je recommande à la plupart des équipes, et la forme de production utilisée dans market-analyst-agent : un worker Python avec un checkpointer PostgreSQL, Redis Streams (ou RabbitMQ) pour la queue entrante, et un sidecar MCP pour les outils. Bien pour des exécutions de 10 minutes à plusieurs heures avec des étapes idempotentes. Le runner local peut contourner la queue pour le développement synchrone, mais la queue fait partie de la forme de production dès que vous avez besoin de soumission asynchrone et de backpressure.
L’application accepte une requête, crée une ligne de session, pousse un job et renvoie un run ID. Le worker récupère le job, exécute le harness, écrit les checkpoints, streame le statut et stocke les artéfacts au fil de l’eau. Postgres survit, les workers sont du bétail, et la profondeur de queue vous donne le backpressure. Le compute Spot/Preemptible fonctionne tant que le checkpointer a le temps d’écrire sur disque avant de signaler le succès.
Dans cette forme, le worker est le harness. Le conteneur worker plus un montage de workspace par thread constituent le sandbox. Postgres possède l’état de session et de checkpoint. Les traces passent par OpenTelemetry vers la stack d’observabilité que vous exécutez.
3. Moteur de workflow durable (style Temporal)
Le code d’orchestration agent s’exécute dans un Temporal Workflow ; les appels modèle et les appels outils s’exécutent comme Activities. L’état du workflow vit dans un journal d’historique d’événements supporté par Cassandra, MySQL ou Postgres, de sorte que l’état se rejoue proprement entre déploiements. L’intégration Temporal × OpenAI Agents SDK, en preview publique, fournit un helper OpenAIAgentsPlugin et un helper activity_as_tool, et le retour d’expérience agentic sandboxes décrit le fork d’un agent en cours d’exécution vers un autre fournisseur de sandbox en plein milieu d’une conversation. Les workflows inactifs ne consomment aucun compute. Les limites sont réelles : les agents streaming et voice ne sont pas supportés dans l’intégration actuelle, et LocalShellTool ainsi que ComputerTool sont désactivés car ils ne s’adaptent pas à un modèle distribué.
Utilisez cette forme quand l’exécution comporte de vrais points d’attente : approbations humaines, callbacks externes, longues mises en sommeil, retries avec règles métier, fenêtres de déploiement. Une approbation humaine devient un sleep durable qui ne consomme aucun compute, pas une boucle de polling.
Le code Workflow est le harness. Le sandbox vit généralement hors de Temporal et est appelé depuis les Activities. L’état de session et de checkpoint s’effondre dans le journal d’historique d’événements de Temporal, tandis que la visibilité des traces vient de l’UI Temporal plus de spans OpenTelemetry sur chaque Activity.
4. Fournisseur de sandbox par session
Une forme plus récente. Chaque exécution d’agent obtient sa propre microVM ou son propre conteneur via un fournisseur de sandbox-as-a-service. Le harness vit quelque part de manière durable ; le sandbox est l’environnement d’exécution jetable.
| Fournisseur | Isolation | Session max | Concurrence | Persistance | Cold start |
|---|---|---|---|---|---|
| E2B | Firecracker microVM | 1 h Hobby / 24 h Pro | 20 / 100 (jusqu’à 1,100 en option) | Pause/reprise, ~4 s/GiB en pause, ~1 s reprise (bêta publique) | ~150 ms p50 |
| Vercel Sandbox | Firecracker microVM | 45 min Hobby / 5 h Pro/Ent | 10 / 2,000 | Jetable | n/a |
| Daytona | Docker (Kata en option) | auto-stop/archive configurable | selon le niveau | Stop → Archive → Delete ; fork supporté | ~90 ms (27 ms sur certaines configs) |
| Modal Sandboxes | gVisor | cycle de vie typique 1–15 min | élevée | Volumes pour la persistance ; snapshot mémoire en preview | « about one second » selon la doc Modal |
| Runloop Devboxes | microVM (hyperviseur custom) | suspend/resume ; snapshot+branch | « more than 30,000 concurrent instances » selon la fiche AWS Marketplace | Snapshot + branch depuis l’état disque | sub-1 s |
Sources : la comparaison E2B vs Daytona, la propre documentation sandboxes de Daytona et son changelog fork/snapshot, le guide sandboxes et le guide cold-start de Modal, la fiche AWS Marketplace de Runloop, et la tarification Vercel Sandbox. La doc Daytona ajoute une remarque utile sur la sémantique de fork : « the new sandbox is fully independent … Daytona tracks the parent-child relationship in a fork tree. » Chaque sandbox forké conserve un lien enregistré vers la base depuis laquelle il a branché, de sorte que vous pouvez interroger la lignée de n’importe quel sandbox dérivé. Le harness Codex d’OpenAI utilise la variante per-worktree : « Codex works on a fully isolated version of that app, including its logs and metrics, which get torn down once that task is complete. »
Utilisez cette forme quand l’agent exécute du code non fiable, de l’automatisation navigateur, des tests ou des installations de packages. Le compromis est le coût et le couplage fournisseur, tous deux plus élevés qu’avec des workers partagés.
Le fournisseur possède uniquement le sandbox. Harness, session, checkpoint et trace restent de votre côté, généralement câblés comme la forme queue + worker du point 2.
5. Anthropic Managed Agents (harness hébergé)
Lancé en bêta publique le 8 avril 2026, derrière l’en-tête bêta managed-agents-2026-04-01. Claude facture Managed Agents aux tarifs standard par token plus 0,08 $ par heure de session. La facturation est granulaire à la milliseconde et ne s’applique que lorsque le statut de session est « running ». Le temps idle est gratuit ; le runtime de session « replaces the Code Execution container-hour billing model when using Claude Managed Agents. » Vous obtenez une session hébergée, un harness, un sandbox et un proxy MCP adossé à un vault. La séparation cerveau/mains est ce que wake(sessionId) achète : le harness peut être réinitialisé sur un nouveau worker sans perte d’état. Modélisez attentivement la forme des coûts ; une boucle de retry incontrôlée sur une facturation à l’heure de session s’accumule plus vite qu’une facturation au token.
Lisez les limites. La remise Batch API ne s’applique pas (« Sessions are stateful and interactive. There is no batch mode. »). Managed Agents n’est pas disponible via AWS Bedrock ni Google Vertex AI. La coordination multi-agent et l’auto-évaluation restent en preview recherche. Le lock-in est élevé : vous échangez la liberté sur le harness contre le fait de ne pas faire tourner la boucle vous-même.
Anthropic héberge les cinq primitives : session, harness, sandbox, checkpoint et trace. Vous lui confiez le runtime et récupérez les sorties.
6. LangChain Deep Agents Deploy (harness open managé)
deepagents deploy empaquette un deepagents.toml dans un déploiement LangSmith avec exécution durable, mémoire, multi-tenant, human-in-the-loop, observabilité, exécution de code sandboxée et runs planifiés. Les modes de déploiement cloud, hybride et self-hosted sont supportés. Les fournisseurs de sandbox (LangSmith Sandboxes, Daytona, Modal, Runloop ou custom) sont interchangeables via une seule valeur de configuration. L’état vit dans un système de fichiers virtuel avec backends interchangeables ; la mémoire est scopeée à l’utilisateur, à l’assistant ou aux deux. Le lock-in est plus faible qu’avec Managed Agents : le harness est sous licence MIT, les instructions utilisent le standard ouvert AGENTS.md, et les agents sont exposés via MCP, A2A et Agent Protocol. Voir le retour d’expérience LangChain runtime-behind-production-deep-agents.
Les cinq primitives sont hébergées par défaut, mais chacune est échangeable par configuration. Le sandbox est derrière une seule valeur de configuration. Session et checkpoint vivent sur un système de fichiers virtuel avec backends interchangeables. La trace va vers LangSmith.
7. Service ou job Google Cloud Run
Cloud Run a deux modes runtime distincts, et celui qui convient dépend de la manière dont l’agent est invoqué. Les services sont liés à HTTP et scale to zero entre les requêtes ; le harness s’exécute comme gestionnaire de requête et retourne quand l’exécution est finie. Les jobs s’exécutent jusqu’à complétion sans point d’entrée HTTP ; le harness s’exécute comme worker one-shot qui se termine quand la tâche est finie. Les deux peuvent héberger le harness, mais aucun ne conserve l’état entre les exécutions. Les sessions et checkpoints doivent vivre dans Postgres, Spanner ou un store externe équivalent.
Les limites dures sont très différentes entre les deux. Timeout de requête Cloud Run service : 300 s par défaut, 3,600 s (60 min) max. Les WebSockets ont le même timeout. Cloud Run jobs : 10 min par défaut par tâche, 168 h (7 jours) max ; pour les tâches utilisant des GPU, 1 heure max. Les services scale to zero sauf si vous activez un CPU always-on ; les jobs n’ont pas d’HTTP et ne font pas d’autoscaling.
Utilisez un service pour des exécutions synchrones jusqu’à 60 minutes. Utilisez un job pour du travail asynchrone ou one-shot plus long. Cloud Run Jobs peut garder une tâche vivante pendant des jours, mais n’offre pas de replay durable entre déploiements, changements de version ou remplacement de worker. Au-delà de 7 jours, n’utilisez pas Cloud Run.
Cloud Run héberge le harness. Session, checkpoint, sandbox et trace sont des services externes que vous câblez, typiquement Postgres ou Spanner pour session/checkpoint, le conteneur lui-même comme sandbox, et Cloud Logging plus OpenTelemetry pour la trace.
8. AWS Lambda (pourquoi c’est le mauvais outil)
Le timeout maximal d’une fonction Lambda est de 900 s (15 minutes), en dur. API Gateway ajoute par-dessus une autre limite de 29 s. Un harness d’agent dont la durée d’exécution minimale utile est de « minutes à heures » ne peut pas survivre sur Lambda sans store d’état externe et sans stratégie de réinvocation qui reconstruit en pratique la forme queue + worker depuis zéro. Utilisez Lambda pour des appels outils individuels, comme des récupérations de fichiers ou des uploads S3, invoqués par un orchestrateur plus long. N’y placez pas l’orchestrateur.
Au mieux, Lambda héberge un appel outil unique dans sa limite de 15 minutes. Harness, session, checkpoint, sandbox et trace doivent tous vivre ailleurs.
9. Tâche AWS ECS / Fargate par exécution
Aucune limite dure documentée sur la durée d’exécution des tâches (contrairement à Lambda). D’après les quotas de throttling Fargate, les lancements sont limités en débit : burst de 100, puis rechargement à 20 par seconde, avec on-demand et spot suivis sur des budgets séparés de 20/s. Quotas ECS service : les services avec découverte de service AWS Cloud Map sont limités à 1,000 tâches par service ; le plafond théorique est de 5,000 instances EC2 par cluster. Fargate impose le mode awsvpc, donc chaque tâche obtient sa propre interface réseau et une IP privée, ce qui est la bonne forme quand vous avez besoin d’accès à des données internes au VPC. Fargate Spot est disponible ; prévoyez les interruptions. La durabilité vous incombe : il n’y a pas de replay de type Temporal intégré.
Fargate héberge le harness et donne à chaque exécution son propre sandbox : une tâche par exécution. Session, checkpoint et trace vont vers des services externes. RDS ou DynamoDB plus CloudWatch/X-Ray sont les choix habituels.
10. Kubernetes Job ou namespace par session
Bien si vous exploitez déjà Kubernetes et voulez un sandbox par session avec des contrôles à l’échelle du cluster. Mauvais si vous avez besoin d’un démarrage en moins d’une seconde, car le pull de l’image conteneur et l’initialisation du pod prennent trop de temps à froid. Le pattern est un Job par exécution d’agent, avec activeDeadlineSeconds, un PersistentVolumeClaim pour le workspace, et un sidecar pour le serveur MCP. La reprise après crash est à construire par vous. Adopter Kubernetes uniquement pour héberger des agents coûte cher en surcharge de configuration et en charge opérationnelle. Cela ne vaut le coup que si vous exploitez déjà K8s pour d’autres raisons.
K8s héberge le harness et le sandbox, généralement comme un Job par exécution et parfois avec un namespace dédié pour une isolation plus forte. Session et checkpoint vivent dans une base externe ou sur un PersistentVolumeClaim. La trace va vers la stack d’observabilité in-cluster que vous exécutez déjà.
11. Docker Compose local (dev only)
La référence pour la section suivante. L’intérêt de cette forme est qu’elle reflète la topologie de production à l’identique (mêmes primitives, même forme réseau) tout en tournant sur une seule machine. Lisez la liste « not production-safe » à la fin de la section suivante avant de mettre en production quoi que ce soit qui ressemble à cela.
Compose reflète la forme #2 sur un seul hôte. Postgres héberge session et checkpoint. Le conteneur worker est le harness. Le montage du workspace est le sandbox partagé. La stack OpenTelemetry optionnelle constitue la trace.
Stack de référence : Docker Compose
La topologie de référence, utilisée dans slavadubrov/market-analyst-agent, est un worker LangGraph, un checkpointer Postgres, Qdrant pour la retrieval, un sidecar MCP, une queue Redis pour des exécutions asynchrones proches de la production, et une stack d’observabilité optionnelle Prometheus / Grafana / Loki / Tempo / OTel. En compose local, Redis n’est optionnel que parce que le runner synchrone peut appeler directement le worker. docker compose up monte toute la topologie en local.
Le seul élément qui mérite d’être montré inline est le câblage canonique de LangGraph. C’est le plus petit exemple concret de la primitive de checkpoint :
from langgraph.checkpoint.postgres import PostgresSaver
DB_URI = "postgresql://agent:${POSTGRES_PASSWORD}@postgres:5432/agent"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
checkpointer.setup() # creates tables on first run
graph = builder.compile(checkpointer=checkpointer)
Une observabilité qui survit à l’exécution
Les gestionnaires de requêtes courtes sont faciles à déboguer : quand quelque chose échoue, vous lisez la réponse et le log en direct. Les agents longue durée n’ont pas ce luxe. Quand une exécution de six heures échoue, l’événement intéressant s’est produit il y a cinq heures, la sortie terminal en direct a disparu, et le worker qui l’a produite a été remplacé. Personne ne va reconstruire l’exécution de mémoire. Vous déboguez donc à partir d’artéfacts durables écrits pendant que l’exécution vivait encore.
Les stacks de production couvrent généralement quatre types d’artéfacts, en deux groupes. Deux d’entre eux se lisent après la fin de l’exécution, pour les postmortems et le replay : un journal d’événements interrogeable de chaque étape, et des traces OpenTelemetry de l’endroit où sont partis le temps et les tokens. Deux autres se lisent pendant l’exécution, pour l’observer en temps réel : un live tail de ce que l’agent produit dans le workspace, et une stack d’observabilité par worktree que l’agent lui-même peut interroger pendant qu’il tourne encore.
Journal d’événements structuré (lecture après l’exécution)
Chaque appel modèle, appel outil, résultat, erreur et approbation est écrit dans un stockage durable, indexé par session ID et horodatage. Une fois l’exécution terminée, vous l’interrogez comme une table de base de données normale. Addy Osmani pose la barre clairement dans 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. »
Traces OpenTelemetry GenAI (lecture après l’exécution)
Le même type de données pas à pas, mais émis sous forme de spans utilisant les attributs standard des conventions sémantiques gen_ai.* : nom du modèle, provider, nombres de tokens en entrée et en sortie, conversation ID, nom du workflow (statut Development à partir de la v1.36.0). Les champs spécifiques au provider vivent dans des sous-espaces de noms (anthropic.*, openai.*) indexés à partir de gen_ai.provider.name. L’intérêt du standard est la portabilité : une même trace s’affiche proprement dans Tempo, Jaeger, Honeycomb ou LangSmith sans avoir à réinstrumenter le code à chaque changement de backend.
Timeline des appels outils plus diffs du workspace (lecture pendant l’exécution)
Le moyen le plus rapide de savoir ce qu’un agent fait maintenant est de suivre ce qu’il produit dans le workspace, pas de grepper un journal de session. Le quick-start Harness Primitives for Long-Running Claude Agents d’Anthropic fournit deux hooks pour cela : watch -n 5 'git log --oneline -8' montre les derniers commits réalisés par l’agent, et watch -n 5 'find screenshots -name "*.png" | tail -5' montre les dernières captures d’écran qu’il a prises. Deux panneaux de terminal rafraîchis toutes les cinq secondes suffisent pour voir si une exécution progresse réellement ou tourne à vide.
Stack éphémère par worktree (lecture par l’agent lui-même, pendant l’exécution)
Selon le billet d’OpenAI sur les harnesses : « Logs, metrics, and traces are exposed to Codex via a local observability stack that's ephemeral for any given worktree. » Chaque worktree d’agent reçoit son propre Loki + Prometheus + Tempo courte durée, scopeé à cette exécution seule. L’agent l’interroge pendant qu’il travaille. C’est ce qui permet à un prompt comme « no span in these four user journeys exceeds two seconds » de devenir quelque chose que l’agent peut vérifier directement, au lieu d’une simple supposition.
(L’évaluateur en contexte frais du tableau des modes de défaillance lit ces artéfacts pour décider « done ». Il relève de l’évaluation, pas de l’observabilité ; voir § cycle de vie d’une exécution saine. Il dépend de toutes les surfaces ci-dessus.)
Une stack d’observabilité self-hosted minimale
Pour quelque chose comme market-analyst-agent :
- OpenTelemetry Collector avec le processeur GenAI et un filtre d’attributs sur
gen_ai.*. - Tempo (ou Jaeger) pour les traces, indexées par
gen_ai.conversation.id/thread_id. - Loki pour les entrées de journal d’événements structuré.
- Prometheus pour
gen_ai.client.token.usage,gen_ai.client.operation.duration,gen_ai.server.time_to_first_token(voir les conventions métriques GenAI). - Grafana avec des dashboards indexés sur
gen_ai.agent.nameetgen_ai.request.model.
Alternatives hébergées (en choisir une, pas trois) :
- LangSmith : intégration native LangGraph ; aussi la cible de déploiement de Deep Agents Deploy.
- Braintrust : le meilleur choix si la priorité est donnée aux suites de régression eval-first.
- Arize Phoenix : OSS, natif OTLP, s’associe à l’instrumentation OpenInference.
- Le dashboard de tracing d’OpenAI : automatique lorsque vous utilisez le OpenAI Agents SDK ou son intégration Temporal.
- Le tracing Claude d’Anthropic : pour les sessions exécutées dans Managed Agents.
Instrumenter le nœud LangGraph
# 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", "claude-sonnet-4-5")
span.set_attribute("gen_ai.response.model", "claude-sonnet-4-5")
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)
Noms d’attributs repris verbatim du registre des conventions sémantiques OpenTelemetry GenAI.
Trois requêtes dont vous avez réellement besoin
# Loki: token usage per agent over 1h
sum by (gen_ai_agent_name) (
rate({service_name="market-analyst-agent"} | json | unwrap gen_ai_usage_output_tokens [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 }
Le pattern debug bundle
Lorsqu’une exécution échoue, le worker doit déposer /workspaces/${THREAD_ID}/_debug/ contenant les artéfacts que vous demanderiez dans un postmortem :
session.jsonl: dump complet du journal d’événements depuis le PostgresSaver (checkpointer.list({"thread_id": ...})).last_state.json:StateSnapshot.valuesdu dernier super-step réussi.trace.json: spans exportés en OTLP pour l’exécution.tool_calls.csv:(ts, tool, input_hash, latency_ms, status, error).workspace.tar.zst: le répertoire workspace plusgit diffpar rapport au commit d’initialisation.screenshots/*.png: ce que l’agent a vu.PROGRESS.md,feature-list.json, et tout autre fichier de progression rédigé par l’agent.env.txt: tags d’image, version du modèle, commit SHA du harness.
Ce bundle est ce dont un humain (ou un autre agent) a besoin pour comprendre ce qui s’est passé. Sans lui, chaque exécution ratée n’est qu’une supposition. « L’agent s’est bloqué » est vague. Un rapport d’échec utile ressemble plutôt à ceci : la session s_123 a dépensé 71 pour cent de ses tokens dans une boucle de retry à trois commandes après l’échec de npm install.
Choisir la bonne forme : guide de décision
L’essentiel de la comparaison ci-dessus se ramène à une poignée de décisions.
Commencer par la durée d’exécution
Utilisez la durée d’exécution comme premier filtre :
- Moins de 30 secondes, idempotent : SDK dans le cycle de vie de la requête d’un serveur d’application.
- 30 s à 60 min, pas de reprise après crash requise : queue + worker + base de checkpoints.
- 60 min à 24 h : même queue + worker, ou un Cloud Run Job pour du travail one-shot. Utilisez un moteur de workflow durable si vous avez aussi besoin de versioning et de replay.
- Plus de 24 h, doit survivre aux déploiements : moteur de workflow durable (style Temporal). Cloud Run Jobs peut tenir des traitements longs jusqu’à sa limite de tâche, mais n’offre pas de sémantique de replay.
- Boucles d’entraînement RL sur plusieurs jours : K8s Job + volume + Temporal.
Une fois la durée d’exécution décidée, le reste relève du choix de plateforme.
Adéquation plateforme selon le cas d’usage
La matrice est dense volontairement : onze formes pour de nombreux types de charge en une seule vue. Deux patterns structurent presque toutes ses lectures.
Deep Agents Deploy est la seule colonne verte sur toutes les lignes. Cela signifie que c’est la seule forme de la liste qui couvre tous les types de charge suivis par la matrice : exécutions courtes, exécutions de plusieurs heures, agents de code, agents de recherche, jobs planifiés. Cette couverture est son argument principal. Le compromis est la maturité. Le harness a été publié récemment, et il a moins de recul en production que des alternatives plus anciennes comme une stack queue + worker + Postgres que les équipes font tourner depuis des années. Si la contrainte la plus importante pour vous est « couvre tous les types de charge sans replatforming », acceptez cette maturité plus faible et choisissez Deep Agents Deploy. Sinon, préférez la forme que vous exploitez déjà.
Anthropic Managed Agents correspond soit parfaitement à votre charge, soit pas du tout. Le produit a trois contraintes dures : hosted-only, Claude-only, et moins de 24 heures par session. Si votre charge respecte les trois, par exemple un agent de code interne qui tourne par salves de 2 à 6 heures et que vous préférez ne pas opérer vous-même un harness, Managed Agents est un bon choix et retire une grande partie du travail plateforme à votre équipe. Si l’une des contraintes casse parce que vous avez besoin d’un modèle non-Claude, de conformité self-hosted, ou d’exécutions de 48 heures, Managed Agents ne convient pas. Aucune configuration n’y changera quoi que ce soit.
La tarification vaut la peine d’être modélisée avant de vous engager, pas après. La ligne session-hour est de 0,08 $/heure en plus des coûts standards par token. Si une seule session tournait en continu, cela représente environ 58 $/mois par session. À 100 sessions en continu, cela fait environ 5 800 $/mois hors tokens. Multipliez 0,08 $ par vos heures attendues de sessions concurrentes, ajoutez cela à votre facture tokens, puis comparez avec le coût d’une stack queue + worker sur votre propre infra. Faites-le avant de vous engager, car migrer hors de Managed Agents plus tard est un replatforming, pas un changement de configuration.
Harness hébergé vs harness possédé
La distinction ici est opérationnelle, pas liée à qui a écrit le code du harness. Hosted signifie que le fournisseur exécute la boucle de harness dans son infrastructure et que vous appelez une API. Owned signifie que vous exécutez la boucle sur votre propre infrastructure, même si le code du harness vient d’un fournisseur.
LangChain apparaît des deux côtés de cette frontière, ce qui trompe souvent. Ils fournissent LangGraph, une bibliothèque sous licence MIT que vous self-hostez (owned), et Deep Agents Deploy, un produit managé qui exécute un harness Deep Agents sur un déploiement LangSmith dans son mode cloud par défaut (hosted). Même entreprise, deux modèles opérationnels distincts. Vous choisissez le modèle, pas le fournisseur. (Deep Agents Deploy a aussi un mode self-hosted pour les équipes qui veulent l’ergonomie du harness sans la composante cloud ; ce mode tombe dans la catégorie owned.)
Choisissez un harness hébergé quand vous n’avez pas la capacité plateforme et que les contraintes fournisseur conviennent. Managed Agents signifie Claude-only. Deep Agents Deploy en mode cloud signifie LangSmith en production. En échange, le fournisseur prend en charge le caching et la compaction.
Un harness owned (LangGraph, Deep Agents Deploy en mode self-hosted, ou un harness custom au-dessus d’un SDK) est le bon choix quand vous avez des ingénieurs plateforme, quand vous devez itérer sur la forme du harness plus vite qu’un fournisseur ne publie de mise à jour, quand la conformité exige que la résidence des données reste sous votre contrôle, ou quand le routage multi-modèle entre fournisseurs est non négociable. Vous le payez en pages et en surface opérationnelle.
La plupart des équipes devraient commencer en hosted, mesurer ce qu’elles ont besoin de changer, et ne migrer vers owned que lorsque les contraintes du mode hosted commencent à faire mal.
Sandbox hébergé vs sandbox Docker / Fargate
Choisissez un sandbox hébergé quand le temps de création du sandbox compte (sub-200 ms), quand vous avez besoin de pause/reprise de session avec état mémoire, ou quand vous avez besoin de sémantiques de fork/branch. Choisissez Docker ou Fargate quand vous payez déjà ce compute, quand vous avez besoin d’un accès interne au VPC vers des sources de données sensibles, ou quand vous avez des contraintes strictes de résidence des données.
Stores d’état : Git, base de données et stockage objet côte à côte
Les agents longue durée utilisent généralement trois stores d’état en même temps, pas un seul, et chacun conserve un type d’état différent. Git stocke l’état du workspace : code, documents et fichiers de progression que l’agent modifie. Chaque commit donne au harness un point de reprise stable et donne à la session suivante un historique compact à inspecter. La base de checkpoints conserve l’état du graphe du harness : ce qui a été décidé, quels nœuds ont tourné, quels résultats sont revenus et ce qui doit tourner ensuite. C’est ce qui permet au worker suivant de reprendre au milieu d’une exécution. Le store d’artéfacts conserve les grosses sorties finales, comme des PDF, fichiers parquet et captures d’écran. Ils n’ont pas leur place ni dans git ni dans la base de checkpoints.
Quand utiliser git comme état
Utilisez git quand la charge a une forme code (modifications multi-fichiers, refactors, génération d’application) ou suffisamment documentaire pour que l’historique des fichiers compte. Le pattern est simple : créer une branche d’exécution, faire un commit d’initialisation, puis committer à des frontières significatives : après le setup, après chaque feature, après le passage des tests, après le nettoyage final. Stockez le SHA du dernier commit workspace à côté de la ligne de checkpoint. À la reprise, le worker suivant checkout la branche, lit git log --oneline -8, inspecte git status et le dernier diff, puis lit PROGRESS.md ou tout autre fichier de handoff écrit par la session précédente.
Git devient ainsi une surface de reprise pour l’artéfact en cours d’édition, pas un remplacement de la base de checkpoints. Git peut répondre à deux questions : qu’est-ce qui a changé, et quelle version a passé les tests. Il ne peut pas dire au harness quel nœud de graphe doit tourner ensuite, quel appel outil attend une approbation, ou quel retry a déjà consommé sa clé d’idempotence. Le harness d’Anthropic utilise des commits d’initialisation plus des commits par feature comme source de vérité pour la reprise du workspace ; le modèle lit git log --oneline -8 pour récupérer l’état. Ignorez git si le produit du travail est une simple réponse conversationnelle. Le coût de la mécanique ne vaut pas le coup.
Quand utiliser le checkpointing en base
Utilisez un checkpointing de type PostgresSaver quand l’agent a une structure en graphe avec plusieurs nœuds dont l’état intermédiaire compte (planner → researcher → writer → verifier). Le dépôt de référence l’utilise précisément pour cette raison. Ne mettez pas des artéfacts workspace à l’échelle du téraoctet dans le checkpoint ; ils vont dans du stockage objet.
Quand utiliser un store d’artéfacts (S3 / GCS)
Utilisez le stockage objet dans trois situations. Premièrement, la sortie dépasse quelques centaines de Ko. Les bases de checkpoints ne sont pas conçues pour stocker de gros blobs, et essayer de les y garder rend pénibles à la fois la base et le format de checkpoint. Deuxièmement, des consommateurs aval comme des outils BI, des clients ou d’autres services ont besoin d’artéfacts adressables par URL qu’ils peuvent récupérer eux-mêmes sans passer par l’agent. Troisièmement, la fenêtre de rétention de l’état d’exécution et celle du livrable divergent. Vous pouvez supprimer le journal de session au bout de 30 jours tout en conservant le rapport final pendant des années. Structurez les clés par (thread_id, checkpoint_id, artifact_name) afin de pouvoir toujours reconstruire quelle exécution a produit quel artéfact.
Quand ajouter des gates d’approbation humaine
Ajoutez des gates quand l’appel outil est destructif et irréversible (écritures BD, mouvement d’argent, envoi de communications externes), quand l’appel outil sort du blast radius de l’agent (déploiements en production, publications visibles par des clients), ou quand les régulateurs exigent une revue. Le interrupt() de LangGraph et le middleware d’approbation de Deep Agents supportent tous deux nativement ces gates. La Partie 4 couvrait pourquoi ces gates relèvent des permissions, pas du prompt.
Une checklist pratique pour la production
Avant de mettre en production un agent longue durée, répondez à ces questions en termes d’infrastructure concrets.
- Quel store possède les événements de session et les checkpoints ?
- Que se passe-t-il si le worker meurt au milieu d’un appel outil ?
- Une exécution peut-elle corrompre le workspace d’une autre ?
- Quelles actions nécessitent une approbation ?
- Le modèle ou le sandbox peut-il lire des credentials bruts ?
- Quels appels outils peuvent être rejoués sans risque ?
- Où le plafond de coût par exécution est-il appliqué ?
- Quel contrôle en contexte frais décide « done » ?
- Où vivent les sorties finales une fois le sandbox détruit ?
- Pouvons-nous expliquer demain une exécution échouée sans la relancer ?
Si la réponse à l’une de ces questions est « le prompt dit à l’agent d’être prudent », le système n’est pas encore déployé. C’est toujours une démo.
Points clés à retenir
- Les agents longue durée ont besoin d’un runtime, pas seulement d’un plus grand timeout HTTP. Le runtime conserve la session, le workspace, les résultats d’outils, les checkpoints, les traces, les budgets, les approbations et les credentials en dehors de la mémoire du modèle.
- Les composants centraux sont session, harness, sandbox, checkpoint et trace. Les contrôles de policy et le courtage de secrets les traversent tous.
- La première question de déploiement est la durée d’exécution. Un helper de 20 secondes peut vivre dans un serveur d’application. Une exécution de coding ou de recherche de six heures a besoin d’une queue, d’un worker, d’un état durable et d’une stratégie sandbox.
- Queue + worker + base de checkpoints est le choix pratique par défaut quand vous voulez posséder le runtime. Les harnesses hébergés comme Anthropic Managed Agents ou Deep Agents Deploy sont meilleurs quand leurs contraintes fournisseur conviennent et que vous ne voulez pas opérer la boucle vous-même.
- Les outils à effets de bord ont besoin de clés d’idempotence. Dans les queues et moteurs de workflow, les retries sont normaux. Sans déduplication, un retry peut envoyer le même email, créer la même PR, ou facturer deux fois le même client.
- L’observabilité doit survivre au worker. Pour une exécution de six heures en échec, les artéfacts utiles sont le journal d’événements, le dernier checkpoint, la trace, la timeline des appels outils, le diff du workspace, les captures d’écran et les métadonnées d’environnement.
- Les hypothèses runtime vieillissent à mesure que les modèles changent. Re-testez les resets de contexte, les patterns d’évaluateur, les surfaces outils et les règles de budget lorsque vous changez de modèle ou de harness.
- Les secrets doivent rester hors du harness et hors du contexte du modèle. L’agent reçoit des capacités d’outil, pas des credentials bruts.
Références
Retours d’expérience d’ingénierie
- OpenAI, Harness engineering: leveraging Codex in an agent-first world.
- Anthropic Engineering, Effective harnesses for long-running agents.
- Anthropic Engineering, Harness design for long-running application development.
- Anthropic Engineering, Scaling Managed Agents: Decoupling the brain from the hands, 8 avril 2026.
- Cognition AI, Rebuilding Devin for Claude Sonnet 4.5: Lessons and Challenges.
- Vercel, We removed 80% of our agent's tools.
- Addy Osmani, Long-running Agents.
LangGraph et Deep Agents
- Documentation LangGraph, Persistence.
- Référence LangGraph, Checkpoints.
langgraph-checkpoint-postgressur PyPI.- Documentation LangChain, Deep Agents overview.
- Blog LangChain, The runtime behind production Deep Agents.
OpenAI Agents SDK
- OpenAI Agents SDK, Sessions.
- OpenAI Agents SDK, Sandbox concepts.
Temporal
- Blog Temporal, Introducing Temporal and agentic sandboxes: the OpenAI Agents SDK.
- Blog Temporal, Production-ready agents with the OpenAI Agents SDK + Temporal.
- README du contrib Temporal × OpenAI Agents SDK (
temporalio/sdk-python).
Plateforme Anthropic
- Anthropic, Claude platform pricing : tarifs session-hour de Managed Agents.
anthropics/cwc-long-running-agents: exercice take-home Code with Claude 2026 avec sous-agent évaluateur et patterns de fichiers de progression.
Fournisseurs de sandbox
- ZenML, E2B vs Daytona: sandbox comparison for platform engineers.
- Robert Mill, E2B vs Fly Machines (Medium, 2025) : benchmark cold start face à face (80 ms même région, 410 ms p50 inter-régions).
- Documentation Daytona, Sandboxes.
- Changelog Daytona, Sandbox fork and snapshot endpoints.
- Documentation Modal, Sandboxes.
- Documentation Modal, Cold start guide.
- Runloop sur AWS Marketplace.
- Tarification et limites Vercel Sandbox.
Timeouts et quotas des plateformes cloud
- Google Cloud, Configure request timeout for services.
- Google Cloud, Using WebSockets.
- Google Cloud, Set task timeout for jobs.
- AWS, Configure Lambda function timeout.
- AWS, Lambda quotas.
- AWS, Fargate throttling quotas.
- AWS, ECS service quotas and API throttling limits.
Observabilité
- OpenTelemetry, Semantic conventions for generative AI systems.
- OpenTelemetry, Gen AI attributes registry.
- OpenTelemetry, Semantic conventions for GenAI agent and framework spans.
- OpenTelemetry, Semantic conventions for generative AI metrics.
Série
- Partie 1 : AI Agent Reasoning Loops in 2026 : ReAct, ReWOO et Plan-and-Execute.
- Partie 2 : AI Agent Memory Architecture in 2026 : checkpoints, vector stores et mémoire documentaire.
- Partie 3 : AI Agent Tool Use in 2026 : MCP, CLI, Skills, exécution de code et ACI.
- Partie 4 : AI Agent Security in 2026 : guardrails, permissions, sandboxes, HITL et scoping MCP.
- Partie 5 : Runtime d’agents IA longue durée en 2026 (cet article)
Le code de Market Analyst Agent (worker LangGraph, checkpointer Postgres, mémoire Qdrant, sidecar MCP et topologie Docker Compose décrite ci-dessus) est sur GitHub.