# D4 · Prompt and Context Engineering

Principes de prompt engineering, patterns de sortie structurée, parsing défensif et validation-retry, et context engineering pour prévenir la dérive et le gonflement.

import { Accordions, AccordionItem, Tabs, TabItem } from '@prosefly/astro-components';

Ce domaine représente environ **6 items sur 53**. Il vérifie que vous savez écrire des prompts qui produisent de manière fiable la forme et la qualité dont vous avez besoin, parser la sortie de manière défensive (sans jamais faire confiance à un texte assuré), et ingénier le contexte pour que le travail de longue durée ne dérive ni ne gonfle. La leçon centrale : **le prompt est l’interface ; le contexte est la mémoire de travail – ingéniez les deux.**

## Objectifs d’apprentissage
À la fin de cette page, vous devriez être capable de :

1. Appliquer les **principes fondamentaux de prompt engineering** : instructions claires/directes, balises XML, exemples/few-shot, rôle, chain-of-thought, prefilling, format de sortie.
2. Produire une **sortie structurée** via `output_config.format` (schéma JSON), l’utilisation d’outil comme schéma, et `strict: true`.
3. Parser la sortie de manière **défensive** avec la **validation-retry** et un scepticisme approprié.
4. Prévenir la **dérive et le gonflement du contexte** : élagage des sorties d’outils, édition de contexte, compaction, résumé.
5. Utiliser l’**isolation du contexte** via des subagents et le bon **ordonnancement du long contexte**.
6. Agencer les prompts pour être **caching-aware**.

---

## 4.1 Prompt-engineering principles

| Principle | What it does | Example lever |
| --- | --- | --- |
| **Clear and direct** | Supprime l’ambiguïté | Énoncer la tâche, les contraintes et la forme de sortie explicitement |
| **XML tags** | Délimite les sections ; sépare les instructions des données | `<document>…</document>`, `<instructions>…</instructions>` |
| **Examples / few-shot** | Montre le pattern souhaité | 2–5 paires entrée→sortie représentatives |
| **Role** | Fixe la perspective et le ton | `system` : 'You are a senior tax analyst.' |
| **Chain-of-thought** | Améliore le raisonnement sur les tâches difficiles | Demander un raisonnement pas à pas, ou utiliser le thinking |
| **Prefilling** | Contraint le début de la réponse | Préremplir le tour de l’assistant avec `{` pour forcer du JSON |
| **Output format** | Rend la sortie parsable | Spécifier le schéma / la structure exacts |

```python
messages = [
    {"role": "user", "content": "Extract fields from <invoice>...</invoice> as JSON."},
    {"role": "assistant", "content": "{"},   # le prefill force le début JSON
]
```

:::tip[Signal d’examen]
« La sortie est incohérente / difficile à parser » → spécifiez le format, utilisez des balises XML, ajoutez des exemples few-shot, et envisagez le prefilling. « Le raisonnement est superficiel sur une tâche difficile » → chain-of-thought / thinking.
:::

---

## 4.2 Structured-output patterns

Trois façons d’obtenir une sortie exploitable par machine, de la plus forte à la plus faible :

1. **`output_config.format` avec un schéma JSON** – le modèle est contraint d’émettre du JSON conforme au schéma.
2. **Utilisation d’outil comme schéma** – définissez un outil dont l’`input_schema` est votre forme cible ; l’input du bloc `tool_use` est votre donnée structurée. Ajoutez **`strict: true`** pour imposer le schéma.
3. **Prompt + prefill + validation** – demandez du JSON, préremplissez `{`, puis validez (le plus faible ; nécessite un parsing défensif).

```json
{
  "model": "claude-sonnet-5",
  "max_tokens": 512,
  "output_config": {
    "format": {
      "type": "json_schema",
      "schema": {
        "type": "object",
        "properties": {
          "total": {"type": "number"},
          "currency": {"type": "string"},
          "line_items": {"type": "array", "items": {"type": "string"}}
        },
        "required": ["total", "currency"]
      }
    }
  },
  "messages": [{"role": "user", "content": "Extract totals from the invoice."}]
}
```

:::caution[Fable 5.1]
Comme Fable 5.1 rejette le `tool_choice` forcé, préférez **`output_config.format`** ou les schémas `strict: true` plutôt que de forcer un outil pour obtenir une sortie structurée.
:::

---

## 4.3 Defensive parsing and validation-retry

Ne présumez jamais qu’une sortie est valide simplement parce qu’elle semble assurée. Validez par rapport au schéma et **réessayez avec l’erreur** en cas d’échec.

```python
import json
from jsonschema import validate, ValidationError

SCHEMA = {"type": "object", "required": ["total", "currency"],
          "properties": {"total": {"type": "number"}, "currency": {"type": "string"}}}

def extract(client, messages, attempts=3):
    for _ in range(attempts):
        resp = client.messages.create(model="claude-sonnet-5", max_tokens=512, messages=messages)
        text = "".join(b.text for b in resp.content if b.type == "text")
        try:
            data = json.loads(text)
            validate(data, SCHEMA)
            return data
        except (json.JSONDecodeError, ValidationError) as e:
            messages.append({"role": "assistant", "content": text})
            messages.append({"role": "user", "content": f"Invalid output: {e}. Return valid JSON only."})
    raise ValueError("could not obtain valid structured output")
```

