Fransys
Tous les cours
F3
2 h
Pédagogie complète

Agents & MCP : boucles, protocole, invariant du tenant

ReAct vs Plan-and-Execute, MCP et sa révision sans état de juillet 2026, et l'erreur de conception la plus instructive du métier : le tenant en argument d'outil.

Parcours FDE — architecture agentique

Pourquoi ce module

Un agent, c'est un modèle à qui on donne des outils et une boucle. Le concept tient en une phrase ; les ennuis commencent à la deuxième.

Ce module couvre les deux boucles d'agent qu'on vous demandera de comparer, le protocole MCP dans sa révision de juillet 2026 — la plus grosse depuis son lancement — et surtout l'erreur de conception la plus instructive du métier : celle qui consiste à passer l'identité du client en argument d'outil.

Bras robotique articulé
F3 : donner des outils à un modèle, et ne pas lui donner les clés

Objectifs pédagogiques

  1. Décrire la boucle d'un agent à outils
  2. Comparer ReAct et Plan-and-Execute, et dire quand chacun convient
  3. Expliquer ce qu'est MCP et ce qu'il résout
  4. Énoncer les changements de la révision 2026-07-28 et leur conséquence
  5. Justifier l'invariant : le tenant vient du transport, jamais des arguments

Plan détaillé

  1. Qu'est-ce qu'un agent
  2. ReAct et Plan-and-Execute
  3. MCP : le protocole
  4. La révision 2026-07-28
  5. L'invariant du tenant — l'erreur à ne jamais commettre
  6. Quatre pièges d'agent en production
  7. Glossaire du module

1. Qu'est-ce qu'un agent

Chargement du schéma…

La boucle d'agent. Tout le reste — ReAct, MCP, garde-fous — n'est qu'un raffinement de ce cycle.

Trois éléments, pas un de plus : un modèle qui décide, des outils qu'il peut appeler, une boucle qui rejoue le modèle avec les résultats jusqu'à une condition d'arrêt.

Ce qui distingue un agent d'un simple appel LLM, et c'est la formulation attendue : l'agent choisit lui-même les actions et leur ordre. On ne lui donne pas une procédure, on lui donne un objectif et des capacités.

C'est aussi ce qui le rend dangereux, et tout le module F5 en découle : un système où le modèle choisit les actions est un système où le contenu qu'il lit peut influencer ce qu'il fait.

2. ReAct et Plan-and-Execute

Chargement du schéma…

ReAct s'adapte à chaque pas. Plan-and-Execute décide une fois puis déroule.
ReActPlan-and-Execute
PrincipeRaisonner, agir, observer, recommencerÉtablir un plan complet, puis l'exécuter
S'adapte à l'imprévu✅ à chaque pas⚠️ seulement en replanifiant
Coût en tokensÉlevé — tout l'historique à chaque tourPlus faible — le plan tient lieu de mémoire
Prévisible / auditable⚠️ trajectoire variable✅ le plan est inspectable avant exécution
Dérive sur tâche longueForteContenue par le plan
Bon terrainExploration, diagnostic, imprévuTâches connues, longues, à valider avant lancement

🎯 La réponse d'entretien. « ReAct quand le chemin est inconnu — un diagnostic, une exploration : chaque observation change la suite. Plan-and-Execute quand la tâche est connue et longue, et surtout quand quelqu'un doit valider le plan avant qu'il s'exécute. Chez un grand compte, cette validation préalable est souvent une exigence de gouvernance, pas un confort. »

Le mode d'échec de ReAct vaut d'être nommé : sur une tâche longue, la boucle peut tourner sans converger — chaque observation relance le raisonnement sans rapprocher du but. D'où les garde-fous élémentaires : nombre maximal d'itérations, budget de tokens, et critère d'arrêt vérifiable.

3. MCP : le protocole

Model Context Protocol. Avant lui, chaque intégration entre un agent et un système externe était du code sur mesure : N agents × M systèmes = N×M intégrations.

Chargement du schéma…

MCP transforme N×M intégrations en N+M

Un serveur MCP expose des outils (des fonctions appelables), et n'importe quel client compatible peut les utiliser. C'est un protocole, pas un produit.

