Skip to content
SergioSboyPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

mas

Учебный проект: сравнительный анализ workflow, одиночного LLM-агента и мультиагентной команды для анализа SQL-данных в PostgreSQL.

Команда: Романов Сергей, Александра Железнова.

Цель: сравнить workflow, одиночного LLM-агента и одну MAS с общей чёрной доской по качеству ответа на SQL-вопросы, затратам и времени.

Что уже можно показать

  • presentation/SQL_Agents_Results_2026-10-22_Clean.pptx — актуальная презентация с реальным LLM-прогоном и заметками докладчика на 5 минут.
  • presentation/SQL_Agents_PostgreSQL.pptx — предыдущая презентация с автономным demo.
  • results/postgres_prepared/report.html — архивные результаты автономного demo, таблицы, графики и история взаимодействий. Открывается обычным браузером без сервера и интернета.
  • DEFENSE.md — сценарий выступления, последовательность показа и вопросы к защите.
  • Все три варианта запускаются через main.py, используют одну базу и общие инструменты.

Реальный прогон в актуальной презентации: qwen/qwen3.5-9b через Polza.ai, PostgreSQL 16.2, шесть задач по пять повторов для каждого из трёх вариантов, всего 90 запусков. Входные файлы с результатами предоставлены пользователем, CSV и JSON сверены. Итоговый успех по исходному оценщику: workflow 25/30, Single 10/30, MAS 4/30. Среднее время: 0,113 / 23,184 / 41,751 с. Тарифы в результатах не заданы, стоимость не рассчитана. Токены Single и MAS известны частично: не менее 49 335 и 146 615 соответственно. Оценщик сравнивает точные метки строк, поэтому правильное число с другой подписью может считаться провалом. Пересчёт качества в этом обновлении не выполнялся.

Архивное demo: results/postgres_prepared/ относится к запрограммированным ответам с намеренными ошибками. Оно остаётся примером запуска каркаса и не является реальным LLM-бенчмарком. Новая презентация использует предоставленный live-прогон, а не эти архивные измерения.

Вариант 1: Docker

Нужен только запущенный Docker Desktop или Docker Engine с Docker Compose. Python, psycopg и PostgreSQL устанавливаются внутри контейнеров.

git clone https://github.com/SergioSboy/mas.git
cd mas
docker compose run --build --rm app

Compose собирает приложение, запускает PostgreSQL, дожидается готовности базы после загрузки учебных данных и выполняет все три варианта на шести вопросах. При первом запуске нужен интернет для образов и зависимостей. Для повторного запуска уже собранного приложения:

docker compose run --rm app

Новый отчёт появляется на компьютере в results/demo_<дата>/report.html, рядом сохраняются CSV и JSON. В сообщении приложения путь начинается с /app/results/: на компьютере это папка results/ внутри репозитория. Результаты сохраняются после удаления контейнера. HTML открывается браузером без сервера.

Приложение — одноразовая команда: после эксперимента оно завершается, база продолжает работать. Остановить контейнеры, сохранив базу и отчёты:

docker compose down

При первом старте создаются выделенная база salesbench, 48 заказов и роль salesbench_reader только с правами чтения. Владелец базы не используется агентами. Учебные пароли demo_owner и demo_reader заданы в Compose и SQL-инициализации. Внутри сети приложение обращается к db:5432, для внешних инструментов база доступна на 127.0.0.1:55432. Существующий том не перезаписывается при повторном запуске.

Вариант 2: Без Docker

Нужны Python 3.10+ и отдельно установленный и запущенный PostgreSQL 14 или новее. Docker не используется ни приложением, ни базой. Оба варианта запуска выполняют один и тот же main.py с одинаковыми задачами и метриками.

Окружение Python и настройки

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
cp .env.example .env

В .env уже указаны учебные подключения к PostgreSQL на 127.0.0.1:5432. Если сервер работает на другом порту или используются другие пароли, измените DATABASE_URL и DATABASE_ADMIN_URL. main.py, init_db.py и тесты автоматически читают .env. Явные переменные терминала всегда имеют приоритет.

Подготовка локального PostgreSQL

Один раз выполните скрипт из scripts/ через psql от имени администратора PostgreSQL:

psql -U postgres -d postgres -f scripts/setup_local.sql
.venv/bin/python init_db.py