:::danger[Scepticisme envers une sortie assurée]
Une réponse fluide et assurée n’est pas une réponse validée. Parsez de manière défensive, validez par rapport à un schéma, et remontez les échecs – ne les avalez pas (anti-pattern nº 7). Ne vous fiez pas à la confiance auto-déclarée du modèle (anti-pattern nº 4).
:::

---

## 4.4 Context drift and bloat

À mesure qu’une conversation ou un agent s’exécute, le contexte se remplit de sorties d’outils, de raisonnement intermédiaire et de tours périmés. Cela **gonfle** le coût et la latence et provoque la **dérive** (le modèle perd le fil ou surpondère le bruit).

| Technique | What it does |
| --- | --- |
| **Élagage des sorties d’outils** | Supprimer ou tronquer les résultats d’outils volumineux/anciens dont on n’a plus besoin |
| **Édition de contexte** | Effacer programmatiquement le contenu périmé (p. ex. anciens résultats d’outils) |
| **Compaction** | Résumé côté serveur préservant le fil narratif |
| **Résumé** | Remplacer un long historique par un résumé courant |
| **Isolation du contexte** | Pousser les sous-tâches vers des subagents ayant leurs propres fenêtres |

:::tip[Signal d’examen]
« Un agent de longue durée ralentit / perd le focus / les coûts explosent » → édition de contexte, compaction, résumé, et isolation par subagents – et non simplement un `max_tokens` plus grand.
:::

---

## 4.5 Long-context ordering and caching-aware layout

Pour les entrées longues, **placez le contenu stable et volumineux en premier et la requête en dernier** :

```text
[ system: role + rules ]        ← stable, cache here
[ tools ]                        ← stable, cache here
[ long documents ]               ← stable, cache here
[ conversation history ]         ← grows
[ the current question / task ]  ← variable, last
```

- Documents d’abord, requête en dernier améliore l’ancrage et la qualité des réponses sur les longs contextes.
- La même disposition est **favorable au caching** : le préfixe stable est mis en cache (0,1× sur les hits), et seule la queue variable est retraitée.

---

## 4.6 Long-context ordering: a worked example

Sur les entrées longues, **placez le contenu stable volumineux en premier et la requête en dernier**. Deux raisons : la qualité de l’ancrage s’améliore quand le modèle lit les preuves avant la question, et le préfixe stable devient mettable en cache. Ci-dessous, les documents et instructions viennent en premier ; la question réelle de l’utilisateur est le dernier bloc.

```json
{
  "model": "claude-sonnet-5",
  "max_tokens": 1024,
  "system": [
    {"type": "text", "text": "You answer strictly from the provided documents. If the answer is not present, say so."}
  ],
  "messages": [
    {"role": "user", "content": [
      {"type": "text", "text": "<documents>\n<doc id='1'>...50 pages of policy text...</doc>\n<doc id='2'>...contract text...</doc>\n</documents>"},
      {"type": "text", "text": "<question>What is the termination notice period, and which clause states it?</question>"}
    ]}
  ]
}
```

L’ordonnancement est : **règles système → documents → question**. Si vous placez la question en premier, le modèle la lit sans les preuves en vue, affaiblissant l’ancrage, et la question variable se retrouverait à l’intérieur de ce que vous vouliez mettre en cache.

:::tip[Signal d’examen]
« Les réponses aux questions sur de longs documents sont mal ancrées » ou « la question est en haut d’un énorme prompt » → réordonnez en **documents d’abord, requête en dernier**. Cela prépare aussi le caching (section suivante).
:::

---

## 4.7 Caching-aware prompt layout

Le prompt caching récompense un **préfixe stable en premier**. Placez le contenu qui se répète octet par octet entre les requêtes (prompt système, outils, longs documents de référence) au début et marquez le dernier bloc stable avec `cache_control`. Tout ce qui est variable (la question courante, les nouveaux tours) va après le point de rupture mis en cache.

```json
{
  "model": "claude-sonnet-5",
  "system": [
    {"type": "text", "text": "Long stable system instructions and schema...",
     "cache_control": {"type": "ephemeral"}}
  ],
  "tools": [
    {"name": "search", "description": "...", "input_schema": {"type": "object"}}
  ],
  "messages": [
    {"role": "user", "content": [
      {"type": "text", "text": "...long reference document reused every request...",
       "cache_control": {"type": "ephemeral"}},
      {"type": "text", "text": "Current question: ..."}
    ]}
  ]
}
```

- Les lectures de cache coûtent ≈ 0,1× l’entrée de base ; les écritures ≈ 1,25× (TTL 5 min) ou 2× (TTL 1 heure).
- Le préfixe minimal mettable en cache est d’environ 1024 tokens (**2048 sur Haiku 4.5**) ; les préfixes plus courts ne seront pas mis en cache.
- Ordonnez la disposition : `system → tools → documents stables → [point de rupture du cache] → question variable`.

