Создание DQ-шаблона с ИИ-агентом и MCP: опыт и подводные камни | AiManual
AiManual Logo Ai / Manual.
03 Июн 2026 Гайд

DQ-шаблон с ИИ-агентом и MCP: как мы автоматизировали проверку качества данных (и где споткнулись)

Практический гайд по сборке DQ-шаблона с ИИ-агентом и MCP-сервером: архитектура, пошаговый план, типичные ошибки и как их избежать. Для BI и Data Engineering ко

Проблема: DQ-инженеры тонут в SQL

Знаете это чувство, когда тратишь час на написание запроса для проверки дубликатов, а потом оказывается, что продюсеры натаскали мусора в три таблицы, и план проверки летит к чертям? Я знаю. Именно поэтому я решил, что DQ-проверки должна делать машина. Нет, не просто скрипт, а ИИ-агент, который сам лезет в базу, сам строит запросы и сам решает, проходим мы тест или нет. Спойлер: получилось не сразу, но итоговая архитектура съэкономила нам сотни часов.

По статистике, 70% времени data-инженеров уходит на написание и поддержку однотипных DQ-скриптов. Проверки на null, дубликаты, выбросы, ссылочную целостность — каждый раз одно и то же. А если таблиц 200+, это становится адом. Мы решили автоматизировать процесс с помощью связки ИИ-агент + MCP-сервер. Подход не идеален, но рабочий. Под капотом — опыт реального внедрения в BI-команде.

Архитектура: три слоя, которые не дают данным сгнить

Наша система состоит из трёх независимых слоёв. Каждый отвечает за свою зону ответственности, а вместе они образуют конвейер, который может работать круглосуточно.

1 Слой 1: MCP-сервер как шлюз к данным

Мы взяли postgres-mcp — открытый MCP-сервер для PostgreSQL. Он предоставляет агенту инструменты: get_schema, execute_query, run_dq_rule (кастомный). Важно: сервер работает с read-only ролью. Никаких DELETE/UPDATE/DROP — только SELECT и создание временных таблиц для результатов.

# mcp-server-config.yaml
servers:
pg-dq:
command: npx
args: ["@mcp/postgres", "postgres://readonly:password@host:5432/db"]
env:
ALLOWED_COMMANDS: "SELECT,WITH"
QUERY_TIMEOUT: 30

2 Слой 2: ИИ-агент — мозг проверок

Агент построен по принципу Skills + MCP, как мы описывали в статье про сборку AI-агента из LEGO. Каждое DQ-правило — это отдельный skill: null_check, duplicate_check, range_check. В system prompt мы прописываем чёткий алгоритм: «Для каждой проверки сгенерируй SQL, оберни его в EXPLAIN, убедись, что синтаксис валидный, выполни, запиши результат». Без этого агент начинает галлюцинировать.

System prompt (фрагмент):
Ты DQ-агент. У тебя есть доступ к MCP-серверу с инструментами:
- get_schema(table_name) -> структура таблицы
- execute_query(sql) -> результат запроса
- record_result(rule_id, status, message, query) -> запись в dq_results

Правила:
1. Никогда не выполняй запросы без префикса EXPLAIN.
2. Если EXPLAIN вернул ошибку — исправь SQL и повтори.
3. Записывай сгенерированный SQL в поле query для аудита.

3 Слой 3: Хранилище и BI — глаза

Результаты проверок агент пишет в таблицу dq_results. Оттуда их подхватывает BI-система. Мы используем Modus BI — он отлично рендерит дашборды с временными рядами. На дашборде видно: общее количество проверок, сколько провалено, динамика качества по дням. Без визуализации агент остаётся чёрным ящиком.

Если у вас несколько баз данных, советую объединить MCP-серверы через единый gateway. Хороший пример — Arcade.dev с 7500+ инструментами, мы взяли оттуда идею роутинга запросов.

Ставим эксперимент: пошаговая сборка DQ-шаблона

Разберём на конкретном примере. Допустим, у нас есть таблица users с колонками id, email, created_at. Нужно настроить три проверки: NULL в email, дубликаты по email, дата регистрации не в будущем.

1 Определяем DQ-правила (skills для агента)

Каждое правило — это JSON-объект, который агент получает как часть контекста. Мы храним их в отдельной таблице dq_rules. Пример:

