- BrainTools - https://www.braintools.ru -

Как LLM могут помочь определить Data Lineage

Как LLM могут помочь определить Data Lineage - 1

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

Приходится постоянно полагаться на традиционную документацию, спецификации по загрузке данных или Source‑to‑Target mapping‑файлы. Эти артефакты, как правило, быстро устаревают, не отражая актуальной логики преобразований, зашитой в ETL‑процессах и SQL‑коде. В результате необходимо вручную поддерживать актуальность такой документации, или, что ещё ресурсозатратнее, проведить реверс‑инжиниринг тысяч строк SQL‑кода хранилища данных для понимания реальных зависимостей. 

Эти проблемы обостряются в контексте постоянных изменений ИТ‑ландшафта, например, миграции в облако, замены устаревших систем‑источников (legacy systems) или интеграции новых платформ. И если нет понимания «жизненного цикла» данных, то это превращается в прямую угрозу для бизнес‑непрерывности. Критичной задачей становится безопасное и контролируемое переключение существующих решений — витрин, дашбордов и отчётов — на новые источники данных при строгом условии минимизации или полного исключения влияния на конечных потребителей.

Здесь на первый план выходит концепция Data Lineage. Это не просто инструмент для документирования пути данных от источника до конечного отчёта, а ключевой механизм управления изменениями. Data Lineage обеспечивает полную видимость всех исходных, промежуточных и итоговых объектов, позволяя точно оценить воздействие планируемой миграции, и даёт ответ на главные вопросы: 

  • Какие витрины и отчёты зависят от этого источника? 

  • Какие преобразования данных необходимо проверить или перенастроить?

  • Откуда в новой системе взять актуальные и корректные данные?

Мы рассмотрим, как с помощью применения больших языковых моделей (LLM) для автоматического анализа SQL‑кода и ETL‑логики извлечь точный Data Lineage.

Подход к решению

Итак, задача: есть SQL‑запрос (часто сложный, с подзапросами, CTE (общими табличными выражениями), объединениями), необходимо автоматически определить, какая таблица является целевой (target), а какие — источниками (sources). При этом требуется использовать полностью квалифицированные имена (схема.таблица), без алиасов и временных объектов, с корректной обработкой UNION ALL и вложенных подзапросов.

Для разработки и тестирования инструментария выбрали 127 скриптов [1] наполнения таблиц данных самой различной сложности. Этот набор использовали в академических целях для оценки точности извлечения Data Lineage. Скрипты охватывают широкий спектр конструкций SQL: от простых INSERT до сложных многоуровневых подзапросов, объединений UNION ALL, CTE и оконных функций. Это позволило всесторонне проверить возможности модели и алгоритма в условиях, приближенных к реальным промышленным хранилищам данных. Например, запрос:

INSERT INTO s_grnplm_vd_t_bvd_db_dmslcl.d_agr_cred_agr_collat_core  
SELECT t.agr_cred_id, t.agr_collat_id, t.start_dt, t.end_dt, t.info_system_id
  FROM ( SELECT a.agr_cred_id, a.agr_collat_id, a.start_dt,
            max(a.end_dt) OVER (PARTITION BY a.agr_collat_id, a.agr_cred_id, a.new_part ORDER BY NULL::text) AS end_dt, a.info_system_id, a.grp_rn
           FROM ( SELECT a_1.agr_cred_id, a_1.agr_collat_id, a_1.sta_1.info_system_id,
                    sum(
                        CASE
                            WHEN (a_1.grp_rn = 1) THEN 1
                            ELSE 0
                        END) OVER (PARTITION BY a_1.agr_collat_id, a_1.agr_cred_id ORDER BY a_1.start_dt) AS new_part,a_1.end_dt, a_1.grp_rn
                   FROM ( SELECT d_agr_cred_agr_collat.agr_collat_id,
                            d_agr_cred_agr_collat.agr_cred_id,
                            d_agr_cred_agr_collat.start_dt,
                            d_agr_cred_agr_collat.end_dt,
                            d_agr_cred_agr_collat.info_system_id,
                                CASE
                                    WHEN ((d_agr_cred_agr_collat.start_dt - 1) > max(d_agr_cred_agr_collat.end_dt) OVER (PARTITION BY d_agr_cred_agr_collat.agr_collat_id, d_agr_cred_agr_collat.agr_cred_id ORDER BY d_agr_cred_agr_collat.start_dt ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)) THEN (1)::bigint ELSE row_number() OVER (PARTITION BY d_agr_cred_agr_collat.agr_collat_id, d_agr_cred_agr_collat.agr_cred_id ORDER BY d_agr_cred_agr_collat.start_dt) END AS grp_rn FROM s_grnplm_vd_t_bvd_db_dmslcl.d_agr_cred_agr_collat) a_1) a) t
  WHERE (1 = t.grp_rn);

