PostgreSQL, Airflow, JupyterLab, MinIO, Superset, шесть MCP-сервисов и локальная модель Ollama в одном воспроизводимом Docker Compose-стенде.
Зачем понадобился этот проект
В учебных проектах по инженерии данных компоненты часто существуют отдельно: SQL-задания — в одной папке, ноутбуки — в другой, оркестратор запускается сам по себе, а демонстрация LLM не связана с результатами расчётов. Мне хотелось собрать цельный стенд, в котором один набор данных проходит полный путь:
-
исходные записи загружаются в PostgreSQL;
-
Airflow обновляет аналитические витрины и выполняет проверки качества;
-
Jupyter-ноутбуки воспроизводят ETL-, логистический и ML-сценарии;
-
сформированные Parquet-файлы сохраняются в MinIO;
-
операции с платформой становятся доступны через MCP-инструменты;
-
локальная языковая модель поясняет уже рассчитанные метрики, не подменяя собой вычисления.
Так появился демонстрационный проект MCP-pro-Github. Он работает на синтетических данных о добыче, телеметрии скважин, отказах оборудования и логистике, поэтому его можно запускать и показывать без доступа к производственным системам.
Что находится внутри
Стенд собирается через Docker Compose и объединяет следующие компоненты.
|
Компонент |
Роль в проекте |
|---|---|
|
PostgreSQL 15 |
Исходные таблицы, аналитические витрины, метрики и LLM-пояснения |
|
Airflow 2.9.1 |
DAG |
|
JupyterLab |
ETL-, логистический и ML-ноутбуки |
|
MinIO |
Локальное S3-совместимое хранилище Parquet-артефактов |
|
Superset |
Интерфейс для ручного подключения источника и построения визуализаций |
|
Ollama |
Локальный запуск модели |
|
MCP-сервисы |
Инструменты для работы с БД, качеством данных, мониторингом, Airflow и Superset |
|
LLM agent |
Пояснение рассчитанных метрик и сохранение результата в PostgreSQL |
Упрощённо поток выглядит так:
Jupyter / ETL ───► PostgreSQL ───► аналитические витрины └────────► MinIO └──► метрики мониторингаMCP-клиент ───► MCP-сервисы ───► PostgreSQL / Airflow / SupersetLLM agent ───► Ollama └────────► PostgreSQL (сохранённые пояснения)
Данные и конвейер Airflow
В PostgreSQL разворачивается схема с синтетическими таблицами производства, поставок и отказов. На их основе строятся витрины для дальнейшего анализа.
DAG oil_pipeline состоит из двух последовательных задач:
-
refresh_martsсоздаёт и пополняет витрины производства и логистики; -
data_qualityрассчитывает долю пропусков давления и количество выбросов по объёму добычи.
Повторный запуск не должен дублировать уже перенесённые записи: загрузка сопоставляет ключевые поля исходных таблиц и витрин.
Три воспроизводимых ноутбука
В JupyterLab находятся три самостоятельных сценария.
ETL pipeline
Ноутбук читает исходные таблицы, выполняет преобразования, формирует витрины и выгружает результат в PostgreSQL и MinIO. В конце выполняются проверки: ожидаемые имена объектов должны присутствовать в бакете.
Logistics pipeline
Сценарий анализирует поставки, задержки и связанные с ними показатели, а затем сохраняет итоговый Parquet-артефакт.
ML and anomaly-detection pipeline
Ноутбук обучает детерминированную базовую модель на синтетических данных, формирует прогнозы и признаки аномалий, сохраняет результат в PostgreSQL и MinIO. Это демонстрация инженерного конвейера, а не заявка на качество производственной модели: финальные ячейки проверяют число строк и наличие созданных артефактов.
Такой формат удобен для проверки: пользователь запускает ячейки сверху вниз и видит не только графики, но и явное сообщение check passed.
Зачем здесь MinIO
PostgreSQL хранит структурированные данные и результаты запросов, а MinIO — файловые артефакты конвейеров. В приватном бакете oil-data появляются витрины и ML-результаты в формате Parquet.
Это разделяет два вида хранения и одновременно позволяет отработать S3-совместимый интерфейс локально. В демонстрации можно проверить не только факт выполнения Python-кода, но и появление конкретных файлов.
Шесть MCP-сервисов
MCP в проекте используется как единый интерфейс к ограниченным операциям платформы. Каждый сервис отвечает за свой набор инструментов.
|
MCP-сервис |
Доступные операции |
|---|---|
|
|
список таблиц и описание схемы |
|
|
число строк, доля пропусков и сводный отчёт о качестве |
|
|
размеры таблиц, health score, метрики и корреляции |
|
|
список DAG, состояние и создание запуска DAG |
|
|
проверка health endpoint и доступности главной страницы |
|
|
запуск |
Контейнер mcp_agents поднимает эти сервисы во внутренней Docker-сети. Smoke test подключается к каждому из них, запрашивает список инструментов и подтверждает, что все шесть интерфейсов инициализированы.
Важно точно описать роль оркестратора. Инструмент run_pipeline создаёт запуск oil_pipeline через Airflow API и возвращает идентификатор запуска вместе со статусом витрин. platform_status выдаёт компактную сводку готовности основных агентов. То есть это практический слой управления конкретным конвейером, а не универсальный планировщик произвольных действий.
Где используется локальная модель
Языковая модель подключена к двум рассчитанным корреляциям:
-
между задержкой доставки и стоимостью;
-
между давлением в скважине и объёмом добычи.
Сначала обычный Python-код определяет знак метрики, формирует статистическую интерпретацию и уровень уверенности по размеру выборки. Только после этого Ollama получает ограниченный запрос: добавить две короткие строки — осторожный бизнес-контекст и конкретный шаг проверки.
Такое разделение принципиально для воспроизводимости. Число, направление связи и предупреждение о том, что корреляция не доказывает причинность, формируются детерминированно. LLM отвечает только за краткий комментарий. Итог сохраняется в таблицу monitoring_explanations, поэтому результат можно проверить SQL-запросом.
Как запустить проект
Понадобятся Docker Desktop с Docker Compose v2, Unix-подобная оболочка и ресурсы для нескольких контейнеров. Для полной LLM-проверки дополнительно загружается локальная модель Ollama.
git clone https://github.com/irina-probono/MCP-pro-Github.gitcd MCP-pro-Github./scripts/init-env.shdocker compose config --quietdocker compose up -d --builddocker compose ps
init-env.sh создаёт локальную конфигурацию для совместного запуска сервисов. Фактические адреса интерфейсов показывает docker compose ps.
Проверить инициализацию MCP-сервисов можно одной командой:
docker compose exec mcp_agents python mcp/smoke_test.py
Для LLM-сценария модель загружается отдельно:
docker compose exec ollama ollama pull qwen2.5:1.5bdocker compose exec llm_agent python server.py --demo
Как я проверяла воспроизводимость
В репозитории есть два уровня автоматизированных проверок.
static-check.sh проверяет синтаксис Python- и shell-файлов, структуру ноутбуков и ожидаемый состав проекта:
./scripts/static-check.sh
preflight.sh создаёт временную копию проекта, генерирует отдельную конфигурацию, собирает контейнеры и последовательно проверяет DAG, ETL, MCP smoke test и три ноутбука:
./scripts/preflight.sh
Полный вариант также загружает модель и запускает LLM-сценарий:
PREFLIGHT_WITH_LLM=1 ./scripts/preflight.sh
Изолированный запуск полезен тем, что проверяет именно содержимое проекта, а не случайно сохранившееся состояние предыдущих контейнеров. После автоматических тестов интерфейсы можно оставить запущенными для ручного просмотра, а затем удалить временное окружение штатным скриптом очистки.
Что получилось
Проект объединяет полный демонстрационный путь данных: от SQL-схемы и ETL до оркестрации, файловых артефактов, MCP-инструментов и локального пояснения метрик. Все компоненты можно запустить на одном компьютере, а ожидаемые результаты описаны в README и подтверждаются автоматическими проверками.
Для меня главными выводами стали три вещи:
-
интеграционный проект ценен не количеством контейнеров, а проверяемой связью между ними;
-
LLM полезнее ставить после детерминированного расчёта и явно ограничивать её роль;
-
воспроизводимый preflight-сценарий и понятные ожидаемые результаты делают техническую демонстрацию значительно убедительнее.
Репозиторий проекта: MCP-pro-Github.
ссылка на оригинал статьи https://habr.com/ru/articles/1064802/