Привет, это Андрей Мелихов, ведущий разработчик интерфейсов в Yandex Cloud. Я работаю в команде DataLens — BI-системы для визуализации больших наборов данных на дашбордах и графиках.
В прошлом году в DataLens появился чат-интерфейс: пользователь общается с ИИ-ассистентом, который строит графики, пишет формулы и решает аналитические задачи. В рамках работы над этим продуктом, который получил имя Нейроаналитик, мы пошли не совсем очевидным путём и перераспределили ответственность между командами фронтенда и бэкенда. В статье — наш опыт. В конце — демо-проект, чтобы увидеть реализацию изнутри.
ИИ, бэкендеры и фронтендеры
Подключение LLM к продукту — задача, с которой сегодня сталкиваются многие команды. Обычно за неё берётся бэкенд. Мы выбрали другой подход: первый этап интеграции с моделью взяла на себя фронтенд-команда. Считаем, что у такого подхода есть конкретные преимущества.
Важная ремарка. Под фронтендерами мы (как минимум наша команда DataLens) понимаем скорее фуллстек-инженеров с уклоном в UX и JavaScript/TypeScript. В нашей зоне ответственности — и браузерный, и серверный код на Node.js, собственные CI/CD-пайплайны и DevOps, обслуживающий задачи фронтенда. Но интерфейсы нам всё же ближе, чем данные.
Типичный сценарий: бэкенд интегрирует LLM, поднимает эндпоинты, а фронтенд подключается к ним и рисует интерфейс чата. Это рабочая схема, но возникает вопрос о распределении ответственности. Действительно ли вся интеграция с моделью должна лежать на бэкенде?
Фронтенд-команды обладают собственной технической экспертизой: умеют строить BFF (бэкенд для фронтенда), могут напрямую взаимодействовать с API, и именно они проектируют интерфейс. А в ИИ-продукте интерфейс — не менее важная часть, чем модель. У фронтенда есть и практические преимущества на этапе интеграции:
- Данные уже под рукой. В современных интерфейсах сходятся данные из множества бэкендов. Если нужно построить ИИ-инструмент поверх — контекст уже на клиенте, и дозапросить нужное несложно.
- Быстрые итерации. Когда команда ищет подходящую нишу для ИИ в продукте, скорость экспериментов критична. Фронтенд позволяет быстро проверять гипотезы без изменений в основном бэкенде.
- Меньше координации на старте. BFF на Node.js — привычная инфраструктура. Подключился к совместимому API — и можно двигаться, не блокируя другие команды.
Это не значит, что бэкенду здесь нечего делать. С развитием продукта неизбежно появляются задачи, которые должны решаться на сервере. Но начать можно силами фронтенда — и результат будет вполне продуктовым.
Архитектура: как это устроено
В нашей архитектуре между клиентом и LLM добавляется слой BFF — например, на Node.js или Bun. Конкретная технология не принципиальна: аналогичное решение можно реализовать и на Python, если фронтенд-команда готова поддерживать его. Важно, что BFF — привычный инструмент для фронтенд-команд. Он изначально отвечает за подготовку view-ориентированных данных. Теперь он берёт на себя и взаимодействие с моделью.
Существующий бэкенд остаётся без изменений. Интеграция на первом этапе переносится в зону ответственности фронтенд-команды. Схема остаётся привычной: просто появляется дополнительный бэкенд.
В периметре BFF находятся ключи доступа, rate limiting, CORS, мониторинг и логирование. Логика взаимодействия с API LLM переносится на сервер — на тот бэкенд, который «бэкенд для фронтенда».
Чтобы показать реализацию, я собрал демо-проект на GitHub — монорепозиторий с сервером на Express и клиентом на React. Интерфейс реализует упрощённую BI-систему: слева дашборд, справа — ИИ-ассистент. Сценарий: пользователь запрашивает, например, топ-5 продуктов. Ассистент вызывает функцию getChartData, получает данные и формирует ответ.
Прототип я собрал с помощью ИИ. Сначала составил план в Superpowers, затем код-ассистент реализовал основу, я проверил и подключил Gravity UI для интерфейса. В итоге — рабочее приложение с простой кодовой базой, доступной в репозитории.
Цель примера — показать, что для фронтенд-разработчика, знакомого с Express, базовая интеграция с LLM не представляет особой сложности. Дальше можно наращивать: тулинг, контекст, продвинутые сценарии.
Четыре компонента интеграции
Для добавления ИИ в продукт фронтенд-разработчику понадобятся четыре вещи:
- UI-кит — компоненты для чат-интерфейса.
- API SDK — библиотека для общения с LLM.
- Тулинг — механизм, позволяющий модели вызывать функции и получать данные.
- Контекст — данные и состояние приложения, передаваемые модели.
UI-кит: интерфейс для чата
Антон Непша сделал хороший обзор UI-китов для создания ИИ-агентов: AI Elements от Vercel, Assistant UI, prompt-kit, shadcn-chatbot-kit.
Но не все одинаково удобны. Решение от Vercel, например, оказалось перегруженным: много слоёв абстракции, проблемы совместимости с опенсорс-моделями, недостаточная гибкость. При выборе важна не только функциональность, но и сложность интеграции.
Мы используем AIKit от команды Gravity UI. У него проработанный визуал, корректная отрисовка ответов, встроенная история вызовов. Не нужно вручную подключать обработку markdown или расширения вроде GFM для таблиц. Кстати, мой коллега Илья Ломтев уже писал о нём на Хабре.
Сейчас AIKit внедряется во все продукты Yandex Cloud, включая консоль и SourceCraft. Он будет активно развиваться и получать функциональность, нужную разным командам.
В моём демо доступна версия с AIKit — она заметно симпатичнее. Эта версия лежит в отдельной ветке.
API SDK: общение с моделью
Когда OpenAI предложили модель через API, это стал поворотный момент. Локальное развёртывание LLM оказалось слишком дорогим — и появился единый сетевой интерфейс, на основе которого разработчики строят продукты.
Сегодня провайдеров много, но большинство ориентируются на совместимость с OpenAI API. Поддержка есть и в Yandex AI Studio. Смена baseURL позволяет использовать Mistral, Groq, Fireworks, Ollama, Together, xAI и другие. Для разработчика это значит: один клиент — много моделей.
Рынок снова присматривается к Anthropic API — во многом благодаря популярности Claude Code и желанию провайдеров привлечь его пользователей. Но в целом OpenAI API доминирует.
Во многих туториалах сразу предлагают LangChain. Это мощный инструмент с реализациями на Python, JavaScript/TypeScript, Java, Go, .NET. Но начинать с него, на мой взгляд, не стоит. Это слишком высокоуровневая абстракция, которая скрывает детали. Дебажить сложно — часто требуются отдельные инструменты вроде LangSmith.
Начинать с LangChain — как изучать веб-разработку с React. Сначала стоит понять, как всё работает на уровне API. LangChain и аналоги — для более зрелых проектов.
Возьмём OpenAI SDK для Node.js. Минимальный пример:
Создаём клиент, передаём массив сообщений. system задаёт поведение модели, user — содержит запрос. Вся коммуникация строится как цепочка сообщений — на этом и основан Chat Completions API.
Ответ API включает usage с количеством токенов (полезно для логирования и контроля затрат) и choices с результатом. Забираем текст, отображаем в интерфейсе — чат готов.
Но без тулинга такая система — просто красивая обёртка над генерацией текста. Модель ничего не знает о данных в вашем продукте.
Тулинг: модель как агент
Тулинг — это механизм, позволяющий модели запрашивать информацию из приложения. Без него чат остаётся «голым» генератором текста. С тулингом система превращается в агента, способного взаимодействовать с данными.
В 2023 году OpenAI добавили в API возможность передавать модели список доступных функций. Теперь модель может явно сообщить: «Хочу вызвать эту функцию с такими параметрами». Аналогичный подход используется в MCP: разработчик описывает инструменты, а модель учится их вызывать.
В параметре tools передаём описание функций:
Описание — это JSON: название, назначение и параметры функции. Например: «У тебя есть функция getChartData, которая принимает массив ID чартов и возвращает их данные».
В ответ модель возвращает tool_calls — список функций, которые хочет вызвать.
Дальше — дело разработчика. Вызываем реальную функцию, получаем данные и возвращаем результат модели в сообщении с ролью tool.
Полный массив сообщений, который уходит модели на следующем шаге:
Получив данные, модель формирует осмысленный ответ. Объём зависит от модели — она может ограничиться парой предложений или развернуть полноценный анализ. Но не стоит питать иллюзий: модель — не калькулятор. Ей нельзя отдавать вычисления на откуп. Для полноценной аналитики нужна серьёзная обвязка из тулинга.
Responses API: что дальше
OpenAI представили новый Responses API и предлагают переходить к нему от Chat Completions. По их словам, старый API был спроектирован в сжатые сроки, но быстро стал основой для большинства интеграций с LLM. Буквально: в пятницу задизайнили, во вторник — уже в продакшене.
Эволюция OpenAI API отражает рост потребностей разработчиков:
- Первое поколение — простая схема «запрос → ответ».
- Второе поколение — Chat Completions, адаптированный под диалог.
- Третье поколение — Responses API, заточенный под агентные сценарии.
Responses API встраивает RAG, function calling, поиск — всё, что раньше приходилось собирать вручную. Для фронтенд-разработчика это упрощает жизнь: нужен BFF на Express, обращение к API, а остальная магия — внутри.
Есть нюанс: передача данных стороннему провайдеру означает, что информация хранится вне вашего периметра. Для продуктовых решений это не всегда приемлемо. Но концепция «агентность по умолчанию» набирает обороты и снижает порог входа.
Контекст: память для модели
У LLM нет памяти. Она опирается только на то, что передано в запросе. Если отправить два сообщения по отдельности — сначала представиться, потом спросить «как меня зовут?» — модель не ответит.
Поэтому в каждом запросе нужно передавать историю переписки. Но на практике одной истории мало. Для нормальной работы ИИ-функциональности модели нужен более широкий контекст.
Проблема в том, что контекстное окно ограничено: 128–256 тысяч токенов, у некоторых — до миллиона. Но даже при большом окне модели не всегда эффективно используют весь объём — они фокусируются на части данных. Возникает задача: какие фрагменты передавать, а какие отбросить?
В DataLens Editor значимым контекстом становится не только чат. Модели нужно знать о коде пользователя, результатах выполнения, ошибках в консоли. Всё это живёт на клиенте — и это территория фронтенда.
Вот что делает управление контекстом сложной задачей:
- Данные могут быть огромными. Микротаблицу легко уложить в контекст. В реальности данные разбиты на страницы, и передать их целиком зачастую невозможно.
- Модели плохо считают. Если дать LLM большой массив чисел и попросить посчитать среднее — нет гарантий, что учтёт все данные. Точные вычисления нужно делать на стороне приложения.
- Контекст быстро растёт. С каждым сообщением и вызовом инструмента объём передаваемых данных увеличивается.
Степень участия бэкенда зависит от архитектуры. Если логика на сервере — часть задач можно делегировать ему. Но клиентский контекст — код, состояние интерфейса, результаты выполнения — доступен только фронтенду. Поэтому даже при классической архитектуре фронтенд-разработчикам приходится самостоятельно управлять этим объёмом. В крупных приложениях обработка контекста становится отдельной инженерной задачей.
С развитием продукта неизбежно появляются задачи для бэкенда: фоновые операции, взаимодействие с клиентом через API. Но реализовать их будет проще, если перед глазами уже есть работающая фича на клиенте.
Работы хватит всем
Базовая интеграция складывается из четырёх компонентов — интерфейс, SDK, тулинг, контекст — и этого достаточно для работающего приложения. Область работы с LLM остаётся новой и быстро развивающейся.
Здесь много серьёзных задач: управление контекстом, проектирование ИИ-интерфейсов, стриминг, function calling. Форматы взаимодействия тоже меняются: ещё недавно все сидели в IDE, а сейчас набирают популярность консольные агенты. Пространство для работы только расширяется.
Фронтенд-команда может взять на себя интеграцию с LLM и получить продуктовый результат с понятной архитектурой, знакомым стеком и готовыми SDK. По мере роста продукта подключатся и бэкендеры — для фоновых операций, масштабирования и глубокой интеграции.
Мы всё ещё в начале пути. Не знаем, куда всё повернёт завтра. Интерфейсы меняются, модели становятся мощнее, а то, что вчера казалось экспериментом, сегодня уже в продакшене. На этом этапе неважно, где — главное делать: пробовать, ломать, проверять гипотезы. Инструменты уже есть, порог входа ниже, чем кажется, и работы действительно хватит всем.