Ожидаемый результат: 

{"target": "s_grnplm_vd_t_bvd_db_dmslcl.d_agr_cred_agr_collat_core", "sources": ["s_grnplm_vd_t_bvd_db_dmslcl.d_agr_cred_agr_collat"]}

Выбор языковой модели играет важную роль в успешном извлечении Data Lineage из SQL‑запросов, так как он напрямую влияет на качество и применимость результатов. SQL имеет строгие правила построения запросов, например, использование ключевых слов, правильное расположение условий, соблюдение порядка операций. Универсальные LLM, ориентированные на обработку естественного языка, могут не справиться с этими требованиями, так как они не всегда способны корректно интерпретировать синтаксические конструкции и логику [2] запросов. Кроме того, SQL‑запросы зависят от определённой структуры базы данных (таблицы, столбцы, связи), поэтому модель должна уметь анализировать контекст и предлагать корректные JOIN‑условия, фильтры и агрегации.

Поэтому использование модели, предназначенной для генерации и анализе кода, позволяет значительно повысить точность результатов. Такие модели обучают на огромных корпусах программного кода, включая SQL, они глубоко понимают синтаксис, структуру и логику запросов. Доступность мощных API‑моделей, таких как GigaChat [3] от Сбера, открывает широкие возможности для их интеграции в прикладные задачи.

На основе GigaChat разработали класс SQLLineageExtractor [4], который использует LangChain [5] для взаимодействия с моделью и LangChain Expression Language (LCEL) для построения цепочек вызовов для форматирования промпта, передачи его в модель и парсинга результата в структурированный JSON. Основные компоненты:

  • GigaChat — класс из библиотеки langchain_gigachat, предоставляющий унифицированный доступ к моделям семейства GigaChat через API. Он поддерживает как синхронные, так и асинхронные вызовы, а также автоматическое управление токенами и таймаутами.

  • PydanticOutputParser — стандартный парсер LangChain, который преобразует ответ модели в структурированный JSON на основе Pydantic‑модели LineageOutput (содержит поля target и sources). Это гарантирует строгое соблюдение ожидаемого формата.

  • PromptTemplate — гибкий шаблон промпта, в который подставляются SQL‑запрос и инструкции по форматированию; при необходимости можно легко заменить шаблон на кастомный. Модель получает промпт с подробными инструкциями, включая правила определения target и sources, исключения, примеры. На выходе ожидается JSON вида: 

{"target": "schema.table", "sources": ["schema1.table1", "schema2.table2"]}

Для объективной оценки качества извлечения Data Lineage необходимо иметь эталонные результаты (ground truth) для тестовых SQL‑скриптов. Для этого создали класс RegexSQLExtractor [6], который извлекает Lineage с помощью регулярных выражений, ориентируясь на специфические именования объектов в нашем наборе данных (префикс s_grnplm). Этот класс позволил автоматически сформировать эталон для данного набора из 127 скриптов, исключив ручную разметку и обеспечив воспроизводимость эксперимента. 

Автоматическую проверку качества извлечения и сравнения с эталоном проводили на основе метрики F1:

  • P=TPTP+FP, если TP+FP > 0, иначе 0;

  • R=TPTP+FN, если TP+FN > 0, иначе 0;

  • F1=2*P*RP+R, если P+R > 0, иначе 0.

Где:

  • True Positive (TP) — источники, правильно найденные моделью;

  • False Positive (FP) — источники, ошибочно добавленные моделью;

  • False Negative (FN) — источники, пропущенные моделью.

Класс SQLLineageValidator [7] выполнял многоуровневую проверку результатов и вычислял стандартные метрики классификации. Метод run_comprehensive_validation выполнял комплексную проверку качества извлечения Data Lineage. Он работает так:

Как LLM могут помочь определить Data Lineage - 2

