/rag

Поисковый слой, который никуда не звонит

Эмбеддинги, ключевой поиск и слияние рангов — всё на вашем процессоре. Вот что происходит с каждым промптом до того, как он дойдёт до модели, и что происходит, когда какой-то части нет.

0.927

MRR — скиллы

0.836

MRR — MCP-инструменты

120 МБ

модель, одна загрузка

3

корпуса, один движок

── конвейер

Два оценщика, одно слияние

Ни одной половине не верят в одиночку: эмбеддинги ловят перефразировку, ключевые слова — идентификатор, который эмбеддинги сглаживают, а reciprocal rank fusion разрешает спор.

01

Плотный — e5-small

Квантованный ONNX через fastembed, мультиязычный, 384 измерения. Считается на блокирующем потоке, поэтому цикл событий никогда не ждёт эмбеддинг.

02

Ключевой — TF-IDF

Стемминг Snowball для русского и английского: release, releasing и «релиз» сходятся к одной основе ещё до подсчёта.

03

Слияние — RRF

Reciprocal rank fusion по обоим рейтингам, затем косинусный порог (min_dense_score = 0.80) для кандидатов без пересечения по словам. Топ-3 на корпус за ход.

semantic/index.rs — the shape of a hit

// dense + lexical, fused by reciprocal rank
skill      releasing            dense 0.93  kw 0.71  → rrf 1
mcp        playwright.click     dense 0.88  kw 0.55  → rrf 2
history    2026-08-29 checkpoints  dense 0.81  kw 0.64  → rrf 3

── три корпуса

Один движок, три вещи, которые стоит помнить

Скиллы, инструменты и ваша собственная история индексируются одинаково и ищутся одним кодом — разница только в том, что позволено делать совпадению дальше.

/skills

Скиллы

Markdown-инструкции, найденные в дюжине агентских каталогов. Совпадение едет подсказкой — «этот скилл может подойти, загрузи его инструментом skill», — так что искать возможности вручную не приходится.

/mcp · tool_search

MCP-инструменты

Инструменты каждого подключённого сервера проиндексированы по имени и описанию. Совпавшим схема вставляется целиком, остальные остаются строкой-сводкой, пока их не спросят.

/search · history_search

История бесед

Сессии нарезаются, векторизуются и сохраняются в data_dir/semantic/history.json — инкрементально, с отметкой на сессию, поэтому перезапуск перечитывает метку, а не корпус.

── отложенные схемы

Инструменты, которыми вы не пользуетесь, не стоят ничего

Один сервер Playwright — это около 25 определений инструментов. Слать их все в каждом запросе — верный способ потратить окно контекста до начала работы.

каждый запрос, как обычно

tools: [
  {"name":"playwright__browser_click",
   "description":"Perform click on a web page…",
   "inputSchema":{"type":"object","properties":{…}}},
  {"name":"playwright__browser_type", …},
  {"name":"playwright__browser_navigate", …},
  … 22 more, every request, whether or not
    this turn has anything to do with a browser
]

каждый запрос, с отложенными схемами

mcp servers:
  playwright (25 tools)
  github (18 tools)

// the turn mentions a browser →
  + playwright__browser_click (full schema, inlined)
// or the model asks for more:
  tool_search("scrape a page")

mcp_schemas = "auto" откладывает после двенадцати инструментов, "full" не откладывает никогда, "deferred" — всегда. Выключите RAG целиком — полные схемы вернутся сами: модель не остаётся в неведении о том, что вообще существует.

── ваша история

Ответ, который вы уже находили

Агент уже решал с вами задачи. Эта переписка — индекс, а не архив: запросить её могут и вы, и модель.

/search compaction

/search how did we fix the PoW stall

  sort: relevance   role: any   unique: on

  1. 2026-08-29 · checkpoints   0.91
     "…the solver moved to a blocking thread so the
      event loop never waits on SHA-3…"
  2. 2026-08-14 · deepseek auth  0.78

  ↵ opens that session   s sort   r role   u unique
/search
Отдельный экран: сортировка по релевантности, свежести или давности, фильтр по роли, схлопывание до одного попадания на сессию. Enter открывает найденную сессию.
history_search
Тот же индекс в виде инструмента: модель вспоминает собственное прошлое решение, даже если вы забыли, что оно было.
инкрементально
Сессия векторизуется один раз и отмечается меткой; ничего не пересчитывается только потому, что вы перезапустились.
на диске
data_dir/semantic/history.json — локально, в открытом виде и удаляемо. Никакого сервиса за этим нет.

── управление

Все ручки, включая выключатель

Слой, который нельзя выключить, — это риск. Здесь он выключается четырьмя командами и четырьмя ключами конфига.

/rag
Живой статус: какие корпуса проиндексированы, какого они размера, готова ли модель.
/rag on|off
Весь слой целиком — подсказки, отложенные схемы, индексация истории. Выключено значит выключено.
/rag reload
Перепроверить (или перекачать) модель и переиндексировать скиллы, MCP-инструменты и историю.
/rag-limit
Потолок батча эмбеддера: auto, off или фиксированное число, когда с памятью туго.

config.toml

[semantic]
enabled = true          # /rag on|off flips this
top_k = 3               # hints per corpus per turn
min_dense_score = 0.80  # cosine floor without keyword overlap
mcp_schemas = "auto"    # auto | full | deferred

── режимы отказа

Он деградирует, а не ломается

Каждая зависимость здесь необязательна в рантайме, и на её отсутствие есть заранее описанный ответ.

модели нет на диске
Поиск сваливается в один лексический режим. Подсказки становятся грубее, работать не перестаёт ничего.
RAG выключен
Полные схемы MCP автоматически возвращаются в системный промпт, поэтому ни один инструмент не становится недоступным.
первый запуск
Модель качается в фоне, статус-бар показывает прогресс. Агент при этом полностью работоспособен.
мало памяти
/rag-limit ограничивает батч — индекс собирается дольше, и это все последствия.

Посмотреть, как устроен цикл вокруг него

deepseek · deepseek-chatctx:0% · | [streaming]