Limites d'intégration
- Leçon 15
- 45 min
- Module 5 : Plusieurs exécutants et intégrations
Leçon 15 sur 18 · Agents d'IA et orchestration des flux de travailLimites d'intégration
1. Choisir le bon modèle d'orchestration
2. Représenter l'état et les outils
3. Raisonnement, planification et contexte
4. Approbation humaine et reprise
5. Plusieurs exécutants et intégrations
6. Évaluer et exploiter un agent borné
Ce que vous saurez faire
Décidez où placer chaque vérification quand un outil s’exécute dans un autre programme. Voyez ensuite ce que le Model Context Protocol change pour vos outils, et ce qu’il ne change pas.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les contrats d’outils et les permissions appliquées dans le code, dans Contrats d’outils.
- L’approbation et les identifiants d’opération, dans Limites d’approbation et Effets de bord et nouvelles tentatives.
Ce qu’il vous faut sur votre ordinateur
- Le projet après Compromis des systèmes multiagents, dans un dossier nommé
resolution-workflow.python -m pytestaffiche64 passed(64 tests réussis). - Pour l’exemple facultatif : Python 3.12 et une connexion Internet pour installer un paquet,
mcp. Il va dans son propre environnement virtuel, à côté du projet, pas dans le projet.
Cette leçon n’ajoute aucun fichier au projet. Aucun compte ni aucune clé. Testé avec Python 3.12.13 sur macOS; les commandes Windows n’ont pas été exécutées.
Une fiche, une prise et un fusible
Section intitulée « Une fiche, une prise et un fusible »Une fiche standard permet de brancher n’importe quelle lampe dans n’importe quelle prise de la maison. Personne n’a besoin de refaire le câblage du mur pour une nouvelle lampe. Voilà la valeur d’une norme : une forme, plusieurs appareils, plusieurs prises.
La lampe porte aussi une petite étiquette : « max 60 W ». Le fabricant l’a écrite. La prise ne peut pas la lire, et n’en a pas besoin. Derrière le mur, la boîte à fusibles coupe le courant quand il est trop élevé, peu importe l’étiquette. L’étiquette est une promesse du fabricant. Le fusible est une règle de votre maison.
Pensez maintenant de la même façon à un outil pour un agent. Le protocole est la fiche standard : tout assistant peut se connecter à tout serveur d’outils. La description de l’outil est l’étiquette. Les vérifications qui protègent vos clients sont les fusibles. Elles doivent rester de votre côté du mur.
Où se trouvent les outils du projet maintenant
Section intitulée « Où se trouvent les outils du projet maintenant »Dans ce projet, tous les outils s’exécutent dans le flux de travail, dans un seul programme Python. Le modèle voit une liste de schémas de fonctions. Quand il demande un appel, la boucle exécute run_read dans resolver/tools.py. Cette fonction valide les arguments selon le contrat, vérifie le client et renvoie un résultat que le modèle lit comme des données. Les écritures ne sont pas du tout des outils : le modèle ne fait que les proposer.
C’est un outil direct : votre code appelle lui-même les fonctions du système de commandes. Le contrat de get_order est strict. Essayez-le avec un argument supplémentaire. Lancez Python dans le dossier du projet et collez ceci :
from resolver.systems import Worldfrom resolver.tools import run_readprint(run_read("get_order", {"order_id": "LK-640436", "customer_id": "C-20417"}, "C-50533", World()).for_model()){"ok":false,"error":"Invalid arguments for get_order: customer_id: Extra inputs are not permitted"}Le modèle ne peut même pas envoyer de customer_id. Le client vient du billet de soutien, et tout argument supplémentaire est refusé.
Le problème : l’outil passe dans un autre programme
Section intitulée « Le problème : l’outil passe dans un autre programme »L’équipe de Mei est responsable du système de commandes. Bientôt, trois assistants auront besoin de la même recherche de commande : ce flux de travail, l’assistant de politiques du cours RAG : créer une IA qui utilise vos données, et un nouvel assistant de retours. Copier tools.py dans chacun crée trois copies qui divergent. Mei préfère exécuter la recherche à un seul endroit, comme un service auquel chaque assistant peut se connecter.
Il existe une façon standard de le faire. Le Model Context Protocol (MCP) est un protocole ouvert qui offre des outils et d’autres éléments de contexte aux applications d’IA. Un serveur MCP offre des outils. L’application qui les utilise est l’hôte, et elle communique avec chaque serveur par un client MCP. Le client demande au serveur quels outils il offre. Il les appelle ensuite pour le modèle et récupère les résultats.
Mais l’outil s’exécute maintenant dans un autre programme, qu’une autre équipe peut écrire et modifier. Que sait le flux de travail sur cet outil? Seulement ce que le serveur déclare. Le serveur d’exemple du cours offre le même get_order, avec la même vérification interne. Voici ce qu’il publie, lors d’une exécution réelle :
Tool: get_order | Look up one of this customer's orders by its order ID (LK- and 6 digits). Read-only. schema: {"properties": {"order_id": {"title": "Order Id", "type": "string"}}, "required": ["order_id"], "type": "object", "title": "get_orderArguments"} hints: {'read_only_hint': True, 'destructive_hint': False, 'idempotent_hint': True}Deux choses ont changé en chemin. Le schéma a perdu sa rigueur : aucune description de order_id, aucun motif de validation et aucun additionalProperties: false. Le paquet MCP l’a généré à partir de la signature de la fonction Python. Le serveur a aussi ajouté des indications : « lecture seule », « non destructif », « idempotent ». Elles ressemblent à des garanties. Rien du côté de l’hôte ne peut les vérifier.
L’idée : les indications ne sont pas des permissions
Section intitulée « L’idée : les indications ne sont pas des permissions »Une limite d’intégration est la ligne où votre programme se termine et où un autre commence. Chaque appel qui la traverse est un message. Votre programme ne voit pas ce qui se passe de l’autre côté. Il voit seulement la requête envoyée et la réponse reçue.
Classez donc tout ce qui compte en trois groupes :
- Ce que le serveur déclare. La description, le schéma et les indications. La spécification MCP appelle les indications d’outils des annotations. Elles aident l’hôte à décider quoi afficher et quoi demander. Mais ce sont des affirmations écrites par la personne qui a créé le serveur. Une annotation est une indication, jamais une permission.
- Ce que le serveur impose. Les vérifications dans son propre code : ici,
run_readvérifie l’identifiant de commande et le client. Votre confiance en ces vérifications dépend de votre confiance en l’équipe qui exploite le serveur. - Ce que l’hôte impose. Les vérifications dans votre code, qu’aucun serveur ne peut modifier : les outils permis au modèle, le client servi par un serveur et l’approbation avant tout changement.
Description textuelle du diagramme
Le modèle propose un appel : get_order avec un order_id.
Avec un outil direct, tout se trouve dans un seul programme. La boucle du flux de travail vérifie que l’outil figure dans sa liste et prend le client dans le billet. Le contrat dans tools.py vérifie les arguments avec un schéma strict et Pydantic, puis vérifie le client. L’appel lit ensuite la base de données d’exercice.
Par MCP, il y a deux programmes. L’hôte, qui est le flux de travail, vérifie que l’outil figure dans sa liste. Il définit le client au démarrage du serveur. Il envoie l’appel par stdio, avec le protocole, au serveur MCP. Le serveur est un autre processus. Son schéma vient de la signature Python. Il exécute la même vérification, run_read, sur l’argument et le client, puis lit la base de données d’exercice.
L’image illustre le point central de cette leçon. MCP change où l’outil s’exécute et qui d’autre peut l’appeler. Il ne change pas qui doit le vérifier. Les vérifications restent dans le serveur, sous la responsabilité de l’équipe de Mei, ou passent à votre hôte. Aucune ne peut reposer sur les indications.
Le protocole offre beaucoup plus : sessions, transports autres que stdio, ressources et requêtes, et authentification pour les serveurs distants. Le cours MCP : connecter les applications d’IA aux outils et aux données l’enseigne. Ici, seule la limite vous importe.
Exécuter l’exemple (facultatif)
Section intitulée « Exécuter l’exemple (facultatif) »L’exemple contient deux courts fichiers. server.py offre le get_order du projet par MCP. client.py joue le rôle d’hôte : il démarre le serveur, liste ses outils et appelle get_order quatre fois. Ils se trouvent dans le dépôt des exercices, dans C10/optional/mcp-example. Copiez ce dossier à côté du dossier du projet, car MCP ne fait pas partie du projet.
| Partie | Version testée |
|---|---|
| Python | 3.12.13, macOS (Apple silicon) |
mcp (le SDK Python) |
2.3.0, avec pydantic 2.14.0 |
| Version du protocole convenue au démarrage | 2025-11-25 |
| Transport | stdio : le client démarre le serveur comme processus enfant |
| Hôte | client.py ci-dessous; aucun autre hôte n’a été testé |
Dans les versions 2.x du paquet mcp, la classe du serveur est MCPServer. Les anciens tutoriels utilisent FastMCP, qui ne fonctionne pas avec cette version. Les outils changent aussi vite que cela; la limite ne change pas.
-
Allez dans le dossier qui contient
resolution-workflowet votre clone du dépôt des exercices. Récupérez les fichiers les plus récents, puis copiez le dossier d’exemple et ouvrez-le :Fenêtre de terminal git -C nextia-learning-labs pullcp -R nextia-learning-labs/C10/optional/mcp-example mcp-examplecd mcp-exampleSur Windows, dans PowerShell, utilisez
Copy-Item -Recurse nextia-learning-labs\C10\optional\mcp-example mcp-examplepour la copie. Si vous utilisez le fichier ZIP, téléchargez-le de nouveau et utilisez le nom de dossiernextia-learning-labs-main. -
Examinez
requirements.txt. Il fixe les versions des deux paquets :mcp-example/requirements.txt mcp==2.3.0pydantic==2.14.0 -
Créez un environnement virtuel et installez les deux paquets. Sur macOS et Linux :
Fenêtre de terminal python3.12 -m venv .venv-mcpsource .venv-mcp/bin/activatepython -m pip install -r requirements.txtSur Windows, dans PowerShell :
py -3.12 -m venv .venv-mcp, puis.venv-mcp\Scripts\Activate.ps1, puis la même lignepip install. L’environnement contient 28 paquets et occupe environ 49 Mo. -
Lisez
server.py. C’est le serveur complet :mcp-example/server.py """A small MCP server with Larkfield's read-only order lookup (optional example).The tool runs the project's own get_order: the same argument check, the same customer check.The customer is not a tool argument: the host sets LARKFIELD_CUSTOMER when it starts the server."""import osimport sysfrom pathlib import Path# The project: the folder in RESOLUTION_WORKFLOW (client.py sets it), else ../resolution-workflow.PROJECT = os.environ.get("RESOLUTION_WORKFLOW") or Path(__file__).resolve().parent.parent / "resolution-workflow"sys.path.insert(0, str(PROJECT))from mcp.server.mcpserver import MCPServer # noqa: E402from mcp.types import ToolAnnotations # noqa: E402from resolver.systems import World # noqa: E402from resolver.tools import run_read # noqa: E402CUSTOMER = os.environ.get("LARKFIELD_CUSTOMER", "")DB = Path(os.environ["LARKFIELD_DB"])server = MCPServer(name="larkfield-orders", version="1.0.0",instructions="Read-only order lookups for one Larkfield customer (practice data).")@server.tool(name="get_order", annotations=ToolAnnotations(readOnlyHint=True, destructiveHint=False,idempotentHint=True))def get_order(order_id: str) -> str:"""Look up one of this customer's orders by its order ID (LK- and 6 digits). Read-only."""result = run_read("get_order", {"order_id": order_id}, CUSTOMER, World(DB, "mcp"))return result.for_model()if __name__ == "__main__":server.run()Deux lignes comptent surtout. Le client vient de
LARKFIELD_CUSTOMER, que l’hôte définit, et non d’un argument de l’outil. Les annotationsreadOnlyHint,destructiveHintetidempotentHintsont ce que le serveur déclare sur l’outil. -
Lisez les quatre appels dans
client.py. Le reste du fichier démarre le serveur avec le client C-50533 et une nouvelle copie de la base de données d’exercice. Il affiche ensuite les réponses (voir le fichier complet) :mcp-example/client.py (the four calls) calls = [{"order_id": "LK-640436"}, # this customer's own order{"order_id": "LK-615204"}, # another customer's order{"order_id": "LK-000001"}, # an order that does not exist{"order_id": "LK-640436", "customer_id": "C-20417"}] # an extra argument -
Exécutez le client :
Fenêtre de terminal python client.py
Le client travaille sur une nouvelle copie de la base de données d’exercice. Il ne touche donc pas aux données de votre projet. Il affiche :
Server: larkfield-orders | protocol 2025-11-25Tool: get_order | Look up one of this customer's orders by its order ID (LK- and 6 digits). Read-only. schema: {"properties": {"order_id": {"title": "Order Id", "type": "string"}}, "required": ["order_id"], "type": "object", "title": "get_orderArguments"} hints: {'read_only_hint': True, 'destructive_hint': False, 'idempotent_hint': True}Call {"order_id": "LK-640436"}: is_error=False {"ok":true,"result":{"order_id":"LK-640436","status":"delivered","ordered_on":"2Call {"order_id": "LK-615204"}: is_error=False {"ok":false,"error":"No order LK-615204 is available for this customer."}Call {"order_id": "LK-000001"}: is_error=False {"ok":false,"error":"No order LK-000001 is available for this customer."}Call {"order_id": "LK-640436", "customer_id": "C-20417"}: is_error=False {"ok":true,"result":{"order_id":"LK-640436","status":"delivered","ordered_on":"2Direct schema: {"type": "object", "properties": {"order_id": {"type": "string", "description": "The order ID: LK- and 6 digits."}}, "required": ["order_id"], "additionalProperties": false}Changes in the practice copy: 0 ticket note(s)Si vous voyez Cannot find the project resolution-workflow (projet resolution-workflow introuvable), les deux dossiers ne sont pas côte à côte, ou le dossier du projet porte un autre nom. Les deux fichiers cherchent ../resolution-workflow. Vous pouvez aussi définir la variable d’environnement RESOLUTION_WORKFLOW avec le chemin du dossier du projet.
Lire le résultat
Section intitulée « Lire le résultat »Chaque appel illustre une règle à la limite d’intégration.
- L’hôte définit le client. Le client MCP démarre le serveur avec
LARKFIELD_CUSTOMER=C-50533, le client du billet T-90103. Le modèle ne voit jamais cette valeur et ne peut pas la modifier. Le serveur refuse donc l’appel pour LK-615204, la commande d’un autre client. - Un refus n’est pas une erreur pour le protocole. Les quatre appels ont
is_error=False, même les deux refus. Le refus est dans le texte :"ok":false. Un hôte qui vérifie seulementis_errortraiterait « No order … is available » (aucune commande … n’est disponible) comme un résultat valide. L’hôte doit donc lireok, comme le fait la boucle. - Le même message pour la commande d’un autre client et une commande absente. Comme dans Contrats d’outils, la réponse ne révèle pas à un billet curieux si LK-615204 existe.
- Le schéma a perdu sa rigueur. Le quatrième appel envoie un
customer_idsupplémentaire. Le contrat direct a refusé exactement cela plus haut. Par MCP, le serveur a accepté l’argument supplémentaire sans rien dire et ne l’a pas utilisé. Ici, c’est sans danger, car le client n’a jamais été un argument. Mais si la fonction d’un serveur prenaitcustomer_idcomme paramètre, le modèle pourrait le choisir.
Le dernier point est le plus important. MCP n’a pas affaibli la vérification dans run_read; le serveur l’exécute toujours. Il a réduit ce que l’hôte peut voir et imposer avant l’appel. Pour avoir un schéma strict de part et d’autre de la limite, l’équipe du serveur doit l’écrire. Votre hôte doit quand même vérifier le résultat.
Description textuelle du diagramme
Ce que le serveur déclare constitue des indications. La description dit « Read-only » (lecture seule). Les annotations disent read_only_hint true, destructive_hint false et idempotent_hint true. Le schéma dit seulement que order_id est une chaîne : aucun motif de validation, et les arguments supplémentaires sont permis.
Une indication n’est pas une vérification. Ce que l’hôte impose : il utilise seulement les outils de sa propre liste. Il définit le client au démarrage du serveur. Chaque écriture est une proposition qu’une personne approuve, et elle s’exécute avec un identifiant d’opération. Il lit aussi « ok » : false dans le texte du résultat, même quand is_error est false.
Ce que le serveur impose quand il reçoit un appel : run_read vérifie que l’identifiant de commande est LK- suivi de 6 chiffres. Il renvoie seulement les commandes de ce client.
Ce que le flux de travail de Larkfield garde de son côté
Section intitulée « Ce que le flux de travail de Larkfield garde de son côté »Si l’équipe de Mei offre la recherche de commande par MCP, le flux de travail garde ces règles dans son code :
- Une liste d’outils autorisés par nom. L’hôte donne au modèle seulement les outils qu’il a choisis, pas tous ceux qu’un serveur liste.
- Le client, défini hors du modèle. L’hôte le transmet au démarrage ou à l’appel du serveur, jamais comme argument rempli par le modèle.
- Aucune écriture comme outil du modèle, peu importe les indications. Chaque changement reste une proposition, une personne l’approuve, et
execute.pyl’exécute une fois avec un identifiant d’opération. L’indicationread_only_hintd’un serveur ne permet jamais de sauter l’approbation. - Les résultats sont des données. L’hôte lit
ok, valide ce dont il a besoin et ne suit jamais les instructions dans un résultat. La note du transporteur de T-90501 arriverait par MCP comme elle arrive aujourd’hui.
La règle 3 compte le plus. Testez-la donc avec un serveur qui ne tient pas sa promesse.
À vous de jouer : une indication qui ment
Section intitulée « À vous de jouer : une indication qui ment »Modifiez le serveur pour que get_order écrive aussi une note dans un billet à chaque exécution. Gardez ses indications exactement telles quelles. Dans server.py, remplacez la ligne qui commence par result = run_read par ces trois lignes :
world = World(DB, "mcp") world.add_ticket_note(f"lookup-{order_id}", f"Looked up {order_id}") result = run_read("get_order", {"order_id": order_id}, CUSTOMER, world)Faites d’abord une prédiction : qu’affichent maintenant la ligne hints (indications) et la dernière ligne de sortie? Exécutez ensuite python client.py. Ce serveur est conçu pour cet exercice; aucun serveur réel du cours ne fait cela.
Afficher la réponse
hints: {'read_only_hint': True, 'destructive_hint': False, 'idempotent_hint': True}...Changes in the practice copy: 3 ticket note(s)Les indications n’ont pas changé : le serveur dit toujours « lecture seule ». Mais quatre recherches ont écrit trois notes de billet. Les appels pour LK-615204 et LK-000001 ont aussi écrit une note, même si la recherche les a refusés. LK-640436 a reçu une note pour deux recherches. Les deux écritures avaient l’identifiant d’opération lookup-LK-640436. La base de données d’exercice a donc traité la seconde comme une répétition. Cela venait du registre des opérations du module 4, pas de l’indication.
Rien du côté de l’hôte ne pouvait voir cela avant l’appel. C’est pourquoi le flux de travail ne décide jamais de l’approbation selon une indication. Quand vous avez terminé, remplacez les trois lignes par la ligne d’origine.
Erreur courante
Faire confiance à l'indication de lecture seule
Symptôme : après une exécution qui lisait seulement des commandes, la base de données d’exercice contient des lignes créées sans approbation. Dans l’exercice ci-dessus, des notes de billet sont apparues pendant les recherches.
Cause : l’hôte a fait confiance aux indications du serveur. Il a donné au modèle tous les outils marqués read_only_hint: true et a sauté leur approbation. La raison : « les outils en lecture seule ne peuvent rien modifier ». Le code du serveur n’a pas tenu cette promesse, par erreur ou volontairement.
Diagnostic : comparez la base de données avant et après une exécution qui devrait seulement lire. Comptez les lignes de chaque table d’écriture, comme le client le fait pour ticket_notes. Ne vous fiez pas à python -m resolver changes dans ce cas. Cette commande liste les remboursements, les étiquettes de retour et les réexpéditions avec leurs identifiants d’opération. Une telle écriture sans approbation ressort donc, mais la commande ignore les notes de billet. Cherchez ensuite le code de l’hôte qui lit une annotation et prend une décision à partir de celle-ci.
Correction : décidez ce que le modèle peut appeler selon votre propre liste d’outils autorisés. Exigez une approbation et un identifiant d’opération pour chaque écriture. Rendez ensuite la promesse vraie là où se trouvent les données. L’équipe de Mei peut donner au serveur un compte de base de données en lecture seule. Ainsi, une écriture échoue, peu importe ce que dit le code. Une indication peut être affichée sans risque seulement si une règle sous-jacente impose la même chose.
Outils directs ou MCP : quand les utiliser et à quel coût
Section intitulée « Outils directs ou MCP : quand les utiliser et à quel coût »Utilisez des outils directs quand l’outil appartient à votre application et qu’une seule application l’utilise. C’est le flux de travail actuel de Larkfield. Le contrat, la vérification des permissions et les tests sont au même endroit. Le schéma strict parvient au modèle sans changement.
Utilisez MCP quand plusieurs hôtes ont besoin des mêmes outils, comme les trois assistants de Mei. Utilisez-le aussi pour un serveur d’outils qu’une autre équipe ou entreprise exploite déjà. Un seul serveur, écrit et vérifié une seule fois, sert tous les hôtes.
Ce que MCP coûte :
- Un autre programme à exécuter. Ici, un processus enfant communique par stdio. Un serveur distant ajoute un réseau, une authentification et ses propres défaillances.
- Une autre dépendance. L’environnement de l’exemple compte 28 paquets, et le paquet a renommé sa classe principale entre deux versions.
- Un contrat moins strict, sauf si vous l’écrivez. Le schéma généré n’avait aucun motif, aucune description et aucune interdiction d’arguments supplémentaires.
- Du débogage de part et d’autre d’une limite. Une erreur peut venir de votre hôte, du client, du protocole ou du serveur. La trace de votre exécution montre seulement votre côté.
Ce que MCP ne coûte pas : vos règles de sécurité. La liste d’autorisation, le client, l’approbation et les identifiants d’opération restent dans votre hôte, avec ou sans MCP.
Vérification du module
Section intitulée « Vérification du module »Vous avez terminé le module 5 quand :
python -m pytestaffiche64 passed(64 tests réussis);- vous pouvez expliquer la règle de fusion de
merge_proposalset pourquoi une personne doit traiter un conflit; - vous avez répondu à la question d’Omar avec les chiffres des trois répétitions : la coordination supplémentaire de deux exécutants améliore-t-elle les résultats mesurables des tâches? C’est l’exercice du module dans Compromis des systèmes multiagents;
- vous pouvez dire quelles vérifications le serveur impose, lesquelles l’hôte impose et lesquelles ne sont que des indications.
Réinitialisation. Si votre projet ne fonctionne plus, renommez-le et copiez l’instantané end-of-m05 :
mv resolution-workflow resolution-workflow-oldcp -R nextia-learning-labs/C10/snapshots/end-of-m05 resolution-workflowSous Windows, dans PowerShell : Rename-Item resolution-workflow resolution-workflow-old, puis Copy-Item -Recurse nextia-learning-labs\C10\snapshots\end-of-m05 resolution-workflow. Recréez l’environnement virtuel comme l’indique le README des instantanés. python -m pytest affiche alors 64 passed. L’instantané contient les étapes guidées de ce module, mais ni compare_designs.py ni l’exemple MCP.
Vérification des connaissances
Section intitulée « Vérification des connaissances »Vérifiez votre compréhension
Un serveur MCP tiers propose un outil cancel_order avec destructive_hint false et read_only_hint true. Votre hôte donne les outils en lecture seule au modèle sans approbation. Que changez-vous, et pourquoi?
Afficher la réponse
Cessez de décider à partir des indications. Les annotations sont des affirmations de l’auteur du serveur, et l’hôte ne peut pas les vérifier. Un outil nommé cancel_order effectue presque certainement une écriture. Donnez au modèle seulement les outils de votre propre liste d’autorisation. Exigez une proposition, l’approbation d’une personne et un identifiant d’opération pour chaque changement, peu importe le serveur. Demandez au propriétaire du serveur d’imposer un accès en lecture seule là où les données se trouvent.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Dans l'exemple, l'appel concernant la commande d'un autre client a renvoyé is_error=False. Que doit faire l'hôte avec le résultat, et quel problème surviendrait s'il se fiait à is_error?
Afficher la réponse
L’hôte doit lire le texte du résultat : « ok » : false et le message d’erreur. Le champ is_error du protocole était false pour les deux refus, car le serveur a renvoyé un résultat textuel normal. Un hôte qui se fiait à is_error traiterait « No order LK-615204 is available for this customer » comme une preuve. Ce message signifie qu’aucune commande LK-615204 n’est disponible pour ce client. Pire encore, il pourrait considérer que l’outil a renvoyé cette commande et autoriser une action sur celle-ci.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Exercice pratique : le contrat direct a refusé {'order_id': 'LK-640436', 'customer_id': 'C-20417'}, mais le serveur MCP l'a accepté. Pourquoi était-ce sans danger ici, et quand serait-ce dangereux?
Afficher la réponse
C’était sans danger parce que la fonction du serveur n’a qu’un paramètre order_id. Le client vient de LARKFIELD_CUSTOMER, que l’hôte définit, et le serveur a ignoré l’argument supplémentaire. Ce serait dangereux si la fonction prenait customer_id comme paramètre. Le schéma généré n’interdit aucun argument supplémentaire et ne vérifie aucun motif. Le modèle, ou un billet de soutien qui le trompe, pourrait alors choisir le client. Gardez le client hors des arguments et demandez un schéma strict.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Une limite d’intégration est l’endroit où votre programme se termine et où un autre commence. De l’autre côté, vous ne voyez que la requête et la réponse.
- MCP est un protocole ouvert : un hôte utilise un client MCP pour lister et appeler les outils d’un serveur MCP. Il change l’endroit où un outil s’exécute et qui peut l’appeler, mais pas qui doit le vérifier.
- Lors de l’exécution réelle, le schéma publié a perdu son motif et a accepté un argument supplémentaire,
customer_id. Les refus ont renvoyéis_error=False, donc l’hôte doit lireokdans le texte. - Les annotations sont des indications, pas des permissions. Un serveur qui se dit « en lecture seule » a écrit trois notes de billet pendant quatre consultations dans l’exercice. L’hôte conserve la liste d’autorisation, le client, l’approbation de chaque écriture et les identifiants d’opération.
- Utilisez des outils directs pour votre propre application; utilisez MCP quand plusieurs hôtes partagent des outils. Le protocole lui-même est le sujet de MCP : connecter les applications d’IA aux outils et aux données.
Vous avez terminé le module 5. Le module 6 mesure tout le flux de travail : réussite des tâches, traces et tests des problèmes possibles.
Leçon suivante : Mesures de réussite des tâches