← Усі статті

Великий файл лишається на сервері: Matryoshka віддає агенту ярлик

Matryoshka на TypeScript тримає документ на сервері й відповідає короткими ярликами. Перевірка «Війни і миру» та журналу без ключа мовної моделі.

Великий файл лишається на сервері: Matryoshka віддає агенту ярлик
Зміст

Коротко

Агенту, якому файл не вміщається у вікно контексту, лишаються два звичні ходи: читати текст скибками навмання або шукати по покажчику, нарізаному наперед. На стику скибок зміст обривається. Matryoshka, проєкт з відкритим кодом на TypeScript, тримає документ цілим на сервері. Агенту дістається не сторінка, а ярлик — картка в читальному залі, коли книга лишається у сховищі. На Dev.to команди набирали вручну: без ключа мовної моделі і без локальної Ollama. Де відповідь можна було звірити лічильником, цифри зійшлися, щойно прояснилися правила команд. Обіцянки економії токенів з опису проєкту автор не вимірював.

Що сталося

За Matryoshka стоїть Дмитро Сотніков (yogthos), автор каркаса Luminus для Clojure. В описі проєкт спирається на статтю про рекурсивні мовні моделі: Алекс Л. Чжан, Тім Краска, Омар Хаттаб, лабораторія MIT CSAIL. Код не їхній — це окрема реалізація ідеї. Четвертого жовтня 2026 року в репозиторії було 149 зірок, 20 копій і жодного відкритого звіту про ваду. Ліцензія Apache-2.0. В npm тоді лежав matryoshka-rlm 0.2.40 від 17 травня 2026 року.

Модель тут не пише JavaScript чи Python. Вона пише команди мовою Nucleus, невеликим дужковим записом: (grep "ERROR"), фільтр за попереднім результатом, підрахунок, сума. Рушій Lattice розбирає команду, перевіряє типи й виконує її по документу. Відповіді лишаються в SQLite в оперативній пам’яті, а клієнт отримує заглушку на кшталт $grep_error з лічильником і коротким початком списку. Справжні рядки забирають окремо, командою lattice_expand. В описі проєкту сказано про «економію токенів понад 97%» і «понад 80% порівняно з прямим читанням файлу» для сервера MCP. Це цифри проєкту. Автор їх не перевіряв.

Сервер lattice-mcp мовної моделі не потребує. Отже, перевірка стосується рушія й інструментів, а не того, чи модель сама вибере команди. На машині стояли Linux x86_64, 8 віртуальних ядер, близько 15 ГБ пам’яті, Node 20.19.2 і pnpm 10.33.4. Пакунок поставили локально поруч з офіційним SDK протоколу MCP, а не глобально, як радить опис: встановлення зайняло 2,5 секунди і 220 МБ каталогу залежностей. pnpm 10 пропустив збірку граматик tree-sitter. Їх лишили незібраними, і список символів у коді все одно запрацював.

Клієнт на TypeScript з’єднався за 409 мс і побачив сервер lattice 0.2.40 з дванадцятьма інструментами: завантаження, запит, розкриття ярлика, закриття, статус, список імен, скидання, нотатки, довідка і два виклики, які готують питання для моделі.

Чому це важливо

Три файли. «Війна і мир» у перекладі Мод з Проєкту Гутенберг: 3,36 МБ, 66 041 рядок, 566 333 слова, близько 770 тисяч токенів (769 825 за токенізатором tiktoken, словник o200k_base). Це більше за вікно більшості моделей. Журнал доступу Apache з прикладів Elastic: 10 000 рядків, 2,37 МБ, трафік травня 2015 року. Плюс власні джерела Matryoshka, щоб перевірити роботу з кодом. Відповіді наперед порахували звичайним пошуком по тексту і коротким скриптом на Python.

Роман завантажився приблизно за 0,75–0,8 секунди. Далі запити займали від 1 до 430 мс.

Питання Команда, за змістом Відповідь Звірка
Заголовки розділів пошук і підрахунок 365 365
Заголовки книг той самий прийом 17 15, доки шаблон широкий
Згадки Наташі підрахунок збігів 1 213 1 213 (на 1 197 рядках)
Рядки про П’єра, де є і Наташа фільтр 44 44
«Генуя» пошук і розкриття рядки 840, 1573, 9153 ті самі
Початок роману рядки 840–846 сім рядків цитати дослівно
Бородіно підрахунок 108 108

Пошук без урахування регістру і рахує збіги, а не рядки. Зайві дві «книги» виявилися звичайними фразами з малої літери book. Прапорці пошуку у джерелі — gmi. Вужчий шаблон ^BOOK [A-Z]+: повернув правильні 15. Після цього підрахунки зійшлися з пошуком без урахування регістру по одному збігу.