На macOS с PostgreSQL из Homebrew администратором часто является текущий пользователь: тогда используйте psql -d postgres -f scripts/setup_local.sql. Если нужен другой адрес, укажите -h, -p, -U для psql и те же адрес и порт в .env. Сам PostgreSQL устанавливается обычным способом для вашей системы, например Homebrew, системным пакетом Linux или официальным установщиком Windows.

SQL-скрипт создаёт отдельные роли salesbench_owner и salesbench_reader, а также базу salesbench. Он не сбрасывает пароли существующих ролей и отказывается менять базу, если у неё другой владелец. Затем init_db.py загружает учебные таблицы в новую схему. Повторный запуск не перезаписывает данные.

Запуск и тесты

./run_local.sh
./run_local.sh --variant mas --task T3
.venv/bin/python -m unittest discover -s tests -v

Можно запускать напрямую: .venv/bin/python main.py. На Windows используйте .venv\Scripts\python.exe main.py и тот же путь к Python для установки зависимостей, инициализации и тестов. Bash-скрипт на Windows не требуется.

На macOS есть отдельный файл Запустить локально.command: он запускает Python из .venv и открывает новый HTML-отчёт. Файл Запустить демо.command по-прежнему запускает Docker-вариант. Локальные отчёты тоже сохраняются в results/. Проверены 18 запусков и 16 тестов напрямую через локальные Python и PostgreSQL 14.17, без Docker.

Для настоящей LLM заполните OPENAI_API_KEY и LLM_MODEL в том же .env и выполните ./run_local.sh --backend live --repeat 5. Тесты используют DATABASE_ADMIN_URL и DATABASE_URL. При необходимости отдельные подключения для тестов можно задать через TEST_DATABASE_ADMIN_URL и TEST_DATABASE_URL.

Задачи и тесты в Docker

docker compose run --rm app --variant mas --task T3
docker compose run --build --rm tests

Тесты используют тот же образ Python и настоящий PostgreSQL. Сервис tests получает доступ владельца только для создания своей временной схемы с уникальным именем и удаления этой схемы после проверки. Приложение app такого доступа не получает. Тестовый сервис не запускается при обычном docker compose up.

Проверено полным запуском в Docker: 18 экспериментов и 16 тестов прошли на PostgreSQL 17.11 и Python 3.12. Результаты сохранились в папке проекта после удаления контейнера приложения.

На macOS Запустить демо.command делает то же самое через Docker и открывает новый отчёт. Открыть результаты.command открывает подготовленный отчёт из репозитория. Для чтения уже готовых HTML-файлов Docker не нужен.

В Dockerfile зафиксирована ветка Python 3.12, в requirements.txt — версия psycopg. В образ попадают только исходники и тесты. .dockerignore исключает локальные окружения, Git, ключи, результаты и презентации. Код копируется в образ, поэтому после правки Python-файлов запускайте с --build. Приложение работает от пользователя app, а не root. На Linux при отличии UID владельца папки результатов от 1000 можно запустить docker compose run --user "$(id -u):$(id -g)" --rm app.

Настройки и существующий PostgreSQL

Для обычного demo файл .env не нужен. Compose автоматически читает .env рядом с compose.yaml и передаёт в приложение только явно перечисленные настройки LLM. При локальном запуске Python читает этот же .env, не переопределяя уже заданные переменные. В Docker файл .env не копируется: настройки приходят через Compose. Ключ передаётся при запуске контейнера, не входит в образ и исключён из Git.

Для подключения контейнера к своему учебному серверу передайте DATABASE_URL через docker compose run -e DATABASE_URL=... app. Внутри контейнера localhost означает сам контейнер. Для PostgreSQL из стандартного Compose используйте имя db, для внешнего сервера — его сетевой адрес. Подробный прямой запуск описан в разделе «Вариант 2: Без Docker».

init_db.py нужен только при ручной настройке отдельного сервера: база и роль чтения должны уже существовать. Он создаёт новую схему salesbench и не меняет существующую. Обычный main.py ничего не создаёт и не сбрасывает. Docker загружает db/01_roles.sql и db/02_seed.sql только на новом томе.

Подготовленный отчёт в results/postgres_prepared/ относится к исходному прогону на PostgreSQL 14.17, а не к контейнерному запуску. Новые Docker-прогоны сохраняются отдельно, в их JSON указана фактическая версия сервера. Предыдущая презентация использует эти исходные измерения. Актуальная версия от 22 октября отражает предоставленный пользователем live-прогон.

Настоящая LLM в Docker