Методы проверки:

  • validate_output_format — проверяет, что результат является словарём с ключами target (строка) и sources (список);

  • validate_target_name — удостоверяется, что целевая таблица не пуста и имеет формат {schema}.{table};

  • validate_source_names — проверяет каждый источник на соответствие формату и отсутствие пустых значений;

  • validate_no_derived_tables — исключает наличие алиасов (например, t1, subquery_1) в списке источников, а также гарантирует, что целевая таблица не попала в источники;

  • validate_unique_sources — проверяет уникальность источников (удаление дубликатов);

  • validate_fully_qualified_names — убеждается, что все имена (target и sources) являются полностью корректными, то есть они соответствуют формату {schema}.{table}.

C базовым промптом базовая модель GigaChat показала точность со средней метрикой F1 = 0,7898, а GigaChat 2 Pro — F1 = 0,9218 [8]. Однако важно понимать, что качество результата напрямую зависит от того, насколько точно сформулирована инструкция — промпт. Его качество определяет, насколько точно модель поймёт, что от неё требуется. Если промпт дан расплывчато или противоречиво, то модель может «додумать» неверные подробности или выдать ответ в неподходящем формате.

Разработка качественной инструкции в данном случае — нетривиальная задача. Даже при подробном описании правил модель может систематически ошибаться: путать алиасы с реальными таблицами, включать временные объекты (CTE) в источники или пропускать таблицы из глубоко вложенных подзапросов. Ручная настройка промпта требует множества экспериментов. Для автоматизации этого процесса мы создали интеллектуальный агент GigaChatSQLLineageAgent [9] (GigaChatBatchLineageAgent — для обработки более одного SQL‑запроса), который самостоятельно должен был улучшить промпт, используя обратную связь от валидатора.

Агент сделали на основе фреймворка LangGraph [10] — библиотеки для создания Stateful, multiactor‑приложений с LLM. LangGraph позволяет представить процесс оптимизации как граф состояний, где каждый узел выполняет какое‑то действие, а переходы между узлами определяются логикой, основанной на текущем состоянии. Мы реализовали классический цикл validate → reflect → validate, который автоматически останавливается при достижении идеального качества или исчерпании попыток. Схематично:

Как LLM могут помочь определить Data Lineage - 3

Агент интегрирован с:

  • SQLLineageExtractor — для экстракции на каждой итерации. Перед запуском экстрактора его с помощью _ensure_query_placeholder обновляет новый промпт, гарантирующий наличие подстановочного шаблона {query}.

  • SQLLineageValidator — для получения объективных метрик и детализированных ошибок.

После нескольких итераций агента‑рефлексии [11] удалось сформировать промпт, с которым LLM давала минимальное количество ошибок экстракта и метрика F1 выросла до 0,9336. Это позволило перейти от экспериментов с промптами к практическому использованию инструмента для анализа реальных SQL‑скриптов. В целом архитектура рефлексии выглядит так:

Как LLM могут помочь определить Data Lineage - 4

Когда речь идёт о сотнях запросов и множестве взаимосвязей, анализировать результаты в виде JSON‑файлов с перечнем целевых таблиц и источников неудобно. Чтобы доступно и наглядно показать происхождение данных мы разработали веб‑интерфейс [12] на основе фреймворка Streamlit [13]. Интерфейс полностью интегрирован с ядром системы (SQLLineageExtractor) и позволяет как анализировать одиночные SQL‑запросы, так и пакетно обрабатывать множество скриптов с последующим исследованием зависимостей.

Веб‑приложение состоит из двух основных вкладок, доступных через верхнее меню:

  • «Single Query Lineage» — предназначена для быстрой проверки работы экстрактора на конкретном SQL. Пользователь видит большое текстовое поле, в которое можно ввести (или вставить) SQL‑запрос. По умолчанию там уже находится пример, чтобы сразу оценить функциональность.

    Как LLM могут помочь определить Data Lineage - 5
  • «Table Lineage (Batch)» — для загрузки нескольких файлов и глубинного анализа по таблицам. Эта вкладка позволяет загружать один или несколько файлов (форматы.sql или.txt), в каждом из которых может содержаться множество SQL‑запросов, разделённых точкой с запятой.

    Как LLM могут помочь определить Data Lineage - 6

На левой боковой панели расположены настройки подключения к модели: ключ авторизации запросов к API, выбор модели и прочие. Эти параметры используются для инициализации экземпляра SQLLineageExtractor.

Подробное описание можно посмотреть в репозитории проекта [14]

Заключение

