# Claude Agent SDK vs Claude CLI : System prompts et cohérence de sortie
← Retour à Claude Code Best Practice Claude
![Diagramme System prompts SDK vs CLI](../../reports/assets/sdk-vs-cli-diagram.svg) --- ## Résumé exécutif En envoyant le même message (par ex. « What is the capital of Norway? ») via le **Claude Agent SDK** versus le **Claude CLI (Claude Code)**, les system prompts accompagnant ces messages sont fondamentalement différents. Le CLI utilise une **architecture de system prompt modulaire** (~269 tokens de base avec du contexte additionnel chargé conditionnellement selon les fonctionnalités), tandis que le SDK utilise un prompt minimal par défaut. **Il n'y a aucune garantie de sortie identique entre les deux**, même avec des configurations correspondantes, en raison de l'absence d'un paramètre seed et du non-déterminisme inhérent à l'architecture de Claude. --- ## 1. Comparaison des system prompts ### Claude CLI (Claude Code) Le Claude CLI utilise une **architecture de system prompt modulaire** avec un prompt de base de ~269 tokens, du contexte additionnel étant chargé conditionnellement : | Composant | Description | Chargement | |-----------|-------------|---------| | **System prompt de base** | Instructions et comportement de base | Toujours (~269 tokens) | | **Instructions d'outils** | 18+ outils intégrés (Write, Read, Edit, Bash, TodoWrite, etc.) | Toujours | | **Directives de code** | Style de code, règles de formatage, pratiques de sécurité | Toujours | | **Règles de sécurité** | Règles de refus, défense contre l'injection, prévention des dommages | Toujours | | **Style de réponse** | Ton, verbosité, profondeur d'explication, usage d'emoji | Toujours | | **Contexte d'environnement** | Répertoire de travail, git status, infos de plateforme | Toujours | | **Contexte de projet** | Contenu CLAUDE.md, paramètres, configuration des hooks | Conditionnel | | **Prompts de sous-agents** | Mode plan, agent Explore, agent Task | Conditionnel | | **Revue de sécurité** | Instructions de sécurité étendues (~2 610 tokens) | Conditionnel | **Caractéristiques clés :** - **Architecture modulaire** avec 110+ chaînes de system prompt chargées conditionnellement - Le prompt de base est modeste (~269 tokens), le total varie selon les fonctionnalités activées - Inclut des couches étendues de sécurité et de défense contre l'injection - Charge automatiquement les fichiers CLAUDE.md dans le répertoire de travail - Contexte persistant en session en mode interactif ### Claude Agent SDK L'Agent SDK utilise un **system prompt minimal par défaut** contenant : | Composant | Description | Impact en tokens | |-----------|-------------|--------------| | **Instructions d'outils essentielles** | Uniquement les outils explicitement fournis | Minimal | | **Sécurité de base** | Instructions de sécurité minimales | Minimal | **Caractéristiques clés :** - Aucune directive de code ni préférence de style par défaut - Aucun contexte de projet sauf configuration explicite - Aucune description d'outils étendue - Requiert une configuration explicite pour correspondre au comportement du CLI --- ## 2. Ce que chaque interface envoie ### Exemple : « What is the capital of Norway? » #### Via le Claude CLI ``` System Prompt : [modulaire, ~269+ tokens de base] ├── System prompt de base (~269 tokens) ├── Instructions d'outils (Write, Read, Edit, Bash, Grep, Glob, etc.) ├── Protocoles de sécurité git ├── Directives de référence de code ├── Instructions d'objectivité professionnelle ├── Règles de sécurité et de défense contre l'injection ├── Contexte d'environnement (OS, répertoire, date) ├── Contenu CLAUDE.md (si présent) [conditionnel] ├── Descriptions d'outils MCP (si configurés) [conditionnel] ├── Prompts de mode Plan/Explore [conditionnel] └── Contexte de session/conversation Message utilisateur : "What is the capital of Norway?" ``` #### Via le Claude Agent SDK (par défaut) ``` System Prompt : [minimal] ├── Instructions d'outils essentielles (si des outils sont fournis) └── Contexte opérationnel de base Message utilisateur : "What is the capital of Norway?" ``` #### Via l'Agent SDK (avec le preset `claude_code`) ```typescript const response = await query({ prompt: "What is the capital of Norway?", options: { systemPrompt: { type: "preset", preset: "claude_code" } } }); ``` ``` System Prompt : [modulaire, correspond au CLI] ├── System prompt Claude Code complet ├── Instructions d'outils ├── Directives de code └── Règles de sécurité // NOTE : N'inclut TOUJOURS PAS CLAUDE.md sauf si settingSources est configuré ``` --- ## 3. Méthodes de personnalisation ### Personnalisation du Claude CLI | Méthode | Commande | Effet | |--------|---------|--------| | **Ajouter au prompt** | `claude -p "..." --append-system-prompt "..."` | Ajoute des instructions en préservant les défauts | | **Remplacer le prompt** | `claude -p "..." --system-prompt "..."` | Remplace entièrement le system prompt | | **Contexte de projet** | Fichier CLAUDE.md | Chargé automatiquement, persistant | | **Styles de sortie** | `/output-style [name]` | Applique des styles de réponse prédéfinis | ### Personnalisation de l'Agent SDK | Méthode | Configuration | Effet | |--------|---------------|--------| | **Prompt personnalisé** | `systemPrompt: "..."` | Remplace entièrement le défaut (perd les outils) | | **Preset avec ajout** | `systemPrompt: { type: "preset", preset: "claude_code", append: "..." }` | Préserve la fonctionnalité CLI + instructions personnalisées | | **Chargement de CLAUDE.md** | `settingSources: ["project"]` | Charge les instructions au niveau projet | | **Styles de sortie** | `settingSources: ["user"]` ou `settingSources: ["project"]` | Charge les styles de sortie enregistrés | ### Tableau comparatif de configuration | Fonctionnalité | CLI par défaut | SDK par défaut | SDK avec preset | |---------|-------------|-------------|-----------------| | Instructions d'outils | ✅ Complètes | ❌ Minimales | ✅ Complètes | | Directives de code | ✅ Oui | ❌ Non | ✅ Oui | | Règles de sécurité | ✅ Oui | ❌ De base | ✅ Oui | | Auto-chargement CLAUDE.md | ✅ Oui | ❌ Non | ❌ Non* | | Contexte de projet | ✅ Automatique | ❌ Non | ❌ Non* | *Requiert une configuration explicite `settingSources: ["project"]` --- ## 4. Garanties de cohérence de sortie ### Constat critique : AUCUN déterminisme garanti **L'API Messages de Claude ne fournit pas de paramètre seed pour la reproductibilité.** C'est une limitation architecturale fondamentale. ### Facteurs empêchant une sortie identique | Facteur | Description | Contrôlable ? | |--------|-------------|---------------| | **System prompts différents** | CLI vs SDK ont des défauts différents | ✅ Oui (avec configuration) | | **Arithmétique en virgule flottante** | Particularités du matériel parallèle | ❌ Non | | **Routage MoE** | Variations de l'architecture Mixture-of-Experts | ❌ Non | | **Batching/ordonnancement** | Différences d'infrastructure cloud | ❌ Non | | **Précision numérique** | Variations du moteur d'inférence | ❌ Non | | **Snapshots de modèle** | Mises à jour/changements de version | ❌ Non | ### Température et échantillonnage Même avec `temperature=0.0` (décodage glouton) : - Le déterminisme complet **N'EST PAS garanti** - Des variations mineures peuvent quand même survenir à cause de facteurs d'infrastructure - Bug connu : [le Claude CLI produit une sortie non déterministe pour des entrées identiques](https://github.com/anthropics/claude-code/issues/3370) --- ## 5. Atteindre une cohérence maximale Pour obtenir les sorties identiques **les plus proches possibles** entre SDK et CLI : ### Configuration de l'Agent SDK ```typescript import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic(); // Option 1 : Utiliser le preset claude_code const response = await client.messages.create({ model: "claude-sonnet-4-20250514", max_tokens: 1024, // Faire correspondre le system prompt du CLI au plus près system: "Your exact system prompt matching CLI", messages: [ { role: "user", content: "What is the capital of Norway?" } ], // Utiliser le décodage glouton pour une cohérence maximale temperature: 0 }); // Option 2 : Avec la fonction query de l'Agent SDK import { query } from "@anthropic-ai/agent-sdk"; for await (const message of query({ prompt: "What is the capital of Norway?", options: { systemPrompt: { type: "preset", preset: "claude_code" }, temperature: 0, model: "claude-sonnet-4-20250514", // Charger le contexte de projet comme le fait le CLI settingSources: ["project"] } })) { // Traiter la réponse } ``` ### Configuration du CLI ```bash # Faire correspondre la configuration du SDK au plus près claude -p "What is the capital of Norway?" \ --model claude-sonnet-4-20250514 \ --temperature 0 ``` ### Toujours pas garanti Même avec des configurations parfaitement correspondantes : - La sortie peut différer entre exécutions - La sortie peut différer entre SDK et CLI - Aucun paramètre seed n'existe pour forcer la reproductibilité --- ## 6. Implications pratiques ### Quand utiliser chaque interface | Cas d'usage | Interface recommandée | Raison | |----------|----------------------|--------| | Développement interactif | Claude CLI | Suite d'outils complète, contexte de projet | | Intégration programmatique | Agent SDK | Contrôle fin, embarquement | | Réponses API cohérentes | Agent SDK + prompt personnalisé | Plus de contrôle sur le system prompt | | Traitement par lots | Agent SDK | Meilleur pour les pipelines d'automatisation | | Tâches ponctuelles | Claude CLI | Mise en place plus rapide, contexte immédiat | ### Recommandations de conception 1. **Ne te fie pas à une reproductibilité au bit près** - Construis des applications robustes aux variations mineures de sortie - Utilise des sorties structurées et de la validation 2. **Pour les pipelines de production exigeant de la cohérence :** - Mets en cache les résultats quand possible - Utilise des sorties structurées avec validation par schéma JSON - Combine avec de la logique déterministe et de la validation - Envisage plusieurs générations avec consensus 3. **Pour faire correspondre le comportement du CLI dans le SDK :** ```typescript systemPrompt: { type: "preset", preset: "claude_code", append: "Your additional instructions" }, settingSources: ["project", "user"] ``` --- ## 7. Impact en tokens du system prompt | Configuration | Architecture | Notes | |---------------|-------------|-------| | SDK (minimal) | Défaut minimal | Uniquement les instructions d'outils essentielles | | SDK (preset claude_code) | Modulaire (~269+ de base) | Correspond au CLI, varie selon les fonctionnalités | | CLI (par défaut) | Modulaire (~269+ de base) | Contexte additionnel chargé conditionnellement | | CLI (avec outils MCP) | Modulaire + MCP | Les descriptions d'outils MCP ajoutent beaucoup de tokens | **Note :** Claude Code utilise une architecture modulaire avec 110+ chaînes de system prompt. Le prompt de base fait ~269 tokens, les composants individuels allant de 18 à 2 610 tokens selon les fonctionnalités activées. **Implication :** Le défaut minimal du SDK te donne plus de contexte pour ta tâche réelle, mais au prix des capacités complètes de Claude Code. --- ## 8. Tableau récapitulatif | Aspect | Claude CLI | Agent SDK (par défaut) | Agent SDK (preset) | |--------|------------|--------------------|--------------------| | **System prompt** | Modulaire (~269+ de base) | Minimal | Modulaire (correspond au CLI) | | **Outils inclus** | 18+ intégrés | Seulement si fournis | 18+ intégrés | | **Auto-chargement CLAUDE.md** | Oui | Non | Non (nécessite config) | | **Directives de code** | Oui | Non | Oui | | **Règles de sécurité** | Complètes | De base | Complètes | | **Contrôle de température** | Oui | Oui | Oui | | **Garantie de déterminisme** | Non | Non | Non | | **Sorties identiques ?** | N/A | Non (vs CLI) | Plus proches, mais non | --- ## 9. Conclusion **Q : Quels system prompts accompagnent le même message en SDK vs CLI ?** Le CLI utilise une **architecture de system prompt modulaire** avec un prompt de base de ~269 tokens et 110+ composants chargés conditionnellement (instructions d'outils, directives de code, règles de sécurité, contexte de projet). Le SDK utilise un **défaut minimal** avec seulement les instructions d'outils essentielles, bien qu'il puisse être configuré pour correspondre au comportement du CLI via le preset `claude_code`. **Q : Y a-t-il une garantie de sortie identique ?** **Non.** Même avec des system prompts correspondants, des entrées identiques et `temperature=0`, il n'y a aucune garantie de sortie identique en raison de : - L'absence d'un paramètre seed dans l'API de Claude - Les variations d'arithmétique en virgule flottante - Le non-déterminisme au niveau de l'infrastructure - Les variations de routage de l'architecture du modèle (Mixture-of-Experts) **Recommandation :** Conçois les systèmes pour être robustes aux variations de sortie plutôt que de te fier à un comportement déterministe. Pour les applications critiques en cohérence, utilise des sorties structurées, du caching et des couches de validation. --- ## Sources - [Modifying System Prompts - Agent SDK](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/sdk#modifying-system-prompts) - [Référence CLI Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/cli) - [Mode Headless Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/headless) - [Bonnes pratiques Claude Code - Anthropic Engineering](https://www.anthropic.com/engineering/claude-code-best-practices) - [Référence de l'API Messages de Claude](https://docs.anthropic.com/en/api/messages) - [GitHub Issue #3370 : Sortie non déterministe](https://github.com/anthropics/claude-code/issues/3370) - [Dépôt des system prompts de Claude Code](https://github.com/Piebald-AI/claude-code-system-prompts) - Analyse de l'architecture de prompt modulaire - [Why Deterministic Output from LLMs is Nearly Impossible](https://unstract.com/blog/understanding-why-deterministic-output-from-llms-is-nearly-impossible/) --- *Ce rapport a été généré par Claude Code avec le modèle Opus 4.5 le 3 février 2026.*