Большие языковые модели (Large Language Model, LLM) используют в разных областях: с их помощью генерируют программный код, ищут информацию, озвучивают реплики чат-ботов. А вот при работе с реляционными данными языковые модели часто ошибаются.

Чтобы справиться с этими ошибками, в мы разработали три пайплайна для работы с базами данных. Эти пайплайны представляют собой цепочку связанных между собой языковых моделей: каждая из них генерирует свой ответ, и следующая модель работает с ответом предыдущей. Таким образом мы получаем дополнительный контекст, и запрос к базе данных становится точнее.
Решаем проблему генерации SQL-запросов
Задача. У нас есть вопрос пользователя и описание схемы базы данных (DDL). На основании вопроса мы хотим сгенерировать запрос, чтобы узнать некую информацию из базы данных. Например, получить список клиентов компании, которые находятся в определенном городе.
Языковые модели хорошо работают с декларативными языками. Поэтому кажется, что чтобы сгенерировать SQL-запрос, нужно просто написать промпт. Но на практике выясняется, что результаты такой генерации приводят к ошибкам: логическим, синтаксическим, ошибкам исполнения и другим.

Чтобы решить эти проблемы, мы разработали пайплайн и добавили к языковой модели дополнительные элементы, которые уменьшают количество возможных ошибок. Вот как он работает.
История чата с пользователем дает языковой модели дополнительный контекст.
Промпт трансформируется в формат chain of thought, или цепочка мыслей. Это техника, при которой LLM поэтапно описывает свой путь действий перед тем, как начать генерацию. Так процесс принятия решений становится более прозрачным, и мы можем выявлять ошибки в рассуждениях модели.
Сформулированная цепочка мыслей поступает в LLM-генератор. На выходе он выдает SQL-запрос — он может быть как чистым, так и скрытым в цепочке мыслей.
LLM-экстрактор извлекает из цепочки мыслей SQL-запрос и приводит его к виду JSON модели.
Получившийся запрос поступает в LLM-критик — он выявляет ошибки и оставляет комментарий. Этот комментарий переходит в шаблон изначального промпта, и затем измененный промпт снова поступает в модель-генератор.
В результате получается цикл. Цикл может выполняться достаточно долго, а если задача не имеет решения — бесконечно. Чтобы этого не происходило, нужно поставить ограничение на количество итераций. Тогда мы выйдем из пайплайна, даже если LLM-критика не устроит результат генерации.
Полученный запрос отправляется в SQL Executor — так мы проверяем, исполнится он или нет.
Если запрос не исполняется, значит, произошла ошибка. Эту ошибку в виде текста мы отправляем в шаблон fixerror prompt и формулируем новый, более точный промпт.
Как показывает практика, такой пайплайн генерации SQL неплохо справляется. Многие ошибки получается отловить на этапе LLM-критика, а те, которые пробиваются через него, находит SQL Executor. Тем не менее, у этого пайплайна есть «точки роста» — возможности для дальнейшего совершенствования.
Одна из ключевых проблем возникает, когда мы работаем с действительно большими и сложными базами данных с тысячами таблиц. DDL такой базы может быть огромным. А у языковых моделей есть ограничение на объем входных данных — «окно контекста». Попытка «скормить» модели DDL для тысяч таблиц обречена на провал: информация просто не поместится в этот лимит. В результате модель либо не сможет обработать запрос, либо получит лишь часть схемы, что приведет к ошибкам при генерации SQL.
Как решить эту проблему? Перспективный подход — не передавать всю схему целиком. Вместо этого можно внедрить дополнительный компонент: специализированную модель-экстрактор. Задача этой модели — выступить в роли «умного фильтра». Получив вопрос пользователя, она анализирует его и всю доступную схему данных (те самые тысячи таблиц), но выбирает из них только те, которые нужны для ответа на вопрос пользователя.
Для каких сценариев подходит пайплайн
Большие языковые модели, генерирующие SQL, помогают преодолеть барьер между человеком и сложным языком запросов. Даже если пользователь не знает SQL, он может напрямую обратиться к данным на естественном языке. Модель выступит «переводчиком»: на основе вопроса пользователя и схемы БД (DDL) она сформулирует корректный SQL-запрос. Это ключевой шаг к демократизации доступа к информации, хранящейся в базах.
Другая важная задача, которую помогают решить LLM, — это создание качественных тестовых данных. Заполнение баз для тестов часто требует много времени, а простые генераторы случайных наборов данных дают нереалистичные результаты. LLM же могут генерировать INSERT-запросы, создавая осмысленные и правдоподобные данные (например, имена и адреса, соответствующие региону). Это значительно ускоряет процессы разработки и прототипирования, предоставляя разработчикам готовые и реалистичные данные для работы.
Возможные проблемы с пайплайном
Проблема 1: Семантические ошибки — LLM не понимает логику бизнеса
Наиболее коварный тип ошибок — семантические. LLM может сгенерировать синтаксически абсолютно правильный SQL, который, тем не менее, неверно отражает бизнес-логику. Происходит это потому, что модель по умолчанию не разбирается специфике вашего бизнеса.
Пример. Пользователь просит рассчитать выручку за прошлый месяц. По определению выручка — это та сумма, которую бизнес получил от реализации своих товаров. LLM составляет запрос, который суммирует все продажи (SUM(sale_amount)), но результат получается неверным. Дело в том, что некоторые покупатели возвращали товар, и чтобы правильно рассчитать выручку, из суммы полученных за продажи денег нужно вычесть эти возвраты.
Причина. У LLM нет доступа к определениям ключевых терминов, метрик и правил расчета, принятых в компании.
Решение. Решить проблему можно при помощи подхода RAG (Retrieval-Augmented Generation — генерация, дополненная поиском). Тогда LLM сначала найдет в базе знаний релевантную информацию, а затем использует эти сведения для того, чтобы сформулировать ответ. В данном случае модель «изучит» бизнес-глоссарий, «выяснит», что такое выручка и как ее считать, и только после этого сгенерирует SQL-запрос.
Проблема 2. Неоптимальный запрос — LLM плохо знает SQL
Пример. Пользователь просит модель посчитать, сколько сотрудников устроилось в компанию за каждый год. LLM сначала обращается к таблице с персоналом отдела маркетинга, фильтрует сотрудников по датам трудоустройства, потом делает то же самое для других отделов и присоединяет с помощью JOIN. А оптимальное решение — сформулировать иерархический запрос (CTE), объединить всех сотрудников в одну временную таблицу и отсортировать ее по датам.
Причина. Языковая модель не знает best practices работы с SQL.
Решение. Эту проблему тоже можно решить с помощью RAG: «скормить» модели учебник по SQL, чтобы она сверялась с ним, когда генерирует ответ.
Работаем с графовыми базами
При работе с данными иногда фокус смещается с отдельных записей на сложные связи и отношения между ними. В таких сценариях возможностей традиционных реляционных баз данных, с которыми работают через SQL, может быть недостаточно. Для решения таких задач были разработаны графовые базы данных. Они представляют информацию в виде графа — интуитивно понятной структуры, состоящей из узлов (объектов) и ребер (связей между этими объектами).
Для работы с графовыми базами используются специализированные языки, например, Cypher. Синтаксис этого языка оптимизирован для описания и поиска паттернов связей между узлами. Cypher встречается реже, чем SQL — это связано именно с его специализацией на графовых моделях данных, которые применяются для определенного круга задач.
Где же графовый подход становится нашим «другом»? Классический пример — социальные сети, когда нужно анализировать связи между пользователями, чтобы увидеть, в какие кластеры они входят. Также с помощью графовой базы можно отслеживать цепочки банковских транзакций и распознавать мошеннические схемы.
Большие языковые модели могут генерировать запросы не только на SQL, но и на других языках, например, на Cypher. Однако на практике генерация корректного Cypher-кода с помощью LLM оказывается значительно сложнее, чем генерация SQL. Основная причина этого — меньшая популярность Cypher. Модели обучались на гораздо меньшем объеме текстов и кода, содержащих Cypher, и в результате их «знание» синтаксиса, специфических конструкций и распространенных паттернов Cypher существенно ограничено, что часто приводит к ошибкам.
Чтобы решить эту проблему, приходится дополнительно «учить» языковую модель писать на Cypher: давать ей подробные инструкции и примеры запросов.
Задача. Проанализировать кодовую базу PostgreSQL. Она довольно большая: около двух миллионов строк чистого кода без учета комментариев. Обычному человеку сложно справиться с такой задачей без помощи средств автоматизации.