```text
[ system + schema ]      ┐
[ tools ]                │  stable prefix → mark cache_control here (cached at 0.1×)
[ reference documents ]  ┘
──────────────────────────────  cache breakpoint
[ current question ]        variable tail → reprocessed each request
```

:::caution[Un préfixe qui change ne se met jamais en cache]
Si un seul octet du préfixe diffère entre les requêtes (un horodatage, un nom par utilisateur inséré dans le prompt système), le cache manque à chaque fois. Gardez la variabilité par requête hors du préfixe et après le point de rupture.
:::

---

## 4.8 Context editing vs compaction

Les agents longs dépassent la fenêtre. Deux contrôles côté serveur la gèrent, et l’examen attend que vous choisissiez le bon.

| | Context editing | Compaction |
| --- | --- | --- |
| Ce qu’il fait | **Efface/élague** programmatiquement le contenu périmé (p. ex. anciens résultats d’outils) | **Résume** les tours plus anciens côté serveur, en **préservant le fil narratif** |
| Préserve le fil narratif ? | Non — il retire du contenu | Oui — il condense en conservant le fil |
| Meilleur quand | Les anciennes sorties d’outils sont volumineuses et inutiles | L’historique complet importe mais est trop long à garder tel quel |
| Risque | Retirer quelque chose encore nécessaire | Le résumé perd un détail nécessaire |

```json
{
  "model": "claude-sonnet-5",
  "context_management": {
    "edits": [
      {"type": "clear_tool_uses", "trigger": {"type": "input_tokens", "value": 100000}}
    ]
  }
}
```

```json
{
  "model": "claude-sonnet-5",
  "context_management": {
    "compaction": {"trigger": {"type": "input_tokens", "value": 150000}}
  }
}
```

:::tip[Signal d’examen]
« Les anciens résultats d’outils gonflent la fenêtre mais le fil de conversation doit rester intact » → **compaction** (résumer, préserver le fil). « De grandes sorties d’outils périmées ne sont plus nécessaires » → **édition de contexte** (les effacer). Ni l’un ni l’autre n’est « juste augmenter `max_tokens` », qui n’affecte que la longueur de sortie.
:::

---

## 4.9 Few-shot example selection

Les exemples few-shot orientent la forme et la qualité de la sortie — mais seulement s’ils sont **représentatifs, diversifiés et corrects**. Une mauvaise sélection d’exemples peut nuire plus qu’aider.

| Principle | Why it matters |
| --- | --- |
| **Représentatifs** | Les exemples doivent correspondre à la distribution réelle des entrées, y compris les cas difficiles/limites |
| **Diversifiés** | Couvrir la gamme de catégories/formats pour que le modèle ne surapprenne pas un seul pattern |
| **Corrects et cohérents** | Un exemple faux ou incohérent enseigne le mauvais pattern ; gardez un formatage identique |
| **Ordonnés délibérément** | Grouper par type ou escalader la difficulté ; garder avant la requête (préfixe stable, mettable en cache) |
| **Bon nombre (2–5)** | Assez pour montrer le pattern sans gonfler le contexte ; plus n’est pas toujours mieux |
| **Sélection dynamique** | Pour des entrées variées, récupérer les quelques exemples les plus similaires à l’entrée courante |

:::tip[Signal d’examen]
« Le modèle gère les cas courants mais échoue sur les cas limites » → ajoutez des **exemples de cas limites représentatifs**, pas seulement plus de cas courants. « La sortie surapprend un seul format » → augmentez la **diversité des exemples**. Placez les exemples dans le préfixe stable pour qu’ils restent mettables en cache.
:::

---

## 4.10 Prefilling, stop sequences and chain-of-thought placement

Trois leviers fins façonnent *comment* le modèle produit la sortie, et l’examen teste quand chacun aide.

| Lever | What it does | When to use | Pitfall |
| --- | --- | --- | --- |
| **Prefill** | Amorcer le début du tour de l’assistant (p. ex. `{`) pour contraindre le format | Forcer un début JSON, forcer une ouverture spécifique | Impossible de préremplir quand le thinking est activé (le thinking doit venir en premier) |
| **`stop_sequences`** | Arrêter la génération à un marqueur | Couper après un délimiteur ; borner la sortie | Le texte du marqueur n’est pas inclus dans la sortie |
| **Chain-of-thought / thinking** | Raisonner pas à pas avant de répondre | Raisonnement multi-étapes difficile | Ne demandez pas du raisonnement *et* du JSON strict dans un seul bloc — séparez-les |

```python
# Prefill pour forcer un début d'objet JSON (thinking OFF)
messages = [
    {"role": "user", "content": "Return the invoice as JSON."},
    {"role": "assistant", "content": "{"},   # le modèle continue un JSON valide à partir d'ici
]
```

:::caution[Prefill vs thinking]
Vous ne pouvez pas préremplir le tour de l’assistant quand le thinking étendu/adaptatif est activé — le bloc `thinking` doit être en premier. Si vous avez besoin à la fois du raisonnement et d’un format contraint, utilisez les **sorties structurées** (`output_config.format`) plutôt qu’un prefill, ou exécutez le raisonnement dans une étape séparée.
:::

---

## 4.11 Grounding and hallucination control

