Mission control для флота AI-агентов

К моменту, когда мы построили торговый Mini App, бот привлечения и AI-агентов-персон, у операционной команды клиента появилась новая проблема: они управляли всем через терминальные окна и прямые запросы к базе. Запустить агента означало SSH на сервер. Посмотреть разговор — запрос в PostgreSQL. Поменять поведение персоны — отредактировать конфиг и рестартануть процесс. Система работала, но была непрозрачной — управлять ей могли только мы. Клиенту нужна была панель управления, которая запихнула бы всю операцию в одно окно браузера.

Стек

  • Next.js 16
  • FastAPI
  • PostgreSQL
  • Redis

управление агентами

Мы построили полнофункциональную админ-панель с аутентификацией через JWT. Её ядро — управление агентами: операторы могут создавать и редактировать определения персон — личностные черты, границы знаний, стиль разговора, запрещённые темы — и видеть отражение этих изменений в работающих агентах без переразвёртывания. У каждого Telegram-аккаунта, используемого агентами, своя статус-карточка с показателями здоровья сессии, последней активностью и метаданными профиля. Из того же интерфейса операторы могут запускать, останавливать или ставить на паузу любой процесс агента. Под капотом эти команды процессам идут через Redis — фронт на Next.js бьёт в эндпоинт FastAPI, который публикует команду в канал Redis, на который подписан Python-раннер агента. Агент отвечает, и UI обновляется через WebSocket в течение одной-двух секунд.

просмотрщик чатов в реальном времени

Просмотрщик чатов в реальном времени стал фичей, которой операционная команда пользуется чаще всего. Он показывает все идущие разговоры агентов в реальном времени — каждое сообщение, с обеих сторон, по мере появления. Операторы могут фильтровать по агенту, по пользователю, по статусу разговора. Когда что-то выглядит не так — агент уходит от темы или высокоценный пользователь задаёт сложные вопросы, — оператор может перехватить разговор прямо из панели. Технический вызов здесь — fan-out: при десятках агентов, ведущих одновременные разговоры, слой WebSocket должен эффективно пушить обновления всем подключённым админ-клиентам. Мы использовали модель pub/sub на Redis, где каждое новое сообщение публикуется однажды, и каждый подключённый WebSocket-клиент, подписанный на нужные каналы, его получает. Просто, но эффективно — время загрузки страницы админки остаётся под двумя секундами даже при сотнях активных разговоров.

кампании и аналитика

Трекинговые ссылки — фича, которую клиент попросил для атрибуции кампаний. Панель генерирует короткие URL в формате `/go/{code}` — публичный эндпоинт редиректа, который логирует клик (реферер, таймстемп, UTM-параметры), прежде чем отправить пользователя на адрес назначения. Аналитический дашборд показывает счётчики кликов, уникальных посетителей и конверсию по ссылкам. Поскольку эндпоинт редиректа публичный и привязан к маркетинговым кампаниям, он периодически держит всплески трафика, превышающие обычную нагрузку на админку. Мы держали обработчик редиректа максимально тонким — один insert в базу и HTTP 302 — с пулом соединений, настроенным так, чтобы не стать узким местом. Агрегация аналитики идёт по отдельному пути чтения, чтобы отчётные запросы никогда не тормозили редиректы.

Дашборд статистики каналов завершает операционную картину — рост подписчиков, активность сообщений и метрики вовлечённости, подтянутые из API Telegram и отрисованные через Recharts. Сам UI построен на Next.js с компонентами Radix UI и Tailwind — намеренно минималистичен и функционален. Операционной команде не нужны анимации и модные переходы — нужна плотность информации и быстрая навигация. Каждая таблица сортируется, каждый список ищется, и вся панель работает на планшете, потому что команда иногда мониторит агентов с телефонов.

инструменты воронки и компромиссы

Управление пользователями для бота-воронки тоже здесь — операторы видят, где каждый пользователь в воронке привлечения, какие сообщения он получил и сконвертился ли. Это read-heavy представление, время от времени требующее ручного вмешательства: вернуть пользователя на шаг назад, переотправить сообщение или пометить аккаунт. Честное архитектурное напряжение в этом проекте: админ-панель мостит два мира — фронт на Next.js и Python-экосистему бэкенда. Каждая операция с агентом пересекает эту границу через Redis, что работает чисто, но означает, что отладка проблем требует переключения контекста между двумя кодовыми базами и двумя ментальными моделями. Если бы начинали заново, мы бы рассмотрели единый рантайм — но компромисс был приемлемым, учитывая, что каждый кусок строился инкрементально по мере роста платформы.