Files
2026-05-12 23:37:04 +03:00

5.7 KiB

GorychBot

Набор сервисов для Telegram-бота шаурмечной "Горыч" с отдельным парсером меню и отдельным RAG API.

Проект разделён на независимые части:

  • tgbot — основной Telegram-бот на aiogram.
  • menu_scraper — сервис, который парсит меню с https://gorych34.ru/.
  • rag_api — FastAPI-сервис с RAG, локальными эмбеддингами sergeyzh/rubert-mini-frida и function calling для подбора блюд.
  • redisdb — Redis для бота.
  • postgredb — PostgreSQL для бота.

Что делает проект

  1. menu_scraper забирает меню с сайта Горыча и сохраняет нормализованный JSON в data/menu/gorich_menu.json.
  2. rag_api индексирует:
    • знания о заведении: описание, контакты, режим, доставка, соцсети;
    • меню: названия, описания, ингредиенты, цены, размеры, фото.
  3. rag_api умеет:
    • отвечать на вопросы о заведении через RAG;
    • вызывать tool find_menu_items для подбора блюд по бюджету, категории и ингредиентам.
  4. tgbot работает отдельно от RAG API и использует PostgreSQL + Redis.

Сервисы

tgbot

Назначение:

  • Telegram-бот на aiogram.
  • Хранит данные в PostgreSQL.
  • Использует Redis для FSM/storage.

Файл env:

  • bot/.env

Зависимости:

  • redisdb
  • postgredb

Стартовая команда:

python aiogram_run.py

menu_scraper

Назначение:

  • Парсит меню с сайта Горыча.
  • Берёт встроенный каталог товаров из JSON на странице gorych34.ru.
  • Пишет результат в data/menu/gorich_menu.json.

Файл env:

  • menu_scraper/.env

Порт:

  • 8010

Основные endpoints:

  • GET /health
  • POST /scrape
  • GET /items
  • GET /items/{item_id}

Пример ответа:

  • один snapshot меню с total_items и массивом items

rag_api

Назначение:

  • Отдельный API для вопросов о заведении.
  • RAG по сайту, доставке, контактам и соцсетям.
  • Локальные эмбеддинги через sergeyzh/rubert-mini-frida на CPU.
  • Function calling через OpenRouter для подбора блюд из меню.

Файл env:

  • rag_api/.env

Порт:

  • внешний 8001
  • внутренний контейнерный 8000

Основные endpoints:

  • GET /health
  • POST /chat
  • POST /admin/reindex
  • GET /menu/search

POST /chat принимает:

{
  "message": "Посоветуй что-нибудь острое из пиццы до 400 рублей",
  "history": []
}

GET /menu/search умеет:

  • query
  • max_price
  • category
  • must_include
  • must_not_include
  • limit

Пример:

curl "http://localhost:8001/menu/search?query=острая%20пицца&max_price=450&category=пицца&limit=3"

Структура данных

data/menu/gorich_menu.json

Содержит:

  • item_id
  • name
  • category
  • description
  • ingredients
  • price
  • price_label
  • size
  • photo_url
  • source_url
  • scraped_at

data/chroma/

Локальная база ChromaDB для RAG:

  • коллекция знаний о заведении;
  • коллекция документов меню.

Настройка

В проекте используются отдельные env-файлы по сервисам:

  • bot/.env
  • menu_scraper/.env
  • rag_api/.env

Примеры:

  • .env.example
  • bot/.env.example
  • menu_scraper/.env.example
  • rag_api/.env.example

Минимум для запуска:

  1. Заполнить bot/.env
  2. Заполнить rag_api/.env
  3. При необходимости поправить menu_scraper/.env

Важно:

  • OPENROUTER_API_KEY нужен только для rag_api.
  • Для OpenRouter лучше использовать модель, которая нормально работает с tools в вашем регионе. Сейчас в конфиге стоит mistralai/mistral-medium-3-5.

Запуск

Поднять всё:

docker compose up -d --build

Проверка сервисов:

curl http://localhost:8010/health
curl http://localhost:8001/health

Пересобрать индекс RAG вручную:

curl -X POST http://localhost:8001/admin/reindex

Перепарсить меню вручную:

curl -X POST http://localhost:8010/scrape

Что уже реализовано

  • отдельный парсер меню;
  • сохранение меню в JSON;
  • отдельный RAG API;
  • ChromaDB;
  • локальные эмбеддинги rubert-mini-frida;
  • function calling для подбора блюд;
  • подбор по семантике + лексическим признакам меню;
  • Docker Compose для всех сервисов.

Что важно знать

  • rag_api сейчас не вшит напрямую в tgbot; это отдельный сервис с HTTP API.
  • rag_api на первом старте может подниматься дольше из-за загрузки модели эмбеддингов.
  • data/ хранит runtime-данные и не должен коммититься в git.