La fiabilité de format (sorties structurées) est distincte de la fiabilité *factuelle*. Pour garder les réponses ancrées, ingéniez le contexte et la requête, pas seulement le schéma.

| Technique | Effect |
| --- | --- |
| **Ordonnancement documents-d’abord, requête-en-dernier** | Le modèle lit les preuves avant la question → meilleur ancrage |
| **« Réponds uniquement à partir des documents fournis ; si absent, dis-le »** | Supprime les suppositions non ancrées |
| **`citations` de document** | Force le modèle à pointer les passages sources utilisés |
| **Récupération (RAG) des bons passages** | Met les preuves réelles dans le contexte |
| **Validation des affirmations par rapport aux sources** | Attrape les valeurs fabriquées avant qu’elles ne partent |

:::tip[Signal d’examen]
« Assuré mais faux / faits fabriqués » → contrôles d’ancrage (documents-d’abord, « réponds uniquement à partir du contexte », citations, RAG, validation des affirmations), pas `temperature` ni un `max_tokens` plus grand. La conformité au schéma n’empêche pas une valeur fausse-mais-bien-formatée.
:::

---

## 4.12 Common misconceptions

| Misconception | Reality | Why it matters on the exam |
| --- | --- | --- |
| Demander du JSON dans le prompt suffit | Le JSON par prompt seul dérive ; utilisez `output_config.format` / `strict` + validation-retry | Questions de sortie structurée |
| Une sortie assurée est une sortie validée | Fluidité ≠ validité ; parsez de manière défensive | Éviter l’anti-pattern nº 7 |
| Réessayer avec le même prompt corrige un mauvais JSON | Réinjectez l’erreur spécifique pour que la tentative suivante la cible | Conception de la validation-retry |
| La conformité au schéma signifie que les valeurs sont correctes | La forme est garantie, pas la sémantique ; validez les valeurs et ancrez les affirmations | Sépare le format de la fiabilité factuelle |
| Un `max_tokens` plus grand corrige un agent gonflé | Traitez le contexte via édition/compaction/isolation | Piège de gestion du contexte |
| L’ordre documents vs question n’a pas d’importance | Documents-d’abord, requête-en-dernier améliore ancrage et caching | Ordonnancement du long contexte |
| Plus d’exemples few-shot aident toujours | Des exemples représentatifs, diversifiés et corrects comptent plus que le volume | Questions d’échec sur cas limites |
| On peut préremplir quand le thinking est activé | Non ; le bloc de thinking doit venir en premier — utilisez plutôt les sorties structurées | Piège prefill-vs-thinking |

---

## 4.13 Scenario walkthrough: a flaky invoice extractor

**Scénario.** Un endpoint d’extraction sur Sonnet 5 doit renvoyer `{total_cents: int, currency: str}` pour chaque facture et citer la ligne d’où il a lu le total. En production, il échoue de trois façons : (1) environ 3 % des réponses sont du JSON presque valide avec un champ supplémentaire en fin ; (2) un `try/except` défensif renvoie actuellement `{}` marqué « success » quand le parsing échoue, laissant passer silencieusement de mauvaises lignes ; (3) sur des factures manuscrites scannées, il renvoie avec assurance un total plausible-mais-faux. L’équipe demande s’il faut augmenter `temperature`, passer à Opus 5, ou augmenter `max_tokens`.

**Trace de raisonnement d’expert.**

1. **Imposez la forme, ne la suppliez pas.** La dérive du champ supplémentaire se corrige avec **`output_config.format` et le schéma JSON** (ou un outil `strict: true`), qui contraint la sortie au schéma. Le JSON par prompt seul est l’option la plus faible.
2. **Arrêtez la suppression silencieuse.** Renvoyer `{}`-comme-succès est l’**anti-pattern nº 7**. Remplacez-le par une boucle de **validation-retry** qui valide par rapport au schéma et, en cas d’échec, réinjecte l’erreur *spécifique* au modèle ; si cela échoue encore, échouez bruyamment avec un contexte de diagnostic. Ne rapportez jamais un échec comme un succès vide.
3. **Ancrez la fiabilité factuelle séparément.** Le total assuré-mais-faux sur les factures manuscrites est un problème d’*ancrage*, pas de format. Activez les **citations de document**, instruisez « réponds uniquement à partir du document fourni », et **validez le total extrait par rapport au passage cité**. Envisagez des **exemples few-shot représentatifs incluant les cas manuscrits** (diversité plutôt que volume).
4. **Rejetez les leviers tentants.** « Augmenter `temperature` » — accroît la variabilité, l’opposé de ce que vous voulez. « Passer à Opus 5 » — peut aider marginalement mais ne corrige ni la contrainte de schéma manquante ni le bug de suppression silencieuse ; c’est un non-correctif sur-dimensionné. « Augmenter `max_tokens` » — traite la troncature, qui n’est pas l’échec rapporté.
5. **Ordonnez le prompt pour l’ancrage et le caching.** Placez les instructions/schéma stables et le document en premier (préfixe mettable en cache), la requête d’extraction en dernier.