Deux transports :

TransportUsageIdentité
stdioProcessus local, poste de travailCelle du processus
HTTP streamableServeur hébergé, multi-clientsPortée par la requête (jeton)

4. La révision 2026-07-28

C'est la plus grosse rupture depuis la création du protocole, et une question d'actualité en entretien.

Le changement central : le protocole devient sans état. La poignée de main initialize/initialized disparaît, ainsi que l'en-tête de session. Chaque requête déclare sa version de protocole et le serveur l'accepte ou la rejette indépendamment.

AvantDepuis 2026-07-28
initialize négocie une fois, la session porte l'étatChaque requête est autoportante
Le serveur maintient un état par clientLe serveur répond sans mémoire de session
Découvrir les capacités = ouvrir une sessionserver/discover : versions, capacités, identité en un appel
Version incompatible = échec de connexionUnsupportedProtocolVersionError, avec les versions acceptées

💡 Pourquoi c'est un sujet d'architecture, pas de trivia. Un protocole avec session impose une affinité : le client doit retomber sur l'instance qui détient son état. Derrière un répartiteur de charge, ça veut dire des sessions collantes, donc des serveurs qu'on ne peut ni scaler horizontalement ni redéployer sans casser les connexions en vol.

Sans état, n'importe quelle instance peut répondre à n'importe quelle requête : le scale-out redevient trivial et un serveur MCP peut tourner en fonction serverless. C'est la même bascule que des sessions serveur vers les JWT côté web, avec les mêmes contreparties : plus de métadonnées transportées à chaque appel.

Autres points datés à connaître : en-têtes Mcp-Method / Mcp-Name obligatoires en HTTP streamable, ttlMs / cacheScope sur les listes et lectures, enregistrement dynamique de clients (DCR) déprécié au profit de CIMD, validation de l'émetteur (iss, RFC 9207), et Roots / Sampling / Logging dépréciés avec un préavis de douze mois.

⚠️ Ce domaine périme vite. Ces faits sont datés du 28 juillet 2026. En entretien, dire « à la révision de juillet 2026 » plutôt que « maintenant » est un signal de sérieux — et vous protège si la révision suivante est sortie entre-temps.

5. L'invariant du tenant — l'erreur à ne jamais commettre

Voici la question, et elle est excellente parce qu'elle a une réponse évidente qui est la pire possible.

Votre fonction de recherche exige un organizationId pour filtrer les documents du bon client. Vous l'exposez comme outil MCP. Un serveur MCP n'a pas de session. Où mettez-vous l'organizationId ?

La réponse spontanée — l'ajouter au schéma de l'outil, comme un paramètre — est celle qu'il faut savoir réfuter.

Chargement du schéma…

Les arguments d'outil sont choisis par le modèle. Le modèle lit le corpus. Donc le corpus choisirait le tenant.

La chaîne de raisonnement, à restituer dans cet ordre :

  1. Les arguments d'un outil sont choisis par le modèle — c'est la définition même du tool use.
  2. Le modèle lit les passages retrouvés dans le corpus.
  3. Le corpus est fait de PDF téléchargés sur le web, donc de contenu non maîtrisé.
  4. Donc un organizationId en argument serait une valeur influençable par le contenu du corpus.
  5. Un document piégé pourrait donc faire lire les données d'un autre client.

C'est la jonction exacte entre l'exposition MCP et l'injection indirecte du module F5 — et c'est ce qui fait de cette question un si bon test.

🎯 L'invariant, à énoncer tel quel : « Le tenant vient du transport, jamais des arguments. »

En stdio, il est figé au démarrage du processus par variable d'environnement : le processus est l'identité. En HTTP, il est résolu à chaque appel depuis le jeton porteur, côté serveur, avant que le modèle ne voie quoi que ce soit.

Le mono-tenant par processus n'est pas un raccourci qui abandonne l'invariant : c'est la forme la plus simple qui le respecte.

Comment on le verrouille. Un invariant qu'aucun test ne protège finit par être violé par quelqu'un de bien intentionné. La parade : un test qui inspecte les schémas réellement publiés par le serveur et échoue si un outil expose un paramètre d'organisation. Ce n'est pas un test de comportement, c'est un test de surface d'API — et c'est ce qui empêche la régression six mois plus tard.

