# Octocode 0.15.0: Локальная работа по умолчанию, гибридный поиск везде

> Octocode 0.15.0 включает гибридный поиск и реранкинг по умолчанию, поставляет локальный стек моделей без необходимости API-ключей и делает структурный grep умнее в отношении паттернов, которые LLM обычно генерируют неправильно.

В первый раз, когда вы запускали `octocode index` на новой машине, вы получали ошибку конфигурации. Требуется: API-ключ Voyage. Нормально для команд, у которых он уже есть — раздражает всех, кто впервые пробует Octocode.

0.15.0 это исправляет. Никаких API-ключей для получения полезного и быстрого индекса. Гибридный поиск и реранкинг включены по умолчанию. А структурный grep теперь автоматически восстанавливается после неправильных паттернов, которые обычно генерируют LLM — вместо того чтобы возвращать ноль результатов и молчать.

42 коммита с 0.14.1. Вот что важно.

---

## API-ключ не нужен

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

```toml
[embedding]
code_model = "fastembed:jinaai/jina-embeddings-v2-base-code"
text_model = "fastembed:nomic-ai/nomic-embed-text-v1.5"

[search.reranker]
enabled = true
model   = "fastembed:jina-reranker-v2-base-multilingual"

[search.hybrid]
enabled = true
default_vector_weight  = 0.6
default_keyword_weight = 0.4
```

Стандартный опыт теперь такой: клонируй репозиторий, запусти `octocode index`, получи результаты. Опции API Voyage, Cohere и Jina никуда не делись — закомментированы в шаблоне — если они нужны.

Одно предупреждение: первый `octocode index` после обновления скачает новые локальные модели, несколько сотен МБ суммарно. Однократная загрузка, затем кэшируется.

---

## Гибридный поиск включён по умолчанию

Раньше Octocode выбирал между плотным векторным поиском и BM25. 0.15.0 объединяет их в каждом запросе с помощью Weighted Reciprocal Rank Fusion, работающей внутри LanceDB.

Плотные векторы проигрывают на запросах с конкретными идентификаторами вроде "find `parse_remote`". BM25 проигрывает на парафразированных запросах вроде "функция, которая управляет настройкой удалённого pull". Объединение означает, что ни один подход не подводит — вы получаете лучшее от обоих в каждом запросе.

Баланс настраивается:

```toml
# Проект с упором на код — доминируют идентификаторы
default_vector_weight  = 0.3
default_keyword_weight = 0.7

# Проект с упором на документацию — доминирует семантика
default_vector_weight  = 0.8
default_keyword_weight = 0.2
```

Небольшая заметка об очистке: старые поля конфигурации `keyword_path_weight`, `keyword_content_weight` и подобные удалены. Они всё равно не имели эффекта. Старые конфиги с этими ключами загрузятся нормально, но значения игнорируются. Вместо них используйте `default_vector_weight` / `default_keyword_weight`.

---

## Структурный grep больше не возвращает пустые результаты

Проблема структурного поиска раньше: LLM часто генерируют неправильные типы узлов. Python использует `function_definition`, а не `function_declaration`. Rust использует `function_item`. LLM выбирает то, что кажется естественным, получает ноль результатов — и никаких подсказок почему.

Теперь когда паттерн ничего не находит, Octocode автоматически пробует всё более мягкие интерпретации — и знает правильный тип для каждого языка. `function_declaration` в Python становится `function_definition`. `func`, `fn`, `function` — всё разрешается правильно, независимо от того, что напечатал LLM.

Когда ничего не сработало, вы получаете полезную ошибку вместо тишины:

> "В Python используйте `function_definition`, а не `function_declaration`"

Ещё одно исправление: большие совпадения — целые тела классов, большие блоки функций — раньше выгружали всё и переполняли контекстное окно. Теперь показываются первые несколько строк и сводка:

```
src/foo.rs:42:  pub fn handle_request(req: Request) -> Result<Response> {
                    let user = authenticate(&req)?;
                    let payload = req.json()?;
                    if !validate(&payload) {
... (24 more lines)
```

Короткие совпадения передаются без изменений.

---

## GraphRAG теперь отслеживает наследование

GraphRAG уже строил граф вызовов и импортов между файлами. С 0.15.0 он также извлекает отношения наследования и реализации интерфейсов — в C++, Go, Java, JavaScript, TypeScript, PHP, Python, Ruby и Rust.

Каждая запись функции/класса теперь включает:

- `extends` — суперклассы, родительские трейты/интерфейсы, embedding структур в Go
- `implements` — реализации интерфейсов, удовлетворения трейтов, `impl Trait for Type` в Rust

