Почему ваш оффлайн-RAG врёт даже с гибридным поиском
Вы настроили гибридный поиск по моему гайду. FAISS плюс BM25. Точность выросла на 48%. Вы думаете – победа. Берёте 120 гигабайт ZIM-архивов с Википедией, запускаете локальный LLM и спрашиваете: \"Когда началась Вторая мировая война?\". Система отвечает: \"Вторая мировая война началась в 1941 году с нападения Германии на Польшу\". Стойте. 1941? Нападение на Польшу? Это же смесь фактов из разных параграфов. Галлюцинация высшего порядка.
Проблема не в поиске. Проблема в том, что происходит ПОСЛЕ поиска. RAG – это не просто \"найди и скорми LLM\". Это цепочка, где каждый следующий этап ломает работу предыдущего.
Вот что происходит в классическом RAG:
- Поисковик находит 10 релевантных чанков.
- LLM получает эти 10 чанков плюс промпт.
- LLM пытается осмыслить 10 страниц текста за один раз.
- LLM путается, теряет контекст, выхватывает фразы из середины и генерирует ерунду.
Multi-Joint RAG решает это радикально. Не одним большим прыжком, а тремя маленькими шагами с проверкой после каждого. Hermit-AI – конкретная реализация этой идеи для оффлайн-работы с терабайтами данных.
Три сустава одного механизма: как устроен Multi-Joint RAG
Название \"Multi-Joint\" (многосуставный) – не маркетинг. Это буквальное описание архитектуры. Представьте механическую руку. Один сустав – грубое движение. Три сустава – точная манипуляция.
| Этап (\"Сустав\") | Что делает | Что ломает в обычном RAG |
|---|---|---|
| Первичный поиск (Retrieval Joint) | Находит 50-100 потенциально релевантных документов быстрым методом | Ищет 10 документов медленным точным методом, тратит время |
| Переранжирование (Reranking Joint) | Берёт эти 100 документов и сортирует их по реальной релевантности | Скармливает LLM все найденные документы без сортировки |
| Верификация фактов (Verification Joint) | Проверяет каждый факт в ответе LLM по исходным документам | Доверяет LLM на слово, получает выдуманные цитаты |
Hermit-AI добавляет сюда четвёртый элемент – JIT (Just-In-Time) индексирование. Зачем индексировать 120 ГБ данных заранее, если пользователь спросит про 0.001% из них?
Hermit-AI изнутри: от команды установки до ответа
Теперь к практике. Я разберу Hermit-AI не как чёрный ящик, а как инженер – покажу, где что скрипит и как это чинить.
1Установка и первая ошибка
Не устанавливайте Hermit-AI через pip install hermit-ai. Это устаревший пакет. Правильный путь – клонировать репозиторий и собирать из исходников. Почему? Потому что зависимости там специфические, и в pip версии половина функций отключена.
Первая ловушка: Hermit-AI требует CUDA 12.1 для некоторых компонентов. Если у вас CUDA 11.8 – будет боль. Лучше запускать в Docker или собирать с флагом –no-deps, потом руками ставить совместимые версии.
После клонирования репозитория вы увидите три основных директории: retrieval_joint, reranking_joint, verification_joint. Это не три разных приложения. Это три модуля одного конвейера.
2Подготовка данных: ZIM файлы и не только
Hermit-AI заточен под ZIM – формат оффлайн-Википедии от Kiwix. Но это не ограничение. Под капотом работает libzim. Если у вас свои данные – конвертируйте их в ZIM или модифицируйте код загрузчика.
Вот как выглядит процесс индексации 100 ГБ ZIM-файла:
- Система читает оглавление ZIM (быстро, это метаданные).
- Создаёт маппинг \"статья → смещение в файле\".
- НЕ читает содержимое статей. Ещё нет.
- Строит инвертированный индекс для BM25 по заголовкам статей.
- Ждёт пользовательского запроса.
Это JIT-индексирование в действии. Индекс заголовков весит мегабайты, а не гигабайты. Когда приходит запрос \"Вторая мировая война дата\", система:
- Ищет по индексу заголовков статьи с совпадениями.
- Находит 50 статей (\"Вторая мировая война\", \"Начало Второй мировой войны\", \"1939 год\").
- ТОЛЬКО теперь читает содержимое этих 50 статей с диска.
- Строит для них векторные эмбеддинги (на лету!).
- Делает семантический поиск поверх BM25.
Потребление памяти: 2 ГБ вместо 20 ГБ. Скорость: поиск по 100 ГБ данных за 800 мс вместо 8 секунд.
3Трехэтапный конвейер: где что тормозит
Retrieval Joint использует гибридный поиск. Но не такой, как в моей предыдущей статье про гибридный поиск для RAG. Там мы совмещали BM25 и FAISS на одном уровне. Здесь BM25 работает как фильтр первого прохода, уменьшая пространство для векторного поиска.
Reranking Joint – самая ресурсоёмкая часть. Здесь используется cross-encoder модель (типа MiniLM). Она принимает запрос и каждый документ попарно, выставляет скор релевантности. Для 100 документов – 100 вызовов модели. На CPU это медленно (2-3 секунды). На GPU – 200-300 мс.
Verification Joint – самый интересный этап. LLM генерирует ответ. Затем та же cross-encoder модель проверяет, насколько каждый факт из ответа соответствует исходным документам. Если факт не подтверждается – система либо удаляет его, либо добавляет пометку \"не проверено\".
Важный нюанс: verification joint не гарантирует 100% точности. Он лишь снижает вероятность галлюцинаций. Если в исходных документах ошибка – система её воспроизведёт. Garbage in, garbage out.
Развёртывание в production: подводные камни
Вы хотите запустить Hermit-AI на своём сервере. Не спешите. Вот что сломается в первую очередь:
- Память. Три модели в памяти (эмбеддинговая, reranking, LLM) съедят 16+ ГБ GPU памяти. Без GPU reranking будет тормозить 5 секунд на запрос.
- Дисковый ввод-вывод. JIT-индексирование читает с диска при каждом запросе. Если диск HDD, а не SSD – поиск по 100 ГБ займёт не 800 мс, а 8000 мс.
- Тепловыделение. Постоянная нагрузка на CPU от libzim плюс GPU от моделей. Нужно мониторить температуру.
Оптимальная конфигурация для 100+ ГБ данных:
| Компонент | Минимум | Рекомендуется |
|---|---|---|
| CPU | 4 ядра | 8+ ядер |
| Оперативная память | 16 ГБ | 32 ГБ |
| GPU | Нет (сильно медленнее) | RTX 3060 12ГБ |
| Диск | HDD | NVMe SSD |
Альтернативы и когда Hermit-AI не подходит
Multi-Joint RAG – не серебряная пуля. Есть случаи, когда проще использовать более простой локальный RAG или даже облачные решения.
Не используйте Hermit-AI если:
- У вас меньше 10 ГБ данных. Overkill.
- Вам нужна latency ниже 100 мс. Три этапа добавят минимум 200-500 мс.
- Вы не контролируете качество исходных данных. Verification joint не спасёт от мусора на входе.
- У вас нет времени на тонкую настройку. Hermit-AI из коробки работает, но хорошо работает только после калибровки.
Что использовать вместо:
- Для маленьких датасетов (до 10 ГБ) – обычный FAISS + хороший промпт.
- Для latency-critical задач – оптимизированный поиск для AI-агентов с кэшированием эмбеддингов.
- Для данных с плохой структурой – мультимодальный RAG, который умеет работать с сырыми файлами.
Финальный совет: начните с малого, масштабируйте осторожно
Не пытайтесь сразу запустить Hermit-AI на 100 ГБ производственных данных. Возьмите 1 ГБ тестовых данных. Настройте конвейер. Измерьте точность и latency. Потом добавьте ещё 10 ГБ. Потом 50 ГБ.
Самая частая ошибка – настроить всё на маленьком датасете, получить отличные результаты, загрузить 100 ГБ и увидеть, как система падает по памяти. Потому что JIT-индексирование не магическое – оно всё равно читает с диска при каждом запросе. 100 ГБ данных – это 100 ГБ на диске, которые нужно просканировать хоть как-то.
Multi-Joint RAG в лице Hermit-AI – мощный инструмент. Но как любой мощный инструмент, он требует уважения. Не торопитесь. Тестируйте каждый этап отдельно. Логируйте промежуточные результаты. И помните – даже самая сложная система не заменит человеческой проверки там, где точность критична.
P.S. Если вы работаете с кодом вместо текстовых данных, посмотрите на Ragex для семантического поиска по коду. Там другие проблемы и другие решения.