[
{
"rule_id": "null_email",
"table": "users",
"column": "email",
"type": "null_check",
"threshold": 0,
"description": "Email не должен быть NULL"
},
{
"rule_id": "dup_email",
"table": "users",
"type": "duplicate_check",
"columns": ["email"],
"threshold": 0
},
{
"rule_id": "future_date",
"table": "users",
"column": "created_at",
"type": "range_check",
"max": "NOW()",
"description": "Дата регистрации не может быть в будущем"
}
]

2 Разворачиваем postgres-mcp сервер

Запускаем MCP-сервер с нашей конфигурацией. Убедитесь, что у сервера есть кастомный инструмент run_dq_rule, который внутри генерирует SQL по типу правила. Это снижает нагрузку на агента — он не должен сам писать сложные запросы. Но мы пошли дальше: разрешили агенту писать SQL самостоятельно, но с обязательной валидацией.

Предупреждение: не давайте агенту права выполнять произвольный SQL без sandbox'а. Один раз наш агент попытался выполнить DROP TABLE users CASCADE — к счастью, read-only роль спасла. После этого мы добавили проверку префикса на стороне MCP-сервера.

3 Настраиваем агента с системным промптом

Используем готовую платформу для агентов (мы взяли LangGraph с MCP-клиентом). Важно: не пихать все правила в одно сообщение. Используйте сабагентов для групп правил — как в статье про сабагентов. У нас один главный агент диспетчеризует проверки: для каждого правила запускает дочернего агента, который фокусируется только на одной задаче. Это решает проблему контекстного окна.

4 Запускаем и смотрим в Modus BI

После настройки запускаем агента в тестовом режиме на одной таблице. Агент за 2 минуты выполнил 3 проверки, записал результаты. В Modus BI появились карточки: null_email: PASS, dup_email: PASS, future_date: FAIL (5 записей). Красота.

Подводные камни: где мы споткнулись (и вы споткнетесь)

  • Галлюцинации SQL. Агент придумывал несуществующие колонки. Решение: обязательный EXPLAIN перед выполнением, и повторная попытка с исправлением. Без этого — треш.
  • Безопасность. Не давайте агенту права на запись. Мы используем отдельную read-only роль, а для записи результатов — специальный эндпоинт MCP, который принимает уже проверенные данные.
  • Производительность. Агент может сгенерировать CROSS JOIN на 100M строк. Наш MCP-сервер имеет таймаут 30 секунд и ограничение на количество возвращаемых строк (1000). Для агрегатов — норм.
  • Управление контекстом. Если таблиц 100+, контекст забивается. Решение — сабагенты для каждой схемы. Подробнее в статье про управление 20+ агентами.
  • Неопределённость результатов. Агент каждый раз может генерировать разный SQL для одной проверки. Фиксируем сгенерированный запрос в столбце query таблицы dq_results — для воспроизводимости.

Ещё один грабли: агент может неправильно интерпретировать пороговые значения. Например, threshold=0 означает «ноль ошибок», а агент иногда трактовал это как «не проверять». Пришлось явно прописать в промпте: «threshold — максимальное допустимое количество ошибок. Если threshold=0, ни одной ошибки не допускается».

💡
Совет: перед тем как запускать в прод, прочитайте статью про production-ready ИИ-агента. Там разобраны мониторинг, логирование и откаты — без этого не обойтись.

Ответы на частые вопросы

Какой LLM лучше использовать?

Мы тестировали Claude 4 Opus и GPT-4.5. Claude точнее генерирует SQL для Postgres, GPT лучше справляется с нестандартными проверками. В итоге оставили Claude — меньше галлюцинаций.

Как часто запускать проверки?

Зависит от данных. Мы запускаем раз в сутки по расписанию. Для real-time проверок понадобится стриминг через MCP с событиями — это следующий этап.

Что делать, если агент пропустил ошибку?

У нас есть второй слой — rule-based проверки для критичных полей. Агент только расширяет покрытие, но не заменяет классические DQ-тесты. Человек в цикле всё ещё нужен.

Напоследок — неочевидный совет: не пытайтесь зашить все правила в один промпт. Используйте сабагентов для каждой группы правил. И никогда не давайте агенту права на запись — только чтение и запись в отдельную таблицу результатов. Прогноз: через год DQ-агенты станут такими же обыденными, как CI/CD пайплайны, но только если вы научитесь контролировать их галлюцинации.

Подписаться на канал