Seidr Studio

Студия анализа SQL-зависимостей. Загрузите код — получите интерактивный граф происхождения данных, impact-анализ и ассистента, который отвечает фактами из графа, а не догадками.

Ниже — как это устроено внутри. Не маркетинг, а механика: что делает каждый слой, на каких алгоритмах, где границы.

Конвейер: от текста SQL к графу

SQL-файлы → Hound (ANTLR4) → атомы → граф (YGG/Ygg.db) → Loom / Knot / Mimir / Anvil

Один проход разбора превращает текст в типизированный граф. Дальше с этим графом работают четыре инструмента: Loom рисует, Knot инспектирует, Anvil считает последствия, Mimir отвечает на вопросы.

Что этим решают — сценарии

Граф зависимостей нужен не сам по себе, а под конкретные задачи. Что Seidr Studio закрывает сегодня:

  • Impact перед изменением схемы. «Что сломается, если изменить или удалить таблицу/колонку?» — Anvil проходит по графу и отдаёт список затронутых процедур и запросов; Mimir отвечает на это словами. Оценка последствий — за секунды, а не за часы ручного разбора.
  • Поиск причины сломанных данных. «Откуда пришла эта цифра?» — трассировка происхождения вверх по колонкам до источника. Виден весь путь, а не только соседний слой.
  • Поиск сирот и неиспользуемого. Таблицы и колонки, в которые никто не пишет или из которых никто не читает, — кандидаты на чистку перед миграцией.
  • Свободное исследование. Незнакомый корпус: drill-down по уровням, фильтры, поиск — понять схему без созвонов и grep по репозиторию.
  • Превью безопасности разбора. Прогон парсинга без записи в граф — посмотреть, что извлечётся, прежде чем фиксировать.

В развитии (roadmap), честно: сравнение версий графа для ревью PR / веток; отслеживание PII по графу; пошаговый план миграции. Пока не готово — говорим прямо.

1. Загрузка и разбор (Hound)

Загрузите файлы — отдельными .sql / .pck или одним ZIP-архивом.

Разбирает их Hound — парсер на ANTLR4. Не регулярки, не эвристики: настоящая грамматика строит синтаксическое дерево (AST), а семантический слой извлекает из него зависимости вплоть до колонок.

Что под капотом:

  • 18 диалектных грамматик в составе парсера (PL/SQL, PostgreSQL, ClickHouse, Greenplum, T-SQL, MySQL, Snowflake, Trino и др.).
  • Семантические listener'ы — для трёх диалектов: PL/SQL (production), PostgreSQL и ClickHouse (beta). Грамматика без семантического listener'а разбирает синтаксис, но не строит граф зависимостей — поэтому «поддержка диалекта» и «наличие грамматики» это разные вещи. Полный честный статус — на странице Диалекты SQL.
  • Точность: 99.93% разбора на 78 файлах синтезированного Oracle PL/SQL-корпуса (255 580 строк; валидные файлы, сгенерированы; ERP).

Разбор корпуса в несколько тысяч файлов занимает от секунд до минут — зависит от объёма, не от регистрации (её нет).

2. Модель графа

Результат разбора — не картинка, а типизированный граф в Ygg.db. На нём держится всё остальное.

Вершины (≈26 типов) описывают структуру кода:
DaliApplication → DaliDatabase → DaliSchema → DaliPackage → DaliRoutine → DaliStatement → DaliAtom, плюс DaliTable, DaliColumn, DaliOutputColumn, DaliJoin, DaliParameter, DaliVariable, DaliCursor, DaliRecord, иерархия ограничений (DaliConstraintDaliPrimaryKey / DaliForeignKey / …).

Рёбра (свыше 60 типов, сгруппированы в таксономию) описывают связи:

  • Структура: CONTAINS_SCHEMA, CONTAINS_TABLE, HAS_COLUMN, CONTAINS_ROUTINE, CONTAINS_STMT.
  • Поток данных (таблицы): READS_FROM, WRITES_TO.
  • Поток данных (колонки): DATA_FLOW, FILTER_FLOW, ATOM_PRODUCES.
  • Разрешение ссылок: ATOM_REF_COLUMN, ATOM_REF_TABLE, ATOM_REF_PARAMETER, ATOM_REF_VARIABLE, ATOM_REF_FUNCTION, ATOM_REF_SEQUENCE.
  • Вызовы: CALLS.

Атомы — как строится колоночная связность

Атом (DaliAtom) — это атомарная ссылка в выражении SQL: колонка, функция, переменная, константа, обращение к последовательности. Каждый атом классифицируется при разборе (RESOLVED / UNRESOLVED / CONSTANT / FUNCTION_CALL …) и привязывается к источнику.

Из атомов рождается колоночная связность: для разрешённого атома, который участвует в выходной колонке оператора, строится ребро DATA_FLOW от исходной колонки к выходной. Так на запросе

CREATE VIEW sales AS
SELECT customer_id, SUM(amount) AS total
FROM orders WHERE status = 'paid'
GROUP BY customer_id;

появятся: orders.customer_id → sales.customer_id (прямой поток), orders.amount → sales.total (агрегат), а orders.status уйдёт в FILTER_FLOW. Это и есть «откуда берётся цифра» — на уровне колонки, а не таблицы.

3. Граф зависимостей (Loom)

Loom — интерактивный холст. Граф не статичен: каждый узел раскрывается, каждая связь прослеживается до источника.

Четыре уровня детализации

Переключение между уровнями — в один клик, с хлебными крошками и возвратом на любой шаг.

