Read in:
Русский

expand: послойная навигация по оглавлению

expand — инструмент MCP для навигации по оглавлению заметки уровень за уровнем (progressive disclosure). Агент спускается по дереву секций сверху вниз и читает только нужный лист — не загружая ни всю заметку, ни её полное плоское оглавление.

Зачем: это и есть экономия токенов. Прочитать одну секцию вместо всей заметки — во много раз дешевле (порядок величины и воспроизводимый замер — token-economy-bench), и ответ не тонет в хвосте длинного контекста, где у модели падает recall. Подробнее о принципе — Token Economy.

Как работает

expand возвращает прямых детей одного узла оглавления:

  • Опусти toc_path (или передай []) — получишь секции верхнего уровня.
  • Передай toc_path узла — получишь его подсекции.

Каждый ребёнок несёт: title, level, path (breadcrumb для следующего вызова) и has_children (есть ли вложенность). Спускаешься, пока не дойдёшь до листа (has_children: false), затем читаешь его через note_html(toc_path=[...]).

Аргументы. Один из идентификаторов заметки (pid, note_id, path или href — берутся из результатов search) + опциональный toc_path:

{ "name": "expand", "arguments": { "pid": 42, "toc_path": ["Goroutines"] } }

Ответ — структурированный список детей; плюс короткая текстовая сводка («N subsection(s)» либо «has no subsections (leaf)»).

Рабочий цикл

1. search(query)
   → результаты со сниппетом, breadcrumb и matches[].toc_path

2. expand(pid=N)            # верхний уровень оглавления
   expand(pid=N, toc_path=[...])  # проваливаемся в нужную ветку
   → повторяем, выбирая ребёнка по смыслу, пока не лист

3. note_html(pid=N, toc_path=[...])
   → читаем только нужную секцию

Можно и короче: если search уже вернул точный matches[].toc_path, читай секцию сразу через note_html(toc_path=...). expand нужен, когда хочется осмотреть структуру и навигировать вглубь, не загружая лишнего.

Раньше search вываливал полный плоский toc каждой заметки. Теперь результаты «тонкие»: структура раскрывается по требованию через expand. Не платишь токенами за оглавление целиком — берёшь ровно тот уровень, что нужен.

expand vs. альтернативы

  • vs «прочитать всю заметку». Лист-секция в разы дешевле полной заметки, выигрыш растёт с её размером (числа — замер). Главное — ответ остаётся вверху контекста, а не в «мёртвой зоне» внизу.
  • vs grep -A -B. grep отдаёт ±N строк вокруг лексического совпадения; expand отдаёт цельную секцию по структуре заголовков, а нужную находит по смыслу (через векторный search), а не по строке. И главное — expand работает по MCP над базой, которую grep в принципе не достанет: хостед, расшаренной команде, удалённой, чужой. Для одного человека и локального волта grep честно достаточно; expand нужен, когда база большая, общая или удалённая.

Доступ

expand уважает права на заметку: агент видит структуру только того, что ему разрешено читать (per-note access). Лишнего оглавления он не получит.

Федерация

federated_expand делает то же по связанным базам — навигируешь структуру удалённой базы знаний через один MCP-эндпоинт. См. MCP Federation.

Проверь сам

Без зависимостей, только Python 3:

python3 scripts/expand_check.py

Скрипт бьёт по https://trip2g.com/_system/mcp, идёт по оглавлению через expand, читает нужную секцию и печатает таблицу «навигация + чтение vs вся заметка».

Связанное