Guide d’étude CCAR-F/Domaine 02 sur 0518 % de l’examen

Conception d’outils et intégration MCP

Cinq sous-domaines, 18 % des points, et une affirmation à mémoriser parce qu’elle les organise tous : le plafond d’un agent, c’est son jeu d’outils. Le modèle apporte le jugement ; les outils apportent la capacité, la visibilité et le rayon d’action. Cette page couvre le contrat qu’est tout outil (interface, erreurs, distribution), le protocole qui les standardise (MCP), et les six outils intégrés que l’examen attend de connaître par leur nom.

Fabs||14 min de lecture|Version anglaise →

Une définition d’outil est un contrat avec un client non déterministe. Le modèle ne peut pas lire votre code source, ne peut pas deviner vos intentions et ne voit pas votre documentation — tout ce qu’il sait d’un outil tient dans le nom, la description et le schéma d’entrée, livrés dans la requête API. Ce trio est l’interface entière, et les questions de ce domaine sont presque toujours « quelle partie du contrat est fausse ? » déguisée en scénario.

01L’interface : nom, description, schéma

Le nom est une adresse : verbe d’abord, spécifique, honnête sur ce qui va se passer — query_orders, pas data_lookup ; create_invoice, pas process. La description est la substance du contrat, et l’examen a une idée fixe de ce qu’elle doit contenir : ce que l’outil fait, quand l’utiliser, quand ne pas l’utiliser, et ce que signifient ses résultats. Un outil relecteur qui « vérifie si un fichier Python suit le guide de style de l’équipe » bat « relit le code », exactement comme une bonne docstring bat une docstring vague — le modèle choisit entre les outils comme un développeur choisit entre des fonctions : en lisant la doc.

Le schéma d’entrée est du JSON Schema, et sa qualité sépare l’outil qui marche de celui qui hallucine des arguments. Peu de paramètres, chacun avec un nom clair, un type déclaré, une description, et des contraintes que le schéma lui-même impose — des enums plutôt que des chaînes libres là où le domaine est fermé, required exactement là où l’exigence est réelle. Le modèle remplira la forme que vous lui donnez ; un schéma où tout est optionnel invite le modèle à deviner des valeurs qu’il aurait dû être forcé de faire émerger. Et le schéma coupe dans les deux sens : une validation stricte des entrées rejette les appels mal formés avant toute exécution, ce qui transforme « comportement mystérieusement faux » en « une erreur lisible dans la section suivante du domaine 2 ».

02Les périmètres : portée, rayon d’action, idempotence

Au-delà de la syntaxe, l’examen teste trois propriétés de périmètre d’un outil bien cadré. Le rayon d’action (blast radius) : préférez la lecture à l’écriture, l’écriture à la suppression, l’étroit au large — un outil qui lit une commande est plus sûr qu’un qui les lit toutes, et un outil qui rédige un courriel est plus sûr qu’un qui l’envoie ; la granularité que vous choisissez est une décision de sûreté, pas de confort. Réversibilité et idempotence : les opérations qui se rejouent sans mal (idempotentes) sont le mariage naturel des agents qui réessaient ; les opérations destructrices et irréversibles méritent leur propre outil, verrouillé par leur propre permission, jamais fondues dans un fourre-tout multi-usage commode. Une seule finalité : un outil, un métier. Les outils qui font « n’importe quoi avec l’API records » produisent des descriptions entre lesquelles le modèle ne peut pas choisir et des échecs que personne ne peut attribuer.

C’est aussi ici que l’interface rencontre les couches d’imposition du domaine 1 : un outil étroit est une restriction par construction. Vous ne dites pas à l’agent « ne supprime rien » en lui tendant delete_everything() avec une description polie ; vous lui donnez les outils dont l’union des capacités est exactement la tâche, et le travail du prompt devient facile parce que la conception l’a déjà fait.

03Les réponses d’erreur structurées

Un appel d’outil peut échouer ; le métier de l’architecte est de rendre l’échec utile. La règle que l’examen répète sous différents costumes : les erreurs sont faites pour être lues par le modèle, et le modèle est un lecteur de langage clair sans accès à votre pile d’exécution. Une erreur structurée dit ce qui a échoué, pourquoi, et — quand c’est possible — ce qui fonctionnerait à la place. « Date invalide : YYYY-MM-DD attendu, reçu “3 mars” » permet à l’agent de se corriger au tour suivant. Une trace de pile nue, un HTTP 500 ou une exception brute le laissent s’agiter, réessayer l’identique, se mettre à deviner — la boucle du domaine 1, qui tourne sur une entrée mal formée jusqu’à ce qu’un budget la sauve.