💡 Le corollaire, souvent demandé en relance : « et le filtre, vous l'appliquez où ? »Avant la fusion, dans la requête de portée elle-même. Filtrer après la fusion laisserait fuiter l'existence de documents d'un autre client par le simple fait qu'ils occupent des rangs dans le classement. Une fuite de métadonnée reste une fuite.

6. Quatre pièges d'agent en production

6.1 Le résumé entre étapes fait entrer l'invention

Un agent RAG multi-étapes qui résume les passages entre deux étapes crée une faille discrète :

L'invention entre par l'accumulateur, silencieusement, parce que chaque étape prise isolément paraît correcte. Le résumé de l'étape 2 est plausible au vu de l'étape 1 ; à l'étape 5, plus rien ne rattache l'affirmation à un passage réel.

Le correctif : les étapes se transmettent des références vers un registre tenu par le serveur, pas du texte reformulé. La citation reste rattachable au passage d'origine tout au long de la chaîne.

6.2 Reprendre une étape suppose l'idempotence

Un harnais qui réessaie une étape en échec introduit un risque classique des systèmes distribués :

Le cas dangereux est un timeout sur un appel qui a réellement réussi côté serveur. L'agent croit avoir échoué, il rejoue — et l'action se produit deux fois.

Clés d'idempotence sur les outils d'écriture, exactement comme ailleurs. Les reprises d'agent ne sont pas un problème nouveau ; c'est le même problème dans un habillage nouveau, et le dire ainsi en entretien est bien vu.

6.3 L'outil qui renvoie 50 000 tokens

Que faire d'une sortie d'outil énorme ? Surtout pas la tronquer en silence.

La troncature silencieuse est de la même classe de défaillance qu'un tableau à moitié récupéré : le modèle traite un résultat partiel comme complet et conclut avec assurance.

Une troncature déclarée — « 200 lignes sur 4 300, page 1 » — permet au modèle de demander la suite, ou de dire qu'il ne peut pas répondre. La pagination et le résumé structuré côté outil valent mieux que le déversement brut.

6.4 Confirmer une action destructrice sans session

La révision sans état a supprimé les requêtes initiées par le serveur, qui exigeaient un flux maintenu ouvert. Comment un agent fait-il alors confirmer une suppression en cours d'appel ?

Par MRTR — le mécanisme de reprise fondé sur resultType: "input_required". L'outil rend un résultat qui déclare avoir besoin d'une entrée, et l'appel reprend ensuite. Aucune connexion à maintenir.

À signaler dans la même respiration : Roots, Sampling et Logging sont dépréciés, avec au minimum douze mois de transition.

7. Trois décisions de conception

7.1 Quand ne PAS construire d'agent

Question fréquente, et la bonne réponse commence par un mot que peu de candidats osent :

« La plupart du temps. »

Le critère unique : le nombre d'étapes est-il connu à l'avance ?

SituationCe qu'on construit
Séquence fixe et connueUn pipeline. Plus simple, testable, déterministe, moins cher
Une récupération + une générationUne fonction. Ce n'est pas un agent
Étapes connues mais longues, à valider avantPlan-and-Execute — le milieu du spectre
Nombre d'étapes inconnu, dépendant des observationsUn agent

Le test utilisable, à donner tel quel : « Le plan peut-il s'écrire à l'avance ? Si oui, écrivez-le — c'est un pipeline. »

⚠️ La relance : « mais le client a précisément acheté une solution agentique. » — On ne gagne pas cette discussion en opposant les mots. On la gagne en montrant que le pipeline atteint le critère de succès convenu, plus vite et moins cher, et que l'agent reste possible là où le pipeline butera. Le client a acheté un résultat ; le mot était son hypothèse sur le moyen.

7.2 Exposer en outil, ou coder en dur ?

Le test : le modèle est-il mieux placé que moi pour prendre cette décision ?