Ранжування впирається в написання. Запит про «битву під Бородіном» без наголосу повернув п’ять рядків, де просто сказано «битва». З наголосом, як у перекладі, п’ять рядків уже містили потрібне сполучення. Нечіткий пошук Natasha Rostova нічого не знайшов, а з наголосами, як у книзі, знайшов одразу. Команда, яку опис називає смисловим пошуком, — це косинусна подібність за частотами слів, не векторні представлення. Фраза про пораненого під Аустерліцом, який дивиться в небо, не витягла відоме місце. Найближче влучення — been looking at. на рядку 15862, на сім рядків раніше. Звичайний пошук lofty sky знайшов уривок на рядку 15869.

У журналі відповіді 404 знайшлися 213 разів, запити Googlebot — 543, відповіді 200 — 9 126. Сума по сирих рядках дала нісенітницю 1 067 060,464: береться перше число в рядку, а це початок адреси клієнта. Якщо спершу витягнути поле розміру відповіді, сума байтів зійшлася: 2 735 455 845.

Перший сеанс по роману — 27 викликів інструментів, відповіді разом 5 625 знаків. Це власний підрахунок автора, не порівняльний тест. Книга лишилася на сервері. Назовні вийшли ярлики і ті рядки, які попросили принести.

На практиці

Шлях «файл завеликий» тут влаштований як замовлення в читальному залі: ви називаєте полицю, отримуєте картку, і лише потім просите принести том. Картка марна, якщо не знати правил каталогу.

Команда npx lattice-mcp з теки, де пакунок не встановлено, звантажила чужий npm-пакунок lattice-mcp версії 1.6.2. Той попросив LATTICE_API_URL і LATTICE_API_TOKEN. Потрібен двійковий файл з matryoshka-rlm. Справжній сервер друкує lattice-mcp v0.2.40.

Далі автор уперся в правила, які легко прийняти за поломку:

  1. Пишіть слова так, як вони стоять у документі, включно з наголосами. Ранжування їх не згортає.
  2. lattice_expand чекає іменований ярлик. Слово RESULTS всередині запиту працює, а як ім’я для розкриття — ні: «невірний ярлик». Імена на кшталт $grep_genoa показує lattice_bindings. Шаблони з лапками отримують загальні імена, тому список варто питати часто.
  3. Сума по сирих рядках журналу бере перше число. Спершу виділіть потрібне поле, потім підсумовуйте.
  4. Завантаження /etc/hostname відхилено: шлях поза робочою текою. Нотатка, збережена через lattice_memo при відкритому романі, розкрилася і після переходу на журнал.
  5. Без підтримки вибірки з боку клієнта пакетне питання до моделі по трьох рядках з помилкою 500 повернуло одну заготовку з трьома готовими інструкціями. Автор сам вписав відповіді bot, bot, human і надіслав їх через lattice_llm_batch_respond. Фільтр за bot нарахував 2. Модель ці рядки не судила.
  6. У lc-solver.ts (2 658 рядків) список функцій повернув 20 штук — стільки ж, скільки пошук оголошень верхнього рівня, — з діапазоном рядків і сигнатурою. Тіло evaluate прийшло цілком, 64 311 знаків, і не як ярлик: велика функція одразу потрапляє в контекст.
  7. Граф викликів на версії 0.2.40 не зібрався на жодному з чотирьох джерельних файлів: «граф символів недоступний». У журнал сервера падало Graph.addEdge: джерело і ціль збігаються. Бібліотека графа не приймає петлю на себе, і рекурсія або виклик з тим самим іменем, схоже, обриває побудову. Наскільки це часто, по чотирьох файлах не сказати.
  8. У lattice-repl пошук Austerlitz і підрахунок дали 51, як окрема звірка. Склеїти завантаження і запит в одному потоці не вийшло: запит прийшов раніше, ніж файл відкрився. Передача файлу аргументом спрацювала. Командна оболонка rlm, де команди вже пише модель, без налаштування йде на Ollama за локальною адресою, тричі повторює виклик і приблизно за 9 секунд зупиняється: три невдачі поспіль, мережа не відповіла. Так і має бути, моделі не було.

Автор не перевіряв живого агента, який сам обирає команди Nucleus, запуск з моделлю, вкладені запити, вибірку протоколу, ущільнення контексту, межі ресурсів, підключення до Claude Code, адаптери за HTTP і каналом, синтез програм, додаткові режими ранжування, кілька документів одразу і будь-які цифри економії токенів з опису чи зі статті.

Підсумок

Там, де завдання буквальне, рушій не промахнувся: підрахунок, пошук і цитата зійшлися зі звіркою, коли правила команд стали зрозумілі. Документ лишається у сховищі. На стіл кладуть картку і лише ті рядки, які попросили принести. Збій частіше сидить у правилах каталогу, ніж у дужках: пошук без регістру і сума за першим числом спокійно назвуть сімнадцять книг і беззмістовний обсяг байтів. Ранжування тримається за написання слів. Граф викликів у 0.2.40 на перевірених файлах не зібрався, а список символів працював.

Пробувати варто там, де агент ходить по великих журналах, стенограмах чи книгах і відповідь треба звірити, а не витягти шматком із покажчика. Далі автор хоче підключити справжню модель і побачити, чи вона сама обійде ці пастки.

Коментарі

Завантаження коментарів…