**Décision correcte.** Sortie contrainte par schéma plus une boucle de validation-retry qui réinjecte les erreurs et échoue bruyamment ; citations de document et « réponds uniquement à partir du contexte » plus validation valeur-vs-source pour l’ancrage factuel ; exemples few-shot manuscrits représentatifs ; disposition documents-d’abord, requête-en-dernier. La température, le changement de modèle et `max_tokens` sont rejetés comme des correctifs de mauvais levier.

---

## Pièges de l’examen dans ce domaine
| Piège | Pourquoi c’est faux |
| --- | --- |
| Faire confiance à une sortie assurée sans validation | Fluidité ≠ validité ; validez par rapport à un schéma |
| Se fier à la confiance auto-déclarée | Anti-pattern nº 4 ; utilisez une validation programmatique |
| Avaler les erreurs de parsing comme un succès vide | Anti-pattern nº 7 ; remontez et réessayez |
| Forcer un outil sur Fable 5.1 pour une sortie structurée | Renvoie 400 ; utilisez `output_config.format` / `strict` |
| Augmenter seulement `max_tokens` pour corriger un agent gonflé | Traitez le contexte via édition/compaction/isolation |
| Placer la requête avant de longs documents | Nuit à l’ancrage et au caching ; documents d’abord, requête en dernier |
| Aucun exemple/spécification de format quand la sortie doit être parsable | Les prompts sous-spécifiés dérivent en forme |
| Application par prompt des règles critiques | Relève des hooks/validation, pas du prompt |
| Insérer des valeurs par requête (horodatage, nom d’utilisateur) dans le préfixe mis en cache | Tout changement d’octet manque le cache ; gardez la variabilité après le point de rupture |
| Utiliser la compaction pour supprimer de grandes sorties d’outils périmées | C’est le rôle de l’édition de contexte ; la compaction résume pour préserver le fil |
| Ajouter plus d’exemples few-shot de cas courant pour corriger les échecs sur cas limites | Ajoutez des exemples de cas limites représentatifs ; la diversité l’emporte sur le volume |
| Placer les exemples few-shot après la requête | Gardez les exemples dans le préfixe stable pour qu’ils restent mettables en cache et lus avant la tâche |
| Traiter la conformité au schéma comme une exactitude factuelle | La forme est garantie, pas les valeurs ; ancrez les affirmations et validez la sémantique |
| Augmenter `temperature` pour corriger une sortie assurée-mais-fausse | La fabrication est un problème d’ancrage ; utilisez documents-d’abord, citations, RAG et validation des affirmations |
| Essayer de préremplir le tour de l’assistant quand le thinking est activé | Le bloc de thinking doit être en premier ; utilisez plutôt les sorties structurées |
| Réessayer un JSON invalide avec le prompt identique | Réinjectez l’erreur de parsing/schéma spécifique pour que la tentative suivante la cible |
| Demander un raisonnement pas à pas et du JSON strict dans un seul bloc | Séparez le raisonnement de la réponse structurée, ou utilisez les sorties structurées |

---