УровеньЧто показывает
L1 — ОбзорПриложения → Базы → Схемы. Агрегированная иерархия: сколько в каждой схеме таблиц и процедур. Точка входа.
L2 — СхемаДва режима (переключатель AGG ↔ EXP): агрегат «процедуры + таблицы» либо детальный разбор операторов внутри схемы.
L3 — Область процедуры/пакетаВсе операторы внутри процедуры/пакета, их вход/выход по таблицам и колоночный путь.
L4 — Дерево оператораОдин оператор целиком: подзапросы, CTE, поток в выходные колонки.

Уточнение для тех, кто видел старые тексты: уровней четыре (L1–L4). L4 — это дерево одного оператора, а не «атомы».

Фильтры

Граф большого корпуса нечитаем без фильтров. На L2/L3 доступны:

  • Глубина обхода — слайдер 1 / 2 / 3 / 5 / 7 / ∞ от стартового узла.
  • Направление — вверх (источники ↑) и/или вниз (потребители ↓), независимо.
  • Точечные фильтры — оставить только пути через конкретную таблицу, оператор, колонку или процедуру.
  • Уровень детализации рёберtableLevelView (только таблицы, без колоночных рёбер) — авто-включается на графах > 500 узлов; отдельный тумблер колоночных рёбер.
  • Внешние связи — включать ли межсхемные READS_FROM/WRITES_TO (по умолчанию область ограничена текущей схемой).
  • Происхождение связи — все / только статические (из кода) / только рантайм (из OpenLineage) / оба.

На L1 — свой набор: глубина иерархии (скрыть базы/схемы), направление, системные объекты, каскад «выбрал базу → видны её схемы».

Поиск, подсветка, раскладка

  • Поиск — по таблицам, колонкам, процедурам, пакетам, операторам, схемам. Серверный индекс, от 2 символов; клик по результату прыгает на нужный уровень с восстановлением контекста.
  • Подсветка при наведении — наводите на узел, подсвечиваются он и его прямые соседи (1 hop), остальное гаснет. Работает на L2–L4, отключается на больших графах (> 600 узлов), чтобы не тормозить.
  • Раскладка — ELK.js, layered, поток слева направо. Стратегия адаптируется к размеру: на плотных графах (много рёбер на узел) — stress-раскладка, на очень больших (> 1800 узлов) — сеточный fallback.

4. Инспектор (Knot)

Knot разбирает результат парсинга сессии по полочкам — шесть вкладок:

ВкладкаЧто внутри
SummaryМетрики сессии: число таблиц, колонок, схем, пакетов, параметров; разбивка операторов (SELECT/INSERT/UPDATE/DELETE/MERGE/…); доля разрешённых атомов.
StructureИерархия таблиц с поиском; по таблице — список колонок и какие операторы её читают/пишут.
RoutinesПроцедуры и пакеты; внутри — операторы (тип, строка), входящие вызовы, параметры, переменные.
StatementsДерево операторов (вложенность); по оператору — фрагменты, атомы, выходные и затронутые колонки.
AtomsРазрешённые атомы со статусом и типом источника (TABLE / STMT / CURSOR), фильтр по статусу разрешения.
SourceИсходный SQL с номерами строк и переходом к строке.

5. Impact-анализ (Anvil)

Клик на таблицу или колонку — и видно всё, что её трогает. Считает это Anvil обходом графа.

  • Impact идёт по рёбрам ATOM_REF_COLUMN + DATA_FLOW + FILTER_FLOW, переменная глубина (по умолчанию 5 переходов, до 10), направление вверх/вниз. Результат ограничен 500 узлами (дальше — флаг «есть ещё»), кэш на 5 минут на тенант.
  • Трассировка происхождения идёт строго по DATA_FLOW (чистая колоночная связность), до 15 переходов, поддерживает оба направления сразу.

Это заменяет ручной поиск по кодовой базе: вместо grep и созвонов — ответ за секунды, с путём до источника.

6. Ассистент (Mimir)

Задайте вопрос на русском — Mimir идёт в граф и возвращается с фактом. Он не угадывает: вызывает реальные инструменты анализа.

«Что сломается, если удалить колонку STATUS из таблицы ORDERS?»
«Какие процедуры пишут в BALANCE?»

Как это работает. Mimir — это tool-calling агент с девятью инструментами над графом: поиск узлов, описание колонок таблицы, исходник процедуры, подсчёт таблиц/процедур в схеме, ad-hoc read-only запрос (SQL/Cypher с принудительным LIMIT), подсчёт зависимостей, плюс делегирование в Anvil за impact и трассировку происхождения. Модель видит сигнатуры инструментов, вызывает нужные, собирает контекст и отвечает — с подсветкой релевантных узлов на холсте. Ассистент знает текущий контекст Loom (уровень, область, выбранный узел) и учитывает его в ответе.

Где работает модель — два режима, честно:

  • Локальная или открытая модель — через Ollama, в вашем контуре. Данные о схеме не покидают периметр — режим для закрытого контура и требований 152-ФЗ.
  • Облачная модель — опция для скорости, без локальных требований к железу.

Память диалога — пер-тенант, изолирована. Для дорогих или потенциально разрушительных запросов предусмотрен необязательный режим подтверждения (Human-in-the-Loop).

7. История изменений схемы

Граф пишется append-only — ничего не стирается. Каждая версия таблицы, колонки, процедуры хранится со своим интервалом действия (datefrom/dateto) и хэшем содержимого для обнаружения изменений (SCD Type 2).

Можно отмотать назад и увидеть, как схема выглядела вчера, месяц назад, до рефакторинга. Снепшоты состояния хранит FRIGG. История — не настройка, которую можно забыть включить. Это архитектура.

Безопасность и доступ

  • Работа в вашем контуре: on-premise, в on-prem поставке — без внешних вызовов.
  • Командный доступ — роли и тенанты через Heimdallr. Изоляция тенантов на уровне отдельных баз.
  • Подробнее — Безопасность и соответствие.

С чего начать