Скопируйте .env.example в .env и укажите OPENAI_API_KEY и точный ID доступной модели в LLM_MODEL. Ключ не нужно добавлять в Dockerfile или передавать при сборке.

cp .env.example .env
# Заполните OPENAI_API_KEY и LLM_MODEL в .env, затем:
docker compose run --build --rm app --backend live --repeat 5

Одна и та же модель используется одиночным агентом и всеми ролями MAS. Workflow LLM не вызывает. Если модель расходует токены на внутренние рассуждения, при необходимости увеличьте --max-output-tokens одинаково для Single и MAS.

API должен поддерживать Chat Completions, response_format=json_object, max_completion_tokens и поле usage. По умолчанию используется https://api.openai.com/v1. Для совместимого сервиса задайте LLM_ENDPOINT с окончанием /v1. Формат запроса проверен по официальной документации OpenAI. Доступ к внешнему API в этой подготовке не проверялся. В тестах транспорт заменяется локальными ответами.

Стоимость рассчитывается только при явно указанных тарифах за миллион токенов, например:

docker compose run --rm app --backend live --repeat 5 --input-price 1 --output-price 4

1 и 4 в примере — условные числа, а не тариф выбранной модели. Укажите актуальные ставки своего сервиса. Стоимость — оценка без скидок на кэш, налогов и пакетных тарифов. Без тарифов стоимость остаётся null, а не превращается в ноль. Если после ошибки API нет usage, итоговый расход также неизвестен, известная часть сохраняется отдельно. Такой запуск остаётся в знаменателе качества и во времени, а в суммарной стоимости будет null. Повторные платные вызовы без информации о расходе блокируются.

Как устроены варианты

Вариант Поведение
Workflow Выбирает готовый SQL по ключевым словам, выполняет его, считает статистику, строит график и шаблонную сводку. Поддерживает пять типов вопросов. Для доли возвратов шаблона нет.
Single Одна LLM выбирает SQL, видит результат и ошибки инструмента, затем выдаёт тип графика, сводку и проверяемое числовое утверждение. Может исправить SQL, отдельного Critic нет.
MAS Planner выдаёт подзадачи и допустимый порядок ролей. SQL Agent формирует запрос, общий инструмент выполняет его. Analyst использует статистику инструмента и формирует отчёт. Critic проверяет смысл SQL, график и сводку. При отказе Planner получает ошибки и строит новый план.

MAS — последовательная команда с чёрной доской, без сложных фреймворков и параллелизма. Planner обязан соблюдать зависимости SQL, Analyst, Critic. При исправлении только отчёта он может пропустить SQL. В первой версии подзадачи сводятся к одному итоговому SQL, сложные соединения и подзапросы выполняет PostgreSQL. Это ограничение небольшого прототипа.

Чёрная доска — словарь question, schema, rules, plan, sql, rows, statistics, report, errors, history. Роли получают это состояние в JSON, результаты возвращаются в него. В results.json остаются полные запросы ролям, ответы, расход и время. Агентам не передаются эталонные запросы и результаты оценщика.

Общие задачи и данные

Искусственная база PostgreSQL: 48 заказов за январь–март 2026, 6 покупателей в 3 регионах, позиции заказов и возвраты. Есть отменённые заказы и несколько причин возврата одного заказа. Фикстура полностью воспроизводима, персональных данных нет.

ID Задача График
T1 Выручка завершённых заказов по месяцам Линейный
T2 Выручка по категориям товаров Столбчатый
T3 Средний чек по регионам Столбчатый
T4 Уникальные покупатели по регионам Столбчатый
T5 Общая выручка завершённых заказов Столбчатый, одно значение
T6 Доля уникальных завершённых заказов с возвратами по регионам Столбчатый

Все варианты видят одинаковые определения показателей. Возвраты в этой версии не вычитаются из выручки. Доход считается по завершённым заказам, возврат — отдельный признак.