## Questions d’entraînement
<Accordions>
  <AccordionItem title="Q1 · Un endpoint d’extraction doit renvoyer à chaque fois du JSON conforme à un schéma fixe. Quelle approche est la plus fiable ? (Sélectionnez une réponse)">
    A. Demander gentiment du JSON dans le prompt et espérer.
    B. Utiliser `output_config.format` avec un schéma JSON (ou un schéma d’outil `strict: true`) plus la validation-retry.
    C. Régler `temperature: 0` uniquement.
    D. Augmenter `max_tokens`.

    **Réponse : B.** La sortie structurée contrainte par schéma avec validation-retry est le pattern fiable. Le prompt seul (A) dérive ; la température (C) et `max_tokens` (D) n’imposent pas la forme.
  </AccordionItem>

  <AccordionItem title="Q2 · Un parser reçoit occasionnellement du JSON malformé et renvoie actuellement un objet vide comme s’il avait réussi. Qu’est-ce qui ne va pas et quel est le correctif ? (Sélectionnez une réponse)">
    A. Rien ; le vide est un défaut sûr.
    B. Il supprime silencieusement les erreurs (anti-pattern nº 7) ; validez par rapport au schéma et réessayez avec l’erreur, ou échouez bruyamment.
    C. Baisser la température.
    D. Passer à Opus 5.

    **Réponse : B.** Renvoyer un succès vide masque les échecs. Le parsing défensif valide et soit réessaie avec l’erreur, soit la remonte. La température (C) et le choix de modèle (D) ne corrigent pas la suppression silencieuse.
  </AccordionItem>

  <AccordionItem title="Q3 · Un agent de longue durée devient plus lent et moins focalisé à mesure que les sorties d’outils s’accumulent. Quelles DEUX techniques traitent cela ? (Sélectionnez deux réponses)">
    A. L’édition de contexte pour effacer les résultats d’outils périmés.
    B. Augmenter `max_tokens`.
    C. La compaction / le résumé de l’historique.
    D. Ajouter plus d’outils.
    E. Augmenter la température.

    **Réponse : A et C.** L’édition de contexte et la compaction/le résumé réduisent le gonflement et la dérive. `max_tokens` (B) plafonne la sortie ; plus d’outils (D) et la température (E) n’aident pas.
  </AccordionItem>

  <AccordionItem title="Q4 · Un prompt place la question de l’utilisateur avant un document de 300 pages. Les réponses sont mal ancrées. Quel ordonnancement est meilleur et pourquoi ? (Sélectionnez une réponse)">
    A. Le garder ; l’ordre n’a pas d’importance.
    B. Placer le document en premier et la question en dernier, ce qui améliore l’ancrage et permet la mise en cache du préfixe stable.
    C. Mettre les deux dans le prompt système.
    D. Découper le document en de nombreux messages au hasard.

    **Réponse : B.** Documents-d’abord, requête-en-dernier améliore l’ancrage sur le long contexte et rend le préfixe stable mettable en cache. L’ordre a bien de l’importance (A) ; le découpage aléatoire (D) nuit à la cohérence.
  </AccordionItem>

  <AccordionItem title="Q5 · Une équipe veut forcer un outil d’extraction spécifique sur Fable 5.1 pour garantir une sortie structurée. Que devrait-elle faire à la place ? (Sélectionnez une réponse)">
    A. Forcer l’outil quand même ; cela fonctionne sur tous les modèles.
    B. Utiliser `output_config.format` avec un schéma JSON, puisque Fable 5.1 rejette le `tool_choice` forcé.
    C. Désactiver le thinking.
    D. Baisser `max_tokens`.

    **Réponse : B.** Fable 5.1 renvoie 400 pour les outils forcés ; utilisez `output_config.format` (ou `strict: true` / `auto` + instruction). Forcer (A) échoue ; le thinking (C) et `max_tokens` (D) sont sans rapport.
  </AccordionItem>

  <AccordionItem title="Q6 · La forme de la sortie est incohérente d’une exécution à l’autre, la rendant difficile à parser. Quels DEUX leviers de prompt améliorent le plus directement la cohérence ? (Sélectionnez deux réponses)">
    A. Fournir 2–5 exemples few-shot entrée→sortie.
    B. Spécifier le format de sortie exact (et envisager de préremplir le tour de l’assistant).
    C. Augmenter la température.
    D. Ajouter une instruction de ton amical.
    E. Retirer le prompt système.

    **Réponse : A et B.** Les exemples et une spécification de format explicite (avec prefill) contraignent la forme. Une température plus élevée (C) accroît la variabilité ; le ton (D) et retirer le prompt système (E) n’aident pas la forme.
  </AccordionItem>

  <AccordionItem title="Q7 · Une boucle de validation-retry rejette le JSON du modèle mais renvoie seulement le prompt d’origine à chaque fois, si bien que la même erreur se reproduit. Quel est le correctif ? (Sélectionnez une réponse)">
    A. Augmenter le nombre de retries à 10.
    B. Réinjecter l’erreur spécifique de schéma/parsing au modèle comme un nouveau tour utilisateur pour qu’il corrige ce problème exact.
    C. Passer à Opus 5.
    D. Baisser `max_tokens`.

    **Réponse : B.** Une validation-retry efficace ajoute la sortie fautive et l’erreur concrète (« Invalid : total must be a number ») pour que la tentative suivante cible le défaut réel. Réessayer aveuglément (A) répète la même erreur ; le choix de modèle (C) et `max_tokens` (D) ne communiquent pas ce qui n’allait pas.
  </AccordionItem>

  <AccordionItem title="Q8 · La fenêtre d’un agent est dominée par de grands résultats d’outils anciens et inutiles, mais le fil narratif de la conversation doit rester cohérent pour le raisonnement ultérieur. Quel contrôle convient, et lequel non ? (Sélectionnez une réponse)">
    A. La compaction, car elle supprime purement les résultats d’outils.
    B. L’édition de contexte pour effacer les résultats d’outils périmés ; si le fil narratif lui-même était trop long, la compaction (résumer, préserver le fil) serait le choix.
    C. Juste augmenter `max_tokens`.
    D. Redémarrer la session et perdre tout l’état.

    **Réponse : B.** L’édition de contexte efface les sorties d’outils périmées ; la compaction sert à condenser un long fil narratif tout en le préservant. `max_tokens` (C) ne plafonne que la sortie ; redémarrer (D) jette l’état nécessaire. La compaction ne se contente pas de supprimer (A).
  </AccordionItem>

  <AccordionItem title="Q9 · Un prompt réutilisé à chaque requête insère l’horodatage courant dans le prompt système, et les taux de cache hit sont proches de zéro. Pourquoi, et quel est le correctif ? (Sélectionnez une réponse)">
    A. Le caching est désactivé sur Sonnet 5.
    B. Tout changement d’octet dans le préfixe (l’horodatage) invalide le cache ; déplacez les valeurs par requête après le point de rupture du cache et gardez le préfixe stable.
    C. Le préfixe est trop court ; remplissez-le d’espaces.
    D. Augmenter le TTL à 1 heure.

    **Réponse : B.** Un préfixe de caching doit être identique octet par octet pour faire un hit ; un horodatage par requête le change à chaque appel. Gardez le contenu variable dans la queue après le point de rupture. Le caching n’est pas désactivé (A) ; le remplissage d’espaces (C) ne corrige pas un préfixe changeant ; un TTL plus long (D) exige toujours des octets identiques.
  </AccordionItem>

  <AccordionItem title="Q10 · Un résumeur traite bien les documents courants mais gère mal de façon répétée un format de cas limite rare. Quels DEUX changements l’améliorent le mieux ? (Sélectionnez deux réponses)">
    A. Ajouter des exemples few-shot représentatifs qui incluent le format de cas limite.
    B. Ajouter dix exemples de plus du format courant.
    C. Augmenter la diversité des exemples pour couvrir la gamme de formats.
    D. Augmenter la température.
    E. Retirer tous les exemples.

    **Réponse : A et C.** Les échecs sur cas limites appellent des exemples de cas limites représentatifs et plus de diversité, pas plus du même cas courant (B). La température (D) ajoute de la variabilité ; retirer les exemples (E) supprime entièrement l’orientation.
  </AccordionItem>

  <AccordionItem title="Q11 · Un prompt de QA sur long document place la question de l’utilisateur en premier, puis 200 pages de source. Les réponses sont mal ancrées et le caching n’aide jamais. Quel réordonnancement corrige les deux ? (Sélectionnez une réponse)">
    A. Garder l’ordre ; déplacer la question dans le prompt système.
    B. Placer les documents (et instructions stables) en premier avec un point de rupture de cache, et la question en dernier.
    C. Intercaler la question entre chaque page.
    D. Découper les documents en de nombreuses requêtes séparées au hasard.

    **Réponse : B.** Documents-d’abord, requête-en-dernier améliore l’ancrage et rend le préfixe stable mettable en cache d’un seul geste. Déplacer la question dans le prompt système (A) la place toujours avant les preuves ; l’intercalage (C) et le découpage aléatoire (D) nuisent à la cohérence et au caching.
  </AccordionItem>

  <AccordionItem title="Q12 · Un parser défensif attrape un JSON invalide et renvoie un résultat vide marqué « success » pour que le pipeline continue de tourner. De quel anti-pattern s’agit-il et que devrait-il se passer à la place ? (Sélectionnez une réponse)">
    A. C’est bien ; les résultats vides sont un défaut sûr.
    B. Suppression silencieuse des erreurs (anti-pattern nº 7) ; validez par rapport au schéma et soit réessayez avec l’erreur réinjectée, soit échouez bruyamment avec un contexte de diagnostic.
    C. Recours à l’auto-déclaration ; demander au modèle sa confiance.
    D. Sur-ingénierie ; retirer la validation.

    **Réponse : B.** Renvoyer un vide-comme-succès masque les échecs en aval (anti-pattern nº 7). Le comportement correct est de remonter l’erreur — réessayer avec le message de validation spécifique ou échouer bruyamment. Les défauts vides (A) masquent le problème ; l’auto-déclaration de confiance (C) est un anti-pattern différent (nº 4) ; retirer la validation (D) aggrave la situation.
  </AccordionItem>

  <AccordionItem title="Q13 · Un extracteur renvoie du JSON bien formaté, mais sur les factures manuscrites scannées, la valeur `total_cents` est fausse avec assurance. Quel ensemble de changements traite le MIEUX ceci ? (Sélectionnez une réponse)">
    A. Augmenter `temperature` pour qu’il explore davantage.
    B. Activer les citations de document, instruire « réponds uniquement à partir du document fourni », valider la valeur par rapport au passage cité, et ajouter des exemples few-shot manuscrits représentatifs.
    C. Augmenter `max_tokens`.
    D. Passer à un schéma `strict: true` et considérer le problème résolu.

    **Réponse : B.** Une valeur assurée-mais-fausse est un problème d’ancrage, traité par les citations, la réponse-uniquement-à-partir-du-contexte, la validation valeur-vs-source et des exemples représentatifs. La température (A) ajoute de la variabilité ; `max_tokens` (C) concerne la troncature ; un schéma strict (D) corrige la forme, pas l’exactitude factuelle.
  </AccordionItem>

  <AccordionItem title="Q14 · Un développeur veut forcer du JSON en préremplissant le tour de l’assistant avec `{`, mais la requête active aussi le thinking adaptatif, et cela renvoie une erreur. Pourquoi, et que devrait-il faire ? (Sélectionnez une réponse)">
    A. Le prefill fonctionne toujours ; l’erreur est transitoire.
    B. Vous ne pouvez pas préremplir quand le thinking est activé (le bloc de thinking doit venir en premier) ; utilisez plutôt les sorties structurées `output_config.format`, ou exécutez le raisonnement séparément.
    C. Le prefill requiert `tool_choice: 'any'`.
    D. Baisser `max_tokens` pour que le prefill tienne.

    **Réponse : B.** Avec le thinking activé, le tour de l’assistant doit commencer par le bloc de thinking, donc un prefill entre en conflit ; les sorties structurées obtiennent du JSON contraint sans prefill. L’erreur n’est pas transitoire (A) ; le prefill ne requiert pas d’outils forcés (C) ; `max_tokens` (D) est sans rapport.
  </AccordionItem>

  <AccordionItem title="Q15 · Quelle affirmation capture le mieux la relation entre la sortie contrainte par schéma et l’exactitude ? (Sélectionnez une réponse)">
    A. Un schéma garantit à la fois la forme et la vérité des valeurs.
    B. Un schéma garantit la forme ; les valeurs peuvent toujours être fausses, donc validez la sémantique et ancrez les affirmations séparément.
    C. Les schémas ne sont que cosmétiques et ne contraignent pas la sortie.
    D. Un schéma supprime le besoin de toute validation.

    **Réponse : B.** `output_config.format`/`strict` contraignent la forme, pas l’exactitude sémantique ; l’ancrage et la validation des valeurs restent nécessaires. Il ne garantit pas la vérité (A) ; il contraint bien la sortie (C) ; et il ne supprime pas la validation sémantique (D).
  </AccordionItem>

  <AccordionItem title="Q16 · Un prompt demande au modèle de raisonner pas à pas et, dans le même bloc, d’émettre uniquement du JSON strict. La sortie est incohérente. Quel est le meilleur correctif ? (Sélectionnez une réponse)">
    A. Augmenter `max_tokens`.
    B. Séparer le raisonnement de la réponse structurée — raisonner d’abord (ou utiliser le thinking), puis produire le JSON via les sorties structurées — plutôt que de mélanger les deux dans un seul bloc.
    C. Augmenter la température pour la variété.
    D. Retirer entièrement le schéma.

    **Réponse : B.** Mélanger un raisonnement libre et du JSON strict dans un seul bloc se contredit ; séparez les étapes ou utilisez les sorties structurées pour la réponse finale. `max_tokens` (A) et la température (C) ne résolvent pas le conflit ; retirer le schéma (D) abandonne l’exigence.
  </AccordionItem>

  <AccordionItem title="Q17 · Une boucle de validation-retry échoue en boucle parce qu’elle renvoie le même prompt et ne dit jamais au modèle ce qui n’allait pas. Quel changement la corrige ? (Sélectionnez une réponse)">
    A. Monter le nombre de retries à 15.
    B. Ajouter la sortie fautive plus l’erreur concrète (« currency must be one of USD/EUR/GBP ») comme un nouveau tour utilisateur pour que la tentative suivante corrige ce défaut exact.
    C. Passer à Opus 5 pour les retries.
    D. Baisser `max_tokens` à chaque retry.

    **Réponse : B.** Réinjecter l’erreur spécifique permet au modèle de cibler le défaut réel. Répéter aveuglément (A) reproduit la même erreur ; un modèle différent (C) n’apprend toujours pas ce qui n’allait pas ; baisser `max_tokens` (D) ne communique rien et risque la troncature.
  </AccordionItem>

  <AccordionItem title="Q18 · Un résumeur gère bien les factures courantes mais échoue sur un format manuscrit rare. Quels DEUX changements few-shot aident le plus ? (Sélectionnez deux réponses)">
    A. Ajouter des exemples représentatifs qui incluent le format manuscrit.
    B. Augmenter la diversité des exemples pour couvrir la gamme de formats.
    C. Ajouter dix exemples de plus du format courant.
    D. Augmenter la température.
    E. Retirer tous les exemples.

    **Réponse : A et B.** Les échecs sur cas limites nécessitent des exemples de cas limites représentatifs et plus de diversité, pas plus du cas courant (C). La température (D) ajoute de la variabilité ; retirer les exemples (E) supprime l’orientation.
  </AccordionItem>