```bash
octocode graphrag get-relationships --node_id src/auth/middleware.rs
```

Теперь возвращает также рёбра наследования и реализации вместе с существующим графом импортов и вызовов. AI-агент теперь может ответить на вопрос "кто реализует `Validator`?" или "какие классы расширяют `BaseHandler`?" без ручного сканирования файлов. Имена типов нормализуются, поэтому разрешение между файлами работает даже с дженериками и типами с неймспейсами.

---

## Экспорт и импорт индекса

Перенос проекта на новую машину раньше означал повторный запуск полного embedder'а. С большим репозиторием и локальными моделями это занимает время.

```bash
# На машине A
$ octocode export
Exported 142.30 MB
/Users/dk/Work/myproject/octocode-abc123-20260520-203708.tar.zst

# Перенесите файл, затем на машине B
$ cd /path/to/same/project
$ octocode import octocode-abc123-20260520-203708.tar.zst
```

Архив включает как основной индекс, так и оверлеи веток. Импорт атомарен — никакого частичного состояния при сбое. Экспорт берёт блокировку индекса, поэтому параллельные операции ждут, а не конкурируют.

---

## Всё остальное

- **Корректность дельты веток** — оверлеи веток больше не применяются молча поверх устаревшего основного индекса. Octocode обнаруживает несоответствие и явно предупреждает вместо того, чтобы возвращать несвязные результаты.
- **Методы теперь несут имя своего класса** — поиск `Suppression.mark_set` или `Foo.bar` теперь находит метод напрямую. Раньше это работало только если описание случайно упоминало получателя.
- **Лучшая разбивка больших классов** — Python, TypeScript, C++ и Ruby теперь индексируют методы по отдельности. Больше никаких результатов в виде одного гигантского блока для класса на 2000 строк.
- **Лимит мульти-запросов поднят с 5 до 10** — агенты, которые раньше делали два запроса, теперь справятся одним.
- **Файлы модулей C++20 распознаются** — `.cppm`, `.ixx`, `.mxx`, `.ccm`, `.cxxm`, `.cc`, `.cxx`, `.c++`, `.hxx` индексируются как код.
- **Больше текстовых форматов индексируется** — `yaml`, `toml`, `dockerfile`, `makefile`, `ini`, `conf`, `env`, `xml`, `html`, `sql`, `csv`, `tsv`, `log` и другие теперь индексируются как текстовые блоки.
- **Обслуживание базы данных автоматическое** — каждый запуск индексации компактирует базу данных. Поиск остаётся быстрым по мере роста индекса.
- **Статические бинарники для Alpine и musl Linux** — больше никаких ошибок `libonnxruntime.so` в минимальных контейнерах.
- **Бинарник меньше, эмбеддинги быстрее** — профиль сборки сменился с `opt-level = 3` на `opt-level = "z"`. Бинарник заметно меньше — и парадоксально, локальные эмбеддинги тоже стали быстрее. Меньший код лучше помещается в кэш инструкций процессора, что важнее для этой рабочей нагрузки, чем агрессивный inlining.
- **Кросс-модальное слияние для `--mode all`** — старое фиксированное разбиение 1/3 между кодом/текстом/документацией заменено на RRF по каждой модальности. Каждый список результатов вносит вклад по рангу внутри своего списка — лучший микс, адаптирующийся к тому, где реально находятся совпадения, без проблем несовместимости масштабов между моделями эмбеддингов.

---

## Путь обновления

1. Создайте резервную копию существующего индекса: `octocode export`
2. Обновитесь:
   ```bash
   brew upgrade muvon/tap/octocode
   # или
   curl -fsSL https://raw.githubusercontent.com/Muvon/octocode/master/install.sh | sh
   ```
3. Выберите модели: примите новые локальные значения по умолчанию (никаких изменений конфигурации не требуется) или вставьте обратно предыдущую конфигурацию `[embedding]` и `[search.reranker]`, чтобы продолжить использовать Voyage/Cohere/Jina.
4. Если нужен чистый реиндекс (рекомендуется — новая разбивка не применится к уже проиндексированным файлам): `octocode clear && octocode index`
5. Опционально: настройте `default_vector_weight` / `default_keyword_weight` под тип вашего проекта.

Если вам нужен чистый векторный ранжинг для точного воспроизведения результатов 0.14.x, используйте `[search.hybrid] enabled = false`. Загрузку модели реранкера при первом поиске можно пропустить через `[search.reranker] enabled = false`.

---

Octocode — open source (Apache 2.0) на [github.com/Muvon/octocode](https://github.com/Muvon/octocode). Он обеспечивает поиск по коду внутри [Octomind](https://octomind.run) — MCP-сервер — это то, как они общаются.
