Blog • AI / Agent
Course AI Coding Agent 2026 : que se disputent vraiment Claude Code, Codex, OpenCode et DeepSeek Agent ? L’architecture Agent Harness vue par le JSON Tool Calling
Les classements demandent encore qui score plus haut. Ouvrez un terminal : ce qui modifie vraiment les fichiers, lance les tests et parle à MCP, ce n’est pas cette réponse en langage naturel.
Claude Code, Codex, OpenCode et DeepSeek Agent ont l’air de vendre un Coding Agent qui fait le travail. L’écart réel, c’est l’Agent Harness : qui possède un saut JSON Tool Calling, des arguments aux effets de bord.
Cet article explique :
- Quelle couche un Coding Agent ajoute par rapport à la complétion
- Ce que l’Agent Harness possède, et ce que le modèle ne possède pas
- Pourquoi JSON Tool Calling est le fil commun des quatre
- Sept sauts dans un tool call : où chaque produit pose la porte
- Comment ouvrir arguments et schema en local dans JSONNote
Retenez ceci : La course 2026 n’est pas « qui complète la ligne suivante plus juste ». Le modèle émet un tool call ; les arguments sont du JSON. Le harness décide s’il peut parser, s’il faut demander, dans quel sandbox ça tourne, et comment le résultat revient. Claude Code ancre des hooks autour de chaque appel. Codex fait du sandbox et de l’approbation la frontière par défaut. OpenCode fait des modèles et des permissions une config interchangeable. DeepSeek Agent découpe tout le pipeline en plugins.
Ce qui se dispute vraiment, ce n’est pas la complétion
La complétion répond à « que mettre sur la ligne suivante ». Un Coding Agent répond à « comment finir cet objectif dans un vrai dépôt » : lire le contexte, choisir un outil, modifier le code, lancer une commande, lire le résultat, décider à nouveau.
Les quatre interfaces ressemblent à un chat. La boucle en dessous est presque la même :
User goal
→ Agent loop
→ LLM emits tool_call (JSON arguments)
→ Harness parses / validates / gates / executes
→ Tool result returns to context
→ Agent decides again
Le modèle raisonne et choisit « qui appeler ensuite ». Le harness décide quels outils le modèle voit, si les arguments comptent comme valides, si une action à haut risque exige un humain, ce que l’outil fait vraiment, comment la session est enregistrée, et ce qui compte comme terminé.
Les checklists de fonctionnalités vont se ressembler. Tout le monde a Skills, MCP, sous-agents et interrupteurs de permission. La différence, c’est où siège le contrôle. Pour le positionnement produit, voir Les AI Coding Agents ne se limitent plus à la complétion : que se disputent Codex, Claude Code, OpenCode et DeepSeek Harness ?. Pour le tour de la boucle, voir Comment fonctionnent les AI Coding Agents ?. Cet article ne découpe qu’un saut : ce que le harness fait après que le JSON Tool Calling a quitté le modèle.
Qu’est-ce qu’un Agent Harness
En 2026, la couche a un nom. Une anatomie du code source de onze Coding Agents de production l’appelle Harness Engineering : un Agent, c’est un modèle plus un harness — le runtime qui couple un LLM au monde réel par une boucle, des outils, du contexte, des contrôles de sécurité, de l’orchestration et des surfaces d’extension.
Une autre expérience de comparaison pose la question plus nettement : changer de harness fait-il résoudre plus de tâches au même modèle ? Les scores moyens restent souvent proches ; les tâches dépôt et les tâches concours peuvent partir en sens inverse ; coût et taux d’annulation changent. La leçon n’est pas « le harness natif gagne toujours ». C’est « vous achetez un chemin d’achèvement, pas un point au classement ».
Donc les quatre ne se disputent pas qui a livré un bouton de plus. Ils se disputent qui organise le plus clairement le contrat d’outil, la frontière d’exécution et le veto humain.
| Couche | Possède | Ne possède pas |
|---|---|---|
| Modèle | Choisir un outil, remplir les arguments JSON, lire le résultat, décider à nouveau | Écrire le disque, lancer le shell, joindre le réseau, autoriser |
| Contrat JSON | À quoi ressemblent arguments et résultats | Si cet appel doit avoir lieu |
| Agent Harness | Outils visibles, validation, approbation, sandbox, réinjection, session | Inventer l’objectif métier à votre place |
Pour les couches de la pile, voir Pile technique Agent IA 2026 : comment combiner LLM, MCP, Function Calling et JSON Schema ?.
Le fil commun : JSON Tool Calling
Le Tool Calling (aussi appelé Function Calling) n’est pas un autre nom pour « le modèle sait écrire du code ». C’est un appel structuré : le modèle choisit un nom dans les outils que vous avez déclarés, puis génère du JSON qui doit coller au contrat de paramètres.
Sur une API compatible OpenAI, le champ parameters de la définition d’outil est lui-même du JSON Schema :
{
"type": "function",
"function": {
"name": "run_tests",
"description": "Run the project test suite and return a structured summary.",
"parameters": {
"type": "object",
"additionalProperties": false,
"properties": {
"suite": { "type": "string", "enum": ["unit", "integration", "e2e"] },
"path": { "type": "string", "minLength": 1 }
},
"required": ["suite"]
}
}
}
Quand le modèle répond, arguments est souvent une chaîne, pas un objet déjà parsé :
{
"id": "call_7f21",
"type": "function",
"function": {
"name": "run_tests",
"arguments": "{\"suite\":\"e2e\",\"path\":\"tests/checkout.spec.ts\"}"
}
}
Donc le harness fait au moins deux choses : parser la chaîne en JSON valide, puis vérifier champs, types et enums contre le schema que vous avez déclaré. Guillemets manquants, virgules en trop et clés non déclarées se jouent sur ce saut.
MCP branche le même fil sur un Server externe : inputSchema / outputSchema restent du JSON Schema, et tools/call reste un appel structuré. Plus de Servers, plus de descriptions et de schemas dans le contexte du modèle, plus de portes à tenir pour le harness. Pour le partage de sécurité, voir Vulnérabilités de sécurité MCP expliquées.
Le champ de bataille : sept sauts dans un tool call
Étalez les quatre produits : les noms de fonctionnalités diffèrent. Le tuyau a la même forme. La course, c’est qui tranche chaque saut :
-
1
Présenter
Quels outils et quelle tranche de schema entrent dans cette requête. Un outil invisible, le modèle ne peut pas l’appeler.
-
2
Émettre
Le modèle choisit un nom et génère une chaîne arguments. Ce saut ne dit que l’intention d’appeler.
-
3
Parser
La chaîne devient un objet. Un JSON invalide doit échouer avant la couche d’exécution.
-
4
Valider
Vérifier champs requis, types, enums et additionalProperties contre JSON Schema.
-
5
Porte
allow / deny / ask. Une forme valide n’est pas une autorisation.
-
6
Exécuter
Exécuter pour de vrai dans un sandbox, un espace de travail, ou les privilèges complets de l’hôte. Les effets de bord commencent ici.
-
7
Réinjecter
Le résultat devient du texte ou du JSON, s’enregistre dans la session, et nourrit le tour suivant. Les échecs ont aussi besoin d’une structure — pas seulement « ça a planté ».
Les quatre parcourent ces sept sauts. La différence : où atterrissent les hooks, à quel point le sandbox par défaut est serré, si le modèle se change, et si le tuyau lui-même se remplace.
Claude Code : des hooks avant et après l’appel
Claude Code renforce l’agent principal : Skills, MCP, sous-agents et CLAUDE.md s’enroulent autour du même Claude Agent. Ce qui mord vraiment le JSON Tool Calling, c’est le hook déterministe autour de chaque appel.
Dans le cycle de vie officiel, chaque appel d’outil de la boucle passe par PreToolUse et PostToolUse. On peut aussi intercepter l’invite de permission (PermissionRequest) ou décider après un échec si un retry est permis (PermissionDenied / PostToolUseFailure).
Le hook lit du JSON d’événement, pas de la prose. Il peut réécrire les entrées, refuser l’appel, demander confirmation, ou après succès ajouter des logs, lancer un formateur, et réinjecter du contexte. Il ne peut pas défaire un effet de bord déjà produit — PostToolUse arrive trop tard.
Les règles de permission se résolvent deny → ask → allow, et deny gagne. Un hook qui renvoie allow saute seulement l’invite interactive ; il ne passe pas outre une liste deny gérée par l’entreprise. Même avec bypassPermissions, un PreToolUse qui renvoie deny bloque encore l’appel.
Le compromis d’ingénierie est net : un agent probabiliste plus une porte déterministe. Lancer les tests après une modification, bloquer les commandes dangereuses, exiger une approbation sur les chemins protégés — le modèle ne doit pas « s’en souvenir » à chaque fois.
Convient si les workflows sont stables et que vous voulez ancrer Skills, sous-agents et hooks sur la boucle principale, et empaqueter l’expérience en unités réutilisables.
Codex : sandbox et approbation avant l’exécution
Codex (y compris Codex CLI) pousse la question à la couche d’exécution. Dès qu’un agent modifie des fichiers, lance le shell, installe des dépendances, et touche le réseau et les identifiants, il doit répondre à deux choses différentes à la fois : la frontière de capacité, et si cette action est permise maintenant.
| Mécanisme | Question tranchée | Interrupteurs typiques |
|---|---|---|
| Sandbox | Que peut-il techniquement toucher ou changer ? | read-only / workspace-write / danger-full-access |
| Approval | Cette action est-elle autorisée maintenant ? | untrusted / on-request / never |
Le récit par défaut, c’est le moindre privilège : d’abord serrer l’environnement, l’ouvrir au besoin. Un répertoire untrusted démarre en lecture seule. Une fois l’espace de travail de confiance, le preset courant est workspace-write plus on-request — lectures, écritures et commandes courantes dans l’espace de travail tournent toutes seules ; sortir de l’espace de travail ou toucher le réseau exige une approbation. Le réseau est fermé par défaut, à ouvrir explicitement.
Les versions récentes décrivent le système de fichiers et le réseau avec un permission profile. Ne pas le mélanger avec l’ancien sandbox_mode. Les noms changent. La découpe non : un cadran « ce qu’il peut toucher », l’autre « a-t-il le droit maintenant ».
Convient si les effets de bord sont lourds, que la trace d’exécution doit être auditable, et que l’isolation plus l’approbation sont des citoyens de première classe. Dépôt open source : openai/codex.
OpenCode : modèles interchangeables, permissions en config
La différence d’OpenCode n’est pas « encore une syntaxe Skills ». La posture par défaut : les modèles sont interchangeables. Licence MIT, terminal d’abord, plusieurs fournisseurs et modèles locaux. La flexibilité vit surtout dans la config — provider, model, permission, agent — pas dans l’éclatement du noyau harness en bus de plugins.
Les permissions sont passées du booléen précoce tools à permission : chaque action est allow, ask ou deny. On écrit des règles par nom d’outil, motif de commande, ou sortie de l’espace de travail (external_directory). La dernière correspondance gagne. Un sous-agent peut être plus strict que l’agent principal — un rôle review qui deny edit d’emblée, par exemple.
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"git push *": "deny"
},
"edit": "allow",
"external_directory": "deny"
}
}
Il gagne en général sur : le multi-modèle par défaut, pas en extra vendeur ; une licence open source et une communauté ; « changer de modèle » comme opération de première classe. Le coût est clair : frontières d’exécution et profondeur de plugins ne sont pas automatiquement l’argument n°1. Vous achetez un harness à modèles interchangeables, pas le produit sandbox le plus lourd, ni un noyau de plateforme « Everything is a plugin ».
Convient si vous vous méfiez d’un seul fournisseur, ou qu’il faut changer de modèle — y compris des poids locaux — dans la même boucle.
DeepSeek Agent : le pipeline lui-même est un plugin
DeepSeek pousse la question d’un cran. Le produit en preview publique est DeepSeek Harness (dsh). Le contrat externe est l’interface Agent ; l’implémentation par défaut est un agent-loop remplaçable. Le slogan : Everything is a plugin — modèle, outils, Skills, session, sandbox, stockage, loop, scheduling et UI sont tous interchangeables.
Ce qui s’aligne sur Tool Calling, c’est le pipeline d’outils, pas une autre boîte de chat. Un ToolDefinition dans le registre porte des paramètres et sorties typés. Le modèle ne voit que name, description et parameters. execute, timeouts, drapeaux de concurrence et présentateurs UI ne doivent pas fuiter dans la requête.
Chaque appel emprunte une cascade fixe :
tools/pre-execute → allow / deny / ask
monotonic guards → 只收紧,不能再放行
tools/execute → 真正派发(可包超时 / 重试)
tools/post-execute → 检查或替换结果
finalizeContent → 定义自己的收尾
tools/result → 冻结后的权威结果
Il peut passer par Function Calling natif, ou PTC (le run_code réservé comme transport ; les sous-appels restent dans le même pipeline). La concurrence se classe par appel : les exclusifs font barrière, les parallélisables entrent dans un pool borné ; les événements s’écrivent toujours dans l’ordre du modèle.
Convient si vous voulez le runtime lui-même comme plateforme, pas seulement un assistant plus fort. Pour la couche modèle, voir Qu’est-ce que DeepSeek V4-Pro ?.
Le même JSON, quatre portes
Le même JSON de tool call heurte une porte différente chez chaque produit :
| Ce saut | Claude Code | Codex | OpenCode | DeepSeek Agent |
|---|---|---|---|---|
| Surface d’outils montrée au modèle | Outils intégrés + Skills + MCP ; les schemas peuvent charger à la demande | Boîte à outils de session + notes projet (AGENTS.md) | Intégrés + MCP + recoupe par agent | Un registre à périmètre projette ToolSchema via une liste d’autorisation |
| Avant que arguments atteigne l’exécution | Les hooks peuvent lire le JSON d’événement tool complet | D’abord la capacité sandbox, puis la politique d’approbation | Les règles permission filtrent nom d’outil et entrée | Après le parse, la cascade pre-execute et les gardes monotones |
| Comment un humain oppose son veto | PermissionRequest ; deny bat un allow de hook | on-request / untrusted ; peut passer à un relecteur | ask ; un sous-agent peut être plus strict | Une décision ask est un résultat de première classe dans le pipeline |
| Où se produisent les effets de bord | Outils locaux + post-hooks | Sandbox OS ; pas de réseau par défaut, espace de travail inscriptible | Exécution locale, snapshots git, undo | Un plugin sandbox remplaçable |
| Comment les résultats reviennent | PostToolUse / hooks d’échec ajoutent du contexte | Événements JSONL, faciles à auditer en CI | Les diagnostics LSP peuvent réentrer dans la boucle | tools/result se fige, puis le journal de session |
La dernière ligne n’est pas un classement. Vous achetez un agent principal plus utilisable, un environnement d’exécution plus contrôlable, une couche de config à modèles interchangeables, ou un runtime composable.
Pour la vue produit de la carte du contrôle, voir les quatre centres d’architecture. Pour qui porte la sécurité une fois que MCP élargit la surface d’outils, voir Quand les AI Agents commencent à attaquer Internet : comment JSON devient une frontière de sécurité.
Pourquoi encore regarder JSON Schema
Aussi forts soient les quatre harness, des paramètres sales dans la couche d’exécution deviennent des incidents. Les arguments remplis par le modèle sont une contrainte souple : arguments peut être du JSON cassé, manquer des champs, ou ajouter des clés non déclarées.
Valide pour le schema n’est pas autorisé. Les deux extraits ci-dessous passent un schema lâche qui n’exige qu’un champ sql. Seul le côté serré range l’opération en enum et écrit l’identifiant en pattern :
{
"loose": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
},
"tight": {
"type": "object",
"additionalProperties": false,
"properties": {
"op": { "type": "string", "enum": ["get_user_by_id"] },
"user_id": { "type": "string", "pattern": "^[a-z0-9-]{8,36}$" }
},
"required": ["op", "user_id"]
}
}
Comment écrire le contrat, et en quoi JSON Mode diffère de Strict Schema, voir Pourquoi l’IA a besoin de JSON Schema ? Structured Output, Function Calling et JSON Schema, et Pourquoi les AI Agents ont besoin de JSON Schema ? De Tool Calling à Structured Output.
Découper un tool call dans JSONNote
Le matériau de debug le plus utile est souvent une tranche de JSON : la définition d’outil, les arguments du modèle, les événements de hooks, la raison du deny. Vous pouvez tout ouvrir en local dans le navigateur. Pas besoin d’envoyer le dépôt.
-
1
D’abord voir si arguments est du JSON valide
Dépliez les échappements de la chaîne et déposez-la dans Formatage JSON. Virgules manquantes, virgules finales et guillemets simples explosent ici.
-
2
Valider contre le schema déclaré
Mettez les parameters / inputSchema de l’outil et l’objet parsé dans JSON Schema. Voyez si un champ manque, si le type est faux, ou si une clé non déclarée a été ajoutée.
-
3
Différencier « ce que vous avez approuvé » et « ce que c’est maintenant »
Mettez la liste d’outils de la semaine dernière et celle d’aujourd’hui dans JSON Diff et cherchez surtout les changements silencieux de description et de schema.
-
4
Il faut le montrer à un collègue ? Utilisez le partage Hash
Les données restent dans le fragment d’URL et ne touchent aucun serveur. Voir Partager du JSON via URL Hash.
FAQ
Que se disputent vraiment Claude Code, Codex, OpenCode et DeepSeek Agent ?
Pas une checklist de fonctionnalités, ni qui complète la ligne suivante plus juste. L’enjeu, c’est l’Agent Harness : qui possède un saut JSON Tool Calling, du parse et du contrat jusqu’à l’approbation, l’exécution sandboxée et la réinjection du résultat.
Qui compte le plus, l’Agent Harness ou le modèle ?
Le modèle raisonne et choisit l’étape suivante. Le harness décide quels outils sont visibles, si les arguments sont valides, si une action à haut risque exige un humain, et où se produisent les effets de bord. Changer de harness ne garantit pas un score moyen plus haut, mais le chemin d’achèvement, le coût et le taux d’annulation changent. Vous choisissez le contrôle, pas un score.
Lequel des quatre choisir ?
Il n’y a pas de champion unique. Hooks déterministes et permissions sur l’agent principal → Claude Code. Sandbox et approbations comme frontière d’exécution par défaut → Codex. Changer de modèle et éviter le verrouillage → OpenCode. Loop, pipeline d’outils et sandbox en plugins remplaçables → DeepSeek Agent (DeepSeek Harness).
Le JSON Tool Calling inclut-il une autorisation ?
Non. Le modèle qui choisit un nom d’outil et remplit arguments ne dit que son intention d’appeler. Bloquer, dans quel sandbox, et renvoyer le résultat au modèle : c’est l’affaire du harness. Sans outil, si la permission est refusée ou si la validation JSON échoue, rien ne se passe sur le disque.
Pourquoi encore valider JSON Schema soi-même ?
Les arguments remplis par le modèle sont une contrainte souple. arguments est souvent une chaîne : champs manquants, mauvais type, ou clés non déclarées. Valide pour le schema n’est pas autorisé. La production a toujours besoin de parse plus validation, puis permissions et sandbox. Aussi forts soient les quatre harness, des paramètres sales dans la couche d’exécution deviennent des incidents.
Résumé
La course des Coding Agents 2026 a l’air d’une guerre de modèles. Dans un dépôt, c’est une guerre de harness.
Le modèle émet du JSON. Le harness décide si ce JSON peut devenir un effet de bord. Les quatre se disputent le contrôle du même tuyau : Claude Code ancre les hooks, Codex serre la frontière d’exécution, OpenCode déverrouille le modèle, DeepSeek Agent fait du runtime lui-même des plugins.
Les fonctionnalités vont continuer à se ressembler. Ce qu’il faut vraiment regarder : qui tranche après qu’un tool call a quitté le modèle.
Ensuite : coller les arguments d’un tool call dans JSONNote