En bref
La fuite du code source de Claude Code a exposé une base de code TypeScript de 512 000 lignes le 31 mars 2026. L'architecture se résume à une boucle `while` qui appelle l'API Claude, distribue les appels d'outils et renvoie les résultats. Vous pouvez créer votre propre version avec Python, le SDK Anthropic et environ 200 lignes de code pour la boucle centrale. Ce guide détaille chaque composant et vous montre comment les recréer.
Introduction
Le 31 mars 2026, Anthropic a publié un fichier de carte source de 59,8 Mo dans la version 2.1.88 de son package npm @anthropic-ai/claude-code. Les cartes sources sont des artefacts de débogage qui permettent de reconstituer le code JavaScript minifié à partir de la source originale. Étant donné que l'outil de build d'Anthropic (le bundler de Bun) les génère par défaut, l'intégralité de la base de code TypeScript était récupérable.
En quelques heures, les développeurs avaient dupliqué le code sur des dizaines de dépôts GitHub. La communauté a rapidement disséqué chaque module, de la boucle de l'agent maître aux fonctionnalités cachées comme le « mode furtif » et l'injection d'outils factices.
Les réactions ont été mitigées. Certains ont critiqué les pratiques de sécurité d'Anthropic. D'autres ont été fascinés par l'architecture. Mais la réponse la plus productive est venue des développeurs qui ont demandé : « Puis-je construire cela moi-même ? »
La réponse est oui. Les modèles de base sont simples. Ce guide parcourt chaque couche architecturale, explique pourquoi Anthropic a fait les choix qu'il a faits et fournit du code fonctionnel que vous pouvez utiliser comme point de départ. Vous apprendrez également à tester les interactions API de votre agent personnalisé avec Apidog, ce qui rend le débogage des conversations API multi-tours beaucoup plus facile que les commandes curl brutes.
Ce que la fuite a révélé sur l'architecture de Claude Code
La base de code en un coup d'œil
Claude Code, dont le nom de code interne est « Tengu », s'étend sur environ 1 900 fichiers. L'organisation des modules se décompose en couches claires :
cli/ - Interface utilisateur en terminal (React + Ink)
tools/ - Plus de 40 implémentations d'outils
core/ - Invites système, permissions, constantes
assistant/ - Orchestration de l'agent
services/ - Appels API, compactage, OAuth, télémétrie
L'interface CLI elle-même est une application React rendue via Ink, un moteur de rendu React pour la sortie terminale. Elle utilise Yoga (un moteur flexbox CSS) pour la mise en page et les codes d'échappement ANSI pour le style. Chaque vue de conversation, zone de saisie, affichage d'appel d'outil et boîte de dialogue d'autorisation est un composant React.
C'est sur-conçu pour la plupart des projets DIY (Faites-le vous-même). Vous n'avez pas besoin d'une interface utilisateur terminale basée sur React pour construire un agent de codage fonctionnel. Une simple boucle REPL fonctionne très bien.
La boucle de l'agent maître
Si l'on retire l'interface utilisateur, la télémétrie et les indicateurs de fonctionnalités, le cœur de Claude Code est une boucle `while`. Anthropic l'appelle en interne « nO ». Voici ce qu'elle fait :
- Envoyer des messages à l'API Claude (invite système + définitions d'outils)
- Recevoir une réponse contenant du texte et/ou des blocs
tool_use - Exécuter chaque outil demandé via une carte de distribution nom-vers-gestionnaire
- Ajouter les résultats de l'outil à la liste des messages
- Si la réponse contient d'autres appels d'outils, revenir à l'étape 1
- Si la réponse est du texte simple sans appel d'outil, la retourner à l'utilisateur
Un « tour » est un aller-retour complet. Les tours continuent jusqu'à ce que Claude produise du texte sans invocation d'outil. C'est le modèle d'agent complet.
Voici une version Python minimale qui capture le cœur :
import anthropic
client = anthropic.Anthropic()
MODEL = "claude-sonnet-4-6"
def agent_loop(system_prompt: str, tools: list, messages: list) -> str:
"""La boucle centrale de l'agent - continue d'appeler jusqu'à ce qu'il n'y ait plus d'utilisation d'outils."""
while True:
response = client.messages.create(
model=MODEL,
max_tokens=16384,
system=system_prompt,
tools=tools,
messages=messages,
)
# Ajouter la réponse de l'assistant à la conversation
messages.append({"role": "assistant", "content": response.content})
# Si le modèle s'est arrêté sans demander d'outils, nous avons terminé
if response.stop_reason != "tool_use":
# Extraire le texte final
return "".join(
block.text for block in response.content
if hasattr(block, "text")
)
# Exécuter chaque appel d'outil et collecter les résultats
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
})
# Renvoyer les résultats sous forme de message utilisateur
messages.append({"role": "user", "content": tool_results})
C'est environ 30 lignes. Le reste de la complexité de Claude Code provient des outils eux-mêmes, du système de permissions, de la gestion du contexte et de la mémoire.
Construire le système d'outils
Pourquoi les outils dédiés sont supérieurs à une simple commande bash
L'une des décisions architecturales les plus claires de la fuite : Claude Code utilise des outils dédiés pour les opérations de fichiers au lieu de tout acheminer via bash.
Il existe un outil Read (pas cat), un outil Edit (pas sed), un outil Grep (pas grep), et un outil Glob (pas find). L'invite système indique explicitement au modèle de préférer ceux-ci aux équivalents bash.
Pourquoi ? Trois raisons :
- Sortie structurée. Un outil
Grepdédié renvoie des résultats dans un format cohérent que le modèle peut analyser. L'enchaînement de commandes bash produit une sortie imprévisible que le modèle a du mal à interpréter. - Sécurité. Le
BashTooldans Claude Code bloque les apostrophes inversées (backticks) et la syntaxe de sous-shell$()pour prévenir l'injection. Les outils dédiés contournent entièrement ce risque. - Efficacité des jetons. Les résultats des outils peuvent être tronqués, échantillonnés ou déchargés sur disque. Les grandes sorties de
catgaspillent les jetons de la fenêtre de contexte.
L'ensemble d'outils essentiel
D'après la fuite, Claude Code expose moins de 20 outils par défaut, avec plus de 60 derrière des drapeaux de fonctionnalité. Pour un agent DIY, vous en avez besoin de cinq :
TOOLS = [
{
"name": "read_file",
"description": "Lit un fichier du système de fichiers. Renvoie le contenu avec les numéros de ligne.",
"input_schema": {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "Chemin absolu du fichier"
},
"offset": {
"type": "integer",
"description": "Numéro de ligne à partir duquel commencer la lecture (indexé à 0)"
},
"limit": {
"type": "integer",
"description": "Nombre maximum de lignes à lire. Par défaut à 2000."
}
},
"required": ["file_path"]
}
},
{
"name": "write_file",
"description": "Écrit du contenu dans un fichier. Crée le fichier s'il n'existe pas.",
"input_schema": {
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Chemin absolu"},
"content": {"type": "string", "description": "Contenu du fichier à écrire"}
},
"required": ["file_path", "content"]
}
},
{
"name": "edit_file",
"description": "Remplace une chaîne spécifique dans un fichier. La old_string doit être unique.",
"input_schema": {
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Chemin absolu"},
"old_string": {"type": "string", "description": "Texte à trouver"},
"new_string": {"type": "string", "description": "Texte de remplacement"}
},
"required": ["file_path", "old_string", "new_string"]
}
},
{
"name": "run_command",
"description": "Exécute une commande shell et renvoie stdout/stderr.",
"input_schema": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "Commande shell à exécuter"},
"timeout": {"type": "integer", "description": "Délai d'expiration en secondes. Par défaut 120."}
},
"required": ["command"]
}
},
{
"name": "search_code",
"description": "Recherche un motif d'expression régulière dans les fichiers d'un répertoire.",
"input_schema": {
"type": "object",
"properties": {
"pattern": {"type": "string", "description": "Motif d'expression régulière"},
"path": {"type": "string", "description": "Répertoire à rechercher"},
"file_glob": {"type": "string", "description": "Filtre de motif de fichier, ex. '*.py'"}
},
"required": ["pattern"]
}
}
]
Distribution du gestionnaire d'outils
La fonction d'exécution d'outils mappe les noms d'outils aux fonctions de gestionnaire :
import subprocess
import os
import re
def execute_tool(name: str, params: dict) -> str:
"""Distribue les appels d'outils à leurs gestionnaires."""
handlers = {
"read_file": handle_read_file,
"write_file": handle_write_file,
"edit_file": handle_edit_file,
"run_command": handle_run_command,
"search_code": handle_search_code,
}
handler = handlers.get(name)
if not handler:
return f"Erreur : Outil inconnu '{name}'"
try:
return handler(params)
except Exception as e:
return f"Erreur : {str(e)}"
def handle_read_file(params: dict) -> str:
path = params["file_path"]
offset = params.get("offset", 0)
limit = params.get("limit", 2000)
with open(path, "r") as f:
lines = f.readlines()
selected = lines[offset:offset + limit]
numbered = [f"{i + offset + 1}\t{line}" for i, line in enumerate(selected)]
return "".join(numbered)
def handle_write_file(params: dict) -> str:
path = params["file_path"]
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w") as f:
f.write(params["content"])
return f"Écriture réussie dans {path}"
def handle_edit_file(params: dict) -> str:
path = params["file_path"]
with open(path, "r") as f:
content = f.read()
old = params["old_string"]
if content.count(old) == 0:
return f"Erreur : '{old[:50]}...' introuvable dans {path}"
if content.count(old) > 1:
return f"Erreur : '{old[:50]}...' correspond à {content.count(old)} emplacements. Soyez plus spécifique."
new_content = content.replace(old, params["new_string"], 1)
with open(path, "w") as f:
f.write(new_content)
return f"Modification réussie de {path}"
def handle_run_command(params: dict) -> str:
cmd = params["command"]
timeout = params.get("timeout", 120)
# Sécurité de base : bloquer les motifs dangereux
blocked = ["rm -rf /", "mkfs", "> /dev/"]
for pattern in blocked:
if pattern in cmd:
return f"Erreur : Motif de commande dangereux bloqué : {pattern}"
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True,
timeout=timeout, cwd=os.getcwd()
)
output = ""
if result.stdout:
output += result.stdout
if result.stderr:
output += f"\nSTDERR:\n{result.stderr}"
if not output.strip():
output = f"Commande terminée avec le code de sortie {result.returncode}"
# Tronquer les grandes sorties pour économiser les jetons de contexte
if len(output) > 30000:
output = output[:15000] + "\n\n... [tronqué] ...\n\n" + output[-15000:]
return output
def handle_search_code(params: dict) -> str:
pattern = params["pattern"]
path = params.get("path", os.getcwd())
file_glob = params.get("file_glob", "")
cmd = ["grep", "-rn", "--include", file_glob, pattern, path] if file_glob else \
["grep", "-rn", pattern, path]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if not result.stdout.strip():
return f"Aucune correspondance trouvée pour le motif : {pattern}"
lines = result.stdout.strip().split("\n")
if len(lines) > 50:
return "\n".join(lines[:50]) + f"\n\n... ({len(lines) - 50} correspondances supplémentaires)"
return result.stdout
Gestion du contexte : le problème difficile
Pourquoi le contexte est plus important que l'ingénierie des invites
La source divulguée révèle que Claude Code consacre plus d'efforts d'ingénierie à la gestion du contexte qu'à l'invite système elle-même. Le compresseur de contexte (appelé en interne « wU2 ») dispose de cinq stratégies.
Pour une construction DIY, vous en avez besoin de deux :
L'auto-compactage se déclenche lorsque la conversation approche la limite de la fenêtre de contexte. Claude Code se déclenche à environ 92 % d'utilisation, réservant un tampon de 13 000 jetons pour le résumé lui-même.
La réinjection de CLAUDE.md garantit que les directives du projet ne dérivent pas pendant les longues sessions. Claude Code réinjecte la configuration du projet à chaque tour, pas à l'initialisation. C'est le modèle le plus efficace pour maintenir un agent de codage sur la bonne voie.
Construire un compresseur simple
def maybe_compact(messages: list, system_prompt: str, max_tokens: int = 180000) -> list:
"""Compacter la conversation lorsqu'elle devient trop longue."""
# Estimation approximative : 4 caractères par jeton
total_chars = sum(
len(str(m.get("content", ""))) for m in messages
)
estimated_tokens = total_chars // 4
if estimated_tokens < max_tokens * 0.85:
return messages # Pas encore à la limite
# Demander au modèle de résumer la conversation jusqu'à présent
summary_response = client.messages.create(
model=MODEL,
max_tokens=4096,
system="Résumez cette conversation. Gardez tous les chemins de fichiers, les décisions prises, les erreurs rencontrées et l'état actuel de la tâche. Soyez précis sur ce qui a été modifié et pourquoi.",
messages=messages,
)
summary_text = summary_response.content[0].text
# Remplacer la conversation par le résumé + les messages récents
compacted = [
{"role": "user", "content": f"[Résumé de la conversation]\n{summary_text}"},
{"role": "assistant", "content": "J'ai le contexte de notre conversation précédente. Sur quoi dois-je travailler ensuite ?"},
]
# Conserver les 4 derniers messages pour le contexte immédiat
compacted.extend(messages[-4:])
return compacted
Réinjection du contexte du projet
Claude Code lit .claude/CLAUDE.md et l'injecte à chaque tour. Voici comment le reproduire :
def build_system_prompt(project_dir: str) -> str:
"""Construire une invite système avec réinjection du contexte du projet."""
base_prompt = """Vous êtes un assistant de codage qui aide aux tâches d'ingénierie logicielle.
Vous avez accès à des outils pour lire, écrire, modifier des fichiers, exécuter des commandes et rechercher du code.
Lisez toujours les fichiers avant de les modifier. Préférez edit_file à write_file pour les fichiers existants.
Gardez les réponses concises. Concentrez-vous sur le code, pas sur les explications."""
# Rechercher les directives du projet
claude_md_path = os.path.join(project_dir, ".claude", "CLAUDE.md")
if os.path.exists(claude_md_path):
with open(claude_md_path, "r") as f:
project_context = f.read()
base_prompt += f"\n\n# Directives du projet\n{project_context}"
# Vérifier également un CLAUDE.md racine
root_md = os.path.join(project_dir, "CLAUDE.md")
if os.path.exists(root_md):
with open(root_md, "r") as f:
root_context = f.read()
base_prompt += f"\n\n# Directives du dépôt\n{root_context}"
return base_prompt
Le système de mémoire à trois couches
La source divulguée montre que Claude Code utilise une architecture de mémoire à trois niveaux. C'est l'une des parties les plus sous-estimées du système.
Couche 1 : MEMORY.md (toujours chargé)
Un index léger qui reste en permanence dans l'invite système. Chaque entrée fait une ligne, moins de 150 caractères. Sert de table des matières pointant vers des connaissances plus approfondies. Limité à 200 lignes / 25 Ko.
- [Préférences utilisateur](memory/user-prefs.md) - préfère TypeScript, utilise les raccourcis Vim
- [Conventions API](memory/api-conventions.md) - REST avec la spécification JSON:API, snake_case
- [Processus de déploiement](memory/deploy.md) - utilise GitHub Actions, déploie sur AWS EKS
Couche 2 : fichiers thématiques (chargés à la demande)
Fichiers de connaissances détaillés chargés lorsque l'index suggère leur pertinence. Ceux-ci contiennent les conventions de projet, les décisions architecturales et les modèles appris.
Couche 3 : transcriptions de session (recherchées, jamais lues)
Journaux de session complets qui ne sont jamais chargés en bloc. L'agent les recherche à l'aide d'identifiants spécifiques (grep). Cela évite l'engorgement du contexte tout en préservant la capacité de recherche.
Construire un système de mémoire minimal
import json
MEMORY_DIR = ".agent/memory"
def load_memory_index() -> str:
"""Charger l'index de mémoire pour l'injection dans l'invite système."""
index_path = os.path.join(MEMORY_DIR, "MEMORY.md")
if os.path.exists(index_path):
with open(index_path, "r") as f:
return f.read()
return ""
def save_memory(key: str, content: str, description: str):
"""Enregistrer une entrée de mémoire et mettre à jour l'index."""
os.makedirs(MEMORY_DIR, exist_ok=True)
# Écrire le fichier de mémoire
filename = f"{key.replace(' ', '-').lower()}.md"
filepath = os.path.join(MEMORY_DIR, filename)
with open(filepath, "w") as f:
f.write(f"---\nname: {key}\ndescription: {description}\n---\n\n{content}")
# Mettre à jour l'index
index_path = os.path.join(MEMORY_DIR, "MEMORY.md")
index_lines = []
if os.path.exists(index_path):
with open(index_path, "r") as f:
index_lines = f.readlines()
# Ajouter ou mettre à jour l'entrée
new_entry = f"- [{key}]({filename}) - {description}\n"
updated = False
for i, line in enumerate(index_lines):
if filename in line:
index_lines[i] = new_entry
updated = True
break
if not updated:
index_lines.append(new_entry)
with open(index_path, "w") as f:
f.writelines(index_lines)
Ajoutez un outil save_memory à votre liste d'outils afin que l'agent puisse conserver ses connaissances entre les sessions.
Ajouter un système de permissions
La fuite révèle cinq modes de permission : default (invites interactives), auto (approbation basée sur l'apprentissage automatique), bypass, yolo (approuver tout), et deny. Chaque action d'outil est classée comme risque FAIBLE, MOYEN ou ÉLEVÉ.
Pour un agent DIY, un système simple à trois niveaux fonctionne :
# Niveaux de risque pour les opérations
RISK_LEVELS = {
"read_file": "low",
"search_code": "low",
"edit_file": "medium",
"write_file": "medium",
"run_command": "high",
}
def check_permission(tool_name: str, params: dict, auto_approve_low: bool = True) -> bool:
"""Vérifie si l'utilisateur approuve cet appel d'outil."""
risk = RISK_LEVELS.get(tool_name, "high")
if risk == "low" and auto_approve_low:
return True
# Montrer à l'utilisateur ce qui est sur le point de se produire
print(f"\n--- Vérification de permission ({risk.upper()} risque) ---")
print(f"Outil : {tool_name}")
for key, value in params.items():
display = str(value)[:200]
print(f" {key}: {display}")
response = input("Autoriser ? [o/n/toujours] : ").strip().lower()
if response == "always":
RISK_LEVELS[tool_name] = "low" # Approuver automatiquement cet outil à l'avenir
return True
return response == "y"
Tester les appels API de votre agent avec Apidog
Construire un agent de codage signifie effectuer des centaines d'appels API à Claude. Le débogage de ces interactions, en particulier les conversations multi-tours avec utilisation d'outils, est pénible avec les journaux bruts.

Apidog vous aide à inspecter et tester les requêtes API exactes que votre agent envoie. Voici comment l'utiliser pendant le développement :
Capturer et rejouer les requêtes API
Configurez Apidog comme proxy pour intercepter les appels de votre agent à l'API Anthropic :
- Ouvrez Apidog et créez un nouveau projet pour votre agent
- Importez le point de terminaison de l'API Anthropic Messages :
POST https://api.anthropic.com/v1/messages - Configurez le corps de la requête avec votre invite système, votre tableau d'outils et vos messages
- Testez les tours individuels en rejouant les requêtes capturées avec des paramètres modifiés
Cela vous permet d'isoler des tours d'utilisation d'outils spécifiques sans exécuter la boucle complète de l'agent. Lorsque le modèle renvoie un appel d'outil inattendu ou un paramètre erroné, vous pouvez modifier le corps de la requête dans l'éditeur visuel d'Apidog et le renvoyer pour voir comment différentes entrées modifient la réponse.
Déboguer les conversations multi-tours
La partie la plus difficile du débogage d'agent est la reproduction d'un état de conversation. Les variables d'environnement d'Apidog vous permettent d'enregistrer des instantanés de conversation :
- Enregistrez le tableau complet
messagescomme variable d'environnement après chaque tour - Rejouez à partir de n'importe quel point de la conversation
- Comparez les résultats des outils entre les exécutions pour trouver où le comportement diverge
Valider les schémas d'outils
Vos définitions d'outils (les schémas JSON que vous transmettez à l'API) déterminent ce que le modèle peut demander. Des schémas malformés entraînent des échecs silencieux où le modèle ignore un outil ou transmet de mauvais paramètres.
Importez vos schémas d'outils dans Apidog et utilisez son validateur de schéma JSON pour détecter les problèmes avant qu'ils n'atteignent l'API. Téléchargez Apidog pour commencer à déboguer les interactions API de votre agent.
Tout assembler : le REPL complet
Voici l'agent complet assemblé sous la forme d'un REPL fonctionnel :
#!/usr/bin/env python3
"""Un agent de codage minimal de style Claude Code."""
import anthropic
import os
import sys
client = anthropic.Anthropic()
MODEL = "claude-sonnet-4-6"
PROJECT_DIR = os.getcwd()
def main():
system_prompt = build_system_prompt(PROJECT_DIR)
memory = load_memory_index()
if memory:
system_prompt += f"\n\n# Memory\n{memory}"
messages = []
print("Agent de codage prêt. Tapez 'quit' pour quitter.\n")
while True:
user_input = input("> ").strip()
if user_input.lower() in ("quit", "exit"):
break
if not user_input:
continue
messages.append({"role": "user", "content": user_input})
# Compacter si nécessaire
messages = maybe_compact(messages, system_prompt)
# Réinjecter le contexte du projet (Claude Code le fait à chaque tour)
current_system = build_system_prompt(PROJECT_DIR)
memory = load_memory_index()
if memory:
current_system += f"\n\n# Memory\n{memory}"
# Exécuter la boucle de l'agent
result = agent_loop(current_system, TOOLS, messages)
print(f"\n{result}\n")
if __name__ == "__main__":
main()
Cela vous donne un agent de codage fonctionnel en moins de 300 lignes de Python. Il lit des fichiers, modifie du code, exécute des commandes, recherche dans des bases de code, gère le contexte et conserve la mémoire entre les sessions.
Ce qu'il faut ajouter ensuite
La source divulguée révèle plusieurs fonctionnalités à développer une fois que votre boucle centrale fonctionne :
Sous-agents pour le travail parallèle
Claude Code génère des sous-agents (appelés agents « bifurqués ») pour des tâches indépendantes. Le sous-agent obtient une copie du contexte parent, exécute sa tâche et renvoie un résultat. Cela évite de polluer la conversation principale avec des travaux exploratoires.
Le modèle : lancer une nouvelle agent_loop() avec une description de tâche ciblée et un sous-ensemble d'outils. Retourner le résultat sous forme de chaîne.
Déduplication de la lecture de fichiers
Claude Code suit les fichiers qui ont été lus et leurs heures de modification. Si un fichier n'a pas changé depuis la dernière lecture, il ignore la lecture et indique au modèle « fichier inchangé depuis la dernière lecture ». Cela économise des jetons sur les relectures lors de longues sessions.
Troncation et échantillonnage de la sortie
Lorsqu'un outil renvoie une sortie massive (plus de 10 000 lignes de résultats grep, par exemple), Claude Code la tronque et indique au modèle le nombre de résultats omis. Sans cela, un seul grand résultat d'outil peut consumer toute votre fenêtre de contexte.
Auto-compactage avec réinjection de fichiers
Le compresseur divulgué ne jette pas le contenu des fichiers. Après avoir résumé la conversation, il réinjecte le contenu des fichiers récemment consultés (jusqu'à 5 000 jetons par fichier). Cela signifie que le modèle conserve une connaissance fonctionnelle de la base de code même après le compactage.
Ce que nous avons appris de la fuite
La fuite du code de Claude Code a confirmé plusieurs modèles que la communauté des agents IA avait théorisés :
- La boucle centrale est simple. Le modèle d'agent entier tient en 30 lignes. La complexité réside dans les outils et la gestion du contexte, pas dans l'ingénierie des invites.
- Les outils dédiés sont plus performants que bash. Les outils structurés et conçus à cet effet offrent au modèle une meilleure densité d'informations par jeton que l'enchaînement de commandes bash.
- La mémoire a besoin de couches. Un index toujours chargé, des fichiers thématiques à la demande et des transcriptions consultables uniquement par grep équilibrent le rappel et les coûts de contexte.
- La gestion du contexte est le vrai produit. L'auto-compactage, la réinjection des directives de projet et la troncature des sorties sont ce qui rend les longues sessions de codage viables.
- Le harnais est le produit, pas le modèle. Le modèle fournit l'intelligence. Le harnais fournit la perception (lecture de fichiers, recherche de code), l'action (écriture de fichiers, exécution de commandes) et la mémoire. Construire un agent de codage, c'est construire le harnais.
Si vous souhaitez tester et déboguer les interactions API de votre agent personnalisé, y compris les conversations multi-tours avec utilisation d'outils, les schémas de requête complexes et la validation des réponses, essayez Apidog gratuitement. Il gère le débogage API afin que vous puissiez vous concentrer sur la logique de l'agent.
FAQ
Puis-je utiliser légalement les modèles de la fuite du code de Claude Code ?
La fuite a exposé des modèles architecturaux, et non des algorithmes propriétaires. Construire un agent de codage qui utilise une boucle `while` avec distribution d'outils est un modèle standard documenté dans la propre documentation API d'Anthropic. Vous ne devriez pas copier le code d'Anthropic mot pour mot, mais recréer l'architecture avec votre propre code est une pratique courante.
Quel modèle devrais-je utiliser pour un agent de codage DIY ?
Claude Sonnet 4.6 offre le juste équilibre entre vitesse et capacités pour les tâches de codage. Claude Opus 4.6 produit de meilleurs résultats sur les décisions d'architecture complexes, mais coûte plus cher et est plus lent. Pour les modifications de fichiers et les recherches simples, Claude Haiku 4.5 fonctionne et coûte 90 % moins cher.
Combien coûte l'exécution de votre propre agent de codage ?
Une session de codage typique (30-50 tours) avec Claude Sonnet 4.6 coûte 1 à 5 $ en frais d'API. Le principal facteur de coût est la taille de la fenêtre de contexte ; un compactage agressif réduit les coûts. La source divulguée de Claude Code montre qu'il déclenche le compactage à 92 % d'utilisation du contexte pour contrôler cela.
Pourquoi Claude Code utilise-t-il React pour une application terminale ?
Ink (React pour les terminaux) permet à l'équipe de réutiliser le modèle de composants et la gestion d'état de React pour des interactions UI complexes comme les dialogues de permission, la sortie en streaming et les affichages d'appels d'outils. Pour un projet DIY, un simple REPL avec input() / print() suffit.
Quelle est la fonctionnalité la plus importante à construire après la boucle centrale ?
Le système de permissions. Sans lui, le modèle peut écraser des fichiers et exécuter des commandes arbitraires sans supervision de l'utilisateur. Même une simple porte de « confirmation avant écriture/exécution » prévient la plupart des dommages accidentels.
Comment Claude Code gère-t-il les erreurs provenant des appels d'outils ?
Les erreurs d'outil sont renvoyées sous forme de contenu texte dans le message tool_result. Le modèle voit l'erreur et décide s'il faut réessayer, essayer une approche différente ou demander à l'utilisateur. Il n'y a pas de gestion d'erreur spéciale ; le raisonnement du modèle gère la récupération.
Puis-je utiliser cela avec des modèles autres que Claude ?
Oui. Le modèle d'utilisation d'outils fonctionne avec n'importe quel modèle qui prend en charge l'appel de fonctions : GPT-4, Gemini, Llama et d'autres. Vous devrez adapter le format d'appel API, mais la boucle de l'agent, les outils et le système de mémoire sont agnostiques au modèle.
Comment empêcher l'agent d'exécuter des commandes dangereuses ?
Commencez par une liste noire de motifs dangereux (rm -rf /, mkfs, etc.) et exigez une approbation explicite pour tous les appels run_command. Claude Code classe chaque opération comme risque FAIBLE, MOYEN ou ÉLEVÉ et bloque ou demande confirmation en fonction de la classification. Faites de même pour vos outils.
