Guide complet du harness engineering : agents IA façon Claude Code
Apprenez le harness engineering avec Claude Code, policy JSON, code Node.js exécutable et workflows réels.
L’idée « écrire un bon prompt et laisser l’IA faire le reste » ne suffit plus pour construire des agents fiables. Le sujet important est désormais le harness engineering : concevoir l’échafaudage qui entoure le modèle. Si vous connaissez le test harness en test logiciel, imaginez l’équivalent pour un agent : outils, contexte, permissions, vérification et boucle de contrôle autour du LLM.
Claude Code est un excellent exemple, car ce n’est pas seulement une interface de chat. Il combine outils de fichiers, commandes shell, CLAUDE.md, hooks, modes de permission, subagents et mémoire. Ce guide explique pourquoi le sujet devient central, comment créer un mini harness Node.js avec un policy JSON, et comment l’appliquer à content automation, code review, SaaS integration, cloud operations et security boundaries.
Pourquoi Le Sujet Monte
Un LLM choisit bien la prochaine action, mais le travail réel exige plus que cela : observer l’environnement, sélectionner le contexte, appeler des outils, gérer les erreurs, limiter les actions dangereuses et prouver que le résultat fonctionne. Tout cela forme le harness.
La documentation du Claude Agent SDK explique qu’il peut charger des éléments façon Claude Code comme project instructions, skills, hooks et permissions. La documentation permissions détaille allow rules, deny rules, permission modes et callbacks. La documentation prompt caching montre comment réutiliser un long contexte statique. Ce sont des choix d’architecture autour du modèle, pas de simples astuces de prompt.
Le OODA loop clarifie les rôles :
| Phase | Ce qui se passe | Responsable |
|---|---|---|
| Observe | lire fichiers, logs, URLs, tickets, état API | Harness |
| Orient | organiser et compresser le contexte | Harness |
| Decide | choisir la prochaine action | LLM |
| Act | exécuter un tool, écrire un fichier, appeler une API | Harness |
Trois phases sur quatre dépendent surtout du harness. Un modèle puissant avec un harness faible reste un agent fragile.
Ce Que Contient Un Harness
Avant le premier appel au modèle, un harness répond à quatre questions : que l’agent peut-il lire, quel artefact doit-il produire, quels checks prouvent la réussite, et quelles actions sont automatiques, ask-first ou interdites ?
Dans un workflow de blog, il ne suffit pas de dire « écris un article ». Le harness lit les slugs existants, choisit un sujet non dupliqué, écrit du MDX, valide le frontmatter, contrôle les code fences, ajoute liens officiels et internes, place des CTAs vers /products/ et /training/, lance le build et vérifie l’URL publique.
| Couche | Exemple | pitfall |
|---|---|---|
| Contexte | règles projet, style, anciens échecs | hypothèses périmées qui persistent |
| Outils | read, grep, write, test, API call | trop d’outils brouillent le choix |
| Politique | allow, ask, deny, sandbox | action destructive sans supervision |
| Vérification | test, diff, screenshot, public URL | sortie plausible mais cassée |
| Mémoire | préférences réutilisables | note temporaire devenue règle permanente |
Schéma Conceptuel
Le harness est la couche de contrôle avant et après le modèle. Le prompt compte, mais policy, context, tools, permission gate et verification loop déterminent si le workflow est fiable.
flowchart LR
A["Goal"] --> B["Harness policy"]
B --> C["Context"]
B --> D["Tools"]
B --> E["Permissions"]
C --> F["LLM decision"]
D --> F
E --> G["Safe action"]
F --> G
G --> H["Verification"]
H --> I["Artifact"]
H --> B
Mini Harness Node.js Exécutable
Cet exemple minimal contient un modèle, deux outils, une policy, une boucle, une limite de chemin et des erreurs lisibles. Définissez ANTHROPIC_API_KEY avant de l’exécuter.
mkdir harness-demo
cd harness-demo
npm init -y
npm install @anthropic-ai/sdk
node -e "const fs=require('node:fs');fs.mkdirSync('sandbox',{recursive:true});fs.writeFileSync('sandbox/README.md','# Demo\nShip a safer agent workflow.\nKeep writes inside sandbox.\n');"
Enregistrez policy.json.
{
"workspace": "./sandbox",
"maxSteps": 6,
"tools": {
"read_file": {
"allow": true,
"risk": "Read UTF-8 text only inside workspace"
},
"write_file": {
"allow": true,
"risk": "Write UTF-8 text only inside workspace"
}
}
}
Enregistrez mini-harness.mjs.
import Anthropic from "@anthropic-ai/sdk";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";
const client = new Anthropic();
const policy = JSON.parse(await readFile(new URL("./policy.json", import.meta.url), "utf8"));
const model = process.env.ANTHROPIC_MODEL || "claude-sonnet-4-6";
const workspace = path.resolve(policy.workspace);
function safePath(requestedPath) {
const resolved = path.resolve(workspace, requestedPath);
const inside = resolved === workspace || resolved.startsWith(workspace + path.sep);
if (!inside) {
throw new Error(`Path escapes workspace: ${requestedPath}. Use a path under ${policy.workspace}.`);
}
return resolved;
}
function ensureAllowed(toolName) {
const rule = policy.tools?.[toolName];
if (!rule?.allow) {
throw new Error(`Tool '${toolName}' is not allowed by policy.json.`);
}
}
const tools = [
{
name: "read_file",
description: "Read a UTF-8 text file from the allowed workspace.",
input_schema: {
type: "object",
properties: { path: { type: "string" } },
required: ["path"],
additionalProperties: false
}
},
{
name: "write_file",
description: "Write a UTF-8 text file inside the allowed workspace.",
input_schema: {
type: "object",
properties: {
path: { type: "string" },
content: { type: "string" }
},
required: ["path", "content"],
additionalProperties: false
}
}
];
async function executeTool(name, input) {
ensureAllowed(name);
if (name === "read_file") {
return await readFile(safePath(input.path), "utf8");
}
if (name === "write_file") {
const target = safePath(input.path);
await mkdir(path.dirname(target), { recursive: true });
await writeFile(target, input.content, "utf8");
return `written ${input.path}`;
}
throw new Error(`Unknown tool: ${name}`);
}
async function run(goal) {
const messages = [{ role: "user", content: goal }];
for (let step = 0; step < policy.maxSteps; step++) {
const response = await client.messages.create({
model,
max_tokens: 1200,
tools,
system: "You are a careful file assistant. Use tools when needed. Keep writes under policy workspace.",
messages
});
messages.push({ role: "assistant", content: response.content });
const toolUses = response.content.filter((block) => block.type === "tool_use");
if (toolUses.length === 0) {
const text = response.content
.filter((block) => block.type === "text")
.map((block) => block.text)
.join("\n");
console.log(text);
return;
}
const results = [];
for (const toolUse of toolUses) {
try {
const output = await executeTool(toolUse.name, toolUse.input);
results.push({ type: "tool_result", tool_use_id: toolUse.id, content: String(output).slice(0, 8000) });
} catch (error) {
results.push({
type: "tool_result",
tool_use_id: toolUse.id,
is_error: true,
content: error instanceof Error ? error.message : String(error)
});
}
}
messages.push({ role: "user", content: results });
}
throw new Error(`Max steps reached: ${policy.maxSteps}`);
}
const goal = process.argv.slice(2).join(" ") || "Read README.md and write summary.md with three bullet points.";
await run(goal);
Lancez :
node mini-harness.mjs
Même petit, cet exemple montre le motif essentiel : schema d’outils, policy, sandbox, limite d’étapes, erreurs utiles et artefact vérifiable. Ajoutez grep, tests, approval UI, API SaaS et hooks pour aller vers un harness à la Claude Code.
Cinq Use Cases Concrets
1. content automation
Un prompt faible dit « écris un article ». Un bon harness lit les anciens posts, évite les doublons, écrit du MDX, valide frontmatter et code fences, ajoute liens officiels et internes, insère les CTAs /products/ et /training/, lance le build et vérifie l’URL publique. Le pitfall est de publier vite des traductions minces.
2. code review
Un review harness lit git diff, résultats de tests, fichiers modifiés et règles locales. Il répond findings-first : bugs, risk, régressions et tests manquants avant le résumé. Le risque est que le modèle décrive le patch sans trouver de défaut.
3. SaaS integration Avec Notion, HubSpot, Stripe ou CRM, séparez read-only lookup, dry-run mutation et approved write. On peut classifier des leads et préparer une mise à jour, mais l’écriture réelle doit demander validation. Le pitfall est d’écrire en production une note client ou une facturation erronée.
4. cloud operations Le cloud ne se résume pas à deploy. Le harness vérifie variables d’environnement, build, diff, target, rollback, health endpoint et public URL. Le risk est de corriger la dernière ligne du log sans traiter la cause racine.
5. security boundaries
Les security boundaries se conçoivent dès le début. Read peut être large, mais Write doit rester dans le workspace. Le shell doit être allow-listé. rm, force push, DB production, billing et secrets doivent être deny ou ask-first. Le harness empêche la confiance excessive.
Ce Que Claude Code Enseigne
D’abord, stratifier le contexte : règles stables dans CLAUDE.md, progression de session dans un plan, préférences durables dans memory.
Ensuite, confier le déterministe aux hooks. Format, lint, tests, link checks et screenshots doivent être des commandes. Claude interprète les erreurs et corrige.
Enfin, isoler le bruit. Logs longs, recherches larges, traductions multilingues et refactors lourds vont mieux dans des subagents ou étapes séparées.
Pitfalls Courants
Trop d’outils diminuent la précision. Commencez par 5 à 10 tools nettes.
Des erreurs illisibles empêchent l’auto-réparation. Remplacez Error: failed par un message indiquant ce qui manque et quoi tenter.
Ignorer prompt caching augmente coût et latence. Séparez contexte statique et dynamique.
Sans vérification, une sortie élégante peut casser en production. Articles : frontmatter et code fences. Code : tests. Cloud : health checks. SaaS : audit log.
Les permissions dérivent facilement. Révisez allow, ask et deny régulièrement.
Prochaine Étape
Pour commencer par la sécurité, lisez le guide des permissions Claude Code. Pour le contexte projet, continuez avec les bonnes pratiques CLAUDE.md. Pour déléguer les gros travaux, voyez les patterns de subagents Claude Code. Pour le coût, consultez l’optimisation des tokens Claude Code.
Gardez aussi le Claude Code Quick Reference Cheatsheet. Les templates et playbooks sont sur /products/. Si votre équipe doit cadrer permissions, review gates, vérification, publication et revenue workflow, partez de /training/.
Ce Que J’ai Vérifié
Dans le workflow ClaudeCodeLab, la valeur principale du harness est de rendre les échecs visibles. Un prompt peut produire un article ; un harness vérifie profondeur, code fences, frontmatter, liens, CTAs et public URL. On ne fait plus seulement confiance à la sortie : on sait quelle porte de contrôle l’a acceptée.
Résumé
Le harness engineering décide ce que le modèle peut voir, faire, quand il doit s’arrêter et comment le résultat est vérifié. Claude Code est un bon exemple parce que sa force vient autant du scaffold que du modèle. Lancez le mini harness ci-dessus, puis ajoutez une boundary et un check à votre propre use case.
Références
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Échelle de sécurité des permissions Claude Code
Passer du read-only aux éditions limitées, preuves et checks de déploiement sans perdre le contrôle.
Claude Code Small PR Proof Pack : rendre les petits changements reviewables
Un pack de preuve pour PR Claude Code : diff, vérifications, URL publique, CTA et rollback.
Gate de review avant commit avec Claude Code
Review avant commit avec Claude Code : diff, build, URL publique, liens Gumroad, CTA consultation, tests manquants et fichiers hors scope.