스크립트
00:00:00Спасибо всем, кто пришел. Сегодня я хочу рассказать об одной из самых странных программ,
00:00:18которые я когда-либо писал. Она находится на стыке самых разных идей,
00:00:22которые я продвигаю в мир. Так что присоединяйтесь. Мы постараемся подойти максимально здраво
00:00:27к весьма странной вещи, которую сделали возможной агенты в MCP и другие технологии. И для начала,
00:00:34я хочу поговорить о приложениях MCP. Не знаю, смог ли кто-нибудь из вас посетить другие
00:00:38выступления сегодня, например, доклад Идо и Лиат, который был примерно час назад. Поднимите руки,
00:00:44кто знаком с приложениями MCP. Отлично, это, пожалуй, лучшая аудитория, перед которой я выступал,
00:00:52на самом деле. Это просто фантастика. Для тех, кто не поднял руки: приложения MCP — это
00:00:57расширение протокола MCP, которое было представлено, кажется, в январе этого года. И идея в том,
00:01:02что перед нами типичный цикл запрос-ответ для инструмента MCP. Пользователь отправляет запрос агенту. Агент
00:01:10в свою очередь решает использовать инструмент MCP, размещенный на сервере MCP. Результат работы инструмента возвращается
00:01:16в контекст агента. И агент решает сформировать какой-то ответ и отправить его пользователю. И по сути,
00:01:23серверы MCP — это фантастический способ добавления функций и бизнес-логики вашим агентам,
00:01:28но прямой связи между пользователем и сервером MCP никогда нет. Она всегда проходит через «мозг»
00:01:34агента и, что еще важнее, через контекстное окно агента. Приложения MCP являются расширением этого подхода,
00:01:40которое позволяет нам фактически обойти агента. Вместо этого происходит следующее:
00:01:44пользователь запрашивает что-то у агента, агент использует инструмент, но вместо того, чтобы запрос инструмента возвращался
00:01:49к агенту, он отправляется пользователю. И отправляется в виде HTML, CSS, JavaScript — полноценного интерфейса.
00:01:55Он может быть абсолютно любым по вашему желанию. Идея заключается в том, чтобы получить способ,
00:02:01так сказать, внедрить интернет в вашего агента. Вы можете поставлять любой кастомный брендированный и полезный интерфейс. Вы можете
00:02:08доставить пользователю любой интерактивный опыт, какой он захочет. И тогда пользователь, как вы видите на
00:02:12диаграмме, теперь может взаимодействовать с приложением. Он может использовать инструменты. Он может отправлять
00:02:17информацию обратно в бэкенд, размещенный в этом приложении, и получить полноценный интерактивный опыт. Представьте себе
00:02:21бронирование столика в ресторане, изменение места в самолете или взаимодействие с расписанием.
00:02:28Для инженеров по ИИ теперь есть множество сценариев, где агент лишь помог все настроить,
00:02:33но взаимодействие происходит напрямую с человеком. И сейчас готовится к выходу расширение,
00:02:37которое появится в июльском релизе MCP, где агент также сможет взаимодействовать с приложением. И это
00:02:43откроет поистине интересные сценарии использования, о которых мы сегодня говорить не будем, но вы можете
00:02:47гипотетически сыграть в шахматы против агента в визуальном приложении, где вы делаете ход,
00:02:52а затем агент тоже взаимодействует с приложением. Думаю, это откроет совершенно новый
00:02:55мир возможностей. Теперь, некоторые из вас, возможно, знают фреймворк, автором которого я являюсь и который моя компания
00:03:03поддерживает — он называется FastMCP. FastMCP — один из самых популярных способов создания серверов MCP. Поэтому, когда в
00:03:09мире MCP появляются новые крутые вещи, я в первую очередь задаюсь вопросом: как я могу доставить это нашим пользователям?
00:03:16И одна из важнейших особенностей нашей пользовательской базы, которой я должен поделиться, заключается в том, что это
00:03:20в основном Python-инженеры. И это создает определенную проблему, когда мы хотим предоставлять
00:03:27фронтенд и пользовательские интерфейсы, потому как нам это вообще сделать? И это тот момент в докладе,
00:03:31когда я осознаю, что не помню точно, что на следующем слайде, так что давайте заглянем туда.
00:03:35Нет, вернемся назад. У нас есть задача: как заставить Python-инженеров создавать
00:03:42интерфейсы, соответствующие лучшим практикам, интерактивные, красивые, полезные, и при этом
00:03:50не пытаться заниматься глупостями вроде того, что уже кто-то пробовал — втиснуть
00:03:54весь фронтенд, всю экосистему, вообще всё в Python в виде какого-то странного, компромиссного,
00:04:00хаотичного Франкенштейна из системы. Я действительно долго ломал над этим голову. Мне нужно,
00:04:04мне действительно нужно, я чувствую обязанность найти способ это предоставить. Но я не могу, я не могу делать вид, будто
00:04:10мы собираемся запускать React на Python. Это не сработает. Поэтому мы крепко задумались: кто наши
00:04:15пользователи в экосистеме FastMCP? Кто эти Python-разработчики, которые обычно работают в крупных компаниях?
00:04:20Чем они занимаются и для чего им нужны эти интерфейсы? Зачем им нужны эти приложения MCP?
00:04:25Им вовсе не нужны потребительские кастомные интерфейсы с полным брендингом. Эти люди занимаются совсем не этим. В основном
00:04:34перед ними стоит задача обмениваться информацией внутри своей организации, а также собирать
00:04:38информацию по всей компании. И это изменило наше представление о том, что от них требуется
00:04:43в рамках фреймворка приложений MCP. Это ограничение оказалось очень полезным. По сути, мы предполагаем,
00:04:48что они будут делать такие вещи, как создание таблиц, сбор информации через формы
00:04:53и демонстрация графиков. И исходя из этого ограничения,
00:04:58мы можем представить программное обеспечение, которое мы выложили в открытый доступ несколько месяцев назад и которое оказалось на удивление
00:05:03популярным среди этой аудитории — оно называется Prefab. Это фреймворк для создания интерфейсов с ограниченной областью применения
00:05:11с целью поставки интерфейсов через агента для тех целей, о которых я упомянул минуту назад. Перед нами карточка приветствия
00:05:17«Hello World». Вы можете встретить её в любом фронтенд-фреймворке. Буквально в любом.
00:05:22Там есть что-то подобное на их сайте, вы вводите свое имя, и оно обновляется в реальном времени.
00:05:27Но, конечно, самое странное здесь то, что код, сгенерировавший это, целиком написан
00:05:31на Python. И я надеюсь, вы чувствуете то же самое, что и я, когда смотрю на это — очень странное
00:05:38сочетание чувств: «да, это круто» и «меня это жутко пугает». Чувство «да, это круто»
00:05:44возникает потому, что в этом коде, даже если вам не рассмотреть его вблизи, а я могу
00:05:48сделать его чуть крупнее, есть что-то, что кажется вполне логичным. Вы можете увидеть
00:05:52структуру интерфейса в коде, но в то же время в нем есть что-то чужеродное и слегка
00:05:58необычное. И когда вы испытываете это при взгляде на него, вы приходите к выводу, что
00:06:04создание фронтенда на Python начинает приносить удовольствие, если правильно ограничить
00:06:09задачу. Мы не пытаемся построить фронтенд с нуля. Мы пытаемся собрать фронтенд
00:06:15из множества первоклассных, хорошо спроектированных компонентов. Именно так мы сохраняем рамки
00:06:20и не забываем о пользователе. Пользователь здесь не пытается сделать что-то произвольное.
00:06:24Он пытается взять хорошо структурированный интерфейс и предоставить его тем, для кого он предназначен.
00:06:29Итак, небольшой экскурс по этому DSL. В основном мы используем менеджеры контекста. Для
00:06:34тех из вас, кто знаком с FastMCP, известно, что FastMCP можно свести к простому тезису:
00:06:39главная инновация FastMCP заключается в использовании декоратора Python для создания целого сервера MCP.
00:06:44Если применить тот же подход к Prefab, можно сказать: мы используем менеджер контекста для
00:06:48создания целого интерфейса. Вкладывая компоненты друг в друга как менеджеры контекста, как показано здесь, мы выстраиваем
00:06:55точную структуру пользовательского интерфейса. Читать это очень легко и естественно. Вы видите, как все
00:07:01структурировано. Каждый элемент интерфейса, каждый компонент, представляющий собой прекрасный компонент shad-sian
00:07:06при рендеринге, как вы можете видеть здесь, является классом, который вы создаете. Вы можете его параметризовать. Вы можете
00:07:11передавать ему такие вещи, как классы CSS, и настраивать его внешний вид. И последнее,
00:07:17на подробное изучение чего у нас сегодня не хватит времени — это реактивные переменные. Я покажу вам их
00:07:21демонстрацию через минуту. По сути, у нас есть полноценный способ создания клиентской интерактивности
00:07:26и привязки данных между компонентами, что позволяет создавать по-настоящему богатый опыт,
00:07:31опять же, без необходимости полностью погружаться в мир JavaScript и покидать экосистему, в которой моя аудитория,
00:07:36по крайней мере, чувствует себя крайне уверенно. И вот пайплайн, который по сути задействует Prefab.
00:07:42Мы используем Python DSL, о котором я только что рассказал. Мы используем его для построения декларативного
00:07:46представления интерфейса. Затем оно сериализуется в протокол JSON. И этот протокол JSON
00:07:53окончательно рендерится приложением React, которое хостится как реальное приложение MCP. Это открывает
00:07:59для нас множество возможностей, которые, опять же, я покажу вам через секунду. Но ключевой
00:08:02момент во всем этом — JSON посередине. Сам Python — это фактически случайность, которую я обнаружил
00:08:07позже, потому что это была странная особенность, которая мне потребовалась. Смысл был в том,
00:08:10«Можем ли мы создать сериализуемое представление интерфейса?» И это снова тот самый протокол JSON.
00:08:17И поскольку он сериализуем, я могу сгенерировать его с помощью агента. Я могу отправить его агенту. Я могу сгенерировать
00:08:22его как человек и попросить агента изменить его. Происходит множество классных вещей благодаря этому
00:08:26промежуточному представлению в JSON. И когда Python DSL просто вырос из этого и оказался очень
00:08:31красивым и простым в использовании, мне показалось, что мы что-то нашли. У нас есть документация. И чтобы
00:08:37подтвердить это, мы приняли еще одно ограничение. Я даже не знаю, что это. Это
00:08:42документация по компоненту таблицы данных в Prefab. Кажется, у нас поставляется 130 или 140 компонентов, которые
00:08:47можно объединять в произвольные формы. Документация Prefab на 100% отрисована на Prefab. Так что таблица данных,
00:08:55представленная здесь в базовом использовании, отображается в реальном времени с помощью Prefab. Код Python, вы видите, как он проскальзывает в
00:09:01нижней части экрана. Этот код на Python интерактивно рендерится движком для создания интерфейса.
00:09:05При желании вы можете взять любой пример из документации Prefab, перейти по ссылке, открыть его в
00:09:09песочнице и в реальном времени редактировать код на Python, и вы увидите, как обновляется интерфейс. И опять же,
00:09:15это супер странно. Если вы чувствуете себя немного неуверенно по этому поводу, это нормально. Все становится
00:09:20гораздо понятнее, если сузить проблему и вспомнить, что мы компонуем пользовательский интерфейс, а не
00:09:24создаем его с нуля. Поэтому я хочу вернуться к тому, с чего начал, а именно к MCP-серверам и, в частности,
00:09:29к MCP-приложениям. Вы можете использовать Prefab для любых задач, связанных с интерфейсами.
00:09:34Моя команда начала применять его для небольших интерактивных приложений с данными и ознакомительных инструментов. Они
00:09:39создавали с его помощью презентации. Мы поставляем темную тему, которая, честно говоря, выглядит примерно так же,
00:09:43как та, что я показываю вам прямо сейчас, для создания слайдов и презентаций. С его помощью можно сделать многое. Но причина,
00:09:48по которой мы его создали, тот сценарий использования, который он удовлетворяет — это MCP-серверы. Поэтому я хочу провести для вас
00:09:54краткий обзор трех способов его использования, трех все более сложных вариантов применения в вашем
00:09:58MCP-сервере. Первый — это создание интерактивного инструмента. Как я показывал вам в начале выступления,
00:10:04обычно инструмент MCP — это то, что вызывает ваш агент, агент получает результат, а у вас нет никакой
00:10:09возможности с ним взаимодействовать. Так каков же самый простой способ улучшить эту интерактивность?
00:10:14Я покажу вам здесь. Это быстрый инструмент MCP. Как видите, он украшен декоратором инструмента,
00:10:20и это просто функция Python, которая возвращает некоторую информацию. Учитывайте, что эта информация поступит к
00:10:24агенту, а не к пользователю. Если мы хотим превратить это в полностью интерактивный инструмент с Prefab,
00:10:30нам нужно внести одно изменение. Вместо того чтобы возвращать в конце словарь Python, который уйдет агенту,
00:10:36мы вернем компонент Prefab. В данном случае это таблица данных. Это то, на документацию
00:10:40которой я только что вам указал. И когда мы возвращаем этот компонент Prefab, Fast MCP автоматически
00:10:46обнаруживает это. Он автоматически догадается, что вы на самом деле хотите вернуть приложение MCP, и запустит
00:10:51весь механизм для получения HTML, JavaScript, CSS, отрисовщика — всего необходимого, чтобы ваш
00:10:55пользователь увидел таблицу данных. Вот как это выглядит на практике. Здесь используется клиент Goose,
00:11:00и он превосходен. Я попросил сервер, у которого была только что показанная функция: покажи мне каталог
00:11:06команды, и то, что появляется... было бы лучше в виде GIF, прошу прощения... то, что появляется — это полностью
00:11:10интерактивный компонент таблицы данных. Он поддерживает поиск, фильтрацию, сортировку, пагинацию
00:11:16и всё в таком духе. И всё, что для этого нужно — то, что я показывал минуту назад: просто вернуть класс таблицы данных,
00:11:21и обо всём остальном позаботятся за нас. Мы можем пойти дальше. Что если в дополнение к таблице данных
00:11:26мы захотим показать круговую диаграмму прямо рядом с таблицей данных, которая детализирует этот каталог команды?
00:11:30Как вы можете догадаться, код очень, очень, очень похож. Вместо одной лишь таблицы данных мы теперь
00:11:35импортируем сетку и круговую диаграмму, и если вы посмотрите вниз, то увидите, что мы объединяем и
00:11:40круговую диаграмму, и таблицу данных в единую сетку самым естественным образом с помощью менеджера контекста, и это
00:11:45результат. Теперь мы получаем круговую диаграмму рядом с нашей таблицей данных. Это следует принципу,
00:11:51которого мы стараемся придерживаться во многих наших программных продуктах в Prefect: одна строка кода, одно заметное изменение.
00:11:55Мы стараемся наращивать сложность постепенно, и это отвечает многим требованиям,
00:11:59которые, на мой взгляд, действительно важны для фреймворков и предметно-ориентированных языков. Очень быстро, поскольку у нас не будет времени вдаваться в подробности,
00:12:05это просто пример, который я собрал и записал — полностью клиентская интерактивность,
00:12:09где все эти элементы управления связаны, всё обновляется, текст обновляется, значения обновляются,
00:12:15и при этом не было написано ни строчки JavaScript. Это просто пара скомпонованных классов, у которых
00:12:19назначен один и тот же атрибут, поэтому все они работают вместе автоматически.
00:12:24О да, я ведь добавил краткий пример кода того, как это выглядит. У нас есть класс под названием Rx, который,
00:12:28как вы могли догадаться, расшифровывается как реактивный. Если вы используете эти реактивные переменные, вы можете просто ссылаться
00:12:33на них в любом месте вашего кода, форматировать их, использовать в качестве имени чего-либо, и это
00:12:38автоматически скомпилируется в корректную реализацию JavaScript. Вторая вещь, которую мы можем сделать —
00:12:43это приложение FastMCP. Если интерактивный инструмент — это разовое решение в стиле «вот пользовательский интерфейс,
00:12:49и вы можете взаимодействовать с ним на клиенте», то приложение FastMCP — это полноценное приложение с бэкендом, и в данном случае
00:12:54бэкендом будет служить MCP-сервер. У нас нет времени разбирать полноценный пример в рамках
00:12:59этой сессии, но вот как выглядит код, просто чтобы вы получили представление об эргономике.
00:13:03Мы напишем класс, который представляет собой наше приложение FastMCP, а затем декорируем по крайней мере
00:13:08две функции с помощью app.ui. Это точка входа, которая будет возвращать компоненты Prefab,
00:13:14составляющие базовый пользовательский интерфейс этого приложения, и затем как минимум одну — хотя, полагаю, это необязательно, то есть ноль или более
00:13:20методов app.tools, которые по сути являются методами бэкенда, на которые теперь можно ссылаться в интерфейсе.
00:13:27Таким образом, у вас может быть кнопка, которая берет введенные пользователем в форму данные и отправляет их в
00:13:31базу данных с помощью подобного декорированного инструмента. То, что мы используем и поставляем в качестве встроенного
00:13:38компонента в FastMCP — это компонент загрузки. Как вы понимаете, поскольку доступ к MCP-серверу имеет только агент,
00:13:46вы не можете просто так взять и загрузить файл на MCP-сервер. Ему приходится проходить через «мозг»
00:13:51агента, и в результате получается так, что многие создают инструмент загрузки на своем MCP-
00:13:56сервере, забывая, что агент действительно должен его вызвать, и в итоге вы занимаетесь самой дорогостоящей
00:14:00операцией копирования и вставки в мире. Вы даете агенту мегабайт текста, агент перепечатывает его символ
00:14:06за символом в MCP, и теперь, да, вы действительно его загрузили, но это крайне, крайне
00:14:12неэффективно. Так что это отличный вариант использования для MCP-приложения, когда вы просите агента открыть
00:14:18интерфейс приложения, перетаскиваете в него файл, и теперь файл минует агента и отправляется прямо на
00:14:23сервер. Мы сократили это до одной строки кода, добавив горсть других полезных инструментов, и
00:14:30это GIF? Это не GIF, а если и GIF, то он не отображается, но в вашем клиенте это выглядело бы так:
00:14:34в любом клиенте, поддерживающем MCP-приложения, если вы попросите агента «мне нужно кое-что загрузить», он сможет
00:14:38показать вам это, и вы сможете загрузить файл безопасно и, главное, дешево. О, у меня всё-таки есть GIF. Неважно.
00:14:45Хороший урок из этого выступления: знайте свои собственные слайды. Итак, здесь агент теперь взаимодействует с
00:14:50файлом, который я только что загрузил методом перетаскивания. Я сделаю эти слайды доступными позже, если
00:14:55вы захотите их посмотреть, ну или, конечно, это делается в одну строку. Вы сможете опробовать это на своих серверах сегодня во второй половине дня.
00:15:00Последнее, о чем я хочу рассказать и что отчасти обеспечивается этой архитектурой —
00:15:04это полностью генеративный пользовательский интерфейс. Мы просто пропустим это и позволим видео воспроизводиться, пока я говорю. Это очень
00:15:10простое демо, где я попросил Claude: «Привет, я выступаю с докладом на эту тему. Просто начни транслировать самый
00:15:15интересный интерфейс, который сможешь придумать». И он просто начал. Здесь мы предоставили инструмент,
00:15:21который принимает JSON, протокольную сериализацию пользовательского интерфейса, на которой основан Prefab. И теперь, по мере того как
00:15:29агент передает эту информацию по сети, мы в реальном времени отрисовываем всё, что получаем,
00:15:35исправляем этот JSON и выводим его. Это было действительно крутое и очень эффективное демо,
00:15:39и людям это нравится, потому что теперь вам даже не нужно проектировать интерфейс самостоятельно. Всё, что нужно сделать —
00:15:43это использовать уже готовый навык, поделиться им с агентом, чтобы он знал, как писать интерфейсы, и дело пойдет.
00:15:48Он может создать для вас всё, что вы захотите. В некоторых клиентах есть встроенные версии этой возможности. Если
00:15:52у них есть встроенная версия, вы вполне можете предпочесть её, ради бога. Но это может стать для вас способом создать
00:15:56собственный подход или ограниченный набор полезных для вас компонентов. Теперь о том, какая интересная
00:16:01вещь произошла, когда мы всё это запустили. Как я уже упоминал, изначально планировалось, что агент будет отправлять
00:16:07JSON по сети, и он будет отрисовываться в это полноценное приложение на React. В итоге мы обнаружили,
00:16:13что представление интерфейса на Python примерно на 70% компактнее, чем представление в формате JSON.
00:16:20Поэтому мы больше так не делаем. Когда я записывал это демо со стримингом JSON, теперь мы делаем так: мы фактически
00:16:26передаем по сети код на Python. Он выполняется в песочнице, на сервере преобразуется в JSON,
00:16:32а затем рендерится. Это дает колоссальную экономию токенов и выигрыш в задержке.
00:16:39Всё работает точно так же, как во время записи этого демо, но это одна из тех вещей,
00:16:43которые мы поняли на ходу. И поистине поразительно, насколько представление на Python компактнее и эргономичнее
00:16:49полноценного JSON. Итак, это Prefab. Если вы хотите с ним ознакомиться, если вам любопытно,
00:16:55если вы хотите увидеть самую странную штуку из всех, что я когда-либо создавал (вместе с другими людьми), вы можете найти
00:17:00документацию на prefab.prefect.io. Вы можете посмотреть полную библиотеку, которая находится на нашем GitHub здесь. И она
00:17:06уже полностью встроена в Fast MCP. Так что, если вы используете недавнюю версию Fast MCP, вы сможете
00:17:11установить это необязательное дополнение, импортировать компоненты, вернуть их и начать работу с этими MCP-приложениями.
00:17:17Спасибо всем, кто пришел.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기