Une interface utilisateur générative... en Python ? — Jeremiah Lowin, Prefect
AAI Engineer
컴퓨터/소프트웨어AI/미래기술
스크립트
00:00:00Merci à tous d'être venus. Je vais vous parler aujourd'hui de l'un des logiciels les plus étranges
00:00:18que j'aie jamais écrits. C'est un peu à la frontière de tout ce que j'ai pu proposer
00:00:22au monde. Alors joignez-vous à moi si vous le voulez bien. Nous allons essayer d'adopter l'approche la plus raisonnée
00:00:27face à un phénomène très particulier que les agents du protocole MCP et d'autres outils ont rendu possible. Et pour commencer,
00:00:34je veux parler des applications MCP. Je ne sais pas si certains d'entre vous ont pu assister aux autres
00:00:38conférences plus tôt aujourd'hui, peut-être celle qu'Ido et Liat ont présentée il y a environ une heure. Juste à main levée,
00:00:44qui connaît les applications MCP ? D'accord, c'est probablement le meilleur public devant lequel j'ai jamais donné cette conférence,
00:00:52en fait. C'est fantastique. Pour ceux qui n'ont pas levé la main, les applications MCP constituent une
00:00:57extension du protocole MCP qui a été introduite, je crois, en janvier de cette année. Et l'idée est la suivante :
00:01:02voici un cycle requête-réponse typique pour un outil MCP. L'utilisateur fait une requête à l'agent. L'
00:01:10agent décide à son tour d'utiliser un outil MCP hébergé sur un serveur MCP. Le résultat de l'outil revient
00:01:16dans le contexte de l'agent. Et l'agent choisit de form mez une réponse et de l'envoyer à l'utilisateur. Et donc,
00:01:23fondamentalement, les serveurs MCP sont d'excellents moyens d'ajouter des fonctions et de la logique métier à vos agents,
00:01:28mais il n'y a jamais de connexion directe entre l'utilisateur et le serveur MCP. Cela passe toujours par le cerveau de l'
00:01:34agent et, plus important encore, par la fenêtre de contexte de l'agent. Ainsi, les applications MCP sont une extension de ceci,
00:01:40qui nous permet en fait de contourner l'agent. À la place, voici ce qui se passe :
00:01:44l'utilisateur demande quelque chose à l'agent, l'agent utilise un outil, mais au lieu que cette requête d'outil ne renvoie
00:01:49vers l'agent, elle est envoyée à l'utilisateur. Et elle est envoyée sous forme de HTML, CSS, JavaScript. C'est une interface complète.
00:01:55Et elle peut être exactement ce que vous voulez qu'elle soit. L'idée est donc d'avoir un moyen d'intégrer
00:02:01en quelque sorte Internet dans votre agent. Vous pouvez déployer n'importe quelle interface utile, personnalisée et à vos couleurs. Vous pouvez
00:02:08offrir à l'utilisateur toute l'expérience interactive qu'il désire. Et ensuite, comme vous pouvez le voir sur
00:02:12le diagramme, l'utilisateur peut interagir avec l'application. Il peut utiliser les outils. Il peut envoyer
00:02:17des informations vers un backend hébergé sur cette application, et vraiment profiter d'une expérience complète. Vous pouvez donc imaginer
00:02:21réserver une table dans un restaurant, changer de siège dans un avion ou interagir avec un planning.
00:02:28Pour les ingénieurs en IA, il y a beaucoup de choses que vous pouvez faire en tant qu'utilisateur où l'agent a facilité les choses,
00:02:33mais où vous allez interagir en tant qu'humain. Et il y a une extension qui arrive. Elle va
00:02:37sortir dans la version MCP de juillet, où l'agent pourra également interagir avec l'application. Et cela
00:02:43va ouvrir des cas d'usage vraiment intéressants dont nous ne parlerons pas aujourd'hui, mais vous pourriez
00:02:47hypothétiquement jouer à une partie d'échecs contre l'agent dans une application visuelle où vous effectuez un mouvement,
00:02:52puis l'agent interagit également avec l'application. Je pense donc que cela va ouvrir un tout nouveau
00:02:55champ des possibles. Maintenant, certains d'entre vous connaissent peut-être un framework dont je suis l'auteur et que mon entreprise
00:03:03maintient, appelé FastMCP. FastMCP est l'un des moyens les plus populaires pour créer des serveurs MCP. Et donc, chaque fois que de nouvelles
00:03:09choses formidables font leur apparition dans le monde de MCP, la première chose que je me demande est : comment puis-je offrir cela à nos utilisateurs ?
00:03:16Et l'une des choses les plus importantes que j'ai à partager avec vous concernant notre base d'utilisateurs, c'est qu'ils sont
00:03:20principalement des ingénieurs Python. Et cela pose un petit problème lorsque nous voulons proposer
00:03:27des interfaces et des designs, car comment allons-nous réellement nous y prendre ? C'est le moment de la présentation
00:03:31où je révèle que je ne me souviens plus exactement de la diapositive suivante, alors nous allons y jeter un coup d'œil.
00:03:35Non, nous allons y revenir. Nous avons un défi à relever. Comment allons-nous faire en sorte que les ingénieurs Python construisent
00:03:42des interfaces conformes aux meilleures pratiques, interactives, magnifiques et utiles, sans
00:03:50faire semblant de faire quelque chose d'absurde, quelque chose qui a déjà été tenté, en fourrant tout le
00:03:54front-end, tout l'écosystème, absolument tout dans Python sous la forme d'un système Frankenstein bizarre,
00:04:00bricolé et compromis. J'ai vraiment eu du mal avec ça. J'ai besoin,
00:04:04j'ai vraiment besoin, je ressens l'obligation de trouver un moyen de proposer cela. Mais je ne peux pas faire semblant qu'on
00:04:10va faire du React en Python. Ça ne marchera pas. Nous avons donc mûrement réfléchi à la question : qui sont
00:04:15nos utilisateurs dans l'écosystème FastMCP ? Qui sont ces développeurs Python qui travaillent généralement en entreprise ?
00:04:20Que font-ils et à quoi ont-ils besoin de ces interfaces ? Pourquoi ont-ils besoin de ces applications MCP ?
00:04:25Ce dont ils n'ont pas besoin, ce sont d'interfaces sur mesure grand public entièrement personnalisées. Ce n'est pas ce que font ces gens-là. Ce dont ils sont principalement
00:04:34chargés, c'est de partager des informations au sein de leur organisation, et de collecter
00:04:38des informations au sein de leur organisation. Cela a donc changé la nature de ce que nous attendons d'eux
00:04:43dans le cadre du framework des applications MCP. Et cette contrainte est devenue très utile. Fondamentalement, nous nous attendons donc à ce qu'ils
00:04:48fassent des choses comme créer des tableaux, collecter des informations via des formulaires,
00:04:53et qu'ils veuillent partager des graphiques. Ainsi, grâce à cette contrainte,
00:04:58nous pouvons introduire un logiciel que nous avons passé en open source il y a quelques mois et qui a connu un succès surprenant
00:05:03auprès de ce public, appelé Prefab. C'est un framework de création d'interfaces au périmètre restreint destiné à
00:05:11fournir des interfaces via un agent pour les objectifs que j'ai mentionnés il y a un instant. Voici donc une carte « Hello World ».
00:05:17Vous pouvez voir cela dans n'importe quel framework front-end. Littéralement n'importe lequel. Il y aura toujours quelque chose
00:05:22qui ressemble à ça sur leur site web, vous tapez votre nom et cela se met à jour en direct.
00:05:27Mais bien sûr, ce qu'il y a d'étrange avec celui-ci, c'est que le code qui l'a généré est entièrement écrit
00:05:31en Python. J'espère donc que vous ressentez ce que je ressens en regardant cela, à savoir cette association très bizarre
00:05:38où l'on se dit « c'est cool » et « ça me fait vraiment flipper ». Le « c'est cool » vient
00:05:44du fait qu'il y a quelque chose dans ce code, même si vous ne pouvez pas le voir de près, je peux
00:05:48l'agrandir un peu, il y a quelque chose ici qui a plutôt de sens. Vous pouvez voir la
00:05:52structure de l'interface dans le code, mais il y a aussi quelque chose d'évidemment extraterrestre et un peu
00:05:58bizarre. Et l'on parvient à cette conclusion lorsqu'on ressent cela en le regardant, c'est-à-dire que
00:06:04lorsqu'on compose un front-end en Python, cela commence en réalité à être agréable tant que l'on délimite correctement
00:06:09le problème. Nous n'essayons pas de construire un front-end à partir de zéro. Nous essayons de composer un front-end
00:06:15à partir d'un ensemble de composants de premier ordre et bien conçus. C'est ainsi que l'on garde des garde-fous,
00:06:20et c'est ainsi que l'on garde l'utilisateur à l'esprit. L'utilisateur ici n'essaie pas de faire quelque chose d'arbitraire.
00:06:24Il essaie de prendre un front-end bien structuré et de le présenter à la personne à qui il le destine.
00:06:29Voici donc un rapide tour d'horizon de ce DSL. Nous utilisons principalement des gestionnaires de contexte. Pour
00:06:34ceux d'entre vous qui connaissent FastMCP, vous savez qu'on pourrait sans doute résumer FastMCP en disant :
00:06:39la principale innovation de FastMCP est d'avoir utilisé un décorateur Python pour créer un serveur MCP entier.
00:06:44Si vous voulez appliquer la même approche réductionniste à Prefab, vous pourriez dire : nous utilisons un gestionnaire de contexte pour
00:06:48créer une interface entière. Et en imbriquant des composants sous forme de gestionnaires de contexte, comme vous le voyez ici, nous construisons
00:06:55exactement la même structure dans l'interface. C'est très naturel à lire. On comprend bien comment les choses
00:07:01sont structurées. Chaque élément de l'interface, chaque composant – qui est un magnifique composant Shadcn
00:07:06lorsqu'il est rendu, comme vous pouvez le voir ici – est une classe que vous instanciez. Vous pouvez la paramétrer. Vous pouvez
00:07:11lui passer des éléments comme des classes CSS pour lui donner l'aspect que vous voulez. Et enfin, ce que nous n'aurons
00:07:17pas le temps d'explorer en profondeur aujourd'hui, ce sont ces variables réactives. Je vais vous faire une démo
00:07:21de tout cela dans un instant. Mais pour l'essentiel, nous disposons d'un moyen complet de créer de l'interactivité côté client
00:07:26et de lier des données entre les composants, ce qui permet de concevoir ces expériences très riches, là encore,
00:07:31sans avoir à plonger corps et âme dans le monde JavaScript et à quitter un écosystème que ma base d'utilisateurs,
00:07:36du moins, maîtrise parfaitement. Et voici le pipeline que Prefab expose essentiellement.
00:07:42Nous utilisons un DSL Python dont je viens de vous parler. Nous l'utilisons pour construire une représentation
00:07:46déclarative d'une interface. Celle-ci est ensuite sérialisée en un protocole JSON. Et ce protocole JSON est
00:07:53finalement rendu par une application React, hébergée en tant qu'application MCP proprement dite. Cela va donc nous ouvrir
00:07:59tout un champ de possibilités que, encore une fois, je vais vous montrer dans un instant. Mais la clé
00:08:02de tout cela, c'est le JSON au milieu. Le code Python est en fait un heureux hasard que j'ai découvert
00:08:07après coup, parce que c'était une bizarrerie idiosyncratique dont j'avais envie. L'objectif initial était :
00:08:10« Pouvons-nous créer une représentation sérialisable d'une interface ? » Et c'est de nouveau ce protocole JSON.
00:08:17Et comme il est sérialisable, je peux le générer à partir d'un agent. Je peux l'envoyer à un agent. Je peux le générer
00:08:22en tant qu'humain et demander à un agent de le modifier. Plein de choses géniales deviennent possibles grâce à cette
00:08:26représentation intermédiaire en JSON. Et lorsque le DSL Python a découlé de tout cela d'une manière très simple et élégante,
00:08:31j'ai eu le sentiment qu'on tenait quelque chose. Nous avons donc ces documentation. Et pour ainsi dire prouver
00:08:37le propos, c'était une autre contrainte que nous nous étions fixée. Je ne sais même pas ce que c'est. Ce sont les
00:08:42documents du composant de tableau de données dans Prefab. Je crois qu'il y a 130 ou 140 composants que nous proposons et que vous
00:08:47pouvez combiner pour former une structure arbitraire. La documentation de Prefab est rendue à 100 % en Prefab. Ainsi, le tableau de données
00:08:55qui se trouve ici dans l'utilisation de base est affiché en direct grâce à Prefab. Le code Python, vous pouvez le voir apparaître
00:09:01au bas de l'écran. Ce code Python est exécuté en direct par le moteur de rendu pour le générer.
00:09:05Si vous le souhaitez, vous pouvez prendre n'importe quel exemple de la documentation de Prefab, cliquer sur un lien, l'ouvrir dans
00:09:09l'aire de jeu et modifier le code en direct, le code Python en direct, et vous verrez l'interface se mettre à jour. Et encore une fois,
00:09:15c'est super bizarre. Si vous vous sentez un peu mal à l'aise avec ça, c'est tout à fait normal. Cela devient
00:09:20tout devient beaucoup plus clair lorsqu'on cerne le problème en se rappelant qu'on compose une interface
00:09:24plutôt qu'on ne la construit. Je souhaite donc revenir à ce dont j'ai parlé au début, à savoir les serveurs MCP
00:09:29et plus particulièrement, les applications MCP. Vous pouvez utiliser Prefab pour tout type de problème d'interface.
00:09:34Mon équipe a commencé à l'utiliser pour de petites applications de données interactives et des outils d'exploration.
00:09:39Ils ont créé des présentations avec. Nous proposons un thème sombre qui ressemble honnêtement à celui
00:09:43que je vous montre en ce moment pour faire des diapos et des présentations. On peut faire énormément de choses.
00:09:48Mais la raison pour laquelle nous l'avons créé, le cas d'usage auquel il répond, c'est pour les serveurs MCP.
00:09:54Je vais donc vous présenter rapidement trois façons de l'utiliser, trois manières de plus en plus sophistiquées
00:09:58de l'intégrer à votre serveur MCP. La première consiste à créer un outil interactif. Comme je vous l'ai montré
00:10:04au début, un outil MCP est généralement appelé par votre agent, qui récupère le résultat sans que vous
00:10:09ne puissiez interagir avec. Alors, quel est le moyen le plus simple d'améliorer cette interactivité ?
00:10:14Je vais vous le montrer ici. C'est un outil Fast MCP. Il a été doté d'un décorateur d'outil, comme vous pouvez le voir,
00:10:20et c'est juste une fonction Python qui renvoie des informations. Gardez à l'esprit que ces informations iront à l'agent,
00:10:24pas à l'utilisateur. Si nous voulons transformer ceci en un outil entièrement interactif avec Prefab,
00:10:30nous allons faire un seul changement. Au lieu de renvoyer un dictionnaire Python à la fin, qui ira à l'agent,
00:10:36nous allons renvoyer un composant Prefab. Dans ce cas, il s'agit du tableau de données.
00:10:40C'est de la documentation dont je viens de vous parler il y a un instant. Et lorsque nous renvoyons ce composant Prefab, Fast MCP le détecte automatiquement.
00:10:46Il en déduira automatiquement que vous souhaitez en fait renvoyer une application MCP, et il mettra en place
00:10:51tous les mécanismes nécessaires pour obtenir le HTML, le JavaScript, le CSS, le moteur de rendu, tout ce qu'il faut
00:10:55pour que votre utilisateur voie un tableau de données. Voici à quoi cela ressemble en pratique. J'utilise le client Goose,
00:11:00qui est excellent. J'ai demandé à un serveur disposant de la fonction que je viens de vous montrer de m'afficher l'annuaire
00:11:06de l'équipe, et ce qui s'affiche (ce serait mieux sous forme de GIF, je m'en excuse), c'est un composant
00:11:10de tableau de données entièrement interactif. Il gère la recherche, le filtrage, le tri, la pagination,
00:11:16et tout le reste. Et tout ça se résume à ce que je vous ai montré il y a un instant : renvoyer la classe de tableau de données,
00:11:21et tout le reste est pris en charge. Nous pouvons aller encore plus loin. Et si, en plus du tableau de données,
00:11:26nous voulions afficher un diagramme circulaire juste à côté pour ventiler cet annuaire de l'équipe ?
00:11:30Comme vous pouvez l'imaginer, le code est très, très, très similaire. Au lieu du tableau de données seul, nous allons
00:11:35maintenant importer une grille et un diagramme circulaire, et si vous regardez en bas, vous verrez que nous assemblons le diagramme
00:11:40et le tableau dans une grille très naturellement grâce à un gestionnaire de contexte, et voici le résultat.
00:11:45Nous obtenons désormais un diagramme circulaire à côté de notre tableau. Cela respecte un principe auquel nous tenons beaucoup
00:11:51pour bon nombre de nos logiciels chez Prefect : une ligne de code, un changement majeur visible.
00:11:55Nous essayons de maintenir cette complexité de manière incrémentielle, ce qui répond à de nombreux aspects qui me semblent
00:11:59très importants concernant les frameworks et les langages dédiés (DSL). Très rapidement, car nous n'aurons pas le temps d'entrer dans les détails,
00:12:05voici simplement un exemple que j'ai préparé et enregistré d'interactivité entièrement côté client,
00:12:09où toutes ces commandes sont liées, tout se met à jour, le texte se met à jour, les valeurs se mettent à jour,
00:12:15sans avoir écrit la moindre ligne de JavaScript. Il s'agit juste de quelques classes assemblées qui possèdent toutes
00:12:19le même attribut assigné, de sorte qu'elles fonctionnent toutes ensemble automatiquement.
00:12:24Ah, et j'ai bien inclus un bref exemple de code montrant à quoi cela ressemble. Nous avons une classe appelée Rx qui,
00:12:28comme vous le devinez, signifie réactif. Si vous utilisez ces variables réactives, vous pouvez simplement les référencer
00:12:33partout dans votre code, vous pouvez les formater, les utiliser pour nommer quelque chose, et cela se convertira
00:12:38automatiquement dans l'implémentation JavaScript correcte. La deuxième chose que nous pouvons faire, c'est
00:12:43une application FastMCP. Si un outil interactif est en quelque sorte ponctuel (voici une interface utilisateur avec laquelle
00:12:49vous pouvez interagir côté client), une application FastMCP est une application complète dotée d'un backend, et dans ce cas,
00:12:54le serveur MCP fera office de backend. Nous n'avons pas le temps de parcourir un exemple complet dans le détail
00:12:59au cours de cette session, mais voici à quoi ressemble le code, pour vous donner une idée de l'ergonomie.
00:13:03Nous allons écrire une classe, qui correspond à notre application FastMCP, puis nous allons décorer au moins
00:13:08deux fonctions avec app.ui. C'est le point d'entrée qui renverra les composants Prefab formant
00:13:14l'interface utilisateur de base de cette application, puis au moins un (je suppose que c'est facultatif, donc zéro ou plus)
00:13:20app.tools, qui sont essentiellement des méthodes backend que vous pouvez désormais référencer dans l'interface.
00:13:27Vous pourriez ainsi avoir un bouton qui récupère les données saisies par l'utilisateur dans un formulaire et les envoie
00:13:31à une base de données grâce à un outil décoré de la sorte. L'un des éléments que nous utilisons et fournissons désormais
00:13:38en tant que composant intégré dans FastMCP est un composant de téléchargement. Comme vous pouvez le voir, puisque seul l'agent a accès
00:13:46à un serveur MCP, vous ne pouvez pas simplement y télécharger un fichier directement. Il doit transiter par le cerveau de l'agent,
00:13:51ce qui amène de nombreuses personnes à créer un outil de téléchargement sur leur serveur MCP
00:13:56en oubliant que l'agent doit réellement l'appeler. On se retrouve alors à réaliser l'opération de copier-coller
00:14:00la plus coûteuse au monde. Vous donnez un méoctet de texte à l'agent, qui le retapes caractère par caractère
00:14:06dans le MCP. Alors oui, le fichier finit par être téléchargé, mais c'est extrêmement, extrêmement inefficace.
00:14:12C'est donc un cas d'usage idéal pour une application MCP : vous demandez à l'agent d'afficher l'interface de l'application,
00:14:18vous y glissez un fichier, et celui-ci contourne l'agent pour aller directement dans le serveur.
00:14:23Nous en avons fait une ligne de code, accompagnée de quelques autres outils utiles, et
00:14:30est-ce un GIF ? Ce n'en est pas un, ou s'il s'agit d'un GIF, il ne s'affiche pas, mais voici à quoi cela ressemblerait dans votre
00:14:34client. Si votre client prend en charge les applications MCP et que vous demandez à l'agent de télécharger quelque chose, il peut désormais
00:14:38vous l'afficher, vous permettant de le faire en toute sécurité et surtout à moindre coût. Ah, j'ai bien un GIF. Autant pour moi.
00:14:45Connaître ses propres diapositives, voilà une bonne leçon à tirer de cette présentation. L'agent interagit donc maintenant
00:14:50avec un fichier que je viens de télécharger par glisser-déposer. Je mettrai ces diapositives à disposition plus tard si
00:14:55vous souhaitez les consulter, ou bien sûr, c'est une seule ligne de code. Vous pourrez les tester sur vos serveurs cet après-midi.
00:15:00Le dernier sujet dont je souhaite parler, rendu possible en quelque sorte par cette architecture,
00:15:04c'est une interface utilisateur entièrement générative. Nous allons simplement passer à la suite en laissant tourner la vidéo pendant que je parle.
00:15:10Il s'agit d'une démo très simple où j'ai demandé à Claude : « Hé, je donne une conférence à ce sujet. Génère en streaming l'interface
00:15:15la plus intéressante possible. » Et il s'est exécuté. Ce qu'il fait ici, c'est que nous avons exposé un outil
00:15:21qui accepte le JSON, la sérialisation de protocole d'une interface sur laquelle Prefab s'appuie. Ainsi, à mesure que
00:15:29l'agent diffuse ces informations en temps réel, nous rendons immédiatement ce que nous recevons,
00:15:35en réparant ce JSON et en l'affichant. C'était une démo vraiment géniale et très efficace,
00:15:39et les gens aiment ça parce qu'il n'est même plus nécessaire de concevoir l'interface soi-même. Tout ce que vous avez à faire,
00:15:43c'est d'utiliser la compétence que nous fournissons déjà, de la partager avec votre agent pour qu'il sache créer une interface, et le tour est joué.
00:15:48Il peut vous fabriquer ce que vous voulez. Certains clients intègrent des versions natives de ceci. S'ils disposent
00:15:52d'une telle version, vous préférerez peut-être l'utiliser, grand bien vous fasse. Mais cela peut être un moyen pour vous de concevoir
00:15:56votre propre approche personnalisée ou un ensemble limité de composants utiles. Un événement très intéressant
00:16:01s'est produit lorsque nous avons lancé ceci. Comme je l'mentionné, le plan initial était que l'agent envoie
00:16:07du JSON pour le rendre sous forme d'application React complète. Ce que nous avons fini par découvrir,
00:16:13c'est que la représentation Python d'une interface est environ 70 % plus petite que la représentation JSON.
00:16:20Par conséquent, nous ne procédons plus ainsi. Lorsque j'ai enregistré cette démo avec du JSON en streaming, ce que nous faisons maintenant,
00:16:26c'est de diffuser directement du Python. Il est exécuté dans un bac à sable, converti en JSON sur le serveur,
00:16:32puis rendu. Cela apporte donc un gain spectaculaire en matière d'efficacité des jetons (tokens) et de réduction de la latence.
00:16:39Cela fonctionne exactement de la même manière que lorsque j'ai enregistré cette démo, mais c'est l'une de ces choses
00:16:43que nous avons apprises sur le tas. Et il est vraiment fascinant de constater que la représentation Python est tellement plus compacte et ergonomique
00:16:49que le format JSON complet. Voilà donc pour Prefab. Si vous souhaitez le découvrir, par curiosité,
00:16:55ou pour voir la chose la plus loufoque que j'aie jamais construite avec d'autres personnes, vous pouvez consulter
00:17:00la documentation sur prefab.prefect.io. Vous y trouverez l'ensemble de la bibliothèque, disponible sur notre GitHub. Et c'est
00:17:06déjà totalement intégré à Fast MCP. Donc, si vous utilisez une version récente de Fast MCP, vous devriez pouvoir
00:17:11installer cette édition optionnelle, importer les composants, les renvoyer et commencer à vous amuser avec ces applications MCP.
00:17:17Merci à tous d'être venus.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기