# Как настроить локальный семантический поиск по файлам с Rummage и EmbeddingGemma 2

> AI Release · @ai_release1 · https://ai-release.org/guides/kak-nastroit-lokalnyy-semanticheskiy-poisk-po-faylam-s.html

## TL;DR

- **Время выполнения:** 40–60 минут
- **Уровень сложности:** Intermediate
- **Понадобится:**
  - Python 3.10+ и `venv` (минимальную поддерживаемую версию сверьте с документацией Rummage)
  - Rummage — CLI-инструмент локальной индексации и поиска по файлам (набор команд и флагов сверьте с документацией проекта)
  - локальные веса модели EmbeddingGemma 2 — модель эмбеддингов семейства Gemma, превращает фрагмент текста в вектор чисел
  - свободное место под веса модели и под индекс (точный размер весов — на странице модели)
  - интернет только на этапе скачивания весов; сами запросы выполняются локально

## Требования и подготовка
![Иллюстрация к разделу «Требования и подготовка»](https://ai-release.org/guides/img/kak-nastroit-lokalnyy-semanticheskiy-poisk-po-faylam-s-ru-1.jpg?v=1792832251)


- ОС: Linux, macOS или Windows с WSL. Права на чтение каталога, который будете индексировать.
- Python: проверить `python3 --version`.
- Изоляция окружения: отдельный `venv`, чтобы не сломать системный Python.
- Диск: место под веса модели + место под индекс (индекс растёт примерно линейно от числа чанков — точную оценку сверьте с документацией Rummage).
- API-ключи: для локального инференса не нужны. Если репозиторий весов на Hugging Face закрыт, потребуется токен — сверьтесь со страницей модели.
- Если работаете в Windows без WSL, часть шагов с путями и правами отличается — см. [Как использовать ИИ-поиск в Windows 11: команды и настройка](https://ai-release.org/guides/kak-ispolzovat-ii-poisk-v-windows-11-komandy-i-nastroyk.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

Чек-лист перед стартом:

- [ ] `python3 --version` отрабатывает без ошибки
- [ ] есть каталог с файлами для индексации (например `~/Documents/wiki`), и вы знаете его полный путь
- [ ] на диске достаточно места под веса модели
- [ ] вы прочитали `rummage --help` и знаете, какие подкоманды есть в вашей версии

**Как устроен поиск.** Понимание потока данных экономит часы отладки:

1. Обход каталога → список файлов, отфильтрованный по `include`/`exclude`.
2. Нарезка файлов на чанки (фрагменты по N символов с перекрытием).
3. Каждый чанк прогоняется через EmbeddingGemma 2 → вектор чисел.
4. Векторы + путь к файлу + смещение чанка записываются в индекс.
5. Запрос пользователя прогоняется через ту же модель → вектор запроса.
6. Считается близость (косинусное сходство — мера «похожести» двух векторов) → топ-K чанков → пути файлов и сниппеты.

Ключевое следствие: **индексировать и искать надо одной и той же моделью**. Если модель эмбеддингов при индексации и при поиске различается, векторы окажутся в разных пространствах, и результат будет мусором.

**Пример:** если проиндексировали `~/Documents/wiki` моделью по пути `~/models/embeddinggemma-2`, то и запрос должен идти с `model.path: ~/models/embeddinggemma-2` в конфиге — не с другой версией весов.

## Шаг 1. Установить Rummage и скачать веса модели

**Что сделать:** создать виртуальное окружение, установить Rummage, скачать веса EmbeddingGemma 2 в локальный каталог.

**Зачем:** веса должны лежать на диске, чтобы поиск работал без сети; а изоляция окружения гарантирует, что команда `rummage` вызывается из нужного Python.

```bash
python3 -m venv ~/.venvs/rummage
source ~/.venvs/rummage/bin/activate
python -m pip install --upgrade pip
pip install rummage
```

**Пример:** имя пакета и способ установки (PyPI / cargo / готовый бинарник) сверьте с документацией Rummage — если пакет ставится иначе, замените строку `pip install rummage` на команду из документации.

Проверка установки:

```bash
rummage --version
rummage --help
```

**Как проверить:** `--version` печатает номер версии, `--help` — список подкоманд. Если оболочка отвечает `bash: rummage: command not found`, окружение не активировано.

Скачивание весов:

```bash
pip install -U huggingface_hub
huggingface-cli download <org>/<repo-embeddinggemma-2> \
  --local-dir ~/models/embeddinggemma-2
```

**Пример:** `<org>/<repo-embeddinggemma-2>` — идентификатор репозитория модели; точное значение сверьте на странице модели EmbeddingGemma 2, подставлять произвольную строку нельзя.

```bash
ls -la ~/models/embeddinggemma-2 | head
```

**Как проверить:** в листинге есть `config.json`, файлы токенизатора и файлы весов. Если каталог пуст — скачивание прервалось, повторите команду.

## Шаг 2. Создать конфиг и построить индекс
![Иллюстрация к разделу «Шаг 2. Создать конфиг и построить индекс»](https://ai-release.org/guides/img/kak-nastroit-lokalnyy-semanticheskiy-poisk-po-faylam-s-ru-2.jpg?v=1792832259)


**Что сделать:** описать конфиг (модель, путь индекса, размер чанка, что включать и что исключать) и прогнать индексацию каталога.

**Зачем:** без явного конфига инструмент либо возьмёт значения по умолчанию, либо не поймёт, где лежат веса. `exclude` критичен: без него в индекс попадут `.git`, `node_modules` и бинарники — индекс раздуется, а качество упадёт.

```yaml
# ~/.config/rummage/config.yaml
model:
  path: /home/<user>/models/embeddinggemma-2
  batch_size: 16
index:
  path: /home/<user>/.local/share/rummage/index
  chunk_size: 800
  chunk_overlap: 100
search:
  top_k: 10
include:
  - "**/*.md"
  - "**/*.txt"
  - "**/*.pdf"
exclude:
  - "**/.git/**"
  - "**/node_modules/**"
  - "**/*.png"
  - "**/*.zip"
```

**Пример:** замените `/home/<user>` на свой домашний каталог (`echo $HOME`). Имена ключей (`chunk_size`, `chunk_overlap`, `top_k`) и их допустимые диапазоны **сверьте с документацией Rummage** — конфиг выше показывает структуру, а не гарантированный для всех версий синтаксис.

**Почему это работает:** чанк — минимальная единица поиска. Слишком большой чанк размывает смысл, слишком маленький теряет контекст; перекрытие (`chunk_overlap`) не даёт разрезать мысль на границе фрагмента.

Индексация:

```bash
rummage index ~/Documents/wiki --config ~/.config/rummage/config.yaml
```

**Пример ожидаемого вывода** (формат зависит от версии):

```
Scanning /home/user/Documents/wiki
Matched 412 files
Embedded 3184 chunks
Index written to /home/user/.local/share/rummage/index
```

**Как проверить:** число `Matched files` больше нуля и примерно совпадает с `find ~/Documents/wiki -type f | wc -l`. Если `Matched 0 files` — фильтры `include`/`exclude` не пропускают ваши расширения.

Пробный запрос:

```bash
rummage search "как настроить резервное копирование" --top-k 5
```

**Как проверить:** в выводе — пути к файлам с оценкой близости. Если все результаты нерелевантны, проверьте, что `model.path` в конфиге указывает на те же веса, которыми строился индекс.

## Шаг 3. Проверить качество и зафиксировать результат
![Иллюстрация к разделу «Шаг 3. Проверить качество и зафиксировать результат»](https://ai-release.org/guides/img/kak-nastroit-lokalnyy-semanticheskiy-poisk-po-faylam-s-ru-3.jpg?v=1792832263)


**Что сделать:** прогнать контрольный набор запросов, убедиться, что нужные файлы попадают в топ, и только потом подключать поиск к своим сценариям.

**Зачем:** «команда отработала» не значит «поиск ищет». Проверять надо на запросах, для которых вы заранее знаете правильный ответ.

```bash
rummage search "договор аренды 2023" --top-k 3 --format json
```

**Пример:** флаг `--format json` (и само его наличие) сверьте с документацией — он нужен, чтобы результат можно было обработать скриптом, а не читать глазами.

Контрольная таблица — заполните её под свой корпус и прогоняйте после каждой переиндексации:

| Контрольный запрос | Ожидаемый файл в топ-3 | Что считать успехом |
|---|---|---|
| «инструкция по восстановлению пароля» | `docs/password-reset.md` | файл в топ-3 |
| «схема резервного копирования» | `ops/backup.md` | файл на 1-м месте |
| «договор аренды 2023» | `contracts/2023/lease.pdf` | файл в топ-3 |

**Как проверить:** из 10 контрольных запросов минимум 7 дают правильный файл в топ-3. Меньше — проблема в чанкинге (попробуйте `chunk_size` 400 и 1200 и сравните) или в том, что нужные файлы не попали в `include`.

Если корпус перерос несколько тысяч файлов и одного локального индекса мало, следующий шаг — вынести векторы в отдельную векторную БД: [Локальный RAG: как поднять Qdrant или Chroma на своём мини-ПК](https://ai-release.org/guides/lokalnyy-rag-na-mini-pk.html?utm_source=tg&utm_medium=channel&utm_campaign=guide_inline&utm_content=guide_to_guide).

## Возможные проблемы и решения

**Проблема. Команда не находится после установки**

- Ошибка: `bash: rummage: command not found`
- Причина: `venv` не активирован, либо пакет поставлен в другой интерпретатор Python.
- Решение: активируйте окружение и проверьте путь к бинарнику.

```bash
source ~/.venvs/rummage/bin/activate
which rummage
```

**Проблема. Модель не загружается по локальному пути**

- Ошибка: `OSError: Incorrect path_or_model_id: '/home/user/models/embeddinggemma-2'. Please provide either the path to a local folder or the repo id.` (текст может быть обёрнут сообщением Rummage — сверьтесь с документацией)
- Причина: в `model.path` опечатка, каталог пуст или веса скачаны не полностью.
- Решение: проверьте содержимое каталога и поправьте путь в конфиге.

```bash
ls ~/models/embeddinggemma-2/config.json
grep -n "path:" ~/.config/rummage/config.yaml
```

**Проблема. Индекс построился, но файлов ноль**

- Ошибка: `Matched 0 files`
- Причина: `include` содержит расширения, которых нет в каталоге, или `exclude` перекрывает всё дерево (например `**/*`).
- Решение: запустите индексацию в подробном режиме и сравните с фактическим списком файлов.

```bash
rummage index ~/Documents/wiki --config ~/.config/rummage/config.yaml --verbose
find ~/Documents/wiki -name "*.md" | wc -l
```

Временная мера для диагностики — убрать `exclude` целиком, переиндексировать и посмотреть на число файлов.

## Резюме и следующие шаги

Вы получили локальный семантический поиск: файлы нарезаны на чанки, векторизованы EmbeddingGemma 2 и лежат в индексе, а запросы ищут по смыслу, а не по точному совпадению слов. Дальше стоит автоматизировать переиндексацию по расписанию и, при росте корпуса, вынести векторы в Qdrant или Chroma.

## FAQ

**Нужен ли интернет для поиска?**
Нет, после скачивания весов модель работает локально; сеть нужна только на этапе установки и загрузки модели.

**Почему поиск находит файлы по словам, которых в них нет?**
Потому что сравниваются не слова, а векторы смысла: запрос «резервное копирование» может найти документ со словами «бэкап» и «снапшот».

**Можно ли сменить модель эмбеддингов на уже построенном индексе?**
Нет, индекс придётся перестроить: векторы разных моделей лежат в разных пространствах и несопоставимы.

**Почему PDF ищутся хуже, чем markdown?**
Текст из PDF извлекается с шумом (колонтитулы, разрывы строк), поэтому чанки получаются грязнее; проверьте качество извлечения на одном файле, прежде чем менять настройки.
