# Claude Agent SDK vs Claude CLI : System prompts et cohérence de sortie

<table width="100%">
<tr>
<td><a href="../">← Retour à Claude Code Best Practice</a></td>
<td align="right"><img src="../../!/claude-jumping.svg" alt="Claude" width="60" /></td>
</tr>
</table>

![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.*