Так работает пайплайн генерации Cypher.
LLM-планер составляет первоначальный план выполнения запроса.
План начинает исполняться и по пунктам поступает в LLM-агент. Запускается цикл.
У агента есть разные инструменты для решения задач. В данном случае он будет применять Search Documents Tool — поиск по документации, Codebase Nodes Summarization Tool — суммаризацию, или подготовку отчета об интересующих пользователя узлах базы, и Search Codebase Graph Tool — генератор Cypher-запроса по исходному промпту. В результате получается сгенерированный запрос.
Готовый запрос с результатом исполнения Cypher отправляется в LLM-репланер. Эта модель может изменить план, если нужно.
Как только все пункты плана выполнены, результат отправляется в LLM-респондер.
Респондер формулирует полноценный ответ и возвращает его пользователю.
Для каких сценариев подходит пайплайн
Как мы уже обсудили, заставить LLM генерировать корректный Cypher сложнее, чем SQL. Эта задача становится оправданной и даже необходимой в сценариях, где ключевую роль играет анализ сложных связей и взаимоотношений в данных. Именно здесь стандартный SQL часто оказывается недостаточно гибким и эффективным, а графовый подход с языком Cypher раскрывает свои сильные стороны.
Генерация Cypher будет полезна в этих областях.
Анализ сетей: исследование социальных графов (связи между людьми), транспортных, логистических или коммуникационных сетей.
Выявление мошенничества и аномалий: отслеживание цепочек финансовых транзакций, выявление скрытых групп связанных лиц или подозрительных паттернов поведения.
Рекомендательные системы: анализ связей типа «пользователь-товар», «пользователь-пользователь» для предоставления точных рекомендаций.
Анализ зависимостей в сложных системах: исследование больших программных проектов, биологических сетей, организационных структур.
Возможные проблемы пайплайна
Проблема 1. Неоптимальный запрос — LLM плохо знает Cypher
Как и в случае с генерацией SQL, при работе с Cypher языковая модель может делать что-то неоптимально из-за недостаточных знаний о кодинге.
Решение. «Научить» LLM языку Cypher.
Проблема 2. Слишком сложный запрос — LLM входит в бесконечный цикл
Языковая модель может сгенерировать сложный Cypher-запрос. Этот запрос зациклится или уйдет в долгую обработку, и в результате никогда не будет выполнен.
Причина. Количество связей между сущностями — а значит, и время обработки запроса — находится в квадратичной зависимости от количества сущностей.
Решение. Настроить прекращение выполнения запроса через определенное время, чтобы затем переформулировать или упростить его.
Проблема 3. Странные ошибки — LLM не понимает синтаксис и семантику
Языковая модель может совершать глупые ошибки, которые никогда не совершит аналитик-человек.
Причина. Как мы указали выше, Cypher — не такой популярный язык, и LLM «знает» его хуже.
Решение. Два варианта решения проблемы.
Добавить в пайплайн еще один элемент, который будет анализировать получившийся запрос сначала с точки зрения синтаксиса, потом с точки зрения семантики.
Использовать более совершенную модификацию языковой модели.
Скармливаем документацию Postgres Pro
У пользователей Postgres Pro могут возникнуть вопросы, ответы на которые придется искать в официальной документации продукта. Ручной поиск может быть не столь эффективным, например, если сложный вопрос требует подтягивать несколько страниц из документации. Да и, в конце концов, не царское это дело — ридми файлы и документацию читать. Если же использовать для этой цели языковую модель напрямую, можно столкнуться с ограничениями: внутренние знания модели могут быть неполными или устаревшими, а огромный объем документации не позволяет загружать её целиком в контекстное окно при каждом запросе.
Для преодоления этих ограничений была разработана специальная система. Для заданного вопроса пользователя эта система сначала находит наиболее релевантные фрагменты в большом корпусе документации Postgres Pro, а затем использует LLM для генерации точного и фактически обоснованного ответа на основе именно этой извлеченной информации. Этот подход, объединяющий этапы извлечения данных (Retrieval) и последующей генерации текста (Generation), известен как RAG (Retrieval-Augmented Generation).
Задача. Проанализировать документацию Postgres Pro.

