Retrieval-слой под book-as-context: почему vector-only не годится
Задача конкретная: поиск по корпусу книг для AI-агента. Vector-only ломается предсказуемо. Разбор архитектурного решения — взять форк готового инструмента, встроить как MCP-слой, понять механику достаточно глубоко, чтобы знать, где он тоже ломается.
Проблема
Когда строишь book-as-context (агент работает с корпусом книг через MCP), первый инстинкт — взять vector-only RAG. На демо-корпусе работает. На реальных технических книгах ломается предсказуемо:
- точные термины, коды, имена глав теряются — эмбеддинг «размывает» лексическое совпадение;
- запрос-навигация («найди главу про two-phase commit у Таненбаума») и запрос-исследование («что пишут про durability») требуют разной механики;
- свежий раздел, добавленный вчера, проигрывает «усреднённо похожим» из старых заметок.
Методика
Вместо написания retrieval с нуля — форк obsidian-hybrid-search, встроенный как MCP-сервер под агентный слой book-as-context. Три сигнала вместо одного:
- 1. BM25 — лексическое совпадение. Точные термины, коды, имена глав не теряются.
- 2. Семантические эмбеддинги — близость по смыслу. Синонимы, перефразировки, концептуальные связи.
- 3. Fuzzy title / alias — навигация к конкретной заметке по имени.
Режимы под тип запроса:
hybrid (по умолчанию),
semantic,
fulltext,
title.
Слияние через RRF-фьюжн: заметка, высоко ранжированная в любом из переформулированных запросов агента, всплывает наверх.
obsidian-search "event bus durability" --mode hybrid --limit 5
{
"path": "tanenbaum/12-message-delivery.md",
"score": 0.87, // итоговый hybrid (RRF)
"matchedBy": ["semantic", "bm25"],
"scores": { "semantic": 0.81, "bm25": 0.93, "fuzzy_title": null }
}
Здесь bm25 (0.93) > semantic (0.81): точное лексическое совпадение
вытянуло наверх результат, который vector-only поставил бы ниже. Видимость по-компонентных scores —
это не отладочный вывод, а то, на основании чего агент решает, доверять ли результату.
Агентный слой поверх retrieval
Гибридный поиск закрывает ранжирование. Без слоя поверх — слепой RAG: чанки в индексе могут быть верные, а запросы идут языком задачи, не языком автора — мисматч. BM25 тогда не спасает: в запросе нет якорей, по которым книга проиндексирована. Про wiki одной книги и traversal от требования к паттерну — book-as-context (шаг 5). Ниже — как тот же retrieval стыкуется с библиотекой всех книг и с внешними источниками.
Два корпуса: obsidian-books и wiki одной книги
| Vault всех книг (obsidian-books) | Wiki одной книги (book-as-context) | |
|---|---|---|
| Содержимое | Сотни книг: сырьё (чанки), конспекты, wiki-заметки | Одна книга → concept-страницы olw, перекрёстные ссылки |
| Retrieval | Тот же hybrid-search (MCP) | Тот же MCP или индексация IDE |
| Зачем | Маркетинг, стратегия, перекрёстные авторы | Инженерная оптика на проекте (Таненбаум в Jira, API, инфра) |
| Риск | Сводки ранжируются выше raw — для цитаты нужен scope на сырьё | Неполное покрытие, draft с низким confidence |
Досье на книги (books/)
На каждую важную книгу — один файл-досье: оглавление, термины автора, синонимы перевода,
«запрос → глава», пары RU/EN. Агент читает досье до
books_search, а не повторяет формулировку пользователя.
Без досье поиск идёт, но шумнее: hybrid не заменяет знание лексики автора.
Fan-out и переформулировка
Вместо одного запроса — 3–5 переформулировок в
queries[]: якоря из досье + plain language задачи,
синонимы перевода, при слабой выдаче — оригинал термина. RRF заточен под fan-out.
После top-k — обязательный
books_read 2–3 полных заметок, не слепая цитата из snippet.
| Плохой запрос (язык задачи) | Хороший запрос (термин автора + plain language) |
|---|---|
| «найди что-то про Kafka» | reliable multicast + FIFO ordering — порядок доставки и надёжная рассылка |
| «как синхронизировать заказы» | persistent vs transient communication — очередь хранит vs получатель online сейчас |
| «гарантии доставки» | AMQP: unsettled → settled → forgotten — три состояния фиксации доставки |
Параллельный поиск в интернете (librarian)
Когда vault не закрывает задачу — два канала параллельно: obsidian-books + hybrid (первоисточник, досье) и веб (книга не в библиотеке, свежий контекст, критика). Приоритет: Obsidian как source of truth, интернет — дополнение. Для маркетинга и стратегии контур типичен; для book-as-context на одной инженерной книге часто хватает vault + wiki.
Артефакт
Форк
github.com/dobryakov/obsidian-hybrid-search
(TypeScript): CLI + MCP-сервер с README — retrieval под obsidian-books и под wiki
book-as-context.
Поверх retrieval: каталог досье books/,
регламент fan-out и books_read,
параллельный контур librarian (vault + веб). Без этой дисциплины hybrid-search остаётся
«правильным top-k на неправильном запросе».
Где ломается
- Веса слияния — не универсальны. Баланс BM25/semantic зависит от корпуса: на коде и на технической прозе разный — нужно калибровать под свои данные.
- Reranking стоит латентности — оправдан, когда агенту важен точный порядок результатов, иначе лишняя задержка.
- Форк не поддерживается upstream. Любые изменения схемы индекса — на тебе. Это осознанный выбор: понимать инструмент достаточно глубоко, чтобы его поддерживать.
- Запрос только языком задачи. Даже идеальный hybrid не найдёт reliable multicast, если в запросе только «Kafka». Нужны досье и fan-out — см. таблицу в методике и book-as-context.
- Сводка выше сырого чанка. В vault конспект/MOC часто ранжируется выше OCR-фрагмента; для дословной цитаты — scope на raw или переход из сводной заметки.
-
Fan-out без read.
Пять переформулировок без
books_read— много похожих snippet'ов, мало проверяемого текста.
Для кого и почему
Если вы строите AI-assisted систему поверх собственного корпуса — книг, вики, документации — этот разбор про retrieval-слой под неё. Не про то, как написать поиск, а про архитектурное решение: взять форк вместо велосипеда, понять механику достаточно глубоко, встроить как слой. В enterprise intake тот же приём — L2 corpus в clarify gate Jira (#11).
Хотите разобраться с retrieval-слоем под вашу AI-систему?
Архитектурный разбор: где vector-only ломается на вашем корпусе, что взять вместо него и как встроить в агентный workflow.
Написать на почтуДругие разборы
Серия инженерных разборов: реальная задача → методика → работающий артефакт → честный разбор, где он ломается.
К серии →