</Accordions>

## À retenir
- Soyez clair et direct ; utilisez des balises XML pour séparer les instructions des données ; ajoutez des exemples ; utilisez rôle, chain-of-thought et prefilling délibérément.
- Préférez la sortie structurée contrainte par schéma (`output_config.format`, outils `strict: true`) au JSON par prompt seul.
- Parsez de manière défensive : validez par rapport à un schéma et réessayez avec l’erreur ; n’avalez jamais les échecs et ne faites pas confiance à la confiance auto-déclarée.
- Sur Fable 5.1, utilisez les sorties structurées plutôt que de forcer un outil.
- Prévenez le gonflement/la dérive du contexte avec l’élagage des sorties d’outils, l’édition de contexte, la compaction, le résumé et l’isolation par subagents.
- Ordonnez les longs contextes documents-d’abord, requête-en-dernier – meilleur ancrage et disposition favorable au cache.
- La conformité au schéma (`output_config.format` / `strict`) garantit la forme, pas les valeurs — ancrez les affirmations avec l’ordonnancement documents-d’abord, les citations, le RAG et la validation des valeurs.
- La validation-retry doit réinjecter l’erreur *spécifique* ; renvoyer le même prompt ne fait que reproduire l’erreur.
- Vous ne pouvez pas préremplir le tour de l’assistant quand le thinking est activé ; utilisez les sorties structurées, et ne mélangez jamais un raisonnement libre avec du JSON strict dans un seul bloc.
- Pour les échecs sur cas limites, ajoutez des exemples few-shot de cas limites représentatifs et augmentez la diversité plutôt que d’empiler plus d’exemples de cas courant.
