«Наэйай мне биай»: учим Apache Superset говорить по-человечески

В моей команде мы недавно разобрали одну до боли знакомую боль: между бизнес-вопросом и ответом на дашборде лежат две-три недели. Не потому что данные плохие, а потому что между «хочу понять, что с маржой в мае» и графиком стоит аналитик, очередь тикетов и десяток правок. Мы собрали AI-агента аналитики поверх Apache Superset с поддержкой MCP, который превращает запрос на естественном языке в готовый дашборд — и написали об этом подробную статью на Хабре.

Для меня это история ещё и личная. Большую часть карьеры до Raft я строил хранилища, BI и дата-пайплайны — прогнозы спроса для ритейла, витрины, ETL на Spark. И я хорошо помню, как выглядит «узкое горлышко аналитики» изнутри: не нехватка инструментов, а нехватка рук, которые переводят бизнес-вопрос в корректный SQL поверх правильной модели данных. Похоже, именно сюда LLM сейчас встают наиболее естественно.

Зачем вообще агент, если есть «LLM + база»

Соблазн понятный: дать модели доступ к базе и пусть пишет SQL. На практике это быстро ломается. Модель галлюцинирует имена колонок, не знает, что «выручка» у вас считается с вычетом возвратов, и спокойно делает запрос, который кладёт прод. Поэтому ключевая идея у нас не «LLM вместо аналитика», а LLM поверх семантического слоя Superset: датасеты, метрики и вычисляемые поля уже выверены под бизнес-логику. Агент не изобретает определения — он ими пользуется.

Архитектура: четыре слоя

Конструкция получилась прозрачной и состоит из четырёх слоёв:

Что здесь делает MCP

MCP (Model Context Protocol) — это мост, который превращает «модель, которая что-то знает» в «агента, который умеет действовать безопасно». Он отвечает за обнаружение инструментов и их спецификацию для LLM, даёт модели понимание семантического слоя, валидирует запрос против реальной схемы до выполнения и пускает SQL через governance-контур Superset, а не напрямую в базу. Приятный побочный эффект: нативная реализация MCP с умным поиском по инструментам сокращает контекст LLM примерно на 70% — а это и деньги, и скорость, и меньше шансов, что модель «утонет» в простыне доступных функций.

Как выглядит один проход

На запрос вроде «собери дашборд по датасету retail_clean» агент идёт по понятному сценарию: смотрит структуру через get_dataset_columns(), собирает преобразование данных через create_virtual_dataset(), проверяет качество через validate_dataset(), сам подбирает типы графиков и фильтры — и отдаёт интерактивный дашборд Superset с drill-down. По нашим замерам, end-to-end это 6–15 секунд и 4–7 вызовов инструментов на запрос.

Аналитик перестаёт «рисовать графики» и начинает делать то, ради чего его держат: проверять инсайты и проектировать метрики. Рутину забирает агент.

Безопасность — не постскриптум, а часть дизайна

Самое интересное (и самое недооценённое) — не «вау, оно строит графики», а то, как не дать ему построить что-нибудь не то. Мы заложили whitelist доступа к инструментам вместо blacklist, AST-валидацию (только SELECT, лимиты на строки), классификатор prompt-injection на входе, человеческое подтверждение для любых операций записи и аудит всех вызовов инструментов с долгим retention. Плюс — соглашение с провайдером модели о том, что данные не уходят в обучение. Без этого слоя «агент с доступом к данным» — это не продукт, а инцидент, который ещё не случился.

Мой практический вывод

Экономика тут считается легко: весь стек стоит заметно дешевле, чем держать отдельного человека только на ad-hoc-запросы, а решения, которые раньше зрели днями, сжимаются до минут. Но я бы предостерёг от ожидания «магии». Это работает ровно настолько, насколько хорош ваш семантический слой. Если метрики в Superset кривые или их нет — агент честно и быстро отдаст вам кривой ответ, просто на естественном языке. Так что главный, неромантичный вывод из всей этой работы простой: сначала наведите порядок в данных и определениях метрик, и только потом ставьте сверху агента. AI здесь — усилитель, а усиливает он то, что уже есть.

Полный разбор — в нашей статье на Хабре: «Наэйай мне биай»: как мы научили Apache Superset говорить по-человечески.

← ко всем записям