↳Une erreur dont le modèle peut se servir, contre une autre
MAUVAIS {"error": "SQLException ligne 42 : contrainte FAILED"}
→ le modèle réessaie l’appel identique, s’agite, brûle des tours
 
BON {"isError": true,
"content": "Rejeté : invoice_date doit être YYYY-MM-DD et
pas antérieure au 2020-01-01. Reçu “3 mars”.
Rappelez avec la date 2026-03-03."}
→ le modèle se corrige au tour suivant
Dans MCP, un outil signale l’échec avec isError: true et l’explication lisible dans content. Le format est le contrat ; la lisibilité est la fonctionnalité.

Pour les outils MCP précisément, la forme est fixée : un appel d’outil échoué est une réponse de protocole réussie dont la charge utile porte isError: true, avec l’explication en contenu que le modèle lit. Deux distinctions que l’examen trace nettement. Une erreur d’outil (« vos arguments étaient invalides », « l’enregistrement n’existe pas ») est une donnée — elle retourne dans la boucle comme contexte, et l’agent peut se rétablir seul. Une erreur de protocole ou de transport (le serveur n’a jamais répondu) est de l’infrastructure — c’est l’affaire de votre couche d’orchestration : nouvelle tentative avec temporisation, timeout, remontée à un humain. Fusionner les deux catégories produit le mauvais design classique : des agents qui réessaient une panne réseau comme s’ils disputaient une erreur de validation.

04Distribuer les outils entre agents — et le tool choice

Quand un coordinateur fait tourner des subagents, la distribution des outils est une décision d’architecture avec un ensemble fixe de bonnes réponses. Principe un : donnez à chaque agent le jeu d’outils que son métier implique, et rien de plus — le chercheur reçoit recherche et lecture ; l’implémenteur reçoit lecture-écriture et shell ; le relecteur reçoit la lecture seule. Chaque outil retenu est un mode d’échec supprimé. Principe deux : surveillez le compteur. Les jeux d’outils qui grossissent sans borne dégradent la qualité de sélection — le modèle se trompe parmi les quasi-doublons et rate le bon outil dans la foule ; les atténuations sont la spécialisation (répartir les jeux entre subagents pour qu’aucun contexte ne les porte tous), la consolidation (retirer les quasi-doublons) et, à l’échelle API, laisser le modèle chercher ou récupérer programmatiquement les définitions d’outils plutôt que d’expédier chaque schéma dans chaque requête. La formulation de l’examen est généralement « l’agent choisit le mauvais outil parmi beaucoup de semblables » — la réponse n’est jamais « écris un prompt système plus long » ; c’est « le jeu d’outils est le problème ».

L’autre moitié du sous-domaine est le réglage tool_choice de l’API — quatre valeurs, et l’examen les attend toutes les quatre au mot près. auto (par défaut) : le modèle décide s’il appelle un outil et lequel. any : un outil doit être appelé — le modèle choisit lequel, mais il ne peut pas répondre en prose ; utilisez-le quand un résultat structuré est obligatoire. tool, avec un nom : force cet outil précis. none : les outils sont visibles mais le modèle ne doit rien appeler. Le langage des scénarios s’y mappe directement : « le modèle répond en prose alors qu’il nous faut une note du schéma » → tool_choice any ; « toujours extraire avec notre schéma, jamais un autre outil » → tool avec le nom ; « laissons-le décider » → auto.

05MCP : serveurs, transports et portées

Model Context Protocol est le standard ouvert qui fait passer la conception d’outils de « codé à la main dans mon application » à « brancher un serveur dans n’importe quel hôte MCP ». Un serveur MCP expose des tools (fonctions que le modèle peut appeler), des resources (données qu’il peut lire) et des prompts (gabarits qu’on peut lui donner) — un seul serveur peut servir les trois. Un hôte — Claude Code, l’Agent SDK, Claude Desktop, votre propre application — se connecte aux serveurs et fusionne leurs offres dans le jeu d’outils de l’agent. Le principe de conception de l’examen est l’isolation : un serveur ne voit pas les autres serveurs, ne voit pas la conversation, ne peut pas mettre la main dans l’hôte. Si un scénario exige une coordination entre serveurs, c’est le coordinateur qui la fait — jamais les serveurs.

Les transports disent comment on atteint un serveur, et deux comptent : stdio pour les serveurs locaux (l’hôte lance un sous-processus et parle le protocole sur l’entrée-sortie standard du processus — stdout est le canal de protocole, les logs vont sur stderr) et streamable HTTP pour les serveurs distants (un point de terminaison sert beaucoup de clients, généralement avec OAuth pour l’authentification). Les indices de formulation de l’examen : « tourne sur la machine de l’utilisateur, sans réseau » → stdio ; « serveur d’équipe partagé, authentifié » → streamable HTTP. Dans Claude Code, les serveurs s’enregistrent avec claude mcp add et vivent à l’une de trois portées : local (par défaut — ce projet, cet utilisateur, non partagé), project (commité dans .mcp.json à la racine du dépôt, pour que chaque clone reçoive les mêmes serveurs) et user (disponible dans tous vos projets). Le verbe du scénario donne la portée : « toute l’équipe, de façon reproductible » → portée projet avec .mcp.json versionné.

↳Portées MCP dans Claude Code
PortéeVit dansQui en bénéficie
localConfiguration par projet et par utilisateurVous seul, dans ce projet seulement (par défaut)
project.mcp.json à la racine du dépôt, commitéToute personne qui clone le dépôt
userVotre configuration au niveau utilisateurVous, dans tous vos projets
La sécurité suit la portée : un .mcp.json de portée projet est de la configuration partagée — chaque coéquipier fait confiance à chaque serveur qu’il contient, donc c’est aussi une surface d’attaque à relire comme du code.

La sécurité MCP a un autre favori de l’examen : le serveur fait confiance à ses entrées. Un serveur doit valider chaque URI de ressource et assainir les chemins de fichiers — le file:// forgé qui remonte d’un répertoire est l’illustration classique de ce qui arrive sinon. L’hôte limite ce qu’un serveur voit (isolation) ; le serveur reste responsable de ce qu’il fait de ce qu’on lui tend. Les deux moitiés sont de votre ressource de conception ; aucune n’excuse l’autre.

06Les outils intégrés, par leur nom

L’examen nomme six outils intégrés et attend une aisance dans leurs arbitrages — c’est la partie la plus « trivia » de l’examen d’architecte, et les points sont réels. Read lit des fichiers (avec offset et limit pour feuilleter les gros — la manière polie envers le contexte de regarder un grand fichier). Glob cherche des fichiers par motif de nom ; Grep cherche du contenu par motif à l’intérieur — la paire forme l’étage recherche, et la recherche ciblée bat la lecture en vrac partout où elle peut répondre à la question. Edit fait des remplacements chirurgicaux : donnez-lui une chaîne exacte à matcher et le remplacement ; le match doit être exact, espaces comprises, et un raté échoue plutôt que d’approximer — ce qui est précisément sa valeur de mutateur sûr. Write crée ou écrase un fichier entier — le mutateur large spectre ; notez la sémantique d’écrasement, parce que « Write pour le correctif chirurgical » est une mauvaise réponse que l’examen aime. Bash exécute des commandes shell avec toute leur puissance et tout leur rayon d’action, et son état de session persiste entre appels — un cd dans un appel s’applique encore au suivant — ce qui est soit un confort, soit un piège, selon qui a écrit la commande.

↳Quel intégré, quand
Vous devezPrendreLe piège
Trouver des fichiers par nomGlobLire toute l’arborescence à la place
Trouver où quelque chose est ditGrepLire chaque fichier candidat en entier
Regarder un bout d’un gros fichierRead avec offset/limitLire tout le fichier dans le contexte
Changer trois lignes d’un fichierEditWrite — il remplace le fichier entier
Créer un fichier de zéroWriteEdit — il n’y a rien à matcher
Lancer un build, un test, gitBashOublier que l’état persiste entre appels
La règle est du moins cher d’abord : chercher avant de lire, lire étroitement avant de lire largement, éditer avant d’écrire, et Bash en dernier parce qu’il peut tout faire — y compris tout ce que vous n’avez pas demandé.

07Les pièges de ce domaine

  • —« L’outil a échoué, donc on lance l’exception et on laisse l’appelant voir la pile. » Le modèle lit du langage clair, pas des traces de pile. isError avec un message actionnable est le contrat ; les exceptions brutes sont la maternité des boucles qui s’agitent.
  • —« Un outil puissant garde le schéma simple. » Un outil fourre-tout rend chaque mauvaise action possible et aucune description honnête. Des petits outils mono-usage au rayon d’action étroit sont la réponse du sénior.
  • —« Envoyer les quarante outils à chaque agent pour la flexibilité. » Les jeux surchargés dégradent la sélection. Répartissez par métier, consolidez les quasi-doublons, et gardez petit le jeu d’outils d’un contexte donné.
  • —« Le modèle ignorait l’outil, donc forcer tool_choice any. » any force un appel — n’importe lequel. Si le problème était le mauvais outil choisi parmi d’autres, forcer aggrave. Réparez d’abord le jeu d’outils ou les descriptions.
  • —« Les serveurs MCP se coordonnent entre eux. » Ils ne se voient pas. La coordination appartient à l’hôte ou à votre coordinateur ; une conception qui suppose un dialogue serveur-à-serveur est une conception qui échoue sur le papier.
  • —« Utilisez Write — c’est plus exhaustif qu’Edit. » Write écrase tout le fichier ; un Edit qui ne matche pas échoue bruyamment au lieu de réécrire silencieusement tout. L’exhaustivité qu’on n’a pas demandée est un dégât.
↳Vérifiez vos acquis — cinq questions de scénario
Q1

Un agent d’extraction doit toujours rendre ses résultats dans votre schéma de facture — jamais en prose, et jamais via un autre outil. Quel réglage ?

  1. Atool_choice: "auto", avec un prompt système sévère
  2. Btool_choice: "any"
  3. Ctool_choice: { "type": "tool", "name": "extract_invoice" }
  4. Dtool_choice: "none"
→Vérifier votre réponse
Réponse : C

Le réglage d’outil nommé force exactement cet outil — ce que demande « toujours ce schéma, jamais un autre outil ». any garantirait un appel d’outil mais laisserait le choix ouvert ; none interdit tout appel.

Q2

Le serveur MCP de vérification de style de l’équipe doit être disponible, à l’identique, pour quiconque clone le dépôt. Quel enregistrement ?

  1. Aclaude mcp add en portée local sur chaque machine
  2. BLe figer dans le prompt système de chaque agent
  3. CLa portée user sur la machine de CI seulement
  4. DUn .mcp.json à la racine du dépôt, commité — portée projet
→Vérifier votre réponse
Réponse : D

La portée projet signifie exactement « partagé par dépôt » : le fichier voyage avec le clone. local est privé par utilisateur ; la portée user suit une personne à travers ses projets.

Q3

Un subagent appelle get_records avec des dates mal formées en boucle. Les dates arrivent dans une douzaine de formats humains. Meilleure correction ?

  1. AAugmenter la limite de tours du subagent
  2. BFaire de la date un paramètre en texte libre validé par le prompt système
  3. CContraindre le schéma (format de date explicite, ou enum si fermé) et renvoyer des erreurs structurées et actionnables avec le format attendu
  4. DEnvelopper get_records dans Bash pour que le shell pré-analyse
→Vérifier votre réponse
Réponse : C

Les contraintes de schéma empêchent l’appel mal formé ; les erreurs structurées rendent auto-correcteur celui qui passe. Les limites de tours sont des filets, les prompts guident, et envelopper dans Bash ajoute du rayon d’action pour résoudre un problème de contrat.

Q4

Un agent relecteur doit inspecter des fichiers mais ne doit jamais les modifier. Quel jeu d’outils est celui de l’architecte ?

  1. ARead, Grep, Glob seulement
  2. BRead, Write, Edit, Bash — plus « ne modifie rien » dans le prompt
  3. CBash seul, exécuté comme utilisateur OS en lecture seule
  4. DTous les intégrés ; compter sur un hook PostToolUse pour annuler les changements
→Vérifier votre réponse
Réponse : A

Restriction par construction : l’étage lecture-recherche ne peut pas exprimer une écriture. Les interdictions de prompt guident mais n’imposent pas ; annuler après coup signifie que l’écriture a eu lieu.

Q5

Un appel d’outil MCP échoue : la base était injoignable. L’agent a réessayé cinq fois l’appel identique. Qu’est-ce qui a cloché dans la conception ?

  1. AL’outil aurait dû renvoyer la chaîne brute du driver
  2. BUne erreur de transport/infrastructure a été présentée comme erreur d’outil — les reprises appartiennent à la couche d’orchestration, avec temporisation, pas au modèle
  3. CL’agent manquait de budget de tours
  4. Dtool_choice aurait dû valoir "none"
→Vérifier votre réponse
Réponse : B

Une base morte n’est pas un retour dont le modèle peut tirer parti. Les erreurs d’infrastructure incombent à votre couche : reprendre ou escalader ; les présenter comme erreurs d’outil invite exactement cette agitation.

Fabs
Fondateur, The Third Way Company
Travailler avec nous