Как создать и развернуть AI-агента: с нуля до продакшена
Yandex Cloud · 2025-11-24 · 1ч 57м · 3 504 просмотров · YouTube ↗
Топики: ai-loop-engineering
🎧 Аудио
📝 Summary
model=deepseek-v4-flash · prompt=summary-v7 · 23 756→2 505 tokens · 2026-07-20 12:13:38
🎯 Главная суть
AI-агент в Yandex Cloud AI Studio — это языковая модель (LLM), оркестрируемая через Responses API и способная вызывать внешние инструменты (через MCP) и поисковые индексы (File Search). Полный цикл от сборки агента до продакшена включает: настройку MCP-сервера с инструментами, создание векторного поиска по документам, обёртку агента в OpenAI Agents SDK, деплой в Serverless Containers и организацию взаимодействия либо через протокол A2A, либо через кастомный UI на базе ChatKit.
Основные компоненты агентской архитектуры
В основе любого агента — языковая модель (LLM), которая получает системную инструкцию, контекст диалога и может планировать решение задачи. Ключевые блоки: сама модель, инструкция (промпт), инструменты (MCP, File Search, Web Search), память (краткосрочная — контекст сессии), среда выполнения и обёртка-оркестратор. Инструменты должны быть явно описаны в инструкции, иначе модель не будет их вызывать — частая ошибка.
Платформа AI Studio
Платформа делится на три слоя. Model Gallery — проприетарные модели Яндекса (YaGPT, YandexART) и opensource (Qwen, GPT-OSS), доступные через Completion API (без оркестрации). Agent Atelier — набор для построения агентов: Responses API (текст+изображения), Realtime API (голос), VectorStore API, Workflows, MCP-Hub. UI/Console — Playground и веб-интерфейс для прототипирования.
MCP-Hub: подключение внешних инструментов
MCP-Hub позволяет либо подключить существующий MCP-сервер, либо создать свой с нуля. При создании можно использовать три типа инструментов: HTTP-запрос к любому API, облачную функцию или Workflows. Администратор может ограничить набор доступных тулов и настроить авторизацию. Есть готовые шаблоны для популярных сервисов (AmoCRM, CounterFocus) — достаточно принести API-ключ.
Responses API как оркестратор
Responses API — Stateful API: автоматически сохраняет историю диалога (через previous_response_id), передаёт контекст модели и вызывает инструменты. Модель сначала листит инструменты (через MCP), затем по описанию выбирает нужные. Responses API циклически вызывает инструменты, пока не получит текстовый ответ. Можно настроить подтверждение пользователя перед вызовом.
Фреймворки для мультиагентных сценариев
Для сложных архитектур с несколькими агентами удобны фреймворки: OpenAI Agents SDK (handoffs — передача управления), LangGraph (сложное состояние), CrewAI (ролевая оркестрация), LlamaIndex (RAG). Все они могут работать с Responses API благодаря совместимости с форматом OpenAI. В вебинаре использован Agents SDK для простоты.
A2A протокол (Agent-to-Agent)
Google-протокол A2A описывает взаимодействие между агентами: discovery (запрос агентской карточки по well-known адресу), отправка задач (методы send / send subscribe), обработка с промежуточными статусами (SSE), завершение. Агентская карточка содержит имя, описание, версию, форматы данных и capabilities (например, поддержка стриминга).
ChatKit: кастомный UI для агента
OpenAI ChatKit — opensource фреймворк для встраиваемого чата. Состоит из backend-сервера (Python) и frontend-компонентов (React/JavaScript). Backend реализует интерфейс ChatKitServer, хранит историю в базе (например, YDB через Document API). Frontend использует готовую панель ChatKitPanel, настраиваемую через тему, стартовые промпты, обработчики. Поддерживает backend-driven UI — сервер шлёт спецификацию интерфейса.
Практика: создание MCP-сервера для REST API
В консоли Yandex Cloud в разделе AI Studio создан приватный MCP-сервер с авторизацией через сервисный аккаунт. Для каждого инструмента (например, "добавить багаж") заполняется имя, инструкция для агента, метод HTTP, URL, авторизация. Параметры (например, ID профиля) описываются в JSON-схеме. Включено логирование для отладки. Важно: имя сервера — латиницей без подчёркиваний.
Практика: поисковый индекс по PDF-документу
Загружен PDF «Правила воздушных перевозок» (110 страниц) в гибридный индекс (текстовый+векторный). После индексации получен ID векторного хранилища, который используется в агенте. Описание индекса (для чего он) критично: модель полагается на него при решении, вызывать ли поиск.
Практика: код агента на Agents SDK
Агент реализован на Python с использованием openai-agents. В конструкторе передаётся MCP-сервер (через SSE), создаётся объект Agent с инструкцией, моделью (YaGPT 5.1 через Responses API) и инструментом FileSearchTool с ID вектора. Конфигурация запуска настраивает OpenAI-совместимый провайдер с API-ключом и базовым URL AI Studio. Метод invoke запускает Runner.run.
Практика: обёртка в A2A сервер
Использован A2A SDK: реализован интерфейс AgentExecutor с методом execute, который получает сообщение пользователя, запрашивает профиль клиента из REST API, объединяет с запросом, вызывает агента и возвращает результат в формате A2A. Карточка агента (AgentCard) содержит URL, версию, навыки. Запуск — через A2EStartApplication (обёртка над FastAPI).
Практика: деплой в Serverless Containers
Создан Docker-образ с кодом агента (размер ~113 МБ), загружен в Container Registry. Далее создан serverless-контейнер: переменные окружения (URL MCP, ID вектора, API-ключ из Lockbox Secret), публичный доступ, тайм-аут увеличен. Использован сервисный аккаунт с ролями: LanguageModelUser, AssistanceEditor, ContainerInvoker, MCP gateway invoker.
Тестирование через A2A Inspector
Инструмент A2A Inspector (из репозитория протокола) подключается к URL контейнера, получает карточку агента. Отправлены запросы: показать профиль клиента, отменить полет. Агент вернул ответ с вызовом MCP-инструмента — статус полёта изменился на "cancelled". Обновлённый профиль включён в сообщение.
ChatKit: backend и хранение истории
ChatKit-сервер также реализован на Agents SDK, но использует streame-метод run_streamed. Ключевое отличие — сохранение previous_response_id в метаданных треда. Для хранения тредов и сообщений реализован Store — in-memory или YDB через Document API. В коде агента история подгружается из Store, что обеспечивает память сессии.
ChatKit: frontend и Object Storage
React-приложение (TypeScript) собирается в статику (index.html + JS/CSS). Библиотека ChatKit React инициализируется с URL контейнера и доменным ключом от OpenAI (только для верификации CDN). Собранный сайт размещён в Object Storage с публичным доступом и настроенным веб-хостингом.
Демонстрация работы чата
В UI слева — чат-интерфейс, справа — панель профиля клиента (перелёты, бронирования). Проверена смена места (вызов MCP-инструмента) и поиск по документу (вопрос про прививку питомца — ответ из индекса, цитата). Благодаря краткосрочной памяти агент помнит предыдущие запросы (например, «что я просил в прошлый раз?» — ответ корректен).
Мониторинг и отладка
В контейнере доступны логи (вызовы REST API, Responses API, MCP gateway). На вкладке "Мониторинг" — графики запросов и времени ответа. В AI Studio во вкладке "Логи" MCP-сервера видны вызовы конкретных тулов и сессии. Также видна активность Responses API на вкладке "Мониторинг" AI Studio.
📜 Transcript
ru · 11 471 слов · 238 сегментов · clean
Показать текст транскрипта
Привет! Меня зовут Дима, я отвечаю за продуктовое развитие платформы AI Studio. И сегодня мы проведем вебинар вместе с Витей, руководителем направления Serverless. Всем привет! Да, и расскажем про разработку и деплой AI-агентов. Но прежде чем мы непосредственно перейдем к самому вебинару, давайте немного расскажу, напомню, где мы сейчас находимся в нашей серии обучений AI Studio Series. В четверг, 20 ноября, был первый вебинар в рамках этой серии. Провел его Дима Сошников и рассказывал про основные, про старт работы в AI-студию, как создавать базовых агентов. В основном это было no или low-code, как подключать MCP, как подключать файловый поиск и так далее. Сегодня мы немного углубимся и разобьем эту тему и поговорим про то, что происходит с агентами дальше. Ну вот хорошо, собрали мы их, например, в UI, можем к ним обратиться, как их задеплоить и как к ним можно обращаться из внешних систем в том числе. Особенно есть какие-то более сложные агенты, где есть не только обращение к одному инструменту. Завтра Саша расскажет про инструмент Workflows более подробно. Дима немного начинал про него говорить, но завтра полностью весь вебинар будет посвящен ему. И Саша расскажет, как можно собрать цепочки для обработки документов с помощью OCR, VLM и других интеграций. И заключительный вебинар этой серии проведет Настя. Она будет рассказывать про голосового агента, про RealTime API. его особенности, как с ним можно работать. Поэтому приглашаем на вебинары завтра и послезавтра. После каждого из вебинаров мы в Telegram-канале и тоже на слайде будем показывать, предлагаем поучаствовать в активностях, например, прислать свой Telegram-бот, который вы собираете на базе Responses или RealTime API, или, например, сегодня тоже мы поделимся ссылкой на форму, которую попросим заполнить. Самых активных участников, которые помогают другим участникам комьюнити, заполняют информацию, мы пригласим на очное мероприятие 1 декабря. Про него мы расскажем чуть подробнее в Telegram-канале. О чем же будет наш сегодняшний вебинар? Как я уже сказал, мы начали с того, что в четверг поговорили о том, какие есть возможности для разработки агентов. Сегодня мы немного повторим эту информацию, напомним, как работать с файловым поиском, с MCP, но фокус будет не на этом, а фокус будет на деплой такого агента. Мы посмотрим, как можно обернуть существующие и доступные в платформе API в SDK и как их можно задеплойить. Далее в конце мы попробуем обратиться к созданным агентам через протокол A2A или через отдельный UI. Таким образом, фокус сегодняшнего вебинара будет именно на Напомню, что самый базовый минимальный агент, которого мы собрали 20-го числа, это был агент, у которого есть в основе языковая модель. У этой языковой модели есть какой-то системный промпт, инструкция, как ей нужно себя вести, как нужно обращаться, например, к внешним инструментам. У нее есть контекст беседы, который Responsys API помнит автоматически. И дальше, соответственно, человек отправляет запрос. С учетом контекста, с учетом инструкции такой агент отвечает на эти вопросы, либо выполняет какие-то действия. В AI Studio таких агентов можно создавать разными способами. Для базовых сценариев, прототипов, для несложных агентов есть веб-интерфейс, который вы видели. Но важно сказать, что он... Ну, скорее, на текущий момент именно для прототипирования. Если вы хотите использовать максимальную гибкость и собирать более сложные агентские архитектуры, подходы, то есть API и есть SDK, которые с этими API могут взаимодействовать. Про это мы как раз будем говорить сегодня подробнее. Если вы вдруг не посмотрели первый вебинар, то вы можете перейти на него по QR-коду и ознакомиться с ним подробнее. Кроме того, здесь еще тоже скажу, что кроме вебинара Дима записал отдельно полноценный практический воркшоп, как можно с помощью Responses API собирать мультиагенные системы. Там он, например, рассматривает такой механизм, как хенд-оффы в OpenAI и Agents SDK, то есть как можно сделать так, чтобы один агент вызывал другого агента. Если вам эта тема интересна, можете перейти по ссылке, и там вы увидите информацию о... вебинаре и отдельном воркшопе. Кроме этого, мы подготовили для вас набор небольших роликов, серия у нас называется «How to», где мы делаем такой общий обзор основных компонентов, которые есть в платформе в UI и в API. Поэтому, если кто-то хочет освежить информацию или подробнее погрузиться, можете перейти по другому QR-коду. Давайте перейдем непосредственно уже к самому контенту вебинара. Начнем мы с того, что какая вообще, когда мы говорим про агентов, да, какие основные блоки есть в такой агентской архитектуре. Мы видели чуть ранее такой самый базовый агентский блок, то есть это LLM и инструменты. Здесь давайте его попробуем немного расширить. То есть, конечно, в основе у нас так или иначе есть языковая модель. Она понимает задачу, может спланировать решение и сделать обращение к различным инструментам, чтобы выполнить, решить эту задачу. Дальше сама задача прописывается в инструкции. Здесь, наверное, важный нюанс. Я видел в сообществе было очень много вопросов, что вроде выбрали модель, подключили инструменты, например, файловые поиски, дальше не происходит вызова. Это может быть связано с тем, что либо сама модель, которую вы выбрали, не очень хорошо умеет вызывать инструменты, либо вы в инструкции недостаточно полно указали, что этот вызов необходимо сделать. То есть модели чаще всего нужно прямо в инструкции отдельно прописать, что вот, например, тебе доступен инструмент поиска по файлам, называется он так-то. и сделай его обращение. То есть всегда обращайся к нему или обращайся, когда спрашивают какую-то конкретную тематику и так далее. Это обязательно должно быть прописано в инструкции. Это сильно повышает вероятность того, что модель сделает вызов. Далее мы поговорим про обертку над моделью. То есть сама модель, если брать ее как набор весов, она не умеет автоматически вызывать инструменты. Модель. по сути, может сказать, что нужно вызвать такой-то инструмент с такими-то параметрами. И дальше как раз уже логика вызова этого инструмента, обработки его результатов и вот этого цикла, она как раз реализована в API, про которую мы сегодня будем говорить в Responses API. Далее это память. Память обычно разделяют на краткосрочную и долгосрочную. Долгосрочная память это прям отдельное большое направление, сегодня мы на нем не будем останавливаться, но немного проговорим про краткосрочную память, то есть условно память сессии или контекст диалога. Ну и окей, мы собрали все эти основные компоненты, а дальше как можно их интегрировать в какие-то свои системы, как их можно использовать извне. Здесь есть одно направление, это сейчас условно такой... популярный, ну или становящийся популярным протокол A2A, который предложил Google, про него мы поговорим подробнее дальше, или, например, задеплоить как там через REST-интерфейс и дать возможность обращаться к нему из внешних UI, тоже сегодня об этом расскажем подробнее. Вот, и да, про среду выполнения у нас будет большой отдельный блок. Таким образом, языковая модель, инструкция. Мы это сегодня соберем на базе Responses API. Дальше мы подключим инструмент MCP и поиска по файлам. У нас будет память сессионная, и мы поговорим про среду выполнения. Все это мы будем собирать на базе двух больших компонентов. Первый компонент это AI-студия. И чуть-чуть напомню, базово какие блоки вообще, какие... компоненты есть в платформе AI Studio. Условно ее можно разделить на три направления. Первое, базовое, то, без чего не могут существовать агенты, это сам парк различных AI-моделей, то, что обозначено на слайде как Model Gallery. Здесь доступны как проприетарные модели Яндекса, такие как, например, Яндекс.GPT, Яндекс.Арт и другие, так и опенсорсные модели GPT-OSS, QAN, и другие. Взаимодействие с этим слоем проходит, как правило, через completion с API, API совместима с OpenAI. Его основная идея — отправить запрос в модель, получить ответ. Автоматически вызывать инструменты или хранить контекст переписки он не умеет. Дополнительно вы можете сделать до обучения легковесных моделек типа Яндекс.GPT Lite или использовать эти модели в пакетном режиме. Второй слой, на котором будет сегодняшний фокус, это так называемое Agent Atelier. Это набор готовых блоков, инструментов, которые вы можете использовать для построения агентских архитектур. Это компонент для построения поисковых сценариев, то есть инструмент поиска по документам File Search и инструмент поиска в интернете Web Search. Кроме этого, это возможность подключать любые MCP-сервера или создавать свои через MCP-хаб. Это возможность выстраивать цепочки вызовов, например, моделей и делать интеграцию с другими инструментами через workflows. И это отдельный блок, который предоставляет компоненты для голосовых сценариев. Это, например, возможность создавать голосовых агентов, дообучать и кастомизировать свой собственный голос и использовать модели speech-to-text и text-to-speech. Основные API на этом уровне это Responses API для текста, Realtime API для голоса и VectorStore API для работы с векторной базой. Ну и конечный слой это UI и консоль, это Playground, это UI для построения агентов, о нем уже говорили подробнее на предыдущем вебинаре. Давайте чуть подробнее остановимся на агентском ателье. Какие здесь есть два направления API? Первый API это Responses API. В чем его ключевая идея? По сути, он поддерживает текст и изображение, то есть на вход вы можете передавать как текстовые промпты, так и изображение. Единственный нюанс это изображение должно быть в формате B64 и сама языковая модель которая используется в Responses API, должна уметь работать с изображениями. Из моделей, которые представлены в базовом инстансе, то есть те, которые тарифицируются по токенам в iStudio, такой моделью сейчас является гема. То есть если вы подключаете гема к Responses API, вы можете передавать их на вход и текст, и изображение. Responses API на самом деле формат, совместимый с API OpenAI, то есть OpenAI не так давно представили Формат Responses API и Responses API доступный в iStudio, он полностью совместим, а это значит, что вы можете его использовать из open-source SDK, из low-code инструментов популярных и так далее. Голосовые агенты, у них есть ряд нюансов, то есть по сути есть ряд очень схожих концепций, то есть в основе языковая модель, которая может вызывать инструменты те же самые, которые вы создаете через... через файловый поиск, через веб-поиск, через mcp, но с голосом есть ряд нюансов, такие как, например, возможность реагировать на перебивание, очень жесткие требования по скорости ответа, обработка различных ивентов. В общем, это отдельное, под голосовой сценарий нужен отдельный API специфический, о котором мы подробнее будем говорить на последней сессии. Пару слов о том. Сегодня мы в примере будем использовать MCP и что он из себя представляет. По сути в AI-студию есть отдельный компонент, который позволяет работать с MCP, называется он MCP-HUB. Он позволяет либо подключать внешние MCP-сервера, то есть, например, у вас уже есть существующий MCP-сервер, или вы идете на какую-то хостинговую платформу, где есть MCP-сервера, он уже развернут, у вас есть адрес, токен, вы можете просто в UI указать, в AI-студию указать его адрес, токен, и он начнет работать. Либо вы можете создать полностью свой MCP-сервер с нуля. Если вы это делаете, то при добавлении в MCP-сервер инструментов у вас есть три типа инструментов. Первый это, по сути, любое API к существующим системам. То есть, если у вас, не знаю, есть своя какая-то специфическая CRM или есть, не знаю, SAP, какие-то системы, которые предоставляют API, вы можете этот API трансформировать в формат MCP, заполнив набор полей в UI для каждого API, и, соответственно, это будет автоматически преобразовываться и таким образом подключаться к агентам. Второй инструмент это клауд-функции. То есть если вы в облаке создаете функцию, облачную функцию, вы можете ее подключить также в качестве инструмента к MCP и по сути можете реализовать любую логику внутри этой клауд-функции. И третье это Workflows, то есть если у вас есть какой-то поток на базе Workflows, вы его также можете подключить в качестве инструмента. Таким образом, у вас появляется единая точка входа для разработчиков-агентов, где у вас доступен список доступных, подключенных существующих MCP-серверов, и вы можете подключать его к агентам. За счет ролевой модели можно разграничить, например, несколько ролей, то есть может быть роль администратора, который делает настройку подключения, и, например, выбор тулов в MCP-сервере, то есть когда вы подключаете внешний MCP-сервер, вы можете ограничить его только теми тулами, которые должны быть доступны для ваших корпоративных задач, или как-то проверены, безопасны и так далее. А дальше уже разработчики могут просто иметь доступ к подключенным MCP-серверам и строить поверх них агентов. Таким образом, MCP можно сравнить, Такое часто расхожее сравнение с неким USB стандартом для агентов, когда мы к языковой модели хотим подключить внешние инструменты. Да, важный нюанс, который я не сказал про MCP-хаб, это набор готовых шаблонов. То есть вы можете подключить внешний, создать с нуля свой MCP-сервер, трансформировав любой API, либо можете использовать уже готовый MCP-сервер из шаблона. У нас здесь приведен не весь список, то есть это шаблоны как для индексовых сервисов, так и внешних провайдеров типа AMA-CRM, CounterFocus и других. То есть когда вы выбираете, например, AMA-CRM, вам достаточно принести свой ключ. добавить дополнительные параметры, типа проектов, и вы можете этот AmoCRM сервер использовать в своих агентах. Пару слов подробнее про Responses API, потому что он нам важен сегодня для сценария. Во-первых, в отличие от Comprehens API, Responses API это Stateful API. Что это значит? Это значит, что у него есть состояние, И он может, во-первых, сохранять весь контекст переписки и делать это автоматически, и автоматически передавать этот контекст при обращении к языковой модели. То есть, видел в чате были вопросы, например, как реализовать тред или как реализовать память. Это уже реализуется автоматически с помощью Responses API. То есть, когда вы делаете обращение, вы можете передать ID предыдущего обращения. Это делается через previous response ID. И таким образом автоматически подтягивается вся история, которая была привязана к этому ID. В ближайшее время мы добавим новый API, который позволит с этой историей работать. То есть вы ее сможете прям отдельно выгружать, изменять и обращаться к response API с измененной историей. Таким образом... Респонсис API можно сравнить с условно оркестратором. Он оркестрирует вызовы к различным инструментам. То есть мы модели даем инструкцию, мы подключаем инструменты и говорим. Модель дальше сама начинает решать, какие инструменты ей нужно вызвать, чтобы решить задачу. Респонсис API делает автоматически этот вызов, получает результат, смотрит, передает его снова в модель. Если модель решает, что все, как бы можно сгенерировать финальный ответ, он возвращается. Если же этого ответа недостаточно, модель считает, что нужно сделать еще один вызов, то этот цикл может идти вот так вот долго, то есть модель может, даже не модель, а response API может делать эти вызовы до тех пор, пока мы не придем к текстовому ответу, текстовому результату, который вернется. Если изобразить это на диаграмме, давайте посмотрим, например, с MCP. То есть, что будет происходить в Responses API? Пользователь делает запрос к Responses. Дальше происходит листинг инструментов. То есть, мы обращаемся к MCP-серверу, получаем список инструментов. Только те инструменты, которые были доступны через MCP-хаб, которые мы прокликали. Дальше модель, соответственно, смотрит на инструкцию, на промпт. на список инструментов, на описание инструментов в MCPC-овере и делает выбор тех инструментов, которые нужно вызвать. Происходит вызов и дальше, в зависимости от того, как вы настроили, это может быть либо автоматический вызов, либо вызов с подтверждением. То есть, если это вызов с подтверждением, пользователю прямо необходимо кликнуть «Да, я подтверждаю», и дальше сделать следующее, то есть разработчик дальше делает следующее обращение к респонсу с информацией о том, что вызов… текущего инструмента подтвержден, и дальше уже происходит непосредственно сам вызов инструмента, обработка результатов, и дальше после вызова это может быть еще один вызов, либо уже возвращение конечного результата. Да, окей, первый слой, как бы понятно, да, взяли респондов как оркестратор, подключили к нему инструменты, но может быть, конечно, часто в разных сценариях более сложная логика. Например, мы хотим, чтобы у нас был не условно один агент, у которого есть 100 инструментов, а 5 агентов, и каждый из агентов специализируется на какой-то своей тематике. Тоже один из вопросов, который часто поднимается. Ну вот я взял Responses API, выбрал модель QWEN, подключил к нему 20 инструментов, качество очень плохое. Он циклится, плохо вызывает и так далее. Гарантировать, что точно произойдет вызов инструментов в языковых моделях нельзя. Он может очень сильно зависеть от задачи, от самой языковой модели, от того, как сформирована инструкция, как описаны сами инструменты. То есть это на самом деле место, где нужно проводить много различных экспериментов и подбирать хорошо проб. И один из подходов, который позволяет снизить сложность на одну конкретную модель, это разбить, агента на несколько подагентов. То есть, условно, у нас есть один общий агент, он может делать вызовы других подагентов, и затем эти подагенты уже с меньшим количеством тулов будут обрабатывать информацию, решать задачи. Такой паттерн очень хорошо и удобно реализовывать, например, через OpenAI Agents SDK. Он опенсорсный, бесплатный, и у него есть механизм, который называется handoffs, который как раз позволяет передавать управление от одного агента к другому через Function Calling. Но и мы будем как раз использовать сегодня этот SDK и поговорим о нем подробнее дальше, но на самом деле он далеко не единственный для решения задач вокруг агентов. То есть есть, например, близкий к нему аналог от Google, Google Agents Development Kit. Очень часто для агентских сценариев, я бы сказал, такой самый популярный вообще фреймворк – это лангчейн и ланграф. Особенно ланграф, когда нужна очень сложная агентская логика с обменом состояниями и так далее. Популярный фреймворк это CruAI, он хорошо подходит для задач, где нужна мультиагенная оркестрация, то есть когда есть агенты с ролями, у них есть свои задачи, им нужно кооперировать, часто используют CruAI. Есть фреймворк LamaIndex, у которого недавно появилось новое направление LamaAgents, но он изначально сфокусирован на RAC сценариях и работе с документами и с данными. На самом деле, за счет того, что Responses API совместим с форматом OpenAI, ну вот все фреймворки, представленные, наверное, за исключением гугловского ADK, они могут работать с Responses. Ну, для простоты мы сегодня взяли Agents SDK просто потому, что у него хорошие, понятные базовые концепции, он не очень сложный, и он хорош для демонстрационного примера. Вот, дальше построили агента, нам надо его задеплоить. И уже продеплоим это дальнейшие шаги. Спасибо, Дима. Давайте разбираться дальше. Какие у нас есть опции и какие есть сервисы для того, чтобы запустить агента в AI-студии и в Яндекс.Клауд? Самое простое — это наш новый инструмент, который мы недавно запустили. Он называется Serverless Workflows. Он позволяет в режиме drag-and-drop без написания кода, то есть это ноу-код инструмент, собирать агентский процесс, и это занимает у вас небольшое количество времени. Вы это можете делать и за минуты, и за часы. Да, вы в этом смысле ограничены только теми кубиками и нодами, которые предоставляет сам инструмент, но зато вы получаете полностью управляемую среду, вам не нужно думать ни о какой эксплуатации, ни о масштабировании, ни о отказоустойчивости. Дальше, сверху вниз, у нас идет традиционный serverless environment, это и клауд-функции, и бессерверные контейнеры. Вы получаете чуть большую гибкость, вы можете выбирать любой из фреймворков и язык разработки, и любой из фреймворков, про которые упоминал Дима. Соответственно, писать код и разворачивать его в облаке занимает это чуть большее время, но все же еще не недели и месяцы, а дни и часы. Не нужно думать о эксплуатации, ну, в меньшей степени нужно думать о эксплуатации. У вас высокий уровень изоляции, отказоустойчивости и масштабирования. И, соответственно, сегодня мы как раз на примере сервера с контейнерс. Посмотрим, собственно, как можно агента задеплоить в облако. На мой взгляд, это такой оптимальный вариант, когда вы, сохраняя определенную гибкость, при этом Снимайте с себя очень многие задачи при построении Production Ready решений и быстром запуске какого-то нового эксперимента продуктового. Есть, безусловно, и совсем классические облачные среды, такие как Compute и Managed Kubernetes, но на них мы не будем подробно останавливаться. Я думаю, что вы о них все и так знаете. Как я уже сказал, будем сегодня использовать серверс-контейнерс. Давайте теперь поговорим о том, как вызывать агента и вообще как он должен смотреть в мир. Это когда агенты могут вызывать других агентов. В арсенале есть запущенный и открытый в свободный доступ Google протокол Agent2A. Он описывает процесс взаимодействия между агентами, позволяет обмениваться данными и задачами в стандартном формате. Важный функционал, как обнаружение агентов и их возможностей, это агентские карточки. Про них мы с вами еще потом в практическом примере подробно посмотрим, из чего состоит агентская карточка, как ее можно описать. Потом агенты могут выполнять как краткосрочные задачи, так и долгие задачи. Соответственно, несколько агентов могут работать над одной задачей, им нужно делить между собой контекст, передавать. информацию про эту задачу. Это тоже затрагивает протокол и учитывает. Как я уже сказал, все форматы используемых в протоколе — это форматы сообщений, форматы данных, они описаны, стандартизированы. Более того, разработчики протокола предоставили еще и под разные языки SDK для того, чтобы быстро оборачивать агентов в этот протокол. Давайте немного подробнее рассмотрим процесс работы протокола. Он состоит из нескольких фаз. Первая фаза — это фаза discovery, когда агент-клиент запрашивает у агента сервера по well-known адресу карточку агентскую, которая содержит основную информацию про агента. Понятно, как с агентом взаимодействовать. Идет вызов основных методов. Их существует два. Это метод send и метод send subscribe. В этом методе передается сообщение агенту, что нужно сделать. Возможно, передается еще task id. Это если уже какая-то задача запущена, и это уже не первый вызов. Дальше идет фаза обработки, и в этой фазе агент выполняет свою работу. Он может по ССЕ-технологии отправлять на клиентскую сторону какой-то статус и промежуточные данные. Вся необходимая информация о выполненной агентом работе и его сообщении. Эта фаза может повторяться. В конце, в комплишн-фазе, агент сервера возвращает терминальное состояние задачи и какие-то конечные данные. через какой-то UI-интерфейс общаться с ними, как мы, в общем-то, все привыкли уже. Вот здесь мы этот вариант реализуем на примере open-source-фреймворка, выпущенного OpenAI, он называется OpenAI Chat Kit. Собственно, это встраиваемый и гибко кастомизируемый интерфейс для создания чат-интерфейсов в веб-приложениях. Он поддерживает современные технологии, это и JavaScript, и React framework. У него есть готовая библиотека UI-компонентов, которая позволяет создавать ваши собственные виджеты, настраивать гибко темы, look and fill, собственно, определять разные формочки в тех случаях, когда пользователю нужно дополнительную информацию вводить и даже делать обработчики соответствующие действия. У него есть у этого фреймворка две части. Есть backend-часть, где на Python необходимо реализовать так называемый chatkit-сервер. Мы на это сегодня подробно посмотрим на практике. И есть клиентская frontend-часть, где на JavaScript вы берете готовые компоненты и встраиваете ваше React-приложение. Еще хочется отметить, что этот фреймворк построен на таком современном подходе backend-driven UI, когда вы прямо с сервера шлете спецификацию вашего UI для того, чтобы клиент просто ее отрисовал. Теперь давайте буквально быстро пробежимся про то, как реализовать это. Мы на практике еще все это посмотрим. Как я уже сказал, бэкэнд часть реализовать нужно интерфейс chatKit-server. Также мы с вами реализуем хранилище для хранения истории сообщений, в случае, если вам нужно в самом интерфейсе показывать разные триды, разные чаты общения с клиентами. Также, если вы хотите использовать вложения, чтобы клиент передавал вложения, нужно реализовать будет интерфейс Attachment Store. Мы в главную страницу HTML-страницу подключим скрипт chatkit.js и в самом React-приложении добавим компонент chatkit-панель, который и отобразит сам чат-интерфейс. Вот такая диаграмма показывает основную архитектуру этой технологии. Она совершенно свободно распространяется. Если вы в целом работаете с OpenAI, вы можете ею пользоваться даже в ваших продакшен решениях. Итак, переступим к практике. На слайде вы видите QR-код. Это QR-код GitHub репозитория, в котором выложен пример, который мы будем с вами сегодня разбирать. Заходите туда, не стесняйтесь, скачивайте код, читайте, разбирайтесь, пробуйте это запускать и даже менять. Пример будет из области службы поддержки клиентов авиакомпаний. Мы с вами построим простенький чат-бот. Что он будет делать? Обычно что делают такие чат-боты? Они консультируют пользователей клиентов про какую-то информацию по тарифам, по правилам перелета, по различным документам воздушных перевозок и правилам перевозок. Также помогают с бронированием билетов, помогают с уже запланированными рейсами. Ну и различные решают в целом экстренные вопросы или обращения с жалобами. Но мы в основном сосредоточимся, наш пример будет, конечно, упрощенный, мы сосредоточимся только на консультации и на работе с уже забронированными билетами. Для того, чтобы реализовать такого агента, нам необходимы будут источники данных. Они могут быть совершенно разные, но мы будем пользоваться правилами воздушных перевозок пассажиров и багажа. В качестве инструментов наш агент будет использовать пять очень простых инструментов. Я для этого написал простенький REST API, который реализует сервис авиакомпании, сервис управления профилями клиентов, развернув в облаке. Но в нашем гид хаб-репозитории вы его найдете и сможете также у себя развернуть. Соответственно, из инструментов это будет возможность отменить поездку, поменять место, добавить багаж, записать какие-то предпочтения по еде и обратиться к живому консультанту. На чем будет построен наш пример? В качестве базового языка мы возьмем Python, это для backend-части, для frontend, понятно, у нас будет использоваться JavaScript и React framework. В качестве соответственно агентского фреймворка мы возьмем, как уже Дима сказал, OpenAI-Agents SDK. В качестве модельки мы будем использовать Яндекс.GPT, который будет у нас обернут. вызываться через Responsys API. Для источников, для обращения к данным мы будем пользоваться реализацией Яндекс.AI-студия VectorStore API, совместимого с OpenAI, и будем пользоваться уже готовым тулом, он называется FileSearchTool, который предоставляется агентским фреймворком. Инструменты мы будем вызывать по протоколу MCP и для этого будем создавать сервер в нашем сервисе MCPHub, который доступен в составе iStudio. Агент будет выполняться, мы его задеплоим в виде бессерверного контейнера в Яндекс.Клауд и взаимодействовать мы с ним будем, как я уже сказал, Будет два примера, один построенный на Agent2Agent протоколе, один на ChatKT. Итак, начнем с первого примера. Это агент с поддержкой Agent2Agent протокола. На слайде показана архитектура такого агента. Какие-то сложные детали я опустил, чтобы не переусложнять схему. Итак, сам агент, соответственно, будет обернут. Написано на фреймворке. Agents SDK будет обернут в A2A сервер на Python языке, соответственно, с использованием SDK, который нам предоставляют сами разработчики A2A, и собран в Docker контейнер и развернут в сервисе Serverless Containers. через него общаться и с моделью, и вызывать МСП-инструменты, и получать дополнительную информацию из источников через вектор Store API. Практическую часть. Сначала посмотрим, как создать MCP-сервер для уже существующего у нас, как я уже сказал, есть простой REST API, который реализует те самые пять инструментов. Мы с вами находимся в консоли Яндекс.Клауд. Я создал предварительно пустой каталог. Он называется AI-agent-webinar. Давайте отсюда... Провалимся в AI-студию. Перешли в AI-студию. Теперь мы можем здесь сразу на главной странице нажать кнопку «Подключить MCP-серверы», либо перейти на вкладку «МСП-серверы» и, соответственно, отсюда приступить к созданию самого MCP. Здесь у нас есть несколько опций, как уже Дима рассказывал подробно. Можно с нуля создать MCP сервер, буквально накликать его из существующих. Можно подключить внешний MCP, можно использовать какой-нибудь из преподготовленных наших шаблонов. Давайте оставим создание нового. И сейчас мы с вами попробуем создать хотя бы один инструмент. Я вам покажу, как это сделать. Здесь у нас есть несколько типов инструментов. Это http-запрос, это вызов функции, вызов workflow процесса. Мы с вами будем делать http-запрос в наш REST API. Это RLine API, я его так назвал. Инструмент добавления багажа. Сейчас мы заполним эту формочку. Здесь вводится имя инструмента. Мы введем имя Back. Также нам понадобится ввести инструкции для агента, которые потом попадут в контекст. У меня есть преподготовленная инструкция. по которому этот инструмент доступен. Мы его тоже сюда сразу скопируем. Я развернул в бессервенном контейнере опишку. Метод будет «Post». В качестве дополнительных параметров можно указать тип авторизации. Мы будем авторизовываться от имени сервисного аккаунта. В случае, если мы вызываем функции, workflow, все, что развернуто в облаке, Там обычно такой тип авторизации используется. У нас будет всего один параметр инструмента — это идентификатор профиля или идентификатор клиента. Также нам тоже понадобится его описание для того, чтобы модель понимала и смогла его автоматически заполнить, генерировать его значение. Что еще мы можем задать? Мы можем дополнительно задать заколовки запроса, но в нашем случае их не будет, поэтому мы просто удалим. И query-параметры тоже в нашем случае не будем. Поле тела запроса оставляем пустым, оно будет передаваться as is. Мы заполнили необходимые параметры. Теперь давайте общие параметры сервера заполним, соответственно название сервера. Он может быть у нас приватный, публичный, публичный, доступный, без авторизации, приватный. с авторизацией. В production решение нужно настраивать авторизацию. Для этого нам нужно создать сервисный аккаунт. Мы его сейчас создадим прямо здесь и выдадим необходимые роли для него, чтобы он мог ходить в тот самый REST API. В нашем случае, так как REST API развернут в виде бессервного контейнера, то нужна будет роль, которая называется «контейнер инвокер». Это удобно, что мы можем здесь же сразу и создать сервисный аккаунт, и назначить ему роли. Итак, отлично, сервисный аккаунт у нас успешно создан и уже подставился сюда. Теперь нам осталось нажать кнопку «Сохранить», и наш MCP-сервер создается. Теперь мы видим карточку собственного MCP-сервера. Мы видим наш инструмент, который мы только что настроили, добавили к нему. Здесь есть вся информация, которую мы заполнили. Также по МСП серверу мы видим сервисный аккаунт, который мы указали, тип доступа приватный, что мы и хотели. И остальная разная информация. Базовый URL, по которому, кстати, доступен, который нам потом понадобится. Теперь смотрите, я сразу перескочил, и вы видите сразу уже все пять инструментов заполненных. Вот они. Я их для того, чтобы сократить время, сам все завел. Кстати, можно посмотреть JSON-схему параметров в формате, специфицированном протоколом MCP. Я забыл еще настроить логирование. Мы сейчас с вами поредактируем MCP-сервер и настроим запись логов, для того чтобы потом, когда мы будем вызывать агента, мы смогли посмотреть. Как он вызвал наши инструменты? Включаем запись логов и просто сохраняем. И видим, что у нас блок с параметрами логирования заполнился и отображается. На этом создание МСП сервера закончено. Дима, давай посмотрим, может быть есть какие-то вопросы по этой части? Вижу, что уже ряд вопросов появился, на них мы обязательно ответим в конце вебинара. Здесь, наверное, два общих комментария, которые бы хотелось добавить. По тем вопросам, что были в сообществе последние дни, две важных вещи. Во-первых, частая ошибка — это название MCP-сервера. Оно должно быть на английском языке, без нижних подчеркиваний. Это важный нюанс. Если вы будете писать его неправильно, у вас будет всплывать ошибка. Обращайте на это внимание. Это первое. И второй, наверное, такой самый расхожий вопрос. Я создал агента, подключил таким образом MCP-сервер, а он не вызывается, уходит в цикл, долго отвечает. Это очень сильно зависит от того, какую вы модель выбираете и как вы формируете промпт. Как показал Витя, у каждого инструмента есть описание, название, на которое ориентируется модель. Но опять же, нет гарантии, что конкретная модель будет хорошо делать вызов конкретных функций. Для сегодняшнего примера мы используем Яндекс.Дпт Pro версии 5.1. Она достаточно неплохо справляется с вызовом небольшого количества инструментов. То есть сегодня мы используем 4.5, плюс поиск по файлам. Она справится хорошо. Если мы говорим про какие-то большие наборы инструментов, то опять же их лучше либо разбивать на несколько подагентов, либо пробовать. моделей побольше типа QIN большого или GPT-USS с 127-миллиардными параметрах. Информацию о том, произошел вызов или нет, вы можете, например, посмотреть в UI. Там есть отдельная иконка, которая показывает факт вызова в MCP-сервер и результаты на его основе. Пока все. Спасибо, Дима. Поехали дальше. Теперь нам нужно... Подключить к нашему агенту, соответственно, понадобится подключить к нему поисковый индекс. Мы его сейчас с вами создадим. Для того, чтобы это сделать, я нашел публично доступный в интернете документ с правилами воздушных перевозок пассажиров и багажа. Я его скачал, и сейчас мы с вами его как раз загрузим. На основе него создадим поисковый индекс. Сейчас я кратко вам покажу этот документ, покажу, что он в нем находится. Собственно, он состоит из 110 страниц, достаточно внушительный документ. В нем есть, соответственно, как я уже сказал, правила перевоза пассажиров, правила перевоза багажа. Вот даже можно увидеть, что правила перевоза животных. Сегодня мы как раз на этом примере посмотрим. про животных, как будет использоваться наш поисковый индекс. Теперь давайте его создадим. Также с главного дашборда iStudy мы нажимаем «Создать поисковый индекс». Давайте перейдем к полной форме, заполним необходимые поля. Во-первых, это имя индекса, так и назовем его «Earline Rules». Можно заполнить описание и добавить метки. Есть разные типы индексов. Есть текстовый для полнотекстового поиска, есть векторный, который используется, строит эмбеддинги. Есть гибридный, который и тот, и другой подход сочетает. Мы оставим гибридный, добавим файл, загрузим его с локального компьютера. Тот самый PDF, который я вам только что показывал. Файл добавлен, есть дополнительно можно различные расширенные настройки указать. Это и размер чанка, и перекрытие чанков, и различные стратегии, которые используются при индексации документа. Мы здесь оставим сейчас дефолтные настройки, но чтобы вы знали, как это сделать, я вам это показал. Нажимаем кнопку «Создать» и ждем какое-то количество времени, которое, конечно же, зависит от размера самого документа. Большой, относительно небольшой, поэтому это буквально несколько секунд займет. Отлично. У нас создался поисковый индекс, и нам в дальнейшем понадобятся его идентификаторы для того, чтобы в фреймворке его указать. Мы видим, что у нас отображаются здесь основные его параметры, и у нас есть вкладка файлы индекса, где мы также видим тот файл, который мы загрузили. Завершено. И дальше мы уже приступим к коду. Дима, тебе слово. Прежде чем к коду, тоже хотелось бы добавить пару комментариев. Первый важный нюанс, который в текущем примере мы пропустили, но он может помочь, это описание индекса. То есть, когда вы создаете индекс, неважно, через UI или через VectorStore API, у вас есть поле описания. Это описание не только, условно, общее безусловное описание, чтобы его было проще найти, но оно еще используется языковой моделью. Поэтому, если вы загрузили поисковый индекс, настроили его, подключили к Responses, но он не вызывается или вызывается не так, одна из рекомендаций — это попробовать добавить к нему. описание текстовое полное о том, что в этом индексе лежит, для чего он может использоваться и так далее. Это поможет модели лучше ориентироваться с поиском. Первое. И второе. Важно помнить, что когда мы говорим про Responses API и его интеграцию с поисковым индексом, надо понимать, что вызов... Индекс вызов поиска — это такой же вызов функции, как, например, вызов MCP. Если кто-то работал до этого, например, с ассистент API или классическими рагами, то там, как правило, такая история. Всегда происходит поиск, результаты поиска передаются в модель, модель отвечает. Здесь это реализовано иначе, здесь модель должна принять решение, что для ответа на вопрос ей нужно обратиться в поиск. Происходит поиск, дальше информация возвращается, и модель отвечает по этой информации. Для того, чтобы модель вызвала поиск в принципе, опять же, ей нужно это прописать в инструкции, прописать в описании индекса, саму информацию об индексе. Рекомендую начинать тестирование буквально с одного документа, то есть загрузили один документ, написали инструкцию, описание, посмотреть нужно, что как бы сам факт поиска происходит, что вызов инструмента действительно случается, и потом уже, когда мы отладили промо таким образом, что мы видим, что Поиск происходит, уже нам дальше начинать отлаживать поиск, если в этом есть необходимость. Вот такие пару комментариев. Спасибо. Так, давайте с вами начнем смотреть код. Соответственно, у меня есть... Я создал проект на языке Python. Значит, здесь мы будем использовать, как уже не один раз сказали, фреймворк... Также мы будем использовать A2A протокол, то есть специальный A2A SDK. Сейчас мы с вами посмотрим на зависимости. Я все эти библиотеки подключил в зависимости. И OpenA agents, и MCP, и A2A SDK. Для описания проекта и управления зависимым я использовал утилиту UV. Весь код находится в каталоге App. Вот он содержит несколько файлов. Давайте перейдем к непосредственно коду агента. Для простоты я системные инструкции и необходимые переменные окружения прямо здесь использую. Вот системная инструкция для агента. Она объясняет модели, как нужно отвечать на вопросы пользователя, чем нужно пользоваться. Далее вся реализация находится в классе Customer Support Agent. У него есть конструктор, в который мы передаем MCP-сервер. Потом я покажу, как мы его создаем, откуда берем параметры. Соответственно, сам агент создается объект структуры. класса Agent из библиотеки Agent SDK. Какие параметры передаем в конструктор при создании этого объекта? Во-первых, это сама модель. Видно здесь, что мы формируем URL-модели, используя идентификатор каталога в облаке. Используем модель, как уже сказали, Яндекс.Гпт. Инструкция передается в параметры instructions. Также есть параметр mcp-servers, параметр необходим, чтобы передать список используемых mcp-серверов. Также есть параметр tools для того, чтобы передать дополнительные инструменты. В нашем случае как раз будет встроен инструмент FileSearchTool, в котором мы идентификатор нашего вектора стора, созданного ранее. Возьмем все необходимые значения из переменных окружения, которые потом я покажу, как мы будем заполнять при деплое агента. Помимо самого объекта Agent, нам необходимо конфигурацию запуска создать и настроить. Здесь можно указать модель, можно не указывать, в случае, если вы задаете ее конкретно в агенте. Но главное, что здесь нужно настроить OpenAI провайдер в нашем случае, потому что мы пользуемся не OpenAI, а Яндекс.AI.Studio. Соответственно, так как мы совместимы с OpenAI Responses API, то мы можем использовать эту реализацию, этот провайдер. Здесь мы передадим API-ключик, который я потом также покажу, как мы сгенерируем. В качестве проекта мы передаем датификатор каталога, базовый URL, по которому Responses API доступен в AI-студия. И еще мы укажем, что с помощью флага UseResponses мы используем Responses API. Сам агент очень простой в нашем случае. Это метод Invoke, в котором мы просто с помощью специального... класса runner, запускаем метод run. Для начала это синхронный метод, потом мы посмотрим, как использовать стриминговую версию этого метода. Сюда нужно передать сообщение, которое мы хотим, чтобы поступило в модель, и передать тот самый конфиг, который мы настроили. Результат будет содержать значение в поле Final Output. Вот такая простая реализация. Чуть позже на примере с чат-китом мы ее усложним для того, чтобы использовать стриминг. Также, как Дима рассказывал, в агенте мы можем настроить дополнительные параметры. Это guardrail, так называемые. Входные и выходные данные, поступающие в модели, это нужно для того, чтобы обезопасить нашего агента от различных взломов, промт-инъекций и прочего. Также можно настроить хэнд-оффы. Это тот самый механизм, который позволяет агенту пользоваться помощью других агентов, вызывать других агентов. В ран конфиге есть дополнительные параметры, не будем подробно на них останавливаться. Если нет вопросов, на которые нужно прямо сейчас ответить, давайте перейдем далее к демонстрации кода A2A-сервера. Мы сейчас возьмем этого агента и обернем в A2A-сервер, используя A2A-SDK. Как я уже сказал, предоставили нам библиотеку, которая сильно упрощает создание A2A сервера. Мы эту библиотеку подключаем также в зависимости. С чего же надо начать реализацию? Во-первых, в файле Executor у нас реализован основной интерфейс. Он называется Agent Executor. Это основной интерфейс, который реализует логику работы агента. У него есть два метода, которые надо реализовать. Во-первых, это execute-метод, откуда мы будем вызывать нашего агента. Сюда приходит на вход контекст с запросом и очередь, куда будем отправлять результат работы. Также есть метод cancel для того, чтобы обработать отмену запроса в случае, если клиент передумал дальше. Итак, мы в классе Customer Support Agent Executor реализуем этот интерфейс. В конструкторе мы создаем MCP-сервер как раз для подключения к нашему MCP. При создании этого объекта мы его конфигурируем. Во-первых, передаем URL нашего сервера, тот, который мы видели в консоли после создания. Передаем сюда ключик. Далее мы посмотрим, как его сгенерировать. И указываем дополнительную опцию, что мы хотим кэшировать список тулов, а не каждый раз его запрашивать. Тут же мы в конструкторе создаем объект Customer Support Agent, потому что мы его будем вызывать далее в методе execute. И реализация метода execute. Во-первых, мы из контекста достанем сообщение пользователя, которое пришло. Также мы из контекста достанем идентификатор контекста. Его мы будем использовать как идентификатор профиля клиента, просто для простоты. Дальше мы сходим в наш REST API и запросим профиль клиента. Мы хотим его добавить в prompt, который будем отправлять в модельку. У меня подготовлен специальный код, который называется airline-client. Здесь просто пару методов. Мы обращаемся, идем с get-запросом в REST API за профилем клиента, получаем его в формате, ответ в формате JSON. И далее просто преобразуем этот JSON в обычное текстовое сообщение. Мы получили профиль prompt и теперь мы юзер-месседж и профиль prompt объединяем в составной prompt, который дальше передаем при вызове агента. Перед тем, как мы вызываем агента, мы устанавливаем соединение с MCP-сервером. Метод Invoke возвращает нам результат, который нам нужно преобразовать в формат. Для этого у нас есть помогательные методы, предоставленные библиотекой. В данном случае NewAgentTextMessage метод, точнее функция, которую мы вызываем, создает специальный объект класса Message. Здесь есть разные поля. Сами данные могут состоять из разных частей разного формата. Также, в случае, если агент вызывает инструмент, он может обновить профиль клиента. Мы получаем обновленный профиль и добавляем в сообщение. Помимо текста ответа LLM, мы добавляем туда профиль клиента. Заключительно, мы в очередь кладем это сообщение для синхронной отправки на клиентскую сторону. Закрываем соединение SMCP сервера. Этот cancel мы оставляем без реализации, просто для упрощения. Перейдем в метод main, через который запускается. Здесь мы рассмотрим, что такое карточка агента. Чтобы составить ее, нужно определить навык агента. Для этого есть специальная структура, agent skill. Мы создаем объект такого типа. Заполняем здесь идентификатор. название, описание, различные теги. Далее мы уже приступаем к созданию карточки. Для этого есть тип AgentCard. Также собираем объект такого типа, указываем название, описание URL, по которому будет доступен агент, его версию, форматы входных и выходных данных. В данном случае у нас будет просто текст. Можно дополнительные capabilities определить агента. Во-первых, наш агент может стримить или отправлять пуш-нотификации. Указываем наш навык или скилл, который мы ранее определили. Еще бывает у нас расширенная карточка, которую дополнительно в нашем случае мы не будем создавать. Мы создаем объект Executor, который ранее я вам показывал. Теперь нам нужно создать объект QuestHandler. Это класс, который предоставлен на реализацию которого предоставлена библиотека, который реализует основные методы 8-way протокола. Это метод send, метод send subscribe. Для того чтобы он принимает запросы, запросы далее перенаправляет в Agent Executor, а также он умеет создавать и работать с задачами. В нашем случае мы будем использовать InMemory реализацию TaskStore. Для полноценного продакшена, особенно если у вас задачи длительные, лучше сделать нормальную базу данных с сохранением на диск. У нас есть от библиотеки A2E Start Application класс, который обертка над FastAPI, известным фреймворком на Python, который позволяет из FastAPI сделать сервер, реализующий JSON RPC. и поверх него A2A протокол. Туда мы передаем нашу карточку и наш HTTP request handler. И запускаем наш сервер. Собственно, вот такой нехитрый код, такая реализация A2A протокола. Нам на самом деле нужно еще с вами собрать нашего агента в Docker образ. Давайте это тоже сделаем. Сейчас я запущу. Для этого у меня описан простенький Docker файл. Это достаточно стандартный для проектов на Python. Здесь мы просто копируем код, устанавливаем зависимости и вызываем специальный shell файлов. Перед тем, как соберем Docker образ, это делается просто с помощью команды Docker build. Ранее я уже собирал, поэтому здесь все быстро произойдет. Теперь нам нужно загрузить этот Docker образ куда-то в облако. Для этого давайте создадим реестр контейнеров в облаке. Это позволяет нам сделать сервис Container Registry. Вводим имя, нажимаем кнопку «Создать реестр». Реестр создан, теперь нам нужен его идентификатор для того, чтобы правильно путь к докер-образу сформировать. Мы выполним команду «Docker Tag» для того, чтобы продегировать наш образ перед загрузкой его в облако. Дальше мы его будем загружать в облако. Хэш образа. Для разнообразия воспользуемся подманом утилиты. Здесь также подставим новый хэш. И подставим идентификатор реестра. Образ небольшой, всего лишь занимает чуть более 100 мегабайт. Это хорошо. Мы его загрузили. Теперь давайте посмотрим, что у нас в консоли появился. Открываем реестр. Смотрим, образ появился. Как я уже сказал, он весит 113 мегабайт всего. И на этом мы готовы к тому, чтобы приступить уже к деплою нашего кода, к деплою нашего образа. Могу продолжать дальше, Дим? Перед тем, как мы с вами создадим бессерверный контейнер, мы должны сначала создать сервисный аккаунт, от которого он будет работать, выдать ему нужные роли. создать API-ключик этому сервисному аккаунту с нужной областью действия. Далее этот API-ключик, создать в локбоксе секрет, куда мы положим этот ключик. И уже при создании контейнера мы все это будем использовать. Мы с вами уже production-ready используем настройки, чтобы наш агент работал безопасно. наше решение было безопасным. Так, создаем сервисный аккаунт. Назовем его AgentSA. Какие роли нам нужны? Во-первых, мы из него будем ходить напрямую в REST API для того, чтобы профиль клиента получать. А, перед этим, смотрите, мы, соответственно, должны уметь получать секретик из локбокса. в котором ключик лежит. Во-вторых, он должен иметь права на то, чтобы пулить Docker образ из Container Registry. Далее мы будем с вами вызывать модель в iStudio, поэтому LanguageModelUser нужна роль. И будем вызывать Responses API, поэтому нужна роль Assistance Editor. Ну и как я уже сказал, да, мы будем дергать контейнер с REST API, поэтому нам нужно... контейнер, инвокер. Еще мы будем ходить в MCP, поэтому нам нужна роль MCP, gateway, инвокер. Мы наделили нашего агента всеми нужными ролями. В идеале, если вы хотите максимально обезопаситься, можно создать несколько сервисных аккаунтов и разделить эти роли. Создаем ключик. Ключи имеют области действия. В нашем случае нам нужны какие скалпы? Во-первых, это использование language models, во-вторых, это вызов контейнеров, и в-третьих, это вызов MCP серверов или MCP gateway. Укажем какой-нибудь срок действия и нажимаем кнопку «Создать». Итак, у нас генерировался ключик моего. где-то себе сейчас сохраним. В дальнейшем он нам сейчас понадобится, мы его в LogBox Secret положим. Давайте создадим LogBox Secret. Введем его имя. Это будет пользовательский негенерируемый секрет, потому что мы принесем сами туда данные. Соответственно, нужно ключик заполнить. Назовем это Piki и вставим То самое значение ключа, которое мы предварительно сгенерировали. Итак, создаем секрет. Секрет создан и видим, что здесь есть наш ключик. Также идентификатор секрета нам в дальнейшем понадобится. Мы его заполним при создании контейнера. Нам осталось создать серверлес-контейнер. Для этого мы находим также с дашборда облака этот сервис, заходим в его панель, нажимаем кнопку «Создать контейнер», вводим название и дальше будем… А, вот видим, что у нас есть ссылка для вызова. Нам ее тоже нужно сохранить, ссылка, по которой будет доступен наш контейнер. Нам нужно сохранить эту ссылку для карточки агента. Делаем сразу наш контейнер публичным, потому что будем из интернета. его вызывать без авторизации. Давайте создадим первую ревизию. Это будет доступный по HTTP-контейнеру. Настроим ресурсы по памяти и по CPU. Здесь укажем тот самый образ, который мы загрузили в созданный специальный реестр. Команду аргумента оставляем пустыми. Теперь нам нужно заполнить те самые переменные окружения, которые мы в коде получаем. Значения которых это, во-первых, сервер, по которому доступен агент для карточки, во-вторых, нам нужен будет фолдер ID, идентификатор фолдера. Как вы помните, нам нужен для того, чтобы сформировать адрес модели. Также нам нужен будет URL REST API, из которого мы будем получать профиль клиента. Также нам нужен URL MCP сервера. Мы с вами его вначале создавали, и нам нужен тот самый идентификатор векторного хранилища или поискового индекса, который мы тоже с вами создавали. Вот собственно все, что нам надо. И конечно же API-ключик, который мы с вами положим в переменную окружения API. А здесь мы прямо сразу укажем, что его нужно взять из локбокс-секрета. Подтягивать секреты, а не plaintext их где-то вставлять сюда. Теперь нам надо указать сервисный аккаунт, который мы создали. Сеть мы не выбираем, тайм-аут укажем чуть побольше, потому что агент может работать дольше в зависимости от того, как LLM-модель отвечает. Можно настроить количество одновременных вызовов контейнера. Если мы хотим избегать код стартов, можно предварительно подготовленные контейнеры создавать. Итак, мы деплоим с вами первую ревизию. Она у нас деплоилась. Таким образом, у нас готов и развернут в облаке наш агент. Теперь мы готовы продемонстрировать его работу. Дима, как у нас с вопросами? Вопросы появляются, но там много. Давай оставим их на конец. Пошли дальше. Разработчики протокола также сделали простенький интерфейс. Он называется E2 Inspector, который позволяет провалидировать, протестировать работу агента, проверить, что он работает в соответствии с протоколом. поддерживает все необходимые форматы данных и так далее. Его можно из открытого репозитория скачать, у себя локально запустить, что я сделал. Давайте теперь вставим туда рул нашего агента и получим карточку. Подключимся к нему. Мы видим, что у нас была подтянута карточка. Мы видим здесь информацию, которую мы в карточке указали. Это навык нашего агента. Урл, по которому он доступен, версию, форматы входных и выходных данных. Теперь давайте зададим вопрос агенту, для того чтобы протестировать его работу. Для начала давайте попросим его показать нам профиль клиента. Уже клиент заготовлен в опишке. Вот он нам отвечает. Ты такой-то клиент, вот твоя карточка. Здесь видно, что у меня уже есть какой-то полет, точнее воздушный, с двумя перелетами. И они у меня запланированы. Собственно, статус запланирован. Теперь давайте попросим его что-то сделать с моей бронью. В примерах у нас есть такой запрос. Помоги мне отменить мой полет. Давайте попросим его. Очевидно, что здесь без инструмента, вызов инструмента не обойтись. И вот видите, он нам говорит, что полет был успешно отменен и запущена процедура возврата денег. В самом сообщении, которое мы получаем, мы видим, что есть текст ответа, плюс тот самый обновленный профиль, который мы с вами... Загружали, и мы видим, что статус нашего полета теперь канцелл. Мы продемонстрировали работу нашего агента. Он работает полностью в соответствии с протоколом и даже вызывает инструменты. Теперь переходим к следующему примеру. Это уже более богатый пример с использованием чат-кит интерфейса. Вот на слайде изображена его архитектура. Чем она отличается? Во-первых, у нас есть фронтенд-часть, код которой я покажу, и мы развернем в Object Storage. Это простенькое приложение. У нас также есть бессервный контейнер, в котором наш агент уже теперь обернут в ChatKit сервер. Это все также на питоне код, мы на него посмотрим. И теперь у нас появилось состояние, которое мы будем хранить в Яндекс.Датабейс. Это состояние будет содержать историю общения, то есть чаты, сообщения в этих чатах и вложения. В нашем случае их не будет, но в общем случае также там могут храниться вложения. Агент также будет через респонсис API работать с моделью, вызывать MCP, использовать источники данных. Здесь все так же, как и в предыдущем примере. Давайте посмотрим на код. Это очень похожий проект, как и в предыдущем примере. Только в данном случае мы в зависимости подключили дополнительную библиотеку, которая называется OpenAge Chat Kit. Также у нас есть библиотека OpenAgents, потому что мы пользуемся все тем же Agents SDK framework. Код агента практически не отличается. Здесь также есть инструкция, загружается необходимое переменное окружение. В конструкторе мы создаем агента, создаем конфигурацию запуска. Единственное отличие, что теперь, во-первых, мы используем версию streamed метода run, run streamed. Во-вторых, мы будем использовать здесь краткорочную память, про которую рассказывал Дима, именно за счет передачи Previous Response ID. Дальше я покажу, откуда мы будем брать и где будем сохранять между запусками и нотификатор предыдущего вызова Responses API. У нас немножко поменялся тип ответа, потому что мы стриминг используем. Чтобы его реализовать, нужно реализовать абстрактный класс ChatKit Server, предоставленный библиотекой. В нем есть основной метод Respond, который мы сейчас реализуем. Он принимает на вход метаданные 3D или метаданные чата. Мы принимаем параметр, это хранилище, которое нужно дальше передать по цепочке в конструктор чат-кит-сервера. Это хранилище, в котором будет храниться история и все чаты. Здесь же мы создаем также объект MCP-сервера SSE, для того чтобы подключаться к нашему MCP-серверу. объект CustomerSupportAgent и реализуем метод Respond. На вход в него приходит Thread, Item — это сообщение пользователя и контекст, который дальше будет передаваться вниз по цепочке запросов. В этом методе мы также получаем сообщение пользователя, достаем его в в текстовом виде, мы получаем профиль клиента. В данном случае это будет идентификатор труда. Идем в наш REST API, получаем профиль. Здесь все также, как в предыдущем примере. Комбинируем промпт из информации о профиле и сообщения пользователя. Создаем специальный объект, который называется AgentContext. Там у нас есть контекст запроса, thread и store. И вот как раз здесь момент важный, откуда мы берем previous response ID. Мы его берем из метаданных thread, а thread на самом деле будет подгружаться из store. То есть это у нас будет храниться прямо в базе данных между вызовами. Таким образом мы реализуем... краткосрочную память, чтобы в контекст модельки добавлялась вся история общения. Запуск самого агента происходит практически так же, как в предыдущем примере, кроме того, что мы передаем сюда previous response id. Ответ немножко в другом формате, это уже формат chat.kita. Здесь мы стримим события, которые нам агент в ответе отдает. Стримим его выше по стеку вызова. Далее нам нужно снова сохранить новый идентификатор response объекта. Мы его сохраняем, прикапываем в нашем сторе. Это реализация метода response. файл main. Здесь у нас создан простой fastapi приложение, в котором мы будем передавать наш customer support сервер, то есть нашу реализацию chatkit сервера. В нее мы сейчас передадим store, чуть позже покажу как. Здесь также у нас будет всего два endpoints. Это, во-первых, основной HTTP запрос, который будет вызывать chatkit в фронтенд-часть. support chat kit. Сюда будет приходить request, и мы из него будем доставать из тела пилот и дальше передавать в наш сервер этот пилот и сам request. Метод process уже реализован в абстрактном классе, он внутри себя будет респонд вызывать. И ответ в зависимости от того, какой он стриминговый или нет, соответственно разные объекты используются. Второй метод, который в нашем сервере будет, это проксирование просто вызова получения профиля клиента. Мы будем проксировать в REST API. Это нужно для того, чтобы избежать лишних настроек course-politics на нашей фронтенд-части. Важно, как мы создаем наш Store. У нас есть две реализации его. Одна — In-memory реализация. Код, который вы можете посмотреть подробно в репозитории. Вторая реализация — это реализация в YDB, базе данных. Она умеет работать по AWS DynamoDB совместимому интерфейсу. Он называется у нас Document API. Мы реализовали такой стор. Вы тоже можете потом подробно изучить, как он реализован. При его создании необходимо передать переменное окружение. На этом вся backend часть нашего чат-кит-агента состоит из этого. Я не буду показывать, как это собирать в докер-образ, потому что я уже показывал, как это загружать в реестр контейнеров. Я только покажу вам. Я покажу саму базу данных, которую я предварительно создал. Покажу ее структуру. В консоли облака мы заходим в «Manage Service for YDB». Здесь созданная база данных. Она создана в режиме «Сервис» просто для того, чтобы не тратить постоянно запущенные ресурсы. Вы можете использовать и «Dedicated» режим, если вам нужны выделенные ресурсы. Это коллекция, которая хранит трэды, потом thread items — это сообщение трэдов, и вложение в коллекции attachments. Я создал сервер-ласс-контейнер рядышком с предыдущим контейнером. В нем поля параметры все те же самые, все также это http-сервер. Единственное, что изменилось, это добавилось дополнительно переменное окружение DynamoDB endpoint, собственно, endpoint — той базы данных, с которой работает наш чат-китовый. На этом показ кода чат-кит-агента завершен. Давайте теперь посмотрим на фронт-энд-часть. Небольшое React-приложение, это TypeScript проект, стандартный достаточно, в нем есть файл package.json, в нем мы подключили необходимую библиотеку, ChatKit React, предоставляемую нам. И сам фронт-энд состоит из single page applications, в нем есть одна страничка индекса HTML. Здесь мы как раз подключаем тот самый chatkit.js скрипт, который нам доступен CDN OpenAI. И само приложение, в общем-то, React-приложение, оно состоит из одной странички, домашней странички. Это страничка Home. И в ней, собственно, что в ней есть? В ней есть заголовок в верхней части. с описанием, кто это такой и что это. И две панельки. Первая панелька — это чат-кит-панелька, это тот самый чат-интерфейс. Слева и справа — это панелька с информацией про клиента, про его полеты и бронирование. Сама чат-кит-панелька — это объектик, который уже есть в библиотеке нами подключенный. создать и сконфигурировать. Для этого нужно указать URL ChatKit сервера, который задеплоен. Это будет URL нашего контейнера. И специальный домен ключик, потому что OpenAI требует верификации домена, на котором чат развернут, для того чтобы JS скрипт подтянуть. Также можно кастомизировать тему чата, задать стартовые приветствия, какие-то стартовые промпты, то есть запросы пользователя, placeholder для поля текста, где будет вводиться клиентам какое-то сообщение. Ну и различные другие параметры, обработчики. Собственно, вот и вся реализация. Попробуем собрать этот код и загрузить его в Object Storage как статический ресурс. Это будет HTML-страничка и пара файлов. Для этого давайте установим зависимости с помощью команды npm install. Сборка кода будет выполняться инструментом invite, который называется. Он позволяет быстро и эффективно собрать весь код в один JS файл. Для того, чтобы это сделать, запускаем команду npm run build. Появляется каталог dist, который состоит из индекса HTML и двух файлов — JavaScript и CSS. Теперь давайте перейдем снова в консоль облака и создадим с вами бакет в Object Storage, куда будем загружать приложение. Нам нужен сервис Object Storage. Находим его в консоли, нажимаем «Создать bucket». Здесь нужно будет заполнить имя bucket. Назовем его Customer Support Chat. Настроим, чтобы доступ к нему был свободный на чтение. Нажимаем кнопку «Создать». Bucket с таким именем уже существует немножко, поэтому изменим название. Создаем снова. Бакет создан. Давайте теперь настроим хостинг вебхостинг файлов из этого бакета. Укажем в качестве главной страницы ту самую страницу index.html. Сохраним настройки. Теперь наш сайт доступен по такому адресу. Теперь нам нужно это доменное имя зарегистрировать в OpenAI для того, чтобы он нам отдал ChatKit.js скрипт. Заходим на страничку OpenAI, заходим в настройки Security, здесь просто указываем этот домен. И он нам создает ключик. Этот ключик мы сейчас положим в переменное окружение в специальный файлик .env, в котором у нас заданы и другие переменные окружения. И теперь снова пересоберем наш проект для того, чтобы уже... В наш JS файл попали все необходимые переменные. Теперь нам осталось только загрузить в bucket эти файлы, объекты. Здесь у нас будет HTML-страничка и наши файлы — это скрипты и скрипт — это CSS-стиль. Безусловно, все, что я вам показываю в консоли, можно сделать с помощью… ну почти все, да, не все, но почти все. многое с помощью утилиты Kli или даже в облаке есть Terraform. На этом готов наш фронтенд. Теперь мы с вами можем посмотреть, как работает наш ChatKit-агент. Слева есть панелька с чат-интерфейсом, справа есть панелька с профилем клиента. В ней основная информация. У меня уже заведен профиль, здесь видно перелет, есть какие-то мои багаж, предпочтения по идее и так далее. Вот мы видим, что в первом перелете у меня место 14А. Давайте попросим его изменить место. У нас подготовлен для этого есть промт, поменять его на 14С. Пришел ответ, был вызван инструмент, место поменялось уже в обновленном профиле. В UI видим, что место 14c. Теперь давайте новый диалог создадим и попробуем проверить, как у нас источник работает, поисковый индекс. Спросим, а за сколько дней до полета нужно привить от бешенства нашего питомца. Эта информация есть точно в этом документе. Мы видим, что в ответе он нам подсказывает, что он использовал источник, тот самый файлик airline rules, который мы загрузили в поисковый индекс по нему. И видим ответ за 20 дней. Так как у нас вся история чатов хранится в базе данных, мы можем посмотреть все наши беседы, можем загрузить какую-то беседу предыдущую. Используется краткосрочная память, и вся история общения поступает также в контекст модели при запросах. Для этого спросим ее, что я просил тебя сделать в предыдущий раз, для того чтобы явно проверить, что она использует в предыдущей истории общения. И вот мы видим, что она нам ответила, что действительно в предыдущем запросе я просил поменять место. Вот так работает интерфейс. Как я уже сказал, можно его кастомизировать различными способами. Теперь давайте посмотрим, как можно мониторить работу нашего агента. Что можно вообще посмотреть? Во-первых, можно зайти в контейнер и посмотреть его логи. На вкладке «Логи» в самом контейнере мы видим, что здесь вызывался REST API, запрашивался профиль клиента. Вызывался респонсис API, вызывался MCP-гитвей. То есть все, как работает агент, мы здесь можем отследить. На самом деле, также мы можем на вкладке «Мониторинг» посмотреть графики. Это и запросы вызова нашего агента, это и время ответа нашего агента. Также мы можем зайти в AI-студию и там посмотреть. Давайте проверим, что мы действительно агент вызывал тулы. Для этого мы заходим в наш MCP-сервер. Заходим на вкладку «Логи» и можем посмотреть, какие тулы были вызваны. Мы видим, что тул изменения места был вызван, его начало вызова, конец вызова, что агент листил тулы и, соответственно, сессии МСП работы. Также можем посмотреть вызовы модельки на вкладке «Мониторинг в AI-студии». Здесь мы видим, что на респонсе сапи вызывался. Также запросы. и время ответа. Такие инструменты есть для того, чтобы мониторить. На этом практическая часть завершена. Безусловно, мы не все рассмотрели. Дальше, Дима, возвращаю тебе слово. Мы понимаем, что вебинар достаточно насыщенный по контенту, поэтому мы поделились ссылкой и потом продублируем ее в чате. Вы сможете повторить все это полностью самостоятельно у себя. Я сделал, наверное, краткое summary, о чем вообще сегодня мы говорили. То есть мы прошли весь путь по сборке агента, начиная с самых базовых шагов настройки инструментов, для которых мы использовали MCP и файловый поиск. Вся оркестрация именно логики агента происходила на базе Responses API подключенных инструментов. Далее мы обернули response API в OpenAI Agents SDK. На самом деле мы не вдавались во все подробности вокруг Agents SDK. Кажется, что для условно... одного агента, который дергает mcp и файл, это все, что мы показали сегодня, немного переусложнение, но как бы в реальности это не будет решаться условно одним агентом, это будет какое-то множество из нескольких агентов, которые могут передавать управление друг другом, и как раз для таких сценариев вот эта вся цепочка, она будет нужна и полезна. Дальше OpenAI мы обернулись сначала в A2A протокол и протестировали, как возможно взаимодействие обернули в A2A, задеплоили в serverless container и дальше протестировали взаимодействие с этим агентом. И в заключение попробовали сделать UI, UI на базе chatkit, который взаимодействует с chatkit-сервером, также задеплоенным на базе serverless container с кодом на OpenAI NGSSDK, который обращается в Responses API. Предложенный путь — это одна из возможных реализаций, понятно, агентских сценариев. И, соответственно, если у вас есть мысли, идеи, какие другие цепочки можно реализовывать, или вы хотите поделиться своими подходами, то мы вас очень призываем поучаствовать в опросе по разработке депло-агентов. Это как раз часть того, что мы просим заполнить для отбора участников на финальную очную встречу 1 декабря. Пожалуйста, переходите по QR-коду, по ссылке. Заполняйте форму, в этот раз не нужно делать примеры, присылать код или телеграм, достаточно будет заполнить опрос. На этом у нас сегодняшний вебинар подходит к концу. Спасибо вам большое за участие. Теперь мы будем готовы ответить на вопросы, видим, что их достаточно много. Давайте к ним перейдем. Сложите с мышкой. Давайте, наверное, вот... Пока развернемся с мышкой, начнем с последнего вопроса, самый близкий к тому, чем заканчивали. Можно еще раз пояснить, откуда появилось облако OpenAI, а мелькала адресная строка платформы OpenAI, если верно рассказал. Да, давайте отвечу на этот вопрос. Это сделано было только для того, чтобы... чат-скрипт.js файлик получить CDN OpenAI, OpenAI требует верификацию домена. Можно было загрузить чат-кит.js куда-нибудь себе и развернуть его в том же Object Storage в Яндекс.Облаке и получать его оттуда. Просто я показал вам, как это изначально было задумано. сервисов OpenAI, и уж тем более вы не будете ничего платить. То есть, еще раз повторю, этот скрипт можно было скачать и загрузить куда угодно. И дальше в HTML-страничке указать путь на новый адрес. Да, на самом деле, чат-кит — это, конечно, одна из большого количества возможных реализаций UI. Мы ее использовали для примера, просто потому что, во-первых, она недавно появилась, интересно проэкспериментировать, и у нас во многом стек ориентировался на open-source компоненты, доступные от OpenAI, поэтому мы решили собрать такой прикол, такой pipeline. Но, конечно, это одна из возможных реализаций, и к OpenAI платформе она никак не привязана. Далее был вопрос про ноду OpenAI в Netany. Будет ли нода OpenAI в Netany работать с iStudio? Да, она будет работать за счет совместимости респонса с API. Вы можете подключить, потестировать. Если вдруг вы обнаружите какие-то сложности, что-то неправильно отрабатывает или какие-то ошибки, переносите в Telegram канал. Будем разбираться, но глобально оно работает. Далее был вопрос по поводу workflows и взаимодействия с моделью VLAN Gemma, которая доступна в AI Studio. Как раз хороший повод сослаться на завтрашний вебинар. Как раз Саша будет показывать пример, где будет происходить вызов этой модельки из workflows. То есть, как бы ответ, да, такая возможность есть. Завтра будет про это подробнее. Еще один вопрос, который был, это про MCP, и умеет ли он переваривать грязные источники из коробки, или нужно писать parser, beautiful soup, pandas, unstructured, и потом кидать уже в него чистые данные. Ну, тут, наверное, мне немного не хватает контекста, чтобы полностью ответить на этот вопрос. То есть глобально MCP, да, это протокол, который позволяет получать какую-то информацию из API, то есть тот... Если вы по API будете передавать грязные данные, то эти грязные данные будут поступать в модель, и модель будет отвечать по ним. Если тут речь идет про какие-то поисковые сценарии в интернете, то есть условно хочется что-то в сторону парсинга сайтов, то здесь рекомендация использовать не MCP, а использовать готовый инструмент Web Search Tool. То есть он как раз, мы про него сегодня подробно не говорили, но на первом вебинаре Дима про него рассказывал. Он как раз позволяет обратиться в интернет, берет контент страниц и передает их в модель для ответов. Следующий вопрос был про поисковый индекс VI Assistant API. Является ли это полностью автоматизированным RAC-контейнером, где автоматически выполняется членкование бэддинга индексации? Здесь, наверное, важно сказать, что AI-assistant API действительно такой API на платформе есть. И он, да, является как раз автоматизированным RAC-контейнером, но assistant API у нас сейчас деприкейтед, то есть мы его больше не поддерживаем. И мы рекомендуем переходить на связку как раз responses API плюс vectors to API. Он закрывает аналогичный функционал, только значительно расширяет его. Сегодня в документации AI Studio появилась отдельная страница, где описывается подход к переходу, то есть с примерами, как перейти, как мегрировать с Assistant API на Responses API плюс VectorStore. Но глобально да, то есть вы через VectorStore API просто загружаете файлы, дальше происходит автоматическое очинкование, построение векторов, индексация и так далее. То есть все это происходит автоматически. Выгрузить получившиеся чанки не получится, но когда, например, вы обращаетесь к responses, происходит поиск, вы получаете ответ, вы можете посмотреть цитаты, то есть посмотреть ссылки на файлы, из которых была введена информация, либо посмотреть сами фрагменты текста чанки, по которым этот ответ формировался. Вопрос про архитектуру агентов, когда мы создаем много агентов и настраиваем общение между ними, через что и как настраивать проброс контекста при переводе. Вот, да, такой достаточно сложный, объемный вопрос. Это, конечно, будет зависеть от фреймворка, который вы используете для реализации. Если говорить конкретно про наш пример сегодня, который мы показывали на OpenAI Agents SDK, то у них реализовано такой механизм, как хэнд-оффы, то есть вы условно собираете одну сущность агента, вторую сущность агента, и вот эту вторую сущность вы можете указать первому агенту как хэнд-офф, то есть это прям отдельный список, хэнд-офф равно, и там указываете агенты. И дальше по дефолту весь контекст передается от одного агента к другому, то есть это происходит автоматически самими механизмами, которые доступны во фреймворке Agents SDK. При этом вы это также можете регулировать, то есть там есть параметр, который наоборот говорит, что передавать контекст не нужно и так далее. То есть это регулируется кодом, который уже написан в RZSDK. Если вы, например, используете ланграф, там есть свои более сложные механизмы, есть механизмы состояния, памяти. По сути, состояние это как раз то, что позволяет обмениваться одной и той же информацией между агентами. В общем, тут надо смотреть на... конкретные фреймворки. Если вот про Agents, опять же, думаю, можно сослаться на ссылку на воркшоп Дмитрия, где он рассказывал про мультиогенные системы. Там как раз был пример с хенд-оффами и как они работают. Вот. Не знаю, тут есть что-то. Нет, ты хорошо все сказал. Да, вопрос про безопасность. Как убедиться, что предложенные LLM в iStudio изолированы, и им на анализ можно передавать чувствительную информацию для анализа, или как подключать свои безопасные в этом аспекте LLM? Наверное, тоже достаточно комплексный вопрос. Тут, наверное, первый вопрос, что именно должно быть изолировано? То есть глобально в облаке изоляция происходит на уровне фолдера, то есть все ресурсы, которые доступны в облаке, они изолируются на уровне фолдера. Это что касается и балансировщиков, и моделей, и так далее. Если говорить про более юридические аспекты, то, например, AI-студию, как и Облако, имеет сертификацию FZ-152, имеет еще ряд других сертификатов, в пользовательском соглашении прописана политика работы с данными и так далее. Думаю, что мы готовим вообще сейчас отдельный документ про глобальную безопасность AI-студию, как ее настраивать, в каких местах она... и как работает, да, то есть там есть и ролевые модели, и шифрование, это все. Вот, этот документ сейчас в процессе, если у вас есть какие-то более конкретные вопросы, да, там что-то нужно уточнить, помочь, то приходите в комьюнити, можете приходить лично в сообщение, разберемся, поможем. Вот, так, еще вопрос, вижу, появился. Если у пользователя есть свой ключ, можно ли отследить конкретного пользователя и содержание его промтов при обработке агента? Могу помочь. Смотрите, во-первых, есть возможность залогировать промт. Это можно сделать в самом веб-приложении, которое у нас на бэкэнде работает на языке Python. Вы можете просто взять http-запрос и по какой-то идентификатор запроса залогировать вместе с... с сообщением, которое у вас в теле приходит. Там будет содержаться проб от пользователя, вы можете это залогировать, потом в логах отследить, куда-то выгружать, соответственно, мониторинг этого делать. Во-вторых, это на уровне http и базового http сервера. Во-вторых, у вас есть в самом фреймворке, я показывал, что есть guardrail, это механизм, который позволяет смотреть на входные данные, поступающие от пользователей в модельку, и фильтровать гардрейлы, настраивать логику их обработки. Также можно будет куда-то логировать, отправлять их содержимое промтов и так далее. Поэтому у вас тут инструментов достаточно, но здесь потребуется какое-то количество вашей работы, чтобы написать эту логику. Да, я дополню, что готового встроенного механизма, например, в том же Responsys API для отслеживания по конкретному пользователю сейчас нет. Ну и, соответственно, это действительно требует обертки дополнительного функционала вокруг, который нужно будет сделать. Вот, еще один вопрос, наверное, тоже тебе больше видеть. Если у меня тяжеловесная обработка идет, например, 10 миллионов точек рисуется и прочее, как лучше организовать работу? Например, есть Tgbot, я могу его на Яндекс функции вебхук держать, и потом как мне дать агенту запрос, чтобы он там обрабатывал, потом ответ пользователя отправил в Tg, когда работа закончена. Я думаю, что здесь можно как раз развернуть агента не в режиме UI-интерфейса, а в режиме way-to-way протоколе. Традиционными способами в сервис повесить триггер, например, о завершении обработки тяжелой сообщать в очередь, дальше на эту очередь повесить триггер и уже дальше в этом триггере вызывать агента, который что-то делает с результатами обработки. А далее уже отправлять ответ в Telegram. чат, используя стандартные Telegram API. Поэтому здесь все как обычно. Если вы используете серверы, то для того, чтобы развязать обработку, сделать синхронно, используете триггеры. Да, видим, что вроде на текущий момент больше вопросов нет. Таким образом, да, мы уже почти два часа рассказываем про этот вебинар. Предлагаю потихоньку завершаться. Напомню еще раз, что Мы очень приглашаем вас заполнить форму и поделиться обратной связью. А мы ждем вас на следующих вебинарах нашей серии. Завтра про workflows, послезавтра про голосовых агентов и про real-time API. Спасибо большое. Всем пока. Спасибо.
⚙️ Pipeline jobs
| Stage | Status | Att. | Updated | Error |
|---|---|---|---|---|
| download | done | 1/3 | 2026-07-20 12:11:43 | |
| transcribe | done | 1/3 | 2026-07-20 12:13:09 | |
| summarize | done | 1/3 | 2026-07-20 12:13:38 | |
| embed | done | 1/3 | 2026-07-20 12:13:41 |
📄 Описание YouTube
Показать
Дмитрий Рыбалко и Виктор Кузенный рассказали, какие возможности для разработки и деплоя агентов есть в Yandex AI Studio, в том числе с использованием MCP, а также как обращаться к агенту через A2A и UI. 00:00 Введение в серию вебинаров AI Studio Series (Дмитрий Рыбалко) 02:36 План вебинара (Дмитрий Рыбалко) 03:19 Базовый AI-агент и его создание в AI Studio (Дмитрий Рыбалко) 04:27 Дополнительные ресурсы для обучения (Дмитрий Рыбалко) 05:28 Основные блоки агентской архитектуры (Дмитрий Рыбалко) 08:39 Компоненты AI Studio (Дмитрий Рыбалко) 11:05 Agent Atelier (Дмитрий Рыбалко) 11:58 Responses API (Дмитрий Рыбалко) 12:22 Особенности голосовых агентов (Дмитрий Рыбалко) 13:00 MCP Hub: Управление внешними системами (Дмитрий Рыбалко) 15:30 MCP Hub: Шаблоны (Дмитрий Рыбалко) 16:17 Responses API как оркестратор и его работа с инструментами (Дмитрий Рыбалко) 18:11 Диаграмма работы Responses API с MCP (Дмитрий Рыбалко) 19:22 Сложная логика агентов: Мультиагентные системы (Дмитрий Рыбалко) 21:01 Фреймворки для разработки агентов (Дмитрий Рыбалко) 22:18 Деплой агентов (Виктор Кузенный) 25:05 Протокол Agent2Agent (A2A) для взаимодействия агентов (Виктор Кузенный) 26:44 Фазы работы протокола A2A (Виктор Кузенный) 28:27 OpenAI ChatKit: UI для взаимодействия с агентами (Виктор Кузенный) 30:12 Реализация ChatKit (Виктор Кузенный) 31:34 Практический пример: Агент поддержки авиакомпании (Дмитрий Рыбалко, Виктор Кузенный) 44:51 Создание поискового индекса (Дмитрий Рыбалко, Виктор Кузенный) 50:06 Демонстрация кода агента (Виктор Кузенный) 56:09 Демонстрация кода A2A-сервера (Виктор Кузенный) 01:04:02 Развёртывание A2A-агента (Виктор Кузенный) 01:15:20 Демонстрация работы A2A-агента (Виктор Кузенный) 01:18:12 Архитектура агента с ChatKit (Виктор Кузенный) 01:28:38 Демонстрация кода фронтенда (Виктор Кузенный) 01:40:02 Общий вывод (Дмитрий Рыбалко) 01:41:44 Опрос по разработке и деплою AI-агентов (Дмитрий Рыбалко) 01:42:32 Ответы на вопросы