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

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

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


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

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

[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". Объединение означает, что ни один подход не подводит — вы получаете лучшее от обоих в каждом запросе.

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

# Проект с упором на код — доминируют идентификаторы
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
octocode graphrag get-relationships --node_id src/auth/middleware.rs

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


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

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

# На машине 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. Обновитесь:
    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. Он обеспечивает поиск по коду внутри Octomind — MCP-сервер — это то, как они общаются.