Эксперт Postgres Professional про выбор LLM и фреймворка для ИИ-агентов
Postgres Professional строит ИИ-агентов поверх PostgreSQL, но инфраструктура меняется, созревает, а ожидания и требования к качеству систем на базе ИИ растут

Эксперт в области ИИ и машинного обучения. Магистр прикладной математики. Преподаватель в МФТИ и Летней школе НГУ по направлению «ИИ в СУБД»
Последние полтора года наша ML-команда делает крайне интересные штуки, например строит ИИ-агентов поверх PostgreSQL, при этом инфраструктура меняется, индустрия созревает, а ожидания и требования к качеству систем на базе ИИ только растут. Начинали мы с одной A100 в VK Cloud и довольно скромных задач, по типу «давайте прикрутим RAG», а сейчас одновременно поддерживаем прод AskPostgres, строим агентов-аналитиков, проводим эксперименты, разворачиваем собственные бенчмарки для агентов и готовимся к переезду на сервер с 8×H200, где уже можно запускать Qwen3-235B и разворачивать серьезные работы по дообучению небольших моделей.
В статье о том, какие задачи мы решаем, как эволюционировало железо, модели и фреймворки, и почему в итоге мы гораздо меньше волнуемся какая модель лучше, и гораздо больше — о контекст-менеджменте и архитектуре агентов. Все описанное актуально на конец 2025 — начало 2026 года.
Задачи, под которые мы строили стек
Вокруг единой LLM-инфраструктуры у нас постепенно вырос целый набор приложений. Чтобы было понятно, о чем речь, перечислю основные направления.
- Классический RAG Fusion над документацией и прочими источниками.
Мы индексируем документацию Postgres Pro, статьи, вопросно-ответные пары, SQL-примеры, книги и прочий текст в pgvector. В качестве эмбеддера используем BGE-M3 и работаем не с BM25, а со sparse-векторами: строим разреженные представления текстов, считаем dense-векторы и комбинируем все это через перемножение, ранжирование, дисконтирование и дополнительные эвристики. Обработка некоторых неструктурированных источников частично делегирована LLM. - Развитие RAG в ИИ-агента на MCP с веб-поиском и SQL-executor.
Классический чат с документацией быстро перестал устраивать: пользователям нужен полноценный ассистент с четкой ролевой моделью и множеством разных инструментов. Поэтому вокруг RAG вырос ReAct-агент, который через Model Context Protocol (MCP) умеет ходить в PostgreSQL, обращаться к веб-поиску и комбинировать эти источники в одной цепочке рассуждений. - ИИ-агент для аналитики.
Это интерфейс поверх аналитических данных: агент понимает вопросы в духе «покажи выручку по регионам за последний год», генерирует SQL, объясняет результат, умеет возвращаться к прошлым шагам, строить графики и постепенно наращивать сложность запросов. - Graph-RAG-агент над большой кодовой базой на C (ИИ-Copilot).
Ядро PostgreSQL и сопутствующие проекты — это миллионы строк C-кода. Мы строим граф знаний в Apache AGE: вершины — директории, файлы, функции, структуры, макросы, переменные; ребра — вложенные зависимости и вызовы. Агент поверх этого графа отвечает на вопросы о том, где реализовано вот это поведение, чем чревато изменение такого-то участка и помогает с навигацией по коду как по базе знаний, а не как по сплошному тексту с поиском. - SQL-генератор.
Развернутый пайплайн text-to-SQL, который мы тренируем и оцениваем на основе EX/EM-метрик и бенчмарков типа Spider/BIRD плюс наши схемы. Для обучения использовали Qwen-0.6B и на ней отрабатывали GRPO/SFT; отдельно экспериментировали с QLoRA-дообучением моделей порядка Qwen2.5-14B на чистом SFT. - Генератор hint-сетов для PostgreSQL.
Здесь в центре всего расширение pg_hint_plan. Модель видит запрос, статистику, индексы и предлагает подсказки в формате hint-сетов. Обучаем это дело при помощи GRPO, параллельно зажимаем формат подсказок формальной грамматикой, чтобы pg_hint_plan мог их распарсить и применить. - Генератор схем БД и бизнес-логики из DSL.
Мы используем DSL (domain specific language), который описывает не только сущности, но и схему транзакций для мутации схемы БД. Сама схема представляется как набор агрегатов с иерархической структурой данных в формате JTD (JSON Typedef). Агент по этому описанию генерирует таблицы, связи, транзакционную обвязку и фрагменты бизнес-логики, придерживаясь JTD-спецификации. - Генератор тестовых данных.
Под капотом это, казалось бы, «простой» генератор INSERT, но с нюансами. Агент умеет подцеплять правдоподобные списки значений (города, имена, адреса), учитывать связи между таблицами. Все выходное описание генерации зажато в формальной грамматике, чтобы потом легко было валидировать и воспроизводить сценарии. - Суммаризация и структурирование тикетов техподдержки.
Цель здесь — не просто пересказать переписку, а разложить ее в понятный отчет: кто что делал, какие гипотезы проверялись, какие команды выполнялись, к какому итогу пришли. Параллельно агент классифицирует тикет по существующим меткам. - Просмотр больших объемов кода в поисках подозрительных фрагментов.
По сути, LLM просеивает большие массивы кода и помечает фрагменты, которые выглядят подозрительно по заданным критериям. Это инструмент ускорения ручного аудита, а не его замена. - Собственные бенчмарки для агентов.
Мы пришли к схеме «тестируемый агент + тестирующий агент + валидатор». Первый решает задачу так, как будет делать это в проде, взаимодействуя с инструментами. Второй играет роль пользователя: отвечает, уточняет, направляет, опираясь только на ограниченное подмножество контекстных знаний. Третий, валидатор, анализирует весь диалог и решает, достигнута ли цель и соблюдены ли условия тестового кейса. Так мы тестируем не IQ модели, а поведение системы целиком. - Исследования памяти и формальных ограничений.
Параллельно мы играемся с тем, как устроить краткосрочную и долгосрочную память агентов, как управлять контекстом (от простого окна до суммарзации, маскирования и графов) и как формальные грамматики и строгий structured output влияют на качество, скорость и устойчивость поведения.
Технически мы используем классический набор: пробовали PEFT/LoRA/QLoRA, LLaMA-Factory и LMPO, но пришли де-факто к стандарту — TRL для экспериментов с SFT и RL-подходами (GRPO, GSPO и тому подобное). При этом для сложных вещей вроде SQL-генератора мы предпочитаем обкатывать методологию на маленьких моделях (например, на Qwen-0.6B), а уже потом переносить отобранные траектории и данные на более крупные.
Главный фильтр, который мы проходим, очень простой: если у нас нет мощностей, адекватного бенчмарка с метриками или данных для задачи, мы не дообучаем модель под эту задачу. Сначала тюнинг через контекст, а потом fine-tuning.
SQL-генератор стал первым местом, где мы подумали: «Ладно, здесь без дообучения будет больно». Нам хотелось, чтобы модель не просто выдавала валидный SQL, но и вела себя предсказуемо, понимала особенности диалекта PostgreSQL и делала какой-никакой schema-linking в процессе ризонинга на типичных запросах пользователей.
В качестве теста мы взяли Qwen-0.6B: на нем запускали SFT и GRPO с LoRA и учились конструировать reward. Это повысило качество при сложных запросах и показало, что подобного рода пайплайны оправданы на маленьких моделях. Также учили и Qwen2.5-14B с QLoRA на чистом SFT. В результате получили улучшение формата, но знаний новых модели это не добавило, что явно отображалось на бенчмарках.
Генератор hint-сетов вырос из этой же логики, но с более жесткими ограничениями. Здесь в центре внимания pg_hint_plan, и любая ошибка в формате подсказки может привести к тому, что планировщик не поймет, чего от него хотят, и просто проигнорирует план. Поэтому мы сразу зажали выход модели формальной грамматикой и тренировали ее с помощью GRPO, максимально аккуратно подбирая наборы подсказок, которые реально ускоряют запросы.
Стоит отметить, что алгоритмов RL море и у каждого свои плюсы и минусы. Так, например, мы пробовали относительно новый GSPO и поняли, что он больше подходит для MoE-архитектур, в то время как GRPO на маленьких dense-моделях сходился быстрее.
DSL, JTD и генерация тестовых данных
Отдельная ветка — работа с DSL. Нам нужен был язык описания, в котором не только схема данных задается декларативно, но и схема транзакций для ее мутации: какие операции возможны, какие инварианты должны сохраняться, какие агрегаты существуют. Для этого мы описали структуру в терминах JTD (JSON Typedef): так получилось связать иерархические агрегаты, бизнес-инварианты и транзакционную логику. Агент, который работает с этим DSL, по сути, выступает переводчиком с языка бизнеса на формальный язык, может задать уточняющие вопросы и создать необходимую мутацию в случае необходимости.
Еще один более приземленный пайплайн — генератор тестовых данных. Он получает схему и набор требований, а на выходе выдает набор INSERT. При необходимости агент подтягивает правдоподобные значения (списки городов, имен, доменов и тому подобное), следит за связями и edge-кейсами. Все, что он выдает, тоже ограничено формальной грамматикой, так что генерацию можно всегда считать синтаксически корректной и валидной для дальнейших этапов работы с тестовой БД.
От «зоопарка» пайплайнов к агентам на MCP
Пока все эти компоненты жили каждый сам по себе, жизнь была непростой. Для RAG — свой пайплайн, для SQL — свой, для Graph-RAG по коду — еще какой-то. Каждый держит собственные подключения к базе, свои форматы логов и свои представления о том, что такое контекст.
Переход к MCP дал долгожданный порядок как в инфраструктуре, так и в головах. Стало гораздо легче объяснять, как агенты работают с инструментами, какие существуют уровни абстракции и какие возможности расширения существуют. Мы стали описывать доступ к данным и инструментам в терминах MCP-серверов, а поверх них строить ReAct-агентов. В результате у нас появился единый слой, где:
- PostgreSQL, файловая система, web-поиск, graph-store и внутренние API выглядят одинаково — как набор инструментов с четкими контрактами;
- разные агенты могут использовать один и тот же набор MCP-серверов без копипаста и «зоопарка» интеграций.
На этом фоне особенно важным стало поведение модели именно как агента: насколько аккуратно она вызывает инструменты, как реагирует на ошибки, умеет ли честно признать, что нужных данных нет. Для начала можно воспользоваться лидербордами, по типу этого, но нужно же оценивать качество и на своих задачах. Это и подтолкнуло нас к созданию собственного бенчмарка с тройкой «тестируемый агент — тестирующий агент — валидатор». Нам оказалось мало просто «хорошей модели», нужна была система, которая ведет себя предсказуемо в длинной траектории решения.
Текущий стек: vLLM, Qwen3-Next-80B и свой агентный слой
К настоящему моменту стек выглядит примерно так.
Внизу лежит vLLM как основной движок для инференса open-source-моделей. Далее идет OpenAI-совместимый MCP-клиент, который занимается стримингом, подключением к MCP-серверам, управляет циклом агента и отвечает за то, чтобы все нужные инструменты были вызваны и весь контекст корректно передался в LLM, как мы хотим. Тут мы сознательно ушли от попыток строить сложные сценарии целиком внутри LangChain/LangGraph, оставив их для быстрого прототипирования. Причина есть: сырость и наличие большого количества багов в продовых сценариях. Логирование и аналитику мы тоже сделали свою на PostgreSQL. Ранее использовали LangFuse, но до тех пор, пока не обнаружили утечку памяти, что благополучно клало нам прод несколько раз в неделю.
Стоит отметить, что ресурсы между командами мы делим через LiteLLM: это удобный gateway с OpenAI-совместимым API, который умеет маршрутизировать запросы на разные модели — как локальные, так и внешние закрытые модели при необходимости.
Инструменты и источники данных живут в отдельном слое MCP-серверов. Это дает возможность подключать и отключать серверы без переписывания логики агентов и делиться ими между разными продуктами/командами.
В описанной конфигурации по цифрам нагрузочного тестирования в многопользовательском режиме получаем в среднем 18 секунд на ответ с использование инструмента поиска по документации, а p95 при этом около 60 секунд, что более чем хорошо для нашего контекста.
Квантизация и ее характер
Если говорить о квантизации, то на практике все свелось к весьма простой картине.
Пока мы жили на A100, AWQ-4bit стал рабочей нормой для больших моделей. В таком виде Qwen3-Next-80B-A3B помещается на карту, показывает достойное качество на наших задачах и позволяет еще строить поверх нее многоступенчатых агентов, не раздувая латентность до неприличия.
В более агрессивные режимы мы иногда заходили, но быстро убедились, что стоимость ошибок возрастает: модель чаще уводит вывод на неправильный язык, зацикливается на шаблонных фразах и чаще ломает формат вызова инструментов (сейчас иногда это тоже происходит). Часть этого лечится промптами и настройкой параметров семплирования (температура, top-p, top-k), но по-настоящему надежной становится связка только тогда, когда вы сверху накрываете модель формальными грамматиками и жесткими спецификациями выходных форматов.
С приходом H200 мы будем активнее смотреть в сторону FP8-квантов и более крупных моделей, но философия вряд ли изменится: квантизация — это trade-off между качеством и скоростью. Мы будем выбирать опираясь на бенчмаркинг и несколько измеряемых критериев, не исключая latency.
Что мы поняли про выбор моделей
Если попробовать выжать весь опыт в один тезис, он будет таким: модель важна, но контекст и архитектура еще важнее.
Да, если взять gpt-5.2 или Gemini Pro 3.0, они объективно будут умнее любого открытого аналога. Но если агент не умеет управлять контекстом, если у него нет памяти и продуманной работы с инструментами, то никакая «мега-триллионная-модель» не спасет ситуацию.
Мы прошли путь от Qwen2.5-14B/32B в Q6_K_M через Ollama до Qwen3-Next-80B-A3B AWQ-4bit на vLLM и сейчас смотрим в сторону Qwen3-235B на H200. На каждом шаге по пути можно было построить полезного агента, при условии что вокруг модели есть все остальное: RAG, MCP, агентный слой, память, грамматики и бенчмарки.
Поэтому сейчас, выбирая LLM под новую задачу, мы в первую очередь спрашиваем себя, не о том, какая модель в прайме. Нас интересует:
- какие данные и источники контекста нам нужны;
- как мы будем управлять этим контекстом;
- какие инструменты и в каком виде нужны агенту;
- как мы будем измерять качество его поведения.
А модель — это просто компонент, который встраивается в эту систему. Пусть даже это будет gpt-5.2: без контекста и архитектуры ничего не поедет
Рубрики
Интересное:
Новости отрасли:
Все новости:
Публикация компании
Достижения
Контакты
Социальные сети
Рубрики