Так работает пайплайн RAG телеграм-бота ChatPPG.
В пайплайн поступает пользовательский вопрос, а также история чата и user query — информация о сеансах этого пользователя.
LLM контекстуализирует вопрос: пытается дополнить его так, чтобы вопрос включал в себя контекст.
По контекстуализированному вопросу запускается векторный поиск релевантных документов. Результат поиска — упорядоченный список документов.
Эти документы поступают в LLM — таким образом модель получает более полный контекст и может более корректно ответить на вопрос пользователя.
Для каких сценариев подходит пайплайн
Необходимость в RAG возникает из-за фундаментальных ограничений LLM:
Знания языковых статичны и ограничены данными на момент обучения — это критично для быстро меняющихся областей или внутренней документации.
Контекст языковых моделей ограничен: они могут принимать на вход не более 128 000 токенов, или 500 000 символов.
Подход RAG кардинально расширяет возможности LLM, позволяя генерировать ответы, основанные на информации из внешних, часто очень больших, источников данных. Основной сценарий применения RAG — создание систем вопросов и ответов (Q&A), работающих с большими объемами специфической информации.
Наглядным примером такого подхода является ChatPPG — Telegram ИИ-бот, который мы разработали. Он помогает решить сразу две задачи пользователей PostgreSQL:
Быстро находит информацию в обширной и постоянно растущей документации (включая ядро PostgreSQL объемом ~2800 страниц, а также документацию Postgres Pro Enterprise, Shardman и других продуктов);
Генерирует SQL-запросы по описанию на естественном языке (русском или английском). Возможность получать точные ответы на вопросы по документации, не изучая тысячи страниц вручную, реализуется в ChatPPG именно с помощью RAG.
Возможные проблемы
Проблема 1. Нерелевантный контекст — LLM не может ответить на вопрос
Контекст языковой модели может быть нерелевантным. Это значит, модель подобрала неподходящие документы — те, которые не отвечают на вопрос пользователя.
Причина. Проблема неполной информации может быть связана с разными факторами. Например, в базе просто нет документов, которые позволяют ответить на пользовательский вопрос.
Решение. Проблему можно решить двумя способами.
Дать модели доступ к большему количеству данных или к интернету вообще. «Пускать» модель в интернет не всегда целесообразно: если бот разработан так, чтобы отвечать на вопросы по документации Postgres Pro, то и искать информацию он должен в документах (документации, книгах, статьях, мейлинг-листах), а не в интернете.
Классифицировать вопросы пользователя как релевантные и нерелевантные. Если вопрос релевантный, запускать пайплайн RAG. Если нет, указывать на то, что заданный вопрос не релевантен теме СУБД и PostgreSQL.
Проблема 2. Неправильный порядок ранжирования — LLM отвечает неправильно
В документах может быть подходящая информация, но бот не может ее получить, и отвечает на вопрос неправильно.
Причина. Модель ранжирует документы не в том порядке: нерелевантные документы находятся в списке выше, чем тот, который действительно отвечает на вопрос пользователя. Это связано с несовершенством пайплайна.
Решение. Есть два способа.
Усложнить пайплайн. Например, переформулировать вопрос, добавить контекст из истории чата и попробовать аугментировать этот вопрос — повторить несколько раз в разных формулировках.
Научить языковую модель поднимать более релевантные документы выше.
Усложненный пайплайн может работать так: пользователь задал вопрос, как уничтожить все строки таблицы. Бот ответил, что можно использовать одну из двух операций: Truncate или Delete. Тогда пользователь задал следующий вопрос: «опиши их плюсы и минусы».
Языковая модель аугментирует вопрос несколько раз и получает новые формулировки: «опиши плюсы и минусы команды Truncate и команды Delete»; «чем Truncate отличается от Delete»; «как Delete может превосходить команду Truncate и в каких случаях»; «что такое truncate»; «что такое delete». Затем она сгенерирует варианты ответов на эти вопросы, получит на каждый из них релевантные документы, и «соберет» из них ответ на вопрос.
Проблема 3. Нехватка контекста
Некоторые документы превышают размер контекста языковой модели, так что загрузить их в пайплайн не получается.
Решение. Разделить документы на небольшие фрагменты, которые модель будет воспринимать как отдельные сущности, к каждой из которых можно сформулировать релевантный вопрос.
Заключение
Использование больших языковых моделей для работы с базами данных — это не утопия, а реальность, которая уже сегодня открывает новые горизонты. Продемонстрированные пайплайны доказывают: LLM способны стать мощным инструментом для генерации SQL- и Cypher-запросов, анализа документации и создания тестовых данных. Ключ к успеху — в правильной архитектуре, которая компенсирует «слепые зоны» моделей за счет циклов проверок, RAG-подхода и специализированных компонентов.
Главная ценность таких решений — в демократизации доступа к данным. LLM стирают границы между экспертами и теми, кто не владеет языками запросов, превращая сложные технические задачи в понятный диалог на естественном языке. Однако важно помнить: даже самые продвинутые пайплайны требуют тонкой настройки под конкретные сценарии. Семантические ошибки, ограничения контекста и неоптимальные запросы напоминают, что ИИ пока не заменяет человека, а дополняет его.
Перспективы направления очевидны. Расширение контекстных окон моделей, интеграция бизнес-логики через RAG, обучение LLM на доменных данных — всё это позволит сократить число ошибок и повысить качество генерации. Уже сейчас решения вроде ChatPPG показывают, как можно автоматизировать рутину и ускорить работу с данными. Остается лишь вопрос времени, когда LLM перестанут быть «игрушкой» для баз данных и станут их полноценными собеседниками. А пока — экспериментируйте, дорабатывайте пайплайны и не бойтесь спорить со скептиками.