Octobrain 0.9.0: знание выходит в мультиплеер
Ваша команда уже написала документацию. Runbook для деплоя, правила «не трогай это без миграции», выстраданные заметки о том, почему платёжный сервис ретраит именно так. Всё это живёт в вики, которую никто не читает, в закреплённом сообщении в Slack и в головах трёх человек. Каждая новая сессия агента — и каждый новый коллега — стартует с нуля и переучивает всё это заново через боль.
0.7.0 научила память каждого агента поддерживать себя саму — sleep consolidation, decay, goal-anchored сворачивание. Это было про одну память, которая умнеет сама по себе.
0.9.0 — про вторую половину проблемы: знание, которое не должно переучиваться на каждой машине. Она делает слой знаний Octobrain общим — версионируется в git, разносится по scope по имени, синхронизируется автоматически — и обостряет recall, чтобы нужный факт побеждал чаще. (Заодно мы свернули сюда и наработки 0.8.0.)
Git-Backed Knowledge Boxes — выкатывайте знание как код
Это главное. Knowledge box — это git-репозиторий, набитый markdown: правила, документация, плейбуки, заметки по архитектуре, — который Octobrain клонирует, индексирует и держит в синхроне. Соберите его один раз, версионируйте как код — и каждый агент на каждой подписавшейся машине получает одно и то же знание, доступное для поиска.
Есть две разновидности, и они покрывают два реальных случая:
Локально для проекта — просто закоммитьте директорию .box/. Сложите живое знание вашего проекта в .box/ в корне репозитория. Любой, кто клонирует репозиторий и запустит Octobrain, получит его проиндексированным автоматически — без лишней команды, без настройки remote. Оно путешествует вместе с кодом, потому что оно и есть в коде.
Remote — подпишитесь на общий box. Укажите Octobrain на git-URL — и он делает shallow-clone box-а и индексирует его под scope:
# Subscribe to your org's shared knowledge box
octobrain box import https://github.com/acme/engineering-knowledge
# Index it at the global scope — visible in every project on this machine
octobrain box import https://github.com/acme/conventions --global
# Pull + smart-reindex every subscribed box and the local .box/
octobrain box sync
# See what you're subscribed to, or drop one
octobrain box list
octobrain box remove github.com/acme/engineering-knowledge
Каждый чанк из box получает стабильный source URI вида box://<host>/<org>/<repo>/..., так что он сгруппирован, атрибутируем и аккуратно удаляем — выдёргиваете box, и все его строки уходят вместе с ним. Ре-синки умные и построены на хэшах: переэмбеддятся только изменившиеся файлы, так что sync по неизменившемуся box стоит почти ничего.
А под MCP вам даже не нужно звать sync — сервер обнаруживает .box/ каждого проекта, прощупывает org-box и обновляет подписанные remote в фоне, один раз за сессию, single-flight-ом, так что это никогда не блокирует запрос. Ваш агент просто начинает находить знание команды в своих поисках.
[knowledge]
chunk_size = 1200 # boxes index through the same chunker as everything else
Суть: runbook перестаёт жить в чьей-то голове. Он живёт в репозитории, ищется по смыслу и всплывает в контексте вашего агента в тот момент, когда он релевантен, — для всех.
Scope-ы заменяют хэши проектов — память с именем
До сих пор Octobrain изолировал память по проектам, хэшируя URL вашего Git remote в непрозрачную SHA-256-директорию. Это работало, но прочитать её было нельзя, нацелиться на неё нельзя и поделиться ею тоже нельзя.
0.9.0 заменяет это на scope-ы: человекочитаемые строки, выводимые автоматически из вашего Git remote (или из локального пути как запасной вариант), которые вы реально видите и можете на них указать.
# Auto-detected from the git remote — nothing to configure
octobrain memory remember "rate limiting approach"
# Or target a scope explicitly
octobrain memory remember "rate limiting approach" --scope acme/payments
# Store something that should be visible everywhere, not just this project
octobrain memory memorize --title "Team convention: trunk-based, no long-lived branches" \
--content "..." --global
Именно scope-ы делают box-ы связными: remote-box по умолчанию привязывается к scope уровня организации, .box/ привязывается к scope своего проекта, а --global ставит знание или память перед каждым проектом на машине. Одна система именования, используемая везде, — пути хранения, фильтры поиска, статистика и логи теперь читаются на человеческом языке, а не хэшами.
Это единственное breaking-изменение, которое вас касается: флаг --project и параметры инструментов project теперь стали --scope. То же поведение, читаемое имя. См. Апгрейд.
Recall по нескольким запросам, который реально окупается — RRF-фьюжн
Octobrain давно поддерживает поиск по нескольким запросам — разложить размытый вопрос на несколько более чётких и искать их вместе:
octobrain memory remember "authentication" "session security" "jwt expiry"
Проблема была в слиянии. Старая логика брала лучший единичный score каждого воспоминания и добавляла плоские 10% за каждое дополнительное совпадение — смешивая по-запросные score, вычисленные в несравнимых масштабах. Воспоминание, которое стабильно ранжировалось по всем трём запросам, могло проиграть разовому топ-попаданию по одному запросу. Декомпозиция на деле не помогала; иногда вредила.
0.9.0 заменяет это на Reciprocal Rank Fusion — тот же ранговый фьюжн с k=60, который Octobrain уже использует для объединения BM25 и векторного поиска внутри хранилища. RRF работает по рангам и не зависит от масштаба: воспоминание, которое хорошо встаёт по многим запросам, обходит то, что выстреливает по одному. Теперь декомпозиция запроса окупается так, как и должна. Это чистая математика — без LLM, без лишнего конфига, — а rrf_fuse — это маленькая, покрытая юнит-тестами функция, которой можно доверять.
Recall знает, что актуально — ранжирование с учётом Supersedes
Факты устаревают. Вы решили использовать Postgres, а через шесть недель переключились на SQLite. Обе заметки в памяти, обе матчат «какую базу мы используем» — и старому ответу нечего делать в победителях.
В Octobrain всегда был тип связи Supersedes, но он определялся, парсился и хранился — а потом никогда не читался при извлечении. Готовая возможность, лежащая мёртвым грузом.
0.9.0 подключает его. Когда активное ребро X Supersedes M помечает результат как устаревший, извлечение мягко понижает устаревший (×0.1 — никогда не удаляя), так что актуальный факт поднимается наверх, а история остаётся доступной для запросов. Два намеренных предохранителя:
- Рёбра уважаются, но никогда не создаются автоматически. Распознать настоящее противоречие требует семантического суждения, и Octobrain намеренно держит это вне горячего пути. Вы (или ваш агент) ставите supersede; извлечение его уважает. По MCP инструмент
knowledgeтеперь активно направляет агентов создавать supersedes-связи, когда они обновляют факт. - Best-effort. Сбой при поиске связи оставляет результат нетронутым, а не выбрасывает его. В худшем случае вы возвращаетесь к старому поведению, но не хуже.
Актуальное решение побеждает; след назад к старому сохраняется.
Recall с привязкой ко времени — временные фильтры и фильтры релевантности
«Что я решил на прошлой неделе?» — вопрос, который люди задают постоянно, и один семантический поиск отвечает на него плохо: релевантность ничего не знает о времени.
MemoryQuery уже поддерживал created_after / created_before (пробрасываемые прямиком в индекс created_at) и min_relevance — но MCP-инструмент remember никогда их не заполнял. Ещё одна готовая, но мёртвая возможность. 0.9.0 выставляет обе:
created_after/created_before— дата в ISO-8601 (2026-06-01) или полный таймстамп RFC3339. Голая дата означает полночь UTC; всё, что не парсится, просто пропускает фильтр, а не падает с ошибкой.min_relevance— пол качества результата на конкретный вызов, перекрывающий глобальный дефолт.
Инструмент говорит агенту вычислить окно самому — он уже знает сегодняшнюю дату, — так что внутри инструмента нет хрупкого парсинга дат на естественном языке. «Что я решил на прошлой неделе» превращается в чистый индексированный range-скан — ровно тот тип привязанных ко времени вопросов, которые измеряет LongMemEval.
Мы подкрепили это цифрами — retrieval-бенчмарки BEIR
0.7.0 добавила LongMemEval для долгосрочной памяти. 0.9.0 добавляет retrieval-харнесс BEIR, чтобы мы могли оценивать слой ранжирования — эмбеддинги + фьюжн BM25 + реранкинг — на стандартных датасетах с настоящими qrels, полностью локально, без LLM-судьи.
С дефолтным локальным эмбеддером (bge-small-en-v1.5, 384-dim, 33M параметров), измерено как nDCG@10:
| Датасет | Octobrain vector | Octobrain hybrid | BM25 | bge-small-en-v1.5 |
|---|---|---|---|---|
| SciFact (5.2K документов, 300 запросов) | 0.722 | 0.742 | 0.665 | 0.713 |
| NFCorpus (3.6K документов, 323 запроса) | 0.341 | 0.363 | 0.325 | 0.343 |
Колонка только-dense воспроизводит опубликованные BEIR-числа эмбеддера — это харнесс, валидирующий сам себя. Колонка hybrid (BM25 + вектор, слитые через RRF, дефолт Octobrain) добавляет +2 nDCG@10 к голому эмбеддингу и обходит классический BM25 на обоих датасетах. Воспроизведите сами: cd benches && bash scripts/run_retrieval.sh. Заявления о recall выше — это заявления, за которые мы можем поручиться.
Под капотом
Более тихие изменения, которые держат всё быстрым и предсказуемым по мере роста корпуса:
Две новые ручки поиска, в конфиге.
search.similarity_threshold(дефолт0.3) — глобальный пол релевантности для семантических запросов;search.max_results(дефолт50) — жёсткий потолок, который не может превысить ни один вызывающий. Обе теперь проброшены сквозь весь путь, а не заявлены-и-проигнорированы.[search] similarity_threshold = 0.3 # min relevance for semantic queries (0.0–1.0) max_results = 50 # hard ceiling on results from any searchТаймауты для эмбеддингов и реранкера. Медленный или зависший вызов провайдера больше не стопорит поиск —
timeout_secs(дефолт30) ограничивает оба, с примером в конфиге реранкера.Фоновая инициализация. Тяжёлые стартовые задачи запускаются вне горячего пути, так что первый запрос после старта не платит за прогрев индекса.
Автоматическое обнаружение scope и переопределение конфига (из 0.8.0). Octobrain выводит ваш scope из рабочей директории автоматически, а
OCTOBRAIN_CONFIG_PATHпозволяет указать на свой файл конфига — удобно для CI, контейнеров и multi-tenant-сетапов. Блокировки проекта и роли были разведены, так что несвязанные сессии перестают конкурировать.Multi-arch Docker. Релиз теперь собирает и пушит multi-arch-образы, так что
arm64(Apple Silicon, Graviton) иamd64оба полноценны.Упрочнённая математика ранжирования. Правки лимита кандидатов реранкера, нормализации RRF, исключения архивированных воспоминаний и PRF-предохранитель подтягивают краевые случаи в новом пути извлечения. Поиск по knowledge теперь также возвращает полную родительскую секцию, а не усечённый фрагмент.
К большинству из них вы не потянетесь напрямую. В этом и смысл.
Как выглядит 0.9.0 на практике
Новый инженер приходит в команду платежей:
- Он клонирует репозиторий. Его директория
.box/— runbook деплоя, правила «не обходи слой идемпотентности», заметки о том, почему мы ретраим, — индексируется автоматически при первом запуске его агента. Ноль настройки. - Его машина подписывается на org-box (
octobrain box import …), так что общекомпанейские конвенции появляются под global scope, в каждом проекте. - Он задаёт агенту размытый вопрос — «как мы тут обрабатываем сбои вебхуков?» Декомпозиция на несколько запросов разворачивает его, RRF сливает ранги, и запись из командного runbook оказывается наверху.
- Решение изменилось в прошлом месяце — команда ушла от очереди, которую раньше рекомендовала. Старая заметка помечена как superseded, так что побеждает актуальный подход, а история по-прежнему в одном запросе.
- Он спрашивает «что мы поменяли на прошлой неделе?» — временной фильтр, чистый индексированный диапазон, без шума полугодовой давности.
Никто заново не объяснял систему. Знание уже было записано — Octobrain просто сделал его находимым, актуальным и общим.
Апгрейд
С 0.7.x или 0.8.x миграция небольшая.
Конфиг — --project становится --scope. Это единственное breaking-изменение. Везде, где вы передавали --project <id> в CLI или параметр project MCP-инструменту, используйте вместо этого --scope <name>. Главное улучшение: значение теперь — человекочитаемая строка (автоматически выводимая из вашего Git remote), а не хэш, — так что почти всегда вы можете вообще выкинуть флаг и отдать всё на откуп обнаружению.
octobrain memory remember "api design" --scope acme/web # was: --project <hash>
Хранилище — делать нечего. Колонка scope и её индекс добавляются при первом запуске, а существующие воспоминания мигрируют на месте. Ни ручных шагов, ни простоя.
Новый конфиг аддитивен. search.similarity_threshold, search.max_results и timeout_secs для эмбеддинга/реранкера — все идут с рабочими дефолтами. Добавляйте их, только если хотите тюнить.
Knowledge boxes — opt-in. Ничего не меняется, пока вы не закоммитите директорию .box/ или не запустите octobrain box import. Существующие проиндексированные источники не тронуты.
MCP-клиенты — обновите список инструментов. remember теперь принимает created_after, created_before и min_relevance; memorize берёт --global. Никаких переименований у пяти основных инструментов — просто новые опциональные поля, которыми может пользоваться ваш агент.
Исходники, бинарники и Docker-образы: github.com/muvon/octobrain. Что-то сломалось — открывайте issue, мы их читаем.