Для специалистов, работающих с базами данных, наличие автоматизированного Data Lineage — это не просто удобство, а необходимость. Он избавляет от ручного ведения документации и реверс‑инжиниринга, сокращает длительность поиска и верификации источников, упрощает аудит и минимизирует ошибки [15]. Но что ещё важнее, Data Lineage становится основой для эффективного управления миграциями, позволяя заранее выявить всех потребителей данных и спланировать переключение, что значительно снижает риски и сроки перехода на новую ИТ‑архитектуру. Практическая значимость работы заключается в демонстрации возможности интеграции LLM для автоматического извлечения Data Lineage из SQL‑кода.

Разработанный инструмент не только решает конкретную техническую задачу, но и приносит ощутимые бизнес‑выгоды: снижает риски, экономит время сотрудников, повышает прозрачность данных и упрощает управление изменениями в ИТ‑ландшафте.

Возможное дальнейшее развитие инструмента:

  • Построение Data Lineage на уровне таблица.поле.

  • Использование RAG‑систем для расширения возможности использования файлов source to target (S2T).

  • Создание агентов для сравнения версий кода (код‑рефакторинг).

Список используемых источников

  • O’Reilly Media, Inc., Prompt Engineering for LLMs. John Berryman, Albert Ziegler

  • Packt Publishing, Generative AI with LangChain: Build production‑ready LLM applications and advanced agents. Ben Auffarth

  • Packt Publishing, Learning LangChain: Building AI and LLM Applications with LangChain and LangGraph. Mayo Oshin, Nuno Campos 

  • Manning, AI Agents in Action. Michael Lanham

  • Reflexion: Language Agents with Verbal Reinforcement Learning: https://arxiv.org/pdf/2303.11366 [16]

  • On the Brittle Foundations of ReAct Prompting for Agentic Large Language Models: https://arxiv.org/pdf/2405.13966 [17]

  • AI Agents: Evolution, Architecture, and Real‑World Applications: https://arxiv.org/html/2503.12687v1 [18]

Автор: Николай Абрамов (@NickAbramov [19]), участник профессионального сообщества Сбера DWH/BigData. Профессиональное сообщество отвечает за развитие компетенций в таких направлениях как экосистема Hadoop, PostgreSQL, GreenPlum, а также BI инструментах Qlik, Apache SuperSet и др.

Автор: Sber

Источник [20]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/33652

URLs in this post:

[1] 127 скриптов: https://github.com/Xpehutta/giga4sql/blob/main/data/DDLs.txt

[2] логику: http://www.braintools.ru/article/7640

[3] GigaChat: https://developers.sber.ru/docs/ru/gigachat/models/main

[4] SQLLineageExtractor: https://github.com/Xpehutta/llm4lineage/blob/main/Classes/model_classes.py

[5] LangChain: https://www.langchain.com/

[6] RegexSQLExtractor: https://github.com/Xpehutta/giga4sql/blob/main/Classes/regexp_extractor.py

[7] SQLLineageValidator: https://github.com/Xpehutta/giga4sql/blob/main/Classes/validation_classes.py

[8] F1 = 0,7898, а GigaChat 2 Pro — F1 = 0,9218: https://github.com/Xpehutta/giga4sql/blob/main/Scores.ipynb

[9] GigaChatSQLLineageAgent: https://github.com/Xpehutta/giga4sql/blob/main/Classes/prompt_refiner.py

[10] LangGraph: https://www.langchain.com/langgraph

[11] итераций агента‑рефлексии: https://github.com/Xpehutta/giga4sql/blob/main/Refiner_batches.ipynb

[12] веб‑интерфейс: https://github.com/Xpehutta/giga4sql/blob/main/Web/App.py

[13] Streamlit: https://streamlit.io/

[14] репозитории проекта: https://github.com/Xpehutta/giga4sql/

[15] ошибки: http://www.braintools.ru/article/4192

[16] https://arxiv.org/pdf/2303.11366: https://arxiv.org/pdf/2303.11366

[17] https://arxiv.org/pdf/2405.13966: https://arxiv.org/pdf/2405.13966

[18] https://arxiv.org/html/2503.12687v1: https://arxiv.org/html/2503.12687v1

[19] @NickAbramov: https://www.braintools.ru/users/NickAbramov

[20] Источник: https://habr.com/ru/companies/sberbank/articles/1058618/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1058618

www.BrainTools.ru

Rambler's Top100