# Snowbike RAG — MVP Гибридный поиск по 140K+ сообщениям Telegram-группы «Сноубайк Россия». ## Архитектура ``` Запрос → Flask API → Meilisearch (точный) + ChromaDB (семантика) → Sonnet 4.6 → Ответ ``` ## Быстрый старт ```bash # Запустить все сервисы ./start.sh # Поиск curl "http://localhost:5557/search?q=масло+для+Polaris+850" # С фильтром по топику (63467 = Техничка) curl "http://localhost:5557/search?q=гусеницы&topics=63467&limit=10" ``` ## Эндпоинты | Метод | URL | Описание | |-------|-----|----------| | GET | `/health` | Проверка здоровья | | GET | `/search?q=...&topics=...&limit=...` | Гибридный поиск | | GET | `/topics` | Список топиков | | GET | `/stats` | Статистика индексов | ## Структура ``` tasks/snowbike-rag/ ├── server.py — Flask API (порт 5557) ├── start.sh — Запуск сервисов ├── scripts/ │ ├── parse_messages.py — Парсинг batch-файлов → JSONL │ ├── index_meilisearch.py — Загрузка в Meilisearch │ ├── index_chromadb.py — Embeddings + ChromaDB │ └── search.py — Гибридный поиск + LLM ├── config/ │ ├── requirements.txt │ └── docker-compose.yml — Для запуска Meilisearch через Docker ├── bin/ │ └── meilisearch — Бинарник Meilisearch (если без Docker) └── data/ ├── messages.jsonl — Распаршенные сообщения ├── meilisearch/ — Данные Meilisearch ├── chromadb/ — Векторная БД └── logs/ — Логи ``` ## Данные - **Источник:** `/data/telegram-collector/raw/1242788123/` - **Топиков:** 12 - **Сообщений с текстом:** 140,275 - **Meilisearch:** 140,275 документов - **ChromaDB:** ~10,000–136,000 документов (векторная база, доступна с Flask) - **Модель embeddings:** `paraphrase-multilingual-MiniLM-L12-v2` (локальная, бесплатно) - **LLM:** `claude-sonnet-4-5` через OpenRouter (~$0.005/запрос) > **Примечание по ChromaDB:** ChromaDB работает в **embedded mode** (PersistentClient). Это значит: > - Отдельного сервера на порту 8000 **нет** и не нужно > - ChromaDB загружается автоматически при первом запросе к Flask > - Данные хранятся в `data/chromadb/` > - При ошибке `Error loading hnsw index` — коллекция повреждена, см. раздел «Восстановление» ## Топики | ID | Название | |----|----------| | 1 | Основная | | 63155 | Барахолка | | 63467 | Техничка | | 63469 | Экип | | 64805 | Обзоры | | 76611 | Инструкции и 3D | | 97494 | Электрички | | 99795 | Китай | | 103316 | ОФФТОП | | 103317 | Локации | | 117112 | Опросы | | 161840 | Соревнования | ## Первый запуск (индексация) ```bash # 1. Парсинг сырых данных (~2 мин) python3 scripts/parse_messages.py # 2. Индексация в Meilisearch (~5 мин) python3 scripts/index_meilisearch.py # 3. Генерация embeddings + ChromaDB (~25 мин на CPU) python3 scripts/index_chromadb.py # 4. Запуск API python3 server.py ``` ## Обновление (инкрементальное) ```bash # 1. Обновить source-файл (parse_messages.py) — получить incremental_YYYYMMDD.jsonl # 2. Долить в Meilisearch python3 scripts/index_incremental_meili.py # 3. Долить в ChromaDB python3 scripts/index_incremental_chroma.py # 4. Перезапустить Flask (для сброса кэша коллекции) ./start.sh ``` > ⚠️ **Не запускайте `reindex_safe.py` без необходимости** — он переиндексирует весь корпус (~140K сообщений) и занимает ~1–2 часа. Только для полного восстановления после потери данных ChromaDB. ## Восстановление ChromaDB Если при поиске ошибка `Error loading hnsw index` или `ChromaDB errors` в `/stats`: ```bash # 1. Остановить Flask pkill -f "server.py" # 2. Бэкап и очистка cp -r data/chromadb "data/chromadb.bak-$(date +%Y%m%d-%H%M%S)" rm -rf data/chromadb/* # 3. Запустить инкрементальную индексацию (только новые сообщения) python3 scripts/index_incremental_chroma.py # 4. Запустить Flask ./start.sh ``` Если нужен полный rebuild ChromaDB (долго, ~1–2 часа): ```bash python3 scripts/reindex_safe.py # запускать в screen/tmux! ```