Coder en durExposer en outil
QuandL'ordre est connuLe choix dépend du contenu de la question
PourquoiUn choix inutile est un mode de défaillance ajoutéLe modèle voit ce que le code ne peut pas anticiper

Deux règles qui vont avec :

  • Si vous exposez un choix, fournissez l'information dont ce choix dépend. Un outil que le modèle doit choisir sans élément pour trancher produira un choix aléatoire.
  • Gardez des surfaces disjointes. Trois outils aux usages qui se chevauchent font chuter la précision de sélection — et le premier réflexe est de réécrire les descriptions, pas le prompt système (cf. F1).

7.3 L'agent qui écrit : le cas de la note de frais

Dès qu'un agent écrit, tout le profil de risque change. Sept points à dérouler :

  1. Reconnaître que l'écriture change tout — un agent en lecture qui se trompe produit une mauvaise réponse ; un agent en écriture produit un fait.
  2. Confirmation humaine avant toute soumission irréversible.
  3. Clé d'idempotence — et nommer le cas dangereux : le timeout sur un appel réussi (§ 6.2).
  4. Identité de service dédiée, au périmètre minimal (cf. F7).
  5. Attribution : les actions de l'agent doivent rester distinguables de celles de l'humain dans les journaux.
  6. Plafonds d'étapes et de coût.
  7. Évaluer la trajectoire, pas seulement la sortie (cf. F4) — six appels là où deux suffisaient est un défaut même si le résultat est bon.

🎯 La relance difficile : « la confirmation annule l'intérêt de l'automatisation. » — Non : elle déplace le travail de la saisie vers la vérification, ce qui est un gain réel. Et le seuil est réglable : confirmation systématique au départ, puis restreinte aux cas hors normes une fois le taux d'erreur mesuré. On ne desserre jamais un garde-fou avant d'avoir le chiffre qui le justifie.

8. Glossaire du module

Terme (EN)Terme (FR)Définition
AgentAgentModèle + outils + boucle, qui choisit lui-même ses actions
Tool use / function callingAppel d'outilCapacité du modèle à invoquer une fonction avec des arguments
Tool schemaSchéma d'outilDescription des paramètres attendus, lue par le modèle
ReActBoucle raisonner → agir → observer, pas à pas
Plan-and-ExecutePlanifier puis exécuterPlan complet établi d'abord, exécuté ensuite
TrajectoryTrajectoireSuite des actions réellement effectuées par l'agent
MCP (Model Context Protocol)Protocole standard entre agents et systèmes externes
stdio transportTransport stdioServeur MCP en processus local
Streamable HTTPTransport MCP HTTP pour serveur hébergé
StatelessSans étatChaque requête est autoportante, aucune session côté serveur
server/discoverRPC renvoyant versions, capacités et identité en un appel
TenantLocataire, clientOrganisation cliente dans un système multi-clients
Multi-tenancyMulti-locataireUn même système servant plusieurs clients isolés
Bearer tokenJeton porteurJeton d'authentification porté par la requête
Confused deputyDéputé confusComposant privilégié amené à agir pour le compte d'un tiers non autorisé
MRTR / input_requiredReprise d'appel pour demander une entrée, sans connexion maintenue
Idempotency keyClé d'idempotenceEmpêche qu'une reprise rejoue une écriture déjà effectuée
Declared truncationTroncature déclaréeSortie d'outil tronquée et signalée, pour que le modèle le sache

Atelier (75 min)

  1. Les deux boucles (20 min) — dessinez ReAct et Plan-and-Execute de mémoire, puis énoncez à voix haute le critère de choix, en anglais.
  2. MCP en une minute (15 min) — expliquez ce que résout MCP à quelqu'un qui n'en a jamais entendu parler. Sans jargon.
  3. L'invariant du tenant (25 min) — c'est l'épreuve orale la plus rentable du parcours. Déroulez les cinq étapes du § 5 à voix haute, puis répondez aux relances : « et si le jeton est compromis ? », « pourquoi filtrer avant la fusion ? », « comment empêchez-vous quelqu'un d'ajouter ce paramètre dans six mois ? »
  4. Datation (15 min) — énoncez trois changements de la révision 2026-07-28 en les datant explicitement.

Pour aller plus loin