Le domaine 5 pèse 15 % — environ 9 questions sur 60. C'est le plus petit, et le plus transversal : ses questions reprennent des situations des quatre autres domaines (sous-agents, outils, sessions, extraction) sous un angle unique — que se passe-t-il quand ça ne tient pas, quand ça tombe, quand ça se contredit ? Un candidat qui a bien travaillé les domaines 1 à 4 a déjà 70 % de ce domaine ; le reste, c'est un petit nombre de réflexes de fiabilité que l'examen attend nommément : résumé structuré plutôt que troncature, résultat partiel avec trous explicites plutôt que rien, erreur enrichie plutôt qu'avalée ou brute, source rattachée à chaque affirmation, normalisation à l'ingestion.
Cette leçon suit les 6 task statements du guide officiel v1.0 (juillet 2026). Les scénarios d'examen qui tirent sur ce domaine sont le Multi-Agent Research System (scénario 3), le Document Processing Pipeline (scénario 6) et Developer Productivity (scénario 4).
La carte du domaine
Trois questions structurent le domaine : combien ça tient (5.1 budget, 5.2 compactage), ce qui survit (5.3 mémoire), et ce qui se passe quand ça casse (5.4 dégradation, 5.5 propagation, 5.6 attribution et formats).
5.1 — Le budget de contexte
La fenêtre de contexte n'est pas « grande » ou « petite » : c'est un budget que quatre postes se partagent. L'examen teste si tu sais ce qui le consomme et ce qui doit y rester.
Ce qu'il faut savoir
Quatre postes. Le system prompt et les définitions d'outils (fixes, payés à chaque tour), l'historique de conversation (croît), les résultats d'outils (le poste qui explose : fichiers lus, pages récupérées, logs). Un agent qui lit 30 fichiers en entier a consommé sa fenêtre avant d'avoir commencé à raisonner.
La qualité se dégrade avant la limite. Ce n'est pas un mur : c'est une pente. Dilution de l'attention (domaine 1, 1.6), instructions du début moins respectées, résultats contradictoires selon la position dans le contexte. Un « modèle avec plus de contexte » repousse le mur, pas la pente.
Déporter le verbeux. Un sous-agent (Explore en Claude Code, Task dans le SDK) fait la lecture dans son propre contexte isolé et ne renvoie qu'un résumé (domaine 3, 3.4). C'est la réponse attendue dès que l'énoncé parle de « lire des dizaines de fichiers », « parcourir le codebase », « dépouiller des documents ».
Résumer avant d'injecter. Un résultat d'outil volumineux est réduit à ses faits utiles avant d'entrer dans la fenêtre : hook PostToolUse (domaine 1, 1.5) ou pré-traitement côté outil.
Restreindre le fixe. Outils par rôle (domaine 2, 2.3), règles à glob chargées conditionnellement (domaine 3, 3.3) : chaque token fixe non pertinent est payé à chaque tour.
5.2 — Compactage : le résumé structuré
Quand la fenêtre approche de la limite en cours de tâche, il faut faire de la place. La question est comment : ce qu'on garde, ce qu'on résume, ce qu'on jette.
Ce qu'il faut savoir
Le résumé structuré. Quand on compacte, on remplace l'historique par un résumé qui conserve : l'objectif et les contraintes d'origine, les décisions prises et pourquoi, les faits vérifiés (avec leur source), les trous et incertitudes, ce qui a été tenté et a échoué, les prochaines étapes. On jette les résultats d'outils bruts et les allers-retours de raisonnement.
Pourquoi pas la troncature. Couper le début supprime l'objectif et les contraintes : l'agent continue à travailler, mais sur une tâche dont il ne connaît plus les règles. La fenêtre glissante (garder les N derniers tours) a le même défaut, avec un coût borné ; acceptable pour une conversation courte sans état, pas pour une tâche multi-phases.
Quand repartir de zéro. Si le compactage laisse un contexte dont la majorité est périmée (le code a changé, les résultats ne reflètent plus l'état réel), on démarre une session neuve avec le résumé structuré en contexte initial (domaine 1, 1.7). Le résumé est le format d'échange entre sessions.
Résumer par phase. Sur une tâche longue, on compacte à chaque changement de phase (fin de l'exploration → résumé → implémentation), pas uniquement quand la limite approche. Le compactage devient un rythme, pas une urgence.
COMPACTION_SCHEMA = {
"name": "compact_context",
"description": "Produit le résumé structuré qui remplace l'historique. Ne conserve AUCUNE sortie d'outil brute.",
"input_schema": {"type": "object", "properties": {
"goal": {"type": "string", "description": "Objectif d'origine, contraintes incluses"},
"decisions": {"type": "array", "items": {"type": "object",
"properties": {"what": {"type": "string"}, "why": {"type": "string"}}, "required": ["what", "why"]}},
"verified_facts": {"type": "array", "items": {"type": "object",
"properties": {"fact": {"type": "string"}, "source": {"type": "string"}}, "required": ["fact", "source"]}},
"open_gaps": {"type": "array", "items": {"type": "string"}},
"failed_attempts": {"type": "array", "items": {"type": "string"}},
"next_steps": {"type": "array", "items": {"type": "string"}},
"touched_files": {"type": "array", "items": {"type": "string"}},
}, "required": ["goal", "decisions", "verified_facts", "open_gaps", "next_steps"]},
}
def compact(messages):
resp = client.messages.create(model=M, max_tokens=2048, tools=[COMPACTION_SCHEMA],
tool_choice={"type": "tool", "name": "compact_context"},
messages=messages + [{"role": "user", "content": "Compacte l'historique."}])
summary = next(b for b in resp.content if b.type == "tool_use").input
# Nouveau contexte : system + résumé structuré + les 2 derniers tours bruts
return [{"role": "user", "content": f"<context_summary>{json.dumps(summary, ensure_ascii=False)}</context_summary>"}] + messages[-4:]5.3 — Mémoire persistante entre sessions
Une session se termine. Ce qui doit survivre dépend de sa nature — et l'examen teste précisément ce choix d'emplacement.
Quel mécanisme de mémoire pour quelle information ?
| Information | Emplacement attendu | |
|---|---|---|
| Conventions, standards, architecture stable | « Toujours vrai », partagé par l'équipe | CLAUDE.md projet (versionné) — domaine 3 |
| État d'un travail en cours | Décisions, trous, prochaines étapes d'une tâche multi-jours | Fichier de mémoire / résumé structuré injecté au démarrage |
| Historique volumineux, recherche | Milliers de tickets, décisions passées, documents | Base externe (SQL, vecteurs) interrogée par un outil |
| Préférences personnelles | Style, langue, outils favoris d'un développeur | ~/.claude/CLAUDE.md (jamais partagé) |
| Résultats d'outils bruts, logs | Fichiers lus, pages récupérées, sorties de tests | Ne PAS persister — se régénèrent, se périment |
| Sessions d'investigation nommées | Reprendre une analyse encore valide | --resume <nom> (+ signaler les fichiers modifiés) |
Ce qu'il faut savoir
Choisir par nature, pas par commodité. Une convention va dans CLAUDE.md parce qu'elle est stable et partagée. L'état d'un travail en cours va dans un fichier de mémoire ou un résumé structuré parce qu'il est temporaire et propre à une tâche. Un historique volumineux va dans une base externe parce qu'il ne tient pas dans un fichier et qu'on le cherche plutôt qu'on ne le lit.
Ce qu'on ne persiste pas. Les résultats d'outils bruts : ils se régénèrent en un appel et se périment vite. Persister un fichier lu hier, c'est raisonner demain sur une version fausse. On persiste les conclusions tirées, avec leur source, pas la matière première.
Le résumé structuré comme format d'échange. Le même schéma qu'en 5.2 sert de mémoire entre sessions : écrit en fin de session, injecté au démarrage de la suivante. Il est daté et liste les fichiers touchés, ce qui permet de savoir ce qui a pu changer.
Mémoire ≠ contexte. Une base externe ne charge pas tout dans la fenêtre : un outil l'interroge et ne renvoie que les entrées pertinentes. C'est ce qui permet d'avoir une mémoire de plusieurs mois sans exploser le budget de 5.1.
CLAUDE.md » : ce fichier est chargé à chaque session, il grossit, et l'état temporaire d'une tâche pollue les conventions permanentes. « Persister l'historique complet de la conversation » : verbeux, périmé, et il faut le relire en entier. « Une base vectorielle pour les conventions d'équipe » : sur-dimensionné pour vingt lignes stables qui doivent être lues à chaque fois, pas cherchées.5.4 — Dégradation gracieuse
Un outil ne répond pas, une source est indisponible, un traitement dépasse son délai. L'examen a une position claire : un résultat partiel honnête vaut mieux que rien, et infiniment mieux qu'un succès menteur.
Ce qu'il faut savoir
Timeouts bornés. Tout appel externe a un délai maximal. Sans lui, un outil qui ne répond pas bloque l'agent, puis le coordinateur, puis le pipeline.
Fallback. Quand l'appel principal échoue : source alternative (deuxième moteur de recherche, cache de la veille), retry avec backoff pour le transitoire (domaine 2, 2.2), ou dégradation de la fonctionnalité (rapport sans la section brevets plutôt que pas de rapport).
Le résultat partiel avec trous explicites. La sortie porte son état de complétude : ce qui est couvert, ce qui manque, pourquoi, si c'est réessayable. Un rapport sur quatre sources sur cinq, avec la cinquième signalée manquante, est un livrable. Un rapport « complet » qui cache l'absence de la cinquième est une erreur de données.
Jamais de succès menteur. Transformer un échec en résultat vide marqué succès est l'anti-pattern le plus grave du domaine (déjà croisé en 2.2 et 5.5). L'incertitude s'exprime : confidence, status, missing[].
5.5 — Propagation d'erreurs entre agents
Question 8 du guide officiel. Le sous-agent de recherche web échoue sur timeout ; selon la version, le coordinateur reçoit une erreur brute qui tue le workflow, ou rien du tout et produit un rapport sans savoir qu'il lui manque une source. Que faire ?
Ce qu'il faut savoir
Récupération locale d'abord. Le sous-agent gère lui-même ce qu'il peut : retry avec backoff sur le transitoire, source alternative si elle est dans son périmètre. Il ne remonte que ce qu'il n'a pas pu résoudre.
Enrichir ce qui remonte. L'erreur transmise au coordinateur contient : la catégorie (transient / validation / business / permission), ce qui a été tenté (et combien de fois), les résultats partiels obtenus, les alternatives possibles. C'est ce qui permet au coordinateur de choisir : re-déléguer, continuer avec un trou signalé, relancer plus tard, escalader.
Le coordinateur décide. Pas le sous-agent : il ne voit que sa tâche, le coordinateur voit l'ensemble (les quatre autres sources, le délai, l'importance relative de la source manquante). C'est cohérent avec le hub-and-spoke du domaine 1.
Ni suppression, ni brut. Les deux distracteurs de la question 8 : « attraper l'erreur et renvoyer un résultat vide en succès » (le coordinateur produit un rapport troué sans le savoir) et « retry local puis statut d'échec générique » (le retry est bon, le générique empêche la décision).
# Sous-agent : récupération locale, puis erreur ENRICHIE vers le coordinateur
def web_search_subagent(queries: list[str]) -> dict:
results, failed = [], []
for q in queries:
try:
results += search_with_retry(q, attempts=2, backoff=1.5, timeout=30) # récupération locale
except TransientError as e:
failed.append({"query": q, "category": "transient", "attempts": 2, "last_error": str(e)})
if not failed:
return {"status": "ok", "results": results}
return { # ni [] silencieux, ni raise brut
"status": "partial" if results else "failed",
"results": results, # partiels conservés
"failed": failed,
"retryable": True,
"alternatives": ["cache_yesterday", "engine_b"],
"coverage": f"{len(queries) - len(failed)}/{len(queries)} requêtes",
}
# Coordinateur : il DÉCIDE avec l'information reçue
out = web_search_subagent(queries)
if out["status"] == "partial":
alt = delegate("web_search", failed_queries(out), source="engine_b") # re-déléguer via l'alternative
report = synthesize(out["results"] + alt["results"], gaps=still_failed(alt)) # trou signalé si persiste[] en succès, jamais raise brut.5.6 — Attribution des sources et formats hétérogènes
Deux sujets liés par la même idée : la fiabilité de ce qui sort dépend de la discipline à l'entrée. Ancrés sur les scénarios 3 (recherche) et 6 (documents).
Ce qu'il faut savoir
Contenu et métadonnées séparés, dès l'ingestion. Le texte d'une trouvaille d'un côté ; l'URL, le document, la page, la date, l'identifiant de source de l'autre. En prose, l'attribution se perd à la première synthèse (domaine 1, 1.3).
La source suit l'affirmation de bout en bout. Chaque agent qui transforme les données conserve les source_ids. Le rapport final peut remonter de n'importe quelle phrase à sa source.
Contraindre par le schéma. « Cite tes sources » dans le prompt produit des références plausibles mais inventées. Le schéma de synthèse a un champ source_ids dont les valeurs sont restreintes à l'enum des sources réellement fournies : une citation hors ensemble est rejetée à la validation (domaine 4, 4.2).
Normaliser à l'ingestion. Dates (Unix, ISO, « 12/03/2026 »), unités (k€, M$), encodages, statuts codés : on convertit une fois, à l'entrée (hook PostToolUse, pré-traitement), et tous les agents aval voient un seul format (domaine 1, 1.5). Demander au modèle de jongler avec les formats est une source d'erreurs à chaque étape.
Contradictions signalées, pas fusionnées. Deux sources donnent deux chiffres pour la même grandeur : on ne prend pas la moyenne, on ne choisit pas au hasard. Un champ conflicts[] porte les deux valeurs, leurs sources et leurs dates ; le lecteur (ou une règle explicite : « la source la plus récente prime ») tranche.
# Trouvaille structurée entre agents : contenu | métadonnées, jamais de prose
finding = {"id": "F42", "claim": "Le marché a atteint 4,2 Md€ en 2025",
"source_id": "S3", "url": "https://…", "doc": "rapport-2026.pdf", "page": 14,
"published": "2026-02-11", "value": {"amount": 4.2e9, "currency": "EUR", "year": 2025}}
# Schéma de synthèse : source_ids contraint aux sources fournies
def synthesis_tool(source_ids: list[str]) -> dict:
return {"name": "write_synthesis",
"input_schema": {"type": "object", "properties": {
"claims": {"type": "array", "items": {"type": "object", "properties": {
"text": {"type": "string"},
"source_ids": {"type": "array", "minItems": 1,
"items": {"type": "string", "enum": source_ids}}, # ← pas d'invention possible
"confidence": {"type": "string", "enum": ["high", "medium", "low"]}},
"required": ["text", "source_ids", "confidence"]}},
"conflicts": {"type": "array", "items": {"type": "object", "properties": {
"topic": {"type": "string"},
"values": {"type": "array", "items": {"type": "object", "properties": {
"value": {"type": "string"}, "source_id": {"type": "string", "enum": source_ids},
"published": {"type": "string"}}, "required": ["value", "source_id"]}}},
"required": ["topic", "values"]}}, # ← contradiction exposée
"gaps": {"type": "array", "items": {"type": "string"}}},
"required": ["claims", "conflicts", "gaps"]}}source_id porté de bout en bout et contraint par le schéma.Les pièges transversaux du domaine 5
- L'honnêteté du résultat prime. Partiel avec trous, contradiction exposée, incertitude déclarée : toute option qui « lisse » pour faire propre est un distracteur.
- La structure préserve, la prose perd. Résumé structuré, trouvaille structurée, erreur structurée : dès que l'information traverse une frontière (tour, session, agent), elle voyage en structure.
- On traite à l'entrée, pas à chaque étape. Normalisation, séparation contenu/métadonnées, résumé du verbeux : une fois, à l'ingestion.
- Le niveau qui voit l'ensemble décide. Le coordinateur, pas le sous-agent ; le schéma, pas le modèle ; la règle explicite, pas le hasard.
Checklist de la veille
Task) ou résumé avant injection ; fixe → outils par rôle, règles à glob.
- Limite proche → résumé structuré (objectif, décisions + pourquoi, faits sourcés, trous, échecs, suite, fichiers touchés), jamais troncature ni fenêtre glissante sur une tâche multi-phases.
- Contexte périmé → session neuve + résumé ; tâche longue → compacter à chaque phase.
- Mémoire par nature : conventions → CLAUDE.md ; état en cours → fichier mémoire / résumé daté ; volume → base externe interrogée par outil ; perso → ~/.claude/CLAUDE.md.
- Ne jamais persister les résultats d'outils bruts.
- Échec partiel → timeout borné + fallback + partiel avec trous explicites (status, missing[], confidence).
- Jamais de succès menteur, jamais de tout-ou-rien.
- Entre agents : retry local, puis erreur enrichie (catégorie, tentatives, partiels, alternatives) ; le coordinateur décide.
- Ni [] en succès, ni exception brute.
- Contenu | métadonnées séparés à l'ingestion ; source_id porté de bout en bout.
- source_ids contraint par le schéma à l'enum des sources fournies → citation inventée impossible.
- Formats hétérogènes normalisés une fois à l'entrée (PostToolUse / pré-traitement).
- Contradictions → conflicts[] avec valeurs, sources, dates ; jamais fusionnées en silence.Cinq questions-scénario originales, corrigées
Questions écrites par nAIvigate dans l'esprit de l'examen, sans reproduction d'items réels.
Question 1 — Scénario productivité. Un agent de migration lit 60 fichiers en entier au début de la tâche, puis perd les contraintes données dans le premier message et produit des changements incohérents. Correction ?
A. Modèle avec une fenêtre plus grande. B. Déléguer la cartographie à un sous-agent Explore qui renvoie un résumé structuré, et compacter à la fin de la phase d'exploration avant l'implémentation. C. Répéter les contraintes à chaque message. D. Tronquer les résultats de lecture aux 200 premières lignes par fichier.
📚Correction Q1
B. Déporter le verbeux + résumé structuré par phase. A repousse le mur sans traiter la dilution. C est un palliatif coûteux. D perd de l'information de façon arbitraire.
Question 2 — Scénario recherche. Sur cinq sources, celle des brevets tombe en timeout. Le pipeline actuel abandonne tout le rapport. Le PO veut « quelque chose de livrable ». Approche ?
A. Augmenter le timeout à 10 minutes. B. Livrer le rapport sur quatre sources avec status: "partial", missing: [{source: "brevets", reason: "timeout", retryable: true}], et proposer une relance. C. Livrer le rapport sur quatre sources sans mentionner la cinquième. D. Réessayer en boucle jusqu'à succès.
📚Correction Q2
B. Partiel honnête avec trou explicite et réessayable. A ne règle pas l'indisponibilité. C est un succès menteur. D n'a pas de borne.
Question 3 — Scénario recherche. Le rapport final cite des URLs qui n'existent pas. Le prompt de synthèse dit « cite toujours tes sources avec l'URL ». Correction ?
A. Renforcer l'instruction. B. Passer les trouvailles en format structuré avec source_id, et contraindre source_ids du schéma de synthèse à l'enum des identifiants réellement collectés. C. Vérifier chaque URL après coup et supprimer les invalides. D. Demander au modèle un score de confiance par citation.
📚Correction Q3
B. Le schéma rend l'invention impossible ; l'instruction (A) reste probabiliste. C supprime des citations mais laisse des affirmations orphelines et ne traite pas la cause. D ne contraint rien.
Question 4 — Scénario documentaire. Trois serveurs MCP renvoient des dates en Unix, ISO et « JJ/MM/AAAA ». L'agent de synthèse se trompe régulièrement de chronologie. Correction ?
A. Ajouter au prompt de synthèse un tableau des formats. B. Normaliser en ISO 8601 à l'ingestion via un hook PostToolUse, pour que tous les agents aval voient un seul format. C. Demander à chaque serveur MCP de changer son format. D. Faire trier les dates par un sous-agent dédié.
📚Correction Q4
B. Normalisation une fois à l'entrée. A fait porter la conversion au modèle à chaque étape. C dépend de tiers. D ajoute un agent pour un problème de données.
Question 5 — Scénario recherche. Deux sources fiables donnent 3,8 Md€ et 4,2 Md€ pour le même marché la même année. Le rapport actuel affiche « environ 4 Md€ ». Que faire ?
A. Garder la moyenne, c'est raisonnable. B. Exposer les deux valeurs dans un champ conflicts[] avec leurs sources et dates, et appliquer une règle explicite si une doit primer (ex. la plus récente). C. Prendre la source la plus connue sans le dire. D. Supprimer le chiffre du rapport.
📚Correction Q5
B. La contradiction est une information ; on la signale avec sa provenance. A détruit l'information. C masque un choix. D perd un fait utile.
Quiz de validation
Quel poste de la fenêtre de contexte croît le plus vite dans un agent qui lit des fichiers ?
📚Lexique du domaine 5 (déroulez)
Budget de contexte — Répartition de la fenêtre entre system prompt, définitions d'outils, historique et résultats d'outils ; planifiée, pas subie.
Dilution de l'attention — Dégradation de la qualité quand trop de contenu est traité en une fois, bien avant la limite dure.
Déport (offloading) — Faire lire le verbeux par un sous-agent (Explore, Task) qui ne renvoie qu'un résumé.
Compactage — Remplacement de l'historique par un résumé structuré quand la fenêtre approche de sa limite.
Résumé structuré — Objectif, décisions et justification, faits sourcés, trous, échecs, prochaines étapes, fichiers touchés ; format d'échange entre tours, phases et sessions.
Troncature — Anti-pattern : couper les messages anciens, perdant objectif et contraintes.
Fenêtre glissante — Garder les N derniers tours ; coût borné, même perte du début ; réservé aux échanges courts sans état.
Mémoire persistante — Ce qui survit à la session : choisi par nature (conventions, état en cours, volume, préférences).
Fichier de mémoire — Résumé structuré daté écrit en fin de session et injecté au démarrage de la suivante.
Base externe — SQL ou vecteurs, interrogée par un outil ; pour le volume et la recherche, sans charger la fenêtre.
Dégradation gracieuse — Livrer un résultat partiel utile plutôt que rien, avec les manques explicites.
Timeout borné — Délai maximal sur tout appel externe ; jamais d'attente infinie.
Fallback — Source alternative, cache, retry avec backoff, ou fonctionnalité dégradée quand l'appel principal échoue.
Résultat partiel explicite — Sortie portant status, covered, missing[] (raison, tentatives, réessayable), confidence.
Succès menteur — Anti-pattern : échec transformé en résultat vide ou incomplet présenté comme complet.
Tout-ou-rien — Anti-pattern : abandonner l'ensemble du traitement pour un échec partiel.
Récupération locale — Gestion par le sous-agent de ce qu'il peut résoudre (retry transitoire, alternative dans son périmètre).
Erreur enrichie — Catégorie, tentatives, résultats partiels, alternatives ; ce qui remonte au coordinateur.
Suppression silencieuse / propagation brute — Les deux anti-patterns de la question 8 : masquer l'erreur, ou la laisser tuer le workflow.
Attribution (provenance) — Rattachement de chaque affirmation à sa source, conservé de bout en bout.
Contenu | métadonnées — Séparation, dès l'ingestion, du texte d'une trouvaille et de son identifiant de source, URL, document, page, date.
source_ids contraint — Champ du schéma de synthèse restreint à l'enum des sources fournies ; empêche les citations inventées.
Normalisation à l'ingestion — Conversion unique des formats hétérogènes (dates, unités, encodages, statuts) à l'entrée, via PostToolUse ou pré-traitement.
conflicts[] — Champ exposant des valeurs contradictoires avec leurs sources et dates, au lieu de les fusionner.
Pour aller plus loin
C'était la dernière leçon de la série. Le guide complet de la CCA-F rassemble les cinq domaines, le format d'examen et le plan de révision ; pour voir la mémoire et la dérive traitées en production, notre article sur la mémoire persistante et la personnalisation et celui sur la dérive des agents IA prolongent ce domaine.
Si tu veux certifier une équipe entière — ou fiabiliser un système multi-agents existant (budget de contexte, compactage, propagation d'erreurs, attribution des sources) avant qu'il ne tombe en production — c'est ce que nAIvigate Studio fait en Sprint.