Настройка LLM и AI-агентов под задачу/aka-gst

Эксперимент 9 · 4 мин

Лабораторная 09: помощник аналитика маркетплейса

Содержание раздела
  1. Задача
  2. Почему сначала считаем без LLM
  3. Запуск первого этапа
  4. Критерии готовности
  5. HTTP API
  6. RAG и диалоговое объяснение
  7. Веб-интерфейс
  8. Результаты выполнения
  9. Конфигурация
  10. Вопрос
  11. Проверенные факты в ответе
  12. Вывод
  13. Сценарий возвратов
  14. Сравнение периодов

Задача

Сделать прототип бокового AI-помощника, который отвечает на вопросы по открытому отчёту и справочным материалам. Используем только искусственные данные — без закрытых документов и данных Wildberries.

Первый сценарий: «Почему процент выкупа маленький?»

Почему сначала считаем без LLM

Языковая модель хорошо объясняет результат, но не должна самостоятельно придумывать цифры. Поэтому приложение:

  1. проверяет структуру CSV;
  2. считает показатели обычным Python-кодом;
  3. выделяет товары с отклонением;
  4. разделяет факты, гипотезы и недостающие данные;
  5. передаёт проверенный результат модели только для понятного объяснения.

Запуск первого этапа

bash
uv run python -c 'from pathlib import Path; from agent_lab.marketplace_analytics import analyze_low_buyout; print(analyze_low_buyout(Path("data/demo/marketplace/sales-report.csv")).model_dump_json(indent=2))'

Критерии готовности

  • процент считается из исходных чисел;
  • повреждённый или неполный CSV отклоняется;
  • возможные причины не смешиваются с доказанными фактами;
  • ответ содержит имя использованного файла;
  • тесты работают без Ollama и интернета.

HTTP API

После запуска FastAPI вопрос можно отправить так:

bash
curl -X POST http://127.0.0.1:8000/v1/marketplace/ask \
  -H 'Content-Type: application/json' \
  -d '{
    "question": "Почему процент выкупа маленький?",
    "report": "sales-report.csv",
    "low_threshold": 70
  }'

На этом этапе API намеренно поддерживает только вопросы о выкупе. Неизвестные виды анализа отклоняются, а доступ к файлам ограничен папкой MARKETPLACE_REPORTS_PATH.

RAG и диалоговое объяснение

Один раз постройте отдельный индекс справочника:

bash
uv run python -m agent_lab.rag index \
  --docs data/demo/marketplace \
  --db data/private/marketplace-rag.sqlite3

После этого /v1/marketplace/chat объединит три части: точный расчёт Python, найденный фрагмент справочника и понятное объяснение Ollama.

bash
curl -X POST http://127.0.0.1:8000/v1/marketplace/chat \
  -H 'Content-Type: application/json' \
  -d '{"question":"Почему процент выкупа маленький?","report":"sales-report.csv"}'

Модель не получает права менять рассчитанные метрики, а указанные ею источники проверяются по результатам RAG-поиска.

Результат живого запуска зафиксирован в RESULTS.md.

Веб-интерфейс

Запустите сервис и откройте http://127.0.0.1:8000/marketplace:

bash
uv run uvicorn agent_lab.service:app --host 127.0.0.1 --port 8000

Страница читает выбранный CSV в браузере и отправляет содержимое в /v1/marketplace/chat-upload без сохранения файла на сервере. API объединяет точный расчёт, RAG и объяснение Ollama. Поддерживаются вопросы о проценте выкупа и возвратах. Для них используются отдельные пороги: 70% для низкого выкупа и 15% для высокой доли возвратов. Ограничение запроса — 5 МБ.

Для сравнения периодов выберите текущий и предыдущий CSV. Страница вызовет /v1/marketplace/compare-chat-upload, рассчитает изменение выкупа в процентных пунктах, выделит товары со снижением и попросит Ollama объяснить результат по RAG-справочнику.

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

После RAG-поиска источники дополнительно фильтруются по сценарию, поэтому ответ о возвратах не должен ссылаться на соседний раздел о проценте выкупа.

Результаты выполнения

Дата проверки: 15 августа 2026 года.

Конфигурация

  • генерация: qwen3:8b через локальную Ollama;
  • embeddings: qwen3-embedding:0.6b;
  • отчёт: искусственный sales-report.csv;
  • справочник: metrics-guide.md;
  • RAG-индекс: 2 фрагмента.

Вопрос

Почему процент выкупа маленький?

Проверенные факты в ответе

  • общий процент выкупа: 69,13% — 159 из 230;
  • кроссовки: 58% — 29 из 50;
  • белая футболка: 62% — 62 из 100;
  • модель не назвала гипотезы доказанными причинами;
  • модель сообщила, каких данных не хватает для точной диагностики;
  • указаны только реально найденные источники:
  • metrics-guide.md#Процент выкупа;
  • metrics-guide.md#Ограничения.

Вывод

Цепочка «проверяемый расчёт → RAG → локальная модель → валидация источников» работает на демонстрационном сценарии. Данные отчёта не отправляются во внешний облачный API.

Сценарий возвратов

Вопрос «У какого товара больше всего возвратов и что стоит проверить?» также проверен через Docker и Ollama. Помощник рассчитал:

  • кроссовки: 20% — 5 возвратов из 25 выкупленных;
  • футболка: 10% — 8 из 80;
  • общий уровень: 12,38% — 13 из 105.

Модель правильно выделила кроссовки, перечислила необходимые для диагностики данные и не назвала предполагаемую причину доказанным фактом.

Сравнение периодов

Проверен сценарий с двумя CSV. Для тестовых данных система определила:

  • кроссовки: снижение выкупа с 80% до 50%, то есть −30 п.п.;
  • футболка: снижение с 80% до 70%, то есть −10 п.п.;
  • самое сильное падение произошло у кроссовок.

Сравнение выполняется проверяемым Python-кодом. Затем Ollama объясняет результат по RAG-справочнику. В живой проверке модель сохранила направление и величину изменений, не назвала гипотезы установленными причинами и сослалась на раздел metrics-guide.md#Сравнение периодов.