Протокол и метрики

  • На одну задачу и вариант: до 12 вызовов модели, 16 000 входных + выходных токенов суммарно, до 700 выходных токенов на вызов, до 120 секунд и 2 попыток SQL/полного цикла MAS. Лимиты общие для всей команды MAS, не для каждой роли. Workflow использует нулевой LLM-бюджет.
  • Допуск следующего вызова использует консервативный резерв по UTF-8-байтам промпта + 256 токенов накладных расходов + выходной лимит. Измеренный расход берётся из API usage, резерв не записывается как расход. Это приблизительный предохранитель, не серверная квота биллинга. Неиспользованный бюджет не требует обязательного расходования.
  • Один запрос PostgreSQL ограничен 2 секундами и 500 строками. Агенты используют роль без прав записи и создания временных таблиц. Каждый запрос выполняется в транзакции READ ONLY с серверным statement_timeout. Один подготовленный SELECT оборачивается в подзапрос с LIMIT 501, после чего проверяется лимит 500 строк. Это учебная защита, не промышленная песочница произвольного SQL.
  • Успех с первой попытки: внешний оценщик проверяет первый полный кандидат отчёта. Ошибка первого SQL или некорректный первый отчёт сразу означает неуспех первой попытки. У MAS кандидат фиксируется до Critic: если Critic исправляет ложное замечание, метрика первого кандидата всё равно отражает его фактическую корректность.
  • Итоговый успех: завершённый отчёт после разрешённых исправлений. У MAS Critic должен принять ответ. Незавершённый прогон из-за лимита входит как провал.
  • Таблица должна совпасть с отдельным эталонным SQL: метки и числа, допуск 1e-6, порядок неважен. Затем проверяются тип графика, наличие сводки и числового утверждения, подтверждённого строкой таблицы. Статистику и график строят общие инструменты.
  • Проверка текста ограничена: код не доказывает смысловую верность всей сводки. Для настоящего исследования участники вручную оценивают соответствие вопросу, подписи и числовые утверждения. Процент успеха здесь прежде всего метрика таблицы и структуры отчёта.
  • Время измеряется от старта варианта до остановки, включая неудачные вызовы, переделки, SQL и подготовку отчёта. Внешняя оценка и сохранение файлов после решения не входят. Выводятся среднее и медиана, неудачи не исключаются.
  • Варианты запускаются в перемешанном порядке с seed 42. Это seed порядка запуска, не гарантия одинаковых ответов LLM. Шесть задач и один demo-повтор не позволяют делать статистические выводы.

Что показывает подготовленный demo

Вариант Первый успех Итоговый успех Вызовы заглушки
Workflow 5/6 5/6 0
Single 4/6 5/6 13
MAS 4/6 6/6 30

Фактические локальные времена лежат в отчёте. Все токены и стоимость API равны нулю, потому что LLM не вызывалась. Вызовы заглушки не являются API-запросами.

В demo оба агентных варианта сначала получают T3 с неверным полем amount и T5 без фильтра status. Single исправляет видимую ошибку PostgreSQL в T3, но принимает неверный по смыслу ответ T5. Demo-Critic проверяет фильтр статуса и отправляет T5 на переделку. Его правило намеренно узкое и не доказывает универсальной проверки SQL. Для T6 Single и MAS получают готовый ответ из публичных шаблонов, а workflow намеренно ограничен пятью типами. Поэтому это заданный учебный сценарий, а не независимый тест обобщения.

Следующий эксперимент

  1. Выбрать точный ID одной доступной модели и записать тарифы и дату в результаты.
  2. Выполнить --backend live --repeat 5: 6 задач × 3 варианта × 5 повторов = 90 запусков, из них 60 агентных, 30 workflow.
  3. Сохранить отдельный отчёт, вручную проверить сводки и заменить demo-таблицу в презентации реальными измерениями.
  4. Расширить набор до 15–20 скрытых перефразированных вопросов. Добавить обоснование отказа Critic и сравнить MAS без Critic при том же общем бюджете.

Файлы

run_local.sh — запуск без Docker. scripts/setup_local.sql — настройка отдельной локальной базы. salesbench/config.py — чтение .env. Dockerfile и .dockerignore — образ приложения. compose.yaml — приложение, PostgreSQL и тесты в Docker. db/ — роли и учебные данные. requirements.txt — psycopg 3. init_db.py — необязательная инициализация своего сервера. salesbench/database.py — подключение. main.py — запуск и протокол. salesbench/data.py — данные и задания. templates.py — workflow и учебные ответы demo. backend.py — адаптер модели и бюджет. architectures.py — три варианта. tools.py — SQL, статистика и график. evaluate.py — изолированный эталон. reporting.py — CSV, JSON, HTML. tests/ — проверки исправлений, скрытой ошибки, лимитов, API-учёта и режима чтения.

Личный вклад участников нельзя восстановить из автоматически подготовленного каркаса. В презентации указано предлагаемое распределение. Перед 22 октября подтвердите выполненные действия и замените соответствующий слайд фактическим вкладом каждого.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages