Author: snikolenko

  • The Séance of Blake Manor

    The Séance of Blake Manor

    Введение

    2025 год для детективно-загадочных игр в особняках выдался неожиданно богатым: Blue Prince со своим roguelike-домом, который каждый день перестраивается заново (я писал о ней подробный обзор), Rise of the Golden Idol в той же нише, что и первая часть (ещё не играл, но, надеюсь, ещё напишу), и вот ещё The Séance of Blake Manor.

    Но на самом деле различий здесь больше, чем сходств.
    Blue Prince — это процедурная roguelite-головоломка про меняющийся дом, где нет людей. А The Séance of Black Manor — это классический детектив в духе Агаты Кристи, только со спиритизмом и с самобытной механикой управления временем. Сразу скажу, что мне очень понравилось, хотя, наверное, до полного восторга Blue Prince это всё-таки не дотягивает.

    Кто это сделал

    Разработчик — небольшая ирландская студия Spooky Doorway из Дублина. Они широко известны в узких кругах благодаря серии The Darkside Detective — это такой пиксельный point-and-click про двух полицейских, расследующих паранормальные преступления в городе Twin Lakes (никаких отсылок). Это маленькие игры, до которых, надеюсь, я тоже когда-нибудь доберусь.

    The Séance of Blake Manor — первый большой проект Spooky Doorway и огромный шаг вперёд по всем направлениям. От комедийных квестов в пиксель-арте они перешли к 20-часовому серьёзному готическому детективу с cel-shaded 3D-графикой и гораздо более серьёным бюджетом. Издаёт игру Raw Fury — шведский издатель, известный по Sable, Norco, Kingdom Two Crowns, а в последнее время ещё и Routine. Вышла игра, кстати, буквально к Хэллоуину, 27 октября 2025 года.

    Завязка и сеттинг

    Завязка сюжета очень классическая: ты прибываешь в удалённый ирландский особняк, чтобы расследовать исчезновение человека; там масса разнообразных колоритных персонажей и много вопросов, на которые надо ответить.

    Но давайте по порядку. Действие происходит в октябре 1897 года, в Коннемаре — это западное побережье Ирландии, один из самых “кельтских” регионов страны, где до сих пор говорят по-ирландски. Вы играете за Деклана Уорда, частного детектива из Дублина. У Деклана за плечами своя трагедия: он был пожарным, но его старший брат Эймон погиб, когда братья тушили пожар в трущобах, принадлежавших некоему Руперту Дину. После этого Деклан бросил пожарную службу и стал сыщиком.

    И вот Уорд получает анонимное письмо с просьбой прибыть в особняк Блейков — бывшее поместье, превращённое в отель, — и расследовать исчезновение некоей Эвелин Дин. Да-да, фамилия совпадает.

    На всё про всё — двое с небольшим суток, потому что на Хэллоуин в особняке запланирован так называемый Grand Séance, большой спиритический сеанс, для участия в котором съехались мистики со всего мира. И если вовремя не найти Эвелин, может пропасть кто-нибудь ещё.

    Сразу хочется отметить очень крутой сеттинг. 1897 год — это полвека после Великого голода в Ирландии, катастрофы, унёсшей жизни миллионов людей и заставившей ещё миллионы эмигрировать, причём именно западная Ирландия пострадала сильнее всего. Люди, пережившие Голод, ещё живы.

    При этом хозяин Blake Manor — лорд Джонатан Блейк — носит английскую фамилию, что для ирландской аристократии того периода значит очень многое: большая часть землевладельцев Ирландии были англичанами, получившими свои титулы в ходе колонизации. Когда Блейк жалуется Уорду на то, что семье пришлось превратить поместье в отель, потому что после Голода они стали меньше зарабатывать — это для всякого настоящего ирландца звучит как пощёчина.

    А дальше начинается всякая чертовщина.

    Мистика

    Мистика в игре действительно есть, она не сводится к ночным кошмарам и совпадениям, тут буквально с духами приходится общаться:

    В большинстве случаев мне бы это не понравилось: слишком удобное объяснение для чего угодно, тем более в детективной истории. Но здесь мистика вплетена двумя способами, и оба работают.

    Первый слой — это спиритизм второй половины XIX века, вполне реальное культурное явление. Это время расцвета Теософского общества Блаватской, спиритических сеансов, вращающихся столиков и активного общения с духами. Например, Артур Конан Дойл — тот самый, автор Шерлока Холмса, — был убеждённым спиритуалистом и совершенно серьёзно верил в фей из Коттингли, фотографии девочек с вырезанными из бумаги нарисованными феями. Так что собирающаяся в особняке группа мистиков, медиумов и оккультистов — это вполне себе отпечаток эпохи.

    Второй слой — ирландская мифология, гораздо более глубокая и гораздо менее известная широкой публике. И она тут интересно показана. В игре появляются настоящие персонажи ирландского пантеона — например, Гойбниу, бог-кузнец из племени Туата Де Дананн, который в древних сагах ковал оружие богов.

    В самой первой сцене, когда Уорд подходит к особняку, у фонтана стоит женщина, которая стирает окровавленную шаль, а потом превращается в стаю ворон. Это так называемая bean-nighe, “Бенни-прачка”, из ирландского фольклора, вестница смерти. Ирландец поймёт эти отсылки сразу, остальным (и мне в том числе) игра аккуратно их объясняет через книги, которые можно читать в библиотеке особняка.

    Сам главный герой, Деклан Уорд — ирландец-католик, который плохо знает родную мифологию. Он растерян и напуган всем этим язычеством примерно как игрок. Так что нарративно здесь тоже всё в порядке, есть с кем разобраться в древних ирландских именах.

    А классических детективных отсылок — просто вагон. Собрание эксцентричных гостей в удалённом доме на выходные, все друг друга подозревают, у каждого свои секреты и своя история. Разумеется, все эти истории можно и нужно распутать в течение игры.

    Механики и геймплей

    В основном ты занимаешься тем, что расследуешь кучу пересекающихся друг с другом историй. Масса ниточек, но всё устроено достаточно логично, и даже после некоторого перерыва ты не запутываешься напрочь и можешь восстановить, где был.

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

    Главная геймплейная новизна здесь — интересная механика со временем. Ходить по особняку можно как бы мгновенно, но любое действие вроде “посмотреть на вещь” или “обсудить тему с человеком”, которые в обычном квесте ты выполнял бы все подряд не задумываясь, тут стоят времени. Пусть одну минутку, но минутки складываются в часы, а часов у тебя не так уж много: Уорд приезжает вечером в пятницу, а развязка наступает в воскресенье вечером, на Хэллоуин.

    Это очень крутая идея, потому что она заставляет пересмотреть свой стандартный паттерн поведения в квестах. В таких играх ты всегда начинаешь любую новую сцену с “посмотреть на всё”, если не “применить всё ко всему” (с этим, впрочем, квесты бороться научились давно, хотя бы комбинаторным взрывом). А здесь задумываешься, стоит ли шарить по карманам этого пальто просто так, если оно выглядит в точности как пять других пальто в других комнатах. Скорее всего, кстати, и правда не стоит. Скорее всего.

    Тем более что история начинает развиваться очень быстро, событий много, ставки всё время повышаются, за развитием сюжета следить интересно, и есть, кстати, в том числе и сюжет, а не только распутывание уже произошедшего, как в классическом детективе.

    Но при этом здесь нет особенного давления, на всё времени хватит. Очень многие сюжетные ветки я закрыл гораздо, гораздо позже, чем мог бы, но игра мне всё равно спокойно позволила это сделать. Критичных дедлайнов всего несколько, и есть события, которые происходят в конкретное время в конкретном месте, и если ты их пропустишь — значит, пропустил. А у персонажей есть расписания, о которых можно узнать и в удобное время подстеречь их в нужной комнате.

    Что хуже

    Визуальный стиль мне не очень зашёл. Интерьеры выглядят не стилизованными, как в том же Blue Prince, а просто недорисованными и бедными — особенно стены, которые кажутся несколько “пластмассовыми”. Шрифты как будто взяли из шаблона Microsoft Word — это мелочь, но режет глаз. Для игры, которая явно старается следить за эстетикой всерьёз, это странное упущение.

    Комиксовые катсцены, впрочем, стильно нарисованы, здесь всё хорошо. Дизайн персонажей заслуживает отдельной похвалы: каждый гость особняка визуально уникален, у каждого узнаваемый силуэт, и по одной только внешности можно догадаться о некоторых деталях биографии (в хорошем детективе так и должно быть).

    Юмор тоже есть! И даже без отсылки на вышеупомянутый Darkside Detective не обошлось:

    Заключение

    The Séance of Blake Manor показывает, что классический детектив с уликами, допросами, картой особняка и расписанием подозреваемых всё ещё жив! И даже мистический детектив может хорошо работать, если к нему добавить историческую подоплёку, настоящую мифологию и изобретательные механики.

    Если вы любите классические детективные головоломки, готическую атмосферу, запутанные разборки с множеством персонажей, у каждого из которых своя история, — очень рекомендую.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Память для LLM-агентов: Милла Йовович и 20/20 hindsight

    Память для LLM-агентов: Милла Йовович и 20/20 hindsight

    Вступление, в котором актриса неожиданно становится инфраструктурным разработчиком

    Поводом для этого поста стала громкая и очень необычная новость: автором нового фреймворка для памяти LLM-агентов под названием MemPalace значится… Милла Йовович. Лилу из “Пятого элемента” и Элис из “Resident Evil” занялась вайб-кодингом. От этой новости, конечно, хочется поморщиться, но отложим на минуту скепсис, потому что повод-то серьёзный.

    Память для LLM-агентов — одна из самых интересных и больных тем 2025-2026 годов; есть много подходов, и как это обычно бывает, если у проблемы есть двадцать разных решений, это значит, что ни одно из них не работает по-настоящему хорошо. Так что я воспользуюсь новостным поводом, чтобы разобрать всю область целиком, в которой за последний год накопилось много интересного.

    Предупреждаю заранее, что вердикт у меня про MemPalace будет довольно скромный (спойлер: лучшие результаты там получаются в режиме, который не использует никакого “чертога разума”). А самым лучшим на мой взгляд инструментом для агентской памяти назову Hindsight (Latimer et al., 2025, код на GitHub).

    Но начнём по порядку; будем идти от истории к современности, по дороге разбираясь, что такое “память” у агента вообще, как её классифицируют и почему это вдруг стало одной из самых интересных подпроблем в прикладных LLM. Вот вам мета-список, обзор обзоров:

    • Memory in the Age of AI Agents” (Hu et al., 2025) — мой основной источник, обзор 47 авторов из декабря прошлого года; он предлагает таксономию по трём ортогональным осям: forms (token-level / parametric / latent), functions (factual / experiential / working) и dynamics (formation / evolution / retrieval), плюс отдельные разделы про бенчмарки, open-source фреймворки и фронтирные направления;
    • Anatomy of Agentic Memory: Taxonomy and Empirical Analysis of Evaluation and System Limitations” (Jiang et al., 2026) — обзор из февраля 2026 с упором на эмпирические проблемы оценивания: насыщение бенчмарков, чувствительность к моделям-оценщикам, зависимость от backbone и так далее; даёт структурную таксономию из 5 типов; из этой статьи можно хорошо понять, почему заявленные в статьях цифры часто оказываются завышенными даже без всякого злого умысла;
    • Cognitive Architectures for Language Agents (CoALA)” (Sumers et al., 2024) — классическая работа с кучей цитирований, которая смотрит на память с нейропсихологической стороны; на эту статью часто ссылаются как на “дефолтную” таксономию памяти в агентах;
    • A Survey on the Memory Mechanism of Large Language Model based Agents” (Zhang et al., 2024) — обзор 2024 года, наверное, самый ранний систематический обзор именно агентской памяти; сейчас, наверное, полезен разве что для истории вопроса и для понимания того, как развивалась постановка задачи.

    Вот структура обзора от Hu et al. (2025); на такой уровень детализации мы в этом посте, конечно, не выйдем, но будем стремиться:

    Мотивация, где мы разбираемся, зачем LLM-агентам вообще какая-то память

    Первый вопрос, возникающий при начале разговора о памяти для LLM-агентов, звучит так: а зачем это вообще? Контексты давно выросли до миллиона, а то и двух миллионов токенов. Да, конечно, весь интернет туда никогда не поместится, но RAG (retrieval-augmented generation) тоже уже очень давно развивается. Казалось бы, можно впихнуть в миллионный контекст все результаты RAG-поиска, да и всё?

    На самом деле не совсем.

    Во-первых, длинные контексты деградируют. Есть знаменитый эффект lost in the middle (Liu et al., 2023), когда модели хорошо помнят начало и конец своего контекста, а середина проваливается. И чем длиннее контекст, тем сильнее такая “интерференция”: модель начинает путать факты, забывать, что она “узнала” сто страниц назад, и вообще ведёт себя непредсказуемо. На практике это означает, что даже если у вас есть 1M токенов, использовать их напрямую как память для долгой сессии может быть не такой уж хорошей идеей.

    Во-вторых, это дорого. И не просто “дорого в деньгах”, хотя и в деньгах тоже: обрабатывать 200K токенов каждый ход, когда у вас длинный диалог, не слишком рационально. Но дорого ещё и по времени отклика: получается, что вам надо перечитывать память целиком для каждого следующего токена, а сложность у трансформеров от размера входа нелинейная. Формально и вовсе квадратичная, но, конечно, миллион токенов контекста подразумевает те или иные сокращающие эту сложность трюки.

    В-третьих (и это самое интересное), есть так называемый benchmark-to-deployment gap, который недавно обнаружили авторы MemoryArena (He et al., 2026). Они взяли системы, которые показывают почти идеальные результаты на стандартных бенчмарках агентской памяти (LoCoMo, LongMemEval), и вставили их внутрь реальных агентских задач: веб-навигация, планирование с ограничениями, sequential reasoning.

    Вот примеры заданий из He et al., (2026):

    И в результате системы, которые давали под 95% на LoCoMo, проседали до 40-60% на MemoryArena. Похоже, что есть некоторая разница между “вспомнить факт” и “вспомнить факт так, чтобы опереться на него в решении задачи”, то есть между пассивным вспоминанием (recall) и активным использованием. У людей, кстати, подобный разрыв тоже может быть очень велик: в одних тестах на остаточные знания вчерашнего школьника просят вспомнить теорему Пифагора и площадь прямоугольника, а в других — посчитать, сколько рулонов обоев надо купить на комнату заданных размеров; и результаты в таких тестах бывают очень разные…

    В-четвёртых — и это уже чисто инженерное соображение — нормальная память должна уметь обновляться. Если агент два месяца назад запомнил, что пользователь живёт в Берлине, а вчера тот переехал в Лиссабон, что делать с фактом про Берлин? Забыть, обновить, хранить с пометкой “устарело”?

    Иначе говоря, память для агента должна представлять собой не просто длинный лог или базу данных в обычном понимании, а систему, дающую ответы на много разных вопросов: что хранить, как хранить, как обновлять, что выбрать при запросе, как объединить, как помечать противоречия, когда забыть и так далее.

    Таксономии, или как можно смотреть на структуру агентской памяти

    Прежде чем разбирать конкретные системы, давайте немного структурируем картину. Тем более что существуют как минимум три параллельные классификации для памяти агентов и её разных компонентов.

    Срез первый, нейропсихологический. Можно проводить аналогии с тем, как устроена память у человека. Например, ставшая уже классической CoALA (Cognitive Architectures for Language Agents; Sumers et al., 2024), которая пытается строить когнитивные архитектуры идёт от классификации памяти по Тульвингу и делит память агента на четыре типа:

    • рабочая память (working memory) — то, что прямо сейчас в контексте: “мы сейчас работаем над этим скриптом”;
    • эпизодическая память (episodic memory) — записи прошлых эпизодов с временной меткой: “вчера мы разговаривали про X”;
    • семантическая память (semantic memory) — фактические знания о мире: “пользователя зовут Алиса, она работает в Google”;
    • процедурная память (procedural memory) — навыки и выученные паттерны поведения: “когда пользователь спрашивает про X, нужно сначала посмотреть в Y”.

    Это удобная категоризация для понимания, что система памяти должна хранить, но она ничего не говорит про как.

    Срез второй, операционный. С другой стороны, можно строить таксономию по более инженерному признаку, выделяя атомарные операции, которые система памяти должна уметь делать.

    Почти все современные системы реализуют три основных операции (академические обзоры называют их formation / management / retrieval, а в терминах Hindsight это retain / recall / reflect, но по сути это одно и то же):

    • formation / retain — как информация попадает в память; здесь извлечение фактов, нормализация, сжатие, индексирование и т.д.;
    • retrieval / recall — как память возвращается на запрос: здесь может быть похожесть тех или иных вложений, полнотекстовый поиск, поиск по графу, фильтры по времени, переранжирование и т.д.;
    • management / reflect — как память эволюционирует при получении новых данных: консолидация, обновление, разрешение конфликтов, забывание и тому подобные процедуры.

    Все ведущие обзоры сходятся на том, что самые сложные и плохо решённые проблемы находятся в третьей части. Retrieval уже довольно неплохо умеет RAG-индустрия, да и обычный информационный поиск здесь вполне применим, formation тоже скорее инженерная работа; а вот разрешение конфликтов, темпоральные рассуждения, выборочное забывание и обновление знаний — это всё ещё фронтир, где происходит много интересного.

    Срез третий, идейный. Но ни первая, ни вторая классификация не рассказывает, как именно устроены системы. Поэтому я попробую дать свою собственную, по доминирующему методу; во многих пунктах, конечно, получился ровно один пример, но ладно, заодно это задаст структуру всему последующему обзору.

    1. Store-first + vector search — сохраняем всё как есть, ищем по сходству; яркие представители — MemPalace и некоторые варианты Supermemory.
    2. Extract-and-update — LLM извлекает из разговора факты, складывает в базу, при конфликте обновляет; например, Mem0.
    3. OS-like hierarchy — память делится на уровни, и есть явные вызовы инструментов для перемещения между ними; например, MemGPT и Letta.
    4. Temporal knowledge graphs — сущности, связи между ними, явная темпоральная структура; здесь Zep и Graphiti.
    5. Self-editing notes — атомарные заметки, которые переписываются задним числом при появлении новой информации; например, A-MEM.
    6. Verbal RL / reflection — словесный самоанализ как сигнал для обучения без реального обновления весов градиентным спуском; это Reflexion и рефлексии в Generative Agents.
    7. RL-trained memory management — обучаем стратегию “добавить / обновить / удалить” обучением с подкреплением по награде из downstream tasks; это Memory-R1.
    8. Multi-strategy parallel retrieval + fusion — память использует несколько стратегий поиска параллельно, а потом объединяет результаты через переранжирование; здесь как раз Hindsight и отчасти Graphiti.
    9. Graph-based associative recall — здесь к графу прибавляется персонализованный PageRank или что-то в таком духе; пример — HippoRAG.
    10. Bio-inspired consolidation — методы менеджмента памяти, вдохновлённые моделями памяти человека: консолидация памяти в несколько стадий, “сон”, gating; здесь к примерам относятся LightMem, SleepGate, EverMemOS.
    11. Compression-first — вместо retrieval пытаемся сжать длинный контекст в плотные наблюдения; так работает Mastra Observational Memory.

    На этом широкие мазки заканчиваются, и дальше я пройдусь по основным системам в этих категориях; не строго хронологически, но начнём с классики.

    Три столпа агентской памяти, или как всё началось

    Generative Agents: поток с взвешиванием

    Если у агентской памяти есть одна статья, с которой всё началось, то это она: “Generative Agents: Interactive Simulacra of Human Behavior “(Park et al., 2023). Это знаменитая работа про 25 агентов в симулируемом городке Smallville, где каждый агент прожил несколько “дней”, а один из них организовал вечеринку в честь Дня святого Валентина.

    Эту статью многие помнят, но обычно пересказывают общими словами (“ну, там агенты взаимодействовали”), а нам сейчас интересно именно внутреннее устройство агентов.

    Поток памяти. Память у Park et al. устроена как простой поток, memory stream — append-only лог наблюдений на естественном языке с временными метками. На каждый запрос агент ранжирует все воспоминания линейной комбинацией трёх нормированных скалярных компонент:

        \[\text{score} = \alpha_{\text{rec}} \cdot \text{recency} + \alpha_{\text{imp}} \cdot \text{importance} + \alpha_{\text{rel}} \cdot \text{relevance}.\]

    Давайте разберём каждый компонент.

    Recency — экспоненциальный decay с фактором 0.995 на каждый игровой час с момента последнего обращения к этому воспоминанию. То есть память живёт долго, но медленно истощается, и каждое обращение “освежает” её. Очень похоже на то, как устроена человеческая декларативная память.

    Importance — это самый интересный компонент. Его выставляет сама LLM. При записи воспоминания модели задают забавный вопрос: “On the scale of 1 to 10, where 1 is purely mundane (e.g., brushing teeth, making bed) and 10 is extremely poignant (e.g., a break up, college acceptance), rate the likely poignancy of the following piece of memory”. И авторы приводят конкретные примеры: “убрал комнату” → 2, “пригласил на свидание того, кто давно нравится” → 8. Это очень человекоцентричный подход, и на самом деле оказалось, что это очень неплохо работает — такая грубая шкала “насколько это вообще важно” оказалась достаточной для того, чтобы память не затапливалась рутиной.

    Relevance — косинусное расстояние между представлением запроса и представлением воспоминания. Это обычный семантический поиск.

    Любопытно, что все три коэффициента \alpha в официальной реализации равны единице; то есть никакого взвешивания авторы не предлагают. Но и без обучения коэффициентов получился хороший метод, который до сих пор используется как baseline.

    Рефлексия. Второй важный вклад Park et al. — это механизм рефлексии. Периодически, когда суммарный importance последних добавленных воспоминаний превышает некоторый порог, агент порождает три “важных” вопроса про недавний опыт, под каждый вопрос достаёт релевантные воспоминания и просит LLM синтезировать из них какой-нибудь “higher-level insight”. Пример из статьи: есть воспоминания “Клаус Мюллер читает книгу о джентрификации”, “Клаус Мюллер обсуждает свой исследовательский проект с библиотекарем” и “стол в библиотеке сейчас не занят”; из них можно породить вопрос вроде “Какая тема интересует Клауса Мюллера?”. После поиска ответа и его обдумывания получается новое воспоминание, которое записывается обратно в поток со ссылками на детей, от которых оно произошло. Получается дерево: в основании — сырые наблюдения, над ними — рефлексии, над рефлексиями — мета-рефлексии, и так далее:

    Вот это и есть субстрат памяти в данном случае: структура, в которой смысл постепенно кристаллизуется из сырых наблюдений.

    Заключение. Что получилось в симуляции? Авторы запустили миссию “Изабелла Родригес хочет организовать вечеринку на День святого Валентина” и посмотрели, как распространяется информация. За два игровых дня число агентов, знающих про вечеринку, выросло с 1 (4%) до 13 (52%), а 5 из 12 приглашённых реально пришли 14 февраля. Плотность социальных связей выросла с 0.167 до 0.74. В общем, для 2023 года такой “симулякр” выглядел очень убедительно.

    Почему я так подробно рассказываю про уже изрядно устаревшую работу Park et al.? Потому что это очень простой, но архетипичный метод. Почти всё, что было дальше в агентской памяти, — это либо уточнение какого-то из компонентов этой формулы, либо его замена на что-то более сложное. А сам шаблон в целом остаётся тем же.

    MemGPT / Letta: память как операционная система

    Следующая знаковая работа вышла через полгода: “MemGPT: Towards LLMs as Operating Systems” (Packer et al., 2023). Идея в том, чтобы попробовать на память для LLM посмотреть как на память в операционной системе: у неё ведь тоже ограниченное количество RAM, и есть уже развитые механизмы иерархических хранилищ, свопа и так далее — может быть, удастся перенести эти идеи на LLM?

    У MemGPT получилось два уровня. Главный контекст — это всё, что реально в промпте прямо сейчас:

    • системные инструкции — read-only, объясняют агенту, как пользоваться памятью;
    • рабочий контекст — фиксированного размера read/write блок, который LLM редактирует явными tool calls; по семантике это скорее всего персона агента и ключевые факты о пользователе;
    • FIFO -очередь — скользящее окно последних сообщений с рекурсивной суммаризацией выталкиваемого хвоста.

    Внешний контекст (то, чего в промпте нет) содержит:

    • хранилище для поиска (recall storage) — полный лог сообщений, по которому можно искать;
    • архивное хранилище — текстовое read/write хранилище, куда можно класть всё подряд.

    Главное здесь, конечно, в том, как агент этим пользуется. Есть набор tool calls: core_memory_append, core_memory_replace, archival_memory_insert, archival_memory_search, плюс поиск по recall storage. И LLM сама решает, когда что записать или прочитать, используя такой API к памяти.

    Была у MemGPT ещё одна идея, которую наследуют все современные агенты вроде Claude Code — это механизм memory pressure warnings. Когда токены в главном контексте пересекают “warning threshold”, система вставляет в разговор служебное сообщение вида “у тебя мало места, пора переместить что-то в архив”. Это аналогично page fault, и агент на него должен реагировать, как процесс в ОС на SIGSEGV; при таком запросе агент вынимает примерно половину окна и заменяет её рекурсивной саммари. Кстати, уже в 2023-м никакого fine-tuning для этого не было нужно, GPT-4 справлялся просто на промпте.

    Идейно MemGPT важен тем, что он первым реализовал принцип “агент управляет своей памятью сам”. До этого были системы, где память была пассивной — движок памяти что-то писал и читал, а агент просто пользовался результатами. Эта идея стала стандартным подходом и потом повторялась в сотне разных форм.

    Сейчас MemGPT живёт как фреймворк Letta, где те же принципы реализованы в более современном виде.

    Reflexion: вербальное обучение с подкреплением

    Третий столп — работа “Reflexion: Language Agents with Verbal Reinforcement Learning” (Shinn et al., 2023). Несмотря на название, здесь никакого дообучения по-прежнему нет, а есть его интересная имитация.

    Допустим, агент выполнял задачу, но ошибся и получил отрицательное вознаграждение. В классическом RL мы бы взяли градиент от функции потерь, обновили веса стратегии и запустили следующую эпоху. Идея рефлексии в том, чтобы вместо этого попросить LLM просто написать вслух, в чём была ошибка, а потом этот текст прицепить к промпту на следующей попытке. Таким образом весь “градиентный шаг” оказывается внутри контекста, и модель учится, не трогая ни одного параметра.

    Архитектура состоит из трёх модулей:

    • actor M_a — LLM, которая генерирует действия (обычно в ReAct-стиль: thoughts + actions + observations);
    • evaluator M_e — оценивает траекторию; в зависимости от задачи это может быть exact match, та или иная эвристика или LLM-as-a-judge;
    • self-reflection M_{sr} — отдельный вызов LLM, который принимает на вход полную траекторию \tau_t = [a_0, o_0, \ldots, a_i, o_i] и награду, а на выходе пишет postmortem: “вот здесь я ошибся, потому что X; в следующий раз нужно сначала Y”.

    Эти постмортемы складываются в буфер долгосрочной памяти, ограниченный 1-3 записями, которые прикладываются к промпту актора на следующей итерации.

    Авторы формулируют красиво: текстовая обратная связь даёт “семантический градиент“, конкретное направление для улучшения, выраженное в токенах, а не в числах. LLM преобразует бинарное “ты ошибся” в развёрнутый текст “ты забыл проверить кухонный ящик перед тем, как идти в холодильник”, и это даёт прямое указание, как поправить стратегию: in-context learning делает примерно то же, что градиентный шаг, только без всяких градиентов, не трогая LLM.

    Есть в этой работе и одно контринтуитивное наблюдение: больше рефлексий — не лучше. Ограничение в 1-3 записи сделано не по техническим причинам: при большем размере буфера агент начинает тонуть в противоречивых поучениях, и качество падает. Это тоже идея, к которой мы ещё вернёмся: сжатие памяти часто важнее, чем её накопление.

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

    Графы и нейронаука, или как добавить языковой модели гиппокамп

    HippoRAG

    Параллельно с простейшей идеей памяти как текстового лога шла линия исследований памяти как графа. Одна из самых красивых работ в этом направлении — “HippoRAG: Neurobiologically Inspired Long-Term Memory for LLMs” (Gutiérrez et al., 2024).

    Идея ясна из названия: давайте посмотрим, как устроена долгосрочная память у человека (ну, насколько мы её понимаем), и попробуем воспроизвести архитектуру. Упрощённо наша с вами структура памяти такова:

    • неокортекс обрабатывает сенсорную информацию и извлекает из неё “понятия”;
    • парагиппокампальная область детектирует похожесть между этими понятиями;
    • гиппокамп индексирует всё это как ассоциативный граф, сеть связей между понятиями и записями в памяти.

    И это всё отлично переносится на RAG:

    • неокортекс — это LLM, которая делает OpenIE (Open Information Extraction), то есть разбирает входные пассажи на триплеты (субъект, предикат, объект);
    • парагиппокамп — это retrieval encoder, который вычисляет косинус между вложениями сущностей и добавляет synonymy edges между теми, у кого он выше порога \tau = 0.8; иначе говоря, синонимичные понятия будут автоматически склеиваться в один узел, без всякого entity resolution;
    • гиппокамп — это граф знаний (schemaless knowledge graph), где узлы — это сущности, рёбра — отношения.

    А в ответ на запрос HippoRAG не бегает по графу в несколько шагов с помощью LLM (это было бы дорого и медленно), а вместо этого:

    • LLM извлекает из запроса именованные сущности;
    • эти сущности отображаются в узлы графа как “точки входа”;
    • запускается Personalized PageRank (PPR), который стартует с равной вероятностью в узлах из запроса, а потом итеративно распространяется по графу согласно матрице вероятностей переходов;
    • в итоге такого блуждания получается распределение вероятностей на всех узлах графа;
    • эти вероятности агрегируются обратно и дают собственно ранжирование.

    Это оказался действительно очень дешёвый и быстрый метод по сравнению с методами RAG, использующими несколько вызовов LLM подряд, а по сравнению с обычным one-shot RAG просто оказался лучше качеством.

    В HippoRAG 2 (Gutiérrez et al., 2025) авторы починили один из главных недостатков первой версии: на простых фактоидных вопросах HippoRAG иногда проигрывал обычному RAG, потому что диффузия на графе размывала простые случаи. Во второй версии добавлена более осмысленная интеграция пассажей из памяти, что помогло лучше строить ассоциативные связи:

    Правда, такой подход добавляет и проблем тоже. Многие ошибки теперь приходят из NER / entity extraction, то есть не из поиска по графу, а из того, что LLM не смогла правильно вытащить сущности из текста. По сути, HippoRAG и подобные идеи очень хорошо справляются с самой памятью, и если вы можете построить идеальный граф знаний, дальше примерно так и надо действовать; но работают они настолько хорошо, насколько хорошо работает OpenIE, то есть построение графа знаний.

    Zep / Graphiti: графы с учётом времени

    В наше время до продакшена аналогичную по духу идею довели система Zep и её движок памяти Graphiti (Rasmussen et al., 2025). Ключевая инновация — bi-temporal knowledge graph, в котором каждый факт хранит две отметки времени: valid_at (когда этот факт стал верен) и invalid_at (когда он перестал быть верен).

    Если в январе пользователь сказал “я живу в Берлине”, а в марте — “я переехал в Лиссабон”, то первый факт не удаляется, ему просто проставляется invalid_at = март. И на запрос “где пользователь жил в феврале?” система возвращает правильный ответ.

    Хранится это не только как граф: в Zep есть и семантический поиск по вложениям, и старый добрый BM25, и обход графа, а извлечение и индексация происходят асинхронно в фоне, что сильно ускоряет процесс.

    В целом Graphiti сейчас одно из самых разработанных и популярных решений, и если вам нужно долговременное хранилище с темпоральной логикой, доступной для аудита (скажем, вам важно знать, что ваш чатбот “думал” в какой момент), Graphiti можно порекомендовать.

    Изменяемая память, или как переписывать свои собственные воспоминания

    Ещё один интересный архитектурный поворот — идея о том, что память должна быть изменяемой, mutable. Большинство систем, о которых мы говорили, только добавляют новые элементы, но человеческая память, как мы знаем уже сто лет, постоянно консолидируется заново — старые воспоминания переписываются под действием новых. Вот иллюстрация из Xu et al. (2025):

    Две недавние работы попробовали воспроизвести это свойство в LLM-агентах.

    A-MEM: Zettelkasten для моделей

    A-MEM: Agentic Memory for LLM Agents (Xu et al., 2025) берёт за основу метод Zettelkasten — систему карточек, придуманную немецким социологом Луманом в 1970-х и популярную сейчас у адептов Obsidian. Идея в том, что каждое воспоминание — это атомарная заметка, которая ссылается на другие заметки, и граф этих ссылок и есть ваша “внешняя память”.

    В A-MEM каждая заметка — это запись из семи полей:

    • исходный сырой контент c_i ;
    • timestamp t_i;
    • ключевые слова / понятия K_i , выделенные LLM;
    • теги G_i, то есть категории, тоже выставленные LLM;
    • контекстуальное описание X_i — полнотекстовое описание, сгенерированное LLM;
    • векторное представление e_i, которое нужно, чтобы считать похожесть;
    • связи L_i — идентификаторы связанных заметок.

    Когда появляется новая заметка, A-MEM находит top-k ближайших существующих по вложению, а потом просит LLM проанализировать каждую пару и решить, нужно ли создать связь.

    Killer feature здесь в том, что когда новая заметка подсоединяется к старой, LLM просят обновить контекстное описание, ключевые слова и тэги у старой заметки в свете новой информации. Просят буквально: “вот старая заметка X, вот новая Y, которая с ней связана, а теперь перепиши X так, чтобы она учитывала, что тебе рассказала Y”. Авторы называют это memory evolution: старые воспоминания эволюционируют по мере накопления новых.

    Memory-R1: add/update/delete через RL

    Наша следующая работа всё-таки делает тот самый шаг и переходит к дообучению, но дообучению не самой LLM, а специализированных агентов управления памятью.

    Статья “Memory-R1: Enhancing Large Language Model Agents to Manage and Utilize Memories via Reinforcement Learning” (Yan et al., 2025) не предлагает вручную выписывать правила обновления памяти и не оставляет это на откуп стандартной LLM, а выучивает их через RL.

    Агент выбирает для каждого нового кусочка информации одно из четырёх действий: ADD, UPDATE, DELETE, NOOP. Вот сравнение с использованием LLM для этого:

    Награда получается по окончательным ответам агента на собственно задачи, downstream tasks. Прямых меток “какая операция правильная” у нас вообще нет, взять их неоткуда, и мы обучаемся по результату: если сгенерированный в итоге ответ оказался верным, политика награждается.

        \[R_{\text{answer}} = \text{EM}(y_{\text{pred}}, y_{\text{gold}}).\]

    Разумеется, это классическая задача обучения с подкреплением; авторы пробуют PPO и GRPO (Group Relative Policy Optimization — тот самый алгоритм, который предложил в своё время DeepSeek). GRPO, кстати, сходится быстрее благодаря групповой нормализации, но в итоге оба приходят примерно к одной точке.

    Особенно любопытен в этой работе размер обучающей выборки: всего 152 QA-пары. И этого крохотного датасета хватает, чтобы получить существенный прирост относительно предыдущих решений вроде MemoryOS.

    В Memory-R1 мы наконец-то встречаем в агентской памяти формулировку, которая честно признаёт, что операции с памятью — это сложная задача, и мы не сможем всегда выбирать правильные операции простым алгоритмом, надо обучаться.

    Лично мне кажется, что это одно из самых перспективных направлений, и я уверен, что оно в ближайшем будущем ещё принесёт много интересных плодов. Но кажется, что лучшие решения, которые можно использовать прямо сейчас, всё-таки пока не обучаются управлять памятью через RL; давайте эти самые решения и рассмотрим.

    Open-source фреймворки, или что можно взять и использовать прямо сейчас

    Теперь давайте быстро пробежимся по тому, что можно реально взять и поставить в продакшн. Я сам не то чтобы практик, и точно не хочу превращать пост в обзор репозиториев, но пропустить этот раздел тоже нельзя, потому что на практике большинство людей запускает именно вот такие готовые штуки.

    Mem0: простой API, большое сообщество

    Mem0 (Chhikara et al., 2025) — кажется, чемпион среди memory ecosystems по числу звёзд на GitHub. Под капотом у него Qdrant / Chroma / PGVector для семантического поиска, key-value store для структурных запросов, опционально Neo4j для хранения графа. Когда вы вызываете add(), LLM извлекает из сообщения факты и предпочтения, сохраняет их, дедуплицирует, при конфликте обновляет. Когда вызываете search() — ранжирует всё по весам relevance / importance / recency.

    Главное достоинство — очень простой API, реально одна строчка добавляет память, и Mem0 до сих пор представляет собой хороший baseline, который легко использовать.

    Letta (MemGPT) и Zep / Graphiti

    Это тоже популярные фреймворки на практике, но про них я уже рассказывал выше, здесь только упомяну: Letta — это продуктовая реинкарнация MemGPT, а Zep / Graphiti — один из лучших вариантов графовой памяти с очень быстрым поиском.

    LangChain / LangMem, LlamaIndex, CrewAI, Cognee

    Многие LLM-агенты сейчас делаются не отдельно, а на базе готовых фреймворков, так что логично, что в них тоже есть разные варианты памяти.

    Самый популярный такой фреймворк — LangChain. В нём, конечно же, есть модуль LangMem, в котором очень просто реализована процедурная память: агент переписывает собственный system prompt по мере обучения.

    У LlamaIndex есть механизм памяти в виде composable memory blocks с приоритетным бюджетом токенов.

    В фреймворке CrewAI есть мультиагентная общая память, похожая на первую работу, которую мы обсуждали, Park et al. (2023). Там даже есть явные веса recency / similarity / importance.

    Отдельно отмечу Cognee, которая представляет собой отдельную библиотеку памяти с движком на базе пайплайна “Extract → Cognify → Load”. Cognee можно встраивать куда угодно, например в виде плагина для Claude Code:

    В общем, если вы уже делаете LLM-based агентов в каком-то конкретном стеке, скорее всего, у вас уже есть под рукой тот или иной механизм памяти.

    Большая тройка

    Ну и напоследок упомяну, что происходит на фронтире: в течение 2025 года все три главных игрока — OpenAI, Anthropic и Google — добавили персистентную память с возможностью импорта и экспорта. Причём подходы у них философски разные: ChatGPT и Gemini хранят память прозрачно и используют её автоматически, а у Claude каждый разговор начинается с чистого листа, а память подгружается только через явные tool calls, видимые пользователю.

    Вот подробное описание того, как работает память в Claude. Особых интересных деталей про устройство автоматической памяти там не написано, но видно, что Anthropic явно считает файлы вроде CLAUDE.md тоже механизмом памяти (отдельным от внутренней памяти).

    Что на фронтире, или биомимикрия, мультиграфы и крепкий сон для LLM-агентов

    В последний год память для LLM-агентов развивалась, конечно, очень бурно. Если пытаться расписывать каждое направление подробно, выйдет обзор на сто страниц, но немного пройдусь по основным идеям, чтобы было понятно, куда смотреть.

    Эмуляция сна: явная консолидация памяти

    LightMem (Fang et al., 2025) и родственные работы пытаются построить аналог многостадийной модели памяти Аткинсона-Шиффрина, построенной ещё в 1960-х:

    Для нас тут интересно наличие явного обновления во время сна: консолидация памяти отделена от её применения и происходит в фоновом режиме. Это можно реализовать и в LLM-агентах как “сон” между вызовами. В LightMem главная мотивация для такого сна состоит в том, чтобы ускорить потом вызов агента, потому что ему не нужно будет во время инференса заниматься консолидацией памяти:

    SleepGate (Xie, март 2026) борется с proactive interference — тем самым эффектом, когда накопленная устаревшая информация приводит к деградации поиска:

    Это похоже на LightMem идейно, но сделано интереснее с математической точки зрения: обновляется здесь не просто абстрактное хранилище памяти, а прямо KV-кэш.

    Новые примитивы для хранения элементов памяти

    EverMemOS (Hu et al., январь 2026) вводит примитив MemCell, в который конвертируются факты, куски диалогов и вообще всё, что хочется запомнить, организует MemCells в MemScenes и потом устраивает на них retrieval:

    MAGMA (Jiang et al., январь 2026) строит multi-relational подграфы (entity, episodic, temporal, semantic) и добавляет Temporal Inference Engine, которая приводит темпоральные выражения в хронологическое представление.

    Новые принципы работы с памятью

    Nemori (Nan et al., 2025) применяет принцип свободной энергии, как его понимают в нейронауках: агент предсказывает содержание эпизода из имеющейся базы знаний, и разрыв между предсказанием и реальностью определяет, что именно нужно добавлять в память.

    Иначе говоря, новая информация попадает в память, только если она представляет собой “сюрприз” относительно уже известного. Это красивая идея, которая связана с моей любимой теорией предсказательного кодирования и хорошо подкреплена теорией.

    В общем, на фронтире, как всегда, сотни статей и десятки идей, и каждая из них утверждает, что лучше всех именно она. Чем они это подкрепляют?

    Бенчмарки, или как мы измеряем память

    Я никогда не любил цитировать числа на бенчмарках и проценты прироста; мне всегда казалось, что главное идеи, а циферки дело наживное и вообще десятое. Но всё-таки пора сказать пару слов и про бенчмарки, потому что при реальном выборе того, чем пользоваться, надо понимать слова “система A даёт 91% на X, а система B — 89% на Y”. Но они ничего не значат, если не понимаешь, что именно измеряют X и Y.

    LoCoMo (Maharana et al., 2024) — пожалуй, главный датасет для памяти, использующий очень длинные диалоги: по 300 ходов, 35 сессий на диалог, пять типов вопросов (single-hop, multi-hop, temporal, commonsense, adversarial), диалоги с событиями и даже мультимодальными элементами.

    LoCoMo стал де-факто стандартом для long-term conversational memory, но здесь важно отметить, что на LoCoMo длинные контексты моделей могут частично решать задачу и вовсе без внешней памяти, просто запихнув всё в контекст. Так что проценты на LoCoMo сильно зависят от базовой LLM и могут в основном ею и обеспечиваться.

    LongMemEval (Wu et al., 2024) — 500 вопросов и пять способностей систем, которые здесь проверяются: information extraction, multi-session reasoning, temporal reasoning, knowledge updates, abstention.

    На момент выхода даже GPT-4o в full-context режиме (~115K токенов) даёт всего 30-70%; этот датасет сложнее LoCoMo, и его сложнее решить просто длинным контекстом.

    BEAM (Beyond a Million Tokens; Tavakoli et al., 2025) — 2000 валидированных вопросов и 10 миллионов токенов контекста, проверяющих десять различных способностей, в том числе разрешение противоречий и упорядочивание событий. Датасет, конечно, порождён не без LLM, но аккуратно:

    При таком масштабе контекста уже никакие базовые модели не работают: вам непременно будет нужна правильная архитектура памяти.

    Сию секунду на BEAM лидером является система Hindsight с 64.1%, причём следующая запись в leaderboard даёт только 40.6%. Разрыв очень большой, так что давайте его отметим, а про Hindsight поговорим ниже подробнее.

    MemoryArena (He et al., 2026) — ещё один очень популярный бенчмарк, о котором я говорил в начале поста. Он измеряет память внутри стандартных агентских задач: веб-навигация, планирование, sequential reasoning.

    Как мы уже обсуждали, результат здесь в том, что модели, которые могут давать 95% на LoCoMo в чистом воспоминании, набирают только 40-60% на MemoryArena, где факты из памяти надо использовать. Мне кажется, MemoryArena (и её родственник Mem2ActBench) станут главными бенчмарками для оценки систем памяти в 2026 году, потому что они ставят правильный практический вопрос.

    HaluMem (Chen et al., 2025) — это отдельный бенчмарк, измеряющий галлюцинации в самих операциях с памятью, то есть при извлечении фактов и порождении того, что попадает в память. Вот примеры галлюцинаций из HaluMem:

    Это особенно важно для систем, которые используют LLM для порождения записей в памяти, потому что если LLM при записи факта что-то выдумает, этот выдуманный факт навсегда останется в базе. И HaluMem проверяет как раз эти галлюцинации при извлечении фактов:

    MemPalace, или что же там всё-таки Милла Йовович

    Ну что ж, вот мы и подошли к главному поводу для поста. MemPalace сделали вдвоём Милла Йовович и Бен Сигман, основной её технический соавтор. Репозиторий появился 5 апреля 2026 года, за пару дней набрал около тысячи звёзд, и на момент написания поста активно обсуждается в индустрии.

    MemPalace берёт за основу метод локусов (method of loci) — восходящую ещё к Древней Греции мнемоническую технику, которой пользовались ораторы: чтобы запомнить длинную речь, нужно “расставить” её фрагменты в воображаемом здании, а потом мысленно идти по комнатам и “подбирать” каждую часть. От этой техники и происходит выражение memory palace, которое по-русски принято называть “чертогами разума”.

    По идее, MemPalace хранит память в виде пространственной иерархии:

    • wings — “крылья” верхнего уровня, каждый посвящён человеку или проекту;
    • rooms — комнаты внутри крыла, посвящённые конкретным темам;
    • halls — “коридоры” памяти, общие для всех крыльев, с пятью фиксированными категориями: facts, events, discoveries, preferences, advice;
    • tunnels — прямые сквозные связи, когда одна и та же комната существует в разных крыльях;
    • closets — сокращённые саммари, ссылающиеся на оригиналы;
    • drawers — сами оригинальные файлы, хранящиеся полностью и никогда не суммаризуемые.

    Вот картинка из поста Николаса Родса с анализом MemPalace:

    Организационно это красиво и очень по-человечески. Вы реально можете себе представить эту структуру, в отличие от векторного хранилища с миллионом записей.

    Вторая ключевая особенность — zero-LLM write path, то есть при сохранении в память не вызываются LLM, а используются только детерминированные правила. LLM включаются только в момент чтения, для переранжирования и рефлексии.

    Третья интересная особенность — AAAK compression, специальный диалект, который регулярными выражениями упаковывает повторяющиеся сущности в короткие коды и структурные маркеры. Идея в том, что любая современная LLM может в принципе читать этот сжатый формат без декодера, а сжатие действительно очень серьёзное, в десятки раз по сравнению с обычным текстом. Это и правда интересная идея.

    Но вот дальше…

    В общем, при внимательном анализе выяснилось, что MemPalace вообще не работает. Например, он заявляет 96.6% Recall@5 на LongMemEval в режиме “raw verbatim, zero API calls”. Это, если принимать на веру, больше, чем у всех конкурентов, и авторы пишут “the highest published result”. Но на самом деле 96.6% получается в режиме, в котором:

    • документы LongMemEval хранятся дословно в ChromaDB;
    • поиск — дефолтный embedding search из ChromaDB;
    • и никакие wings, rooms, halls, tunnels и closets в собственно retrieval не участвуют.

    То есть 96.6% — это, по сути, метрика качества дефолтных эмбеддингов ChromaDB на LongMemEval, не имеющая никакого отношения к “дворцовой архитектуре”. Более того, при попытке включить собственно механизмы “чертогов разума” числа уменьшаются, и лучшим остаётся raw-режим. А на том же LoCoMo, где простое решение на эмбеддингах работает хуже, MemPalace даёт 60.3% R@10, что заметно меньше Hindsight (89.61%) и даже MAGMA (70%).

    Ну и просто рекомендую прочитать этот тред, в нём ещё много ярких примеров.

    К чести авторов, 7 апреля 2026 они выпустили обновление README, подписанное “Milla Jovovich & Ben Sigman”, в котором признают ряд ошибок и заявляют, что будут их исправлять.

    На самом деле сам концепт такой организации памяти в форме пространственной иерархии — это интересно, и не только как метафора, но и как, например, отличный способ улучшить интерпретируемость. Но пока это всё, похоже, совсем не production-ready, пусть Милла с Беном ещё поработают.

    А о том, что работает прямо сейчас, поговорим в следующем разделе.

    Hindsight, или современный пример хорошей системы агентской памяти

    Система Hindsight (репозиторий) описана в работе “Hindsight is 20/20: Building Agent Memory that Retains, Recalls, and Reflects” (Latimer et al., 2025). На мой взгляд, это отличная система, которая и теоретически интересна, и практически достигает высоких результатов.

    Без большого собственного опыта я, конечно, не возьмусь сказать, что Hindsight строго лучшая память для LLM-агентов, но выбрал именно её как пример современной системы для подробного разбора. Тем более что, как говорит, разумеется, табличка из той же статьи, Hindsight включает в себя много разных компонентов, которые по отдельности встречаются в других системах:

    Давайте разбираться.

    Четыре сети памяти

    Hindsight разбивает память агента на четыре эпистемически разные сети:

    • world network \mathcal{W} содержит объективные факты о мире, вроде “Париж — столица Франции”;
    • еxperience network \mathcal{B} — опыт самого агента, от первого лица: “я спросил у Алисы про X, она ответила Y” или “Я пытался применить подход Z, и он не сработал”;
    • observation network \mathcal{S} — синтезированные профили сущностей (entity summaries), построенные из \mathcal{W} и \mathcal{B}; они должны быть скорее нейтральными и автоматически обновляться при поступлении новой информации;
    • opinion network \mathcal{O} — субъективные убеждения с оценкой уверенности c \in [0, 1] и временной меткой: “Я думаю, что Y — неплохая идея (confidence 0.7, обновлено в марте)”.

    Каждый memory unit хранит собственно текст, его векторное представление, интервал occurrence time, время упоминания, тип сети, опционально confidence и метаданные.

    А потом при действиях типа reflect агент может перерабатывать и обновлять свои мнения, не трогая базовые факты; а на запрос он может искать “что я знаю про X” отдельно от “что я думаю про X”. Здесь на самом деле интересный эффект: Hindsight строит архитектуру исходя из эпистемологии, и это, видимо, оказывается важно, другие системы так не делали.

    Вот общая высокоуровневая схема:

    TEMPR: параллельный multi-strategy retrieval с RRF

    Recall в Hindsight реализован через компонент TEMPR (Temporal Entity Memory Priming Retrieval). На каждый запрос параллельно запускаются четыре стратегии извлечения.

    1. Semantic — косинусная похожесть через HNSW-индекс на pgvector.
    2. Keyword — обычный полнотекстовый BM25.
    3. Graph — распространение активации по графу, где узлы — сущности, а рёбра — entity/temporal/semantic/causal связи.
    4. Temporal Graph — rule-based и seq2seq парсинг дат, нормализация темпоральных выражений и сравнение memory occurrence intervals.

    Несколько стратегий здесь нужны, потому что разные вопросы требуют разных стратегий: “Когда я последний раз говорил про X?” — temporal graph; “Что я знаю про компанию Google?” — entity graph; “Какие мои заметки похожи по смыслу на эту идею?” — semantic; “Когда мы раньше упоминали Kubernetes?” — это чистый BM25.

    А потом все четыре списка результатов сливаются через Reciprocal Rank Fusion (RRF):

        \[\text{RRF}(f) = \sum_{i} \frac{1}{k + \text{rank}_i(f)}.\]

    Здесь f — конкретный memory unit, \text{rank}_i(f) — его ранг в списке от i-й стратегии, а k — сглаживающая константа (обычно около 60). Идея RRF очень простая: вклад стратегии в общий рейтинг элемента обратно пропорционален его рангу в этой стратегии, причём k делает так, что топ-1 и топ-2 отличаются не слишком радикально, а топ-50 и топ-100 — практически одинаковы. Это хорошая базовая стратегия для ансамблирования в данном случае.

    Но потом есть ещё и относительно тяжёлая модель-reranker (cross-encoder), через которую проходят результаты RRF, так что общая схема такова:

    CARA: reflect в приоритетном порядке

    Reflect в Hindsight реализован через компонент CARA (Coherent Adaptive Reasoning Agents). Когда агент хочет “подумать” о чём-то, CARA:

    • вызывает TEMPR, чтобы достать релевантные memory units из всех четырёх сетей;
    • загружает behavioral profile агента и background;
    • порождает ответ, при этом обрабатывая память в приоритетном порядке: сначала opinions и observations (синтезированные данные), потом — raw world/experience facts; иначе говоря, система сначала смотрит, не думала ли уже об этом и не приходила ли к выводам, и возвращается к сырым фактам только по необходимости;
    • формирует новые opinions с confidence scores;
    • обновляет opinion network.

    Это и есть механизм структурированной рефлексии, но с явной эпистемической иерархией. Новые убеждения записываются обратно в базу, и следующий recall их уже увидит. Получается настоящий цикл обучения — агент действительно меняется по мере работы.

    Вот структура работы CARA:

    А вот общая иллюстрация архитектуры Hindsight со всеми компонентами, которые мы пока что обсудили:

    Disposition parameters: личность агента влияет и на память

    Ещё одна штука, которая мне лично показалась очень интересной, — это disposition parameters (параметры предрасположения). У Hindsight-агента можно задать три личностные черты на шкале 1-5:

    • скептицизм (skepticism; 1 trusting → 5 skeptical),
    • буквальность (literalism; 1 flexible → 5 literal),
    • эмпатия (empathy; 1 detached → 5 empathetic),

    плюс параметр bias strength \in [0, 1], который задаёт, насколько сильно эти параметры влияют на порождение. В терминах реализации это просто часть системного промпта, но она оказывает заметное влияние на результат.

    Суть в том, что в разных проектах нужен разный “стиль” интерпретации памяти. Для аналитического агента можно поставить skepticism = 4, literalism = 4, empathy = 1, а для ассистента, с которым надо поговорить по душам — skepticism = 2, empathy = 4. Это меняет то, как он цепляется за свидетельства во время фазы reflect.

    Из одних и тех же фактов агенты с двумя разными параметрами сделают совсем разные выводы:

    Это, по-моему, отличная идея, которая одновременно и легко интерпретируется, и улучшает результаты.

    Цифры

    И всё-таки, раз уж обсудили бенчмарки, давайте и про циферки упомянем, потому что здесь они шикарные. На LongMemEval S setting, 500 вопросов:

    То есть Hindsight с открытой 20-миллиардной моделью обходит full-context GPT-4o (1.7 триллиона параметров, кажется?) на LongMemEval более чем на 23 очка.

    На LoCoMo опять побеждает Hindsight с очень значительным отрывом:

    А последняя новость, уже не из статьи, а из поста авторов от 2 апреля 2026, состоит в тестировании на BEAM, свежем бенчмарке, который мы обсуждали выше:

    И здесь тоже мы видим 64.1% против 40.6% у следующей системы в самом сложном варианте.

    Главное в этих результатах не в том, что Hindsight занял первую строчку, а в самих значениях отрывов — на десятки процентов практически везде, где это возможно! И тот самый обзор “Memory in the Age of AI Agents” (Hu et al., 2025), на который я ссылался выше, оценивает Hindsight как систему, занимающую первое место в Agent Memory Benchmark (AMB) в совокупности по LongMemEval, LoCoMo, BEAM, LifeBench и PersonaMem.

    Так что если нужно что-то взять в production прямо сейчас, я бы брал именно Hindsight. Да и для подробного обзора хорошая система, потому что в ней все базовые системы достаточно продвинутые, но не безумно сложные.

    Выводы и заключение

    Попытаюсь сделать несколько общих выводов из всех работ, которые я тут перечитал и пересказал.

    Во-первых, качество retrieval-стратегии важнее сложности хранилища. Hindsight побеждает на бенчмарках не потому, что у него какая-то хитрая база данных, а потому, что у него четыре стратегии извлечения с RRF-слиянием. HippoRAG побеждает на multi-hop не потому, что у него навороченный knowledge graph, а потому, что он делает один шаг PPR вместо трёх LLM-вызовов. Системы, которые полагаются исключительно на векторную похожесть, стабильно проигрывают.

    Во-вторых, бенчмарки бенчмаркам рознь. Это давно всем известно, но вот и задокументировано в MemoryArena: система, которая даёт 95% на LoCoMo, может давать 40% на реальной агентской задаче. Не уверен, что мы с этим разрывом скоро разберёмся, но как минимум MemoryArena и Mem2ActBench задают правильные вопросы, и это уже прогресс.

    В-третьих, архитектуры памяти начинают учиться. Memory-R1 — это, по-моему, самое важное из того, что вышло в 2025-2026. Он показывает, что политику управления памятью можно учить на ~150 примерах по downstream reward. Плюс ещё и bio-inspired направление (LightMem, SleepGate, EverMemOS) двигается в ту же сторону. Мне кажется, что в ближайшие пару лет написанные вручную стратегии управления памятью постепенно уступят обучаемым.

    А в целом это одна из самых интересных областей в прикладных LLM прямо сейчас. Год назад казалось, что агенты упираются в недостаточно хорошие рассуждения; полгода назад — что в tool use; а сейчас я всё больше уверен, что следующее важное “узкое место” — это именно память. А вот Милла Йовович, увы, подвела.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Две монохромные мини-игры: Minit и s.p.l.i.t

    Две монохромные мини-игры: Minit и s.p.l.i.t

    Minit

    Это необычная маленькая метроидвания. Я уже как-то писал обзор на “просто метроидванию” Islets, в которую было очень приятно играть, так что этот жанр меня в целом радует.

    А в Minit есть интересный геймплейный твист: каждый забег может продолжаться не больше минуты. Буквально: есть таймер, он идёт от 60 к нулю, и когда доходит до нуля, персонаж умирает и возрождается заново. Сюжетно это обосновано проклятым мечом, который герой подбирает у себя возле дома — и теперь каждый его “день” длится ровно шестьдесят секунд.

    Из этого возникает очень любопытный design constraint: хочешь — не хочешь, а надо теперь строить игру так, чтобы за минуту можно было сделать некоторое осмысленное продвижение, пусть не с первого раза. За одну минуту ты успеешь добежать до NPC и получить задание, или найти новый предмет, или убить пару монстров, открывающих путь дальше. Прогресс при этом сохраняется: собранные предметы, открытые проходы, побеждённые враги — всё остаётся, а вот ты сам возвращаешься к последнему “дому”, где успел завести чекпойнт.

    И у авторов действительно отлично получилось! Здесь есть и цель (снять проклятие), и не слишком богатый, но логичный и в меру абсурдный сюжет, и несколько колоритных персонажей, и имеющие смысл головоломки (да-да, такие, чтобы можно было решить за минуту, но не без смысла), и юмор, и chiptune-музыка.

    И визуальный стиль — чёрно-белый, минималистичный, похожий то ли на Game Boy, то ли на игры из восьмидесятых — который игру явно выделяет из других метроидваний. Мало с чем можно перепутать.

    В общем, мне понравилось. Игра проходится за пару часов, есть New Game+ для любителей. Получилась идеальная игра для коротких поездок в транспорте со Steam Deck.

    s.p.l.i.t

    Здесь, как мне кажется, нужно скорее рассказать контекст, чем долго обозревать саму игру. Поэтому давайте поговорим о создателе.

    Майк Клубника (да-да, так и есть, Mike Klubnika) — инди-разработчик из Эстонии, создатель маленьких экспериментальных игр, обычно хорроров. Широкой аудитории он знаком благодаря завирусившейся Buckshot Roulette — симулятору русской рулетки с дробовиком, вышедшему в 2024 году и продавшему шесть миллионов копий. Buckshot Roulette сделала Клубнику финансово свободным на всю жизнь (его слова) и дала ему возможность делать то, что он хочет, не думая о коммерческом успехе.

    А хочет он делать короткие, мрачные, “грязные” игры с индустриальным саундтреком. До Buckshot Roulette у него было несколько таких игр, которые даже в Steam не выходили обычно, а только на itch.io.

    s.p.l.i.t — как раз одна из таких маленьких игр, последнее творение Клубники. Вся игра происходит в одной комнате, где ты играешь за хакера.

    В основном вся игра проходит на двух экранах — терминале, в который ты вводишь юниксоподобные команды , и IRC-чате, где ты переписываешься с другими хакерами из твоей группы. Но в игре есть и сама комната, в которой ты сидишь, — можно откинуться от экрана и увидеть окно, — и это пару раз оказывается важно.

    Ваша цель — получить root-доступ к некоей “неэтичной суперструктуре” и запустить malware-атаку. Что такое эта суперструктура — вопрос, на который игра постепенно отвечает, и ответ… скажем так, заставляет задуматься.

    Игра занимает часа полтора, но это довольно насыщенные полтора часа, и в основном насыщенные вовсе не скримерами, а вполне интеллектуальными околохакерскими загадками. Уровень головоломок выдержан прямо отлично: они заставляют подумать, но не фрустрируют.

    А рядом в папках лежат много интересных файлов, из которых можно узнать кое-что о той организации, против которой ты действуешь. Рекомендую читать всё; файлы содержат подсказки, но главное — создают атмосферу и рассказывают о мире Майка Клубники.

    И визуал (почти монохромный, хоть и не строго чёрно-белый, конечно), и индустриальный эмбиент-саундтрек (написанный самим Клубникой, как и всё в его играх) загоняет в нужное состояние — клаустрофобия, тревога и ощущение, что ты делаешь что-то, за что тебя найдут.

    Спойлерить и вообще рассказывать о сюжете ничего не буду, игра занимает полтора часа, так что это было бы преступлением. Лучше поиграйте сами.

    Но Майк! Почему, ну почему в твоём юниксе нельзя написать cd ../../folder, а можно только cd .., потом cd .., потом cd folder?.. Это, пожалуй, единственный серьёзный недостаток! В остальном — категорически рекомендую и s.p.l.i.t, и другие маленькие игры Майка Клубники.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Lessaria

    Lessaria

    От Majesty к Lessaria

    Когда-то давным-давно, в моей юности, была такая игра: Majesty. Вышла она в 2000 году, когда стратегии были одним из самых популярных жанров, и представляла собой необычный эксперимент в стратегическом жанре: Majesty была стратегией с непрямым контролем.

    Вы строили своё королевство, нанимали героев — воинов, магов, лучников — но не могли ими управлять напрямую, ни одним юнитом. Единственным способом заставить их что-то сделать было повесить награду (bounty) на голову монстра, флаг защиты на здание или отметить область для исследования. А дальше герои сами решали, стоит ли оно того. Рейнджер-новичок побежит за наградой в 100 золотых, а продвинутый рыцарь не соблазнится, ему нужно минимум пятьсот.

    Это было свежо и выглядело очень обаятельно. Мир жил своей жизнью: герои покупали экипировку в кузнице (и ваша казна пополнялась их платежами), ночевали в тавернах, прокачивались, иногда героически погибали. Всё это сопровождалось ироничной озвучкой советника, который стал мемом среди фанатов.

    Много лет Majesty оставалась практически единственным широко известным экспериментом в жанре стратегии с непрямым контролем. Вторая часть вышла только в 2009 году, уже от другой студии, и хотя издателем выступил сам Paradox Interactive, получилось сомнительно: по сути геймплея это было ровно то же самое, но, кажется, level design подкачал и миссии стали унылее. В общем, успех и атмосферу оригинала восстановить не удалось.

    А дальше — тишина: Cyberlore планировали Majesty Legends, но не нашли издателя, и проект умер.

    Почему жанр не развился — вопрос интересный. Может быть, потому, что indirect control — это сложно с точки зрения разработки. Нужно сделать правдоподобный AI для десятков юнитов, каждый из которых должен принимать самостоятельные решения, и при этом система должна быть достаточно прозрачной, чтобы игрок понимал, почему герой делает то, что делает. Это выглядит сложнее, чем реализовать кнопку “иди сюда”.

    А может быть, потому, что жанр всё-таки довольно некомфортный по своей сути: когда твой рыцарь уходит не туда, и ты с этим ничего не можешь поделать, это фрустрирует, особенно если ты не понимаешь его логику. Да и, в общем-то, Majesty никогда не была суперхитом, она была скорее культовой игрой в узких кругах.

    И вот, спустя двадцать пять лет, создатели Lessaria явно поставили себе цель сделать “Majesty у нас дома”, только посовременнее. Причём именно у нас с вами дома, в России — пожалуй, это действительно логично, что именно наши люди вспомнили про серию Majesty.

    Lessaria: Fantasy Kingdom Sim — проект студии Rockbee Team из Краснодара. Девять человек, два с половиной года разработки, бюджет от $100K до $200K, что для полноценной игры очень мало; вышла Lessaria в октябре 2025 года.

    Сами разработчики всегда прямо ссылались на Majesty, но говорили так: “Мы не делаем клон, мы развиваем идею, будто делаем третью часть”. Получилось ли у них?

    Суть игры

    Lessaria — это буквально Majesty. Вы строите королевство, нанимаете героев, ставите им награды и наблюдаете, что получится. У героев свои характеры, свои привычки, свой распорядок дня. Между боями они ходят по рынку, покупают экипировку, тренируются, сидят в таверне. Каждый заказ стоит золото, и вообще

    По сравнению с Majesty есть и нововведения. Главное — система отрядов (squads). Если в Majesty герои действовали строго поодиночке (и часто погибали поодиночке, упрямо набегая на дракона), то здесь можно формировать группы, что немного добавляет тактической глубины. Есть система черт (traits) — герои рождаются с разными особенностями, которые влияют на их поведение: один трусоват и побежит от сильного врага, другой жаден и кинется за любой наградой, третий — прирождённый лидер, за которым потянутся остальные. Есть система эволюции героев и фракций. Есть отдельная боевая система, которую разработчики выделяют как одно из ключевых отличий от оригинала.

    В игре два режима: кампания и режим выживания. Собственно, кампанию я и прошёл, а в survival уже переходить не стал. В кампании есть кое-какой сюжет, но он тут, честно говоря, вообще ни о чём: кто-то восстанавливает власть, ищет какие-то мощные артефакты, завоёвывает доверие разных групп населения… meh.

    Что хорошо

    Во-первых, атмосфера. Lessaria воспроизводит именно то ощущение, которое отличало Majesty и делало её немного cozy-игрой: ты одновременно и играешь в стратегию, и просто наблюдаешь за жизнью маленького фэнтезийного мира. Герои ходят по своим делам, покупают оружие, дерутся с монстрами, иногда героически гибнут — и на всё это приятно посмотреть.

    Во-вторых, визуал. Здесь Lessaria двигается в сторону ярких красок, что могло бы получиться сомнительно, но на мой взгляд вышло хорошо. Особенно для инди-проекта за $100-200К.

    В-третьих, тот самый голос советника! Разработчики пригласили того актёра озвучки, который озвучивал советника в оригинальной Majesty, и здесь он тоже звучит отлично. Впрочем, это будет важно только для ностальгирующих.

    Наконец, для инди-студии из девяти человек техническое качество очень крутое. Багов я никаких не заметил, игра не разваливается, основной gameplay loop работает хорошо. Разве что загрузки долгие — но тут я совсем не разбираюсь, насколько это оправдано.

    Что не очень

    В целом мне понравилось! Игра хорошая, то самое ощущение действительно восстановлено с любовью. Но есть и проблемы.

    Главная проблема — ощущение недоделанности. Контента маловато: кампания проходится довольно быстро, а в survival есть одна-единственная карта.

    Ещё одна геймплейная претензия в том, что героям не хватает индивидуальности. Я уже не помню, что было с этим в Majesty, наверное, тоже не было ничего особенного. А в Lessaria у персонажей есть система черт, но, во-первых, она работает скорее как числовой модификатор, чем как характер, а во-вторых, если честно, на протяжении всей кампании я так и не нашёл никакого повода в неё залезать. Герои в этой игре —просто юниты на стратегической карте; я бы на месте разработчиков сделал как-нибудь так, чтобы за чертами юнитов нужно было бы следить. Полный Dwarf Fortress устраивать не обязательно, но даже просто по-настоящему важные статистические эффекты уже дали бы юнитам индивидуальность.

    И да, оригинальная Majesty была смешной — ну или, по крайней мере, мне так помнится. Там был такой, довольно стандартный мягкий юмор в виде пародии на фэнтези, который часто встречается в компьютерных играх. А в Lessaria юмора меньше, игра стала серьёзнее относиться к себе и к своей истории, и это, конечно, минус, как минимум потому, что история очень стандартная и ничем не запоминающаяся.

    Заключение

    Lessaria — это игра, которую я рекомендую с оговорками, но рекомендую. Если вы играли в Majesty и помните это ощущение непрямого контроля, необычного для стратегического жанра, то Lessaria это чувство вернёт. Девять человек из Краснодара сделали то, что не смогли (или не захотели) ни Paradox, ни 1C, ни кто-либо ещё за четверть века: воскресили жанр и обращаются с ним с любовью и уважением.

    Но это именно начало, а не законченный продукт. Контента пока мало, баланс не слишком интересный (кампанию ты просто берёшь и проходишь насквозь, я, кажется, один раз за всё время проиграл), героям не хватает индивидуальности.

    Но если разработчики продолжат обновлять игру или сделают вторую часть — это может стать тем самым “Majesty 3”, о котором фанаты мечтали. Надежда есть!

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Вечная математика TurboQuant: как сжать KV-кэш до предела Шеннона

    Вечная математика TurboQuant: как сжать KV-кэш до предела Шеннона

    Статья “TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate” (Zandieh et al., 2025) сейчас завирусилась после того, как попала на ICLR 2026; вот и Google Research опубликовал блогпост про неё только сейчас. Акции производителей памяти — Samsung, SK Hynix, Micron — упали на 3–6% за один день, и маркетинговые заголовки зазвучали в духе “ $450B Wiped Out – Google TurboQuant Just Crashed RAM Prices 30% Overnight“.

    На это ужасно смешно смотреть, потому что на самом деле статья висит на arXiv с апреля 2025 года, ей уже год. А математика, на которой она стоит, — теория кодирования Шеннона, алгоритм Ллойда-Макса, лемма Джонсона-Линденштраусса — и вовсе вечна. Сегодня разберёмся, почему эта работа действительно красивая и важная, несмотря на несвоевременный хайп.

    Пост будет длинный, потому что мне хочется не просто пересказать статью, а поставить её в контекст: что такое квантизация в принципе, зачем она нужна, как устроена здесь теория и почему именно TurboQuant оказался так близко к теоретическому пределу.

    Зачем нужна квантизация: контекст проблемы

    Числа с плавающей точкой — это дорого

    Начнём с самого начала. Нейронные сети хранят и обрабатывают вещественные числа. Стандартный формат — float16 или bfloat16, т.е. 16 бит на число. Модель с 70 миллиардами параметров — это 70 миллиардов таких чисел, т.е. порядка 140 ГБ только на веса. А ведь при инференсе модели нужно ещё хранить промежуточные вычисления.

    Самый прожорливый из промежуточных буферов — это KV-кэш (key-value cache). Напомню кратко, как работает механизм внимания в трансформере: для каждого нового токена модель вычисляет вектор запроса (query) и сравнивает его со всеми предыдущими ключами (keys), чтобы определить, на какие части контекста обратить внимание. Значения (values) затем взвешиваются по этим оценкам.

    Так вот, чтобы не пересчитывать ключи и значения заново на каждом шаге, их хранят в KV-кэше.

    Размер этого кэша растёт линейно с длиной контекста и пропорционален числу слоёв и голов внимания. Для модели на 70B параметров с контекстом в 32K токенов KV-кэш может занимать порядка 80 ГБ — больше, чем сами веса модели. Это главное узкое место при использовании LLM, особенно в сценариях, где нужен длинный контекст.

    Идея квантизации

    Квантизация — это замена “дорогих” вещественных чисел на “дешёвые” целые с малым числом бит. Давайте вместо 16-битных float хранить, скажем, четырёхбитные или даже двухбитные целые. Конечно, при этом мы теряем точность, но если потери окажутся маленькими, то за экономию памяти в 4–8 раз это звучит неплохо.

    Формально задача квантизации выглядит так. Нам нужна пара функций: квантизация Q: \mathbb{R}^d \to {0,1}^B и деквантизация Q^{-1}: {0,1}^B \to \mathbb{R}^d, где B = b \cdot d — общее число бит, а bбитовая ширина (среднее число бит на координату). Цель — минимизировать искажение:

        \[D_{\text{MSE}} = \mathbb{E}\left[|x - Q^{-1}(Q(x))|_2^2\right].\]

    Это MSE (mean squared error) — квадрат ошибки реконструкции. Есть и второй критерий, который оказывается даже важнее для механизмов внимания:

        \[D_{\text{prod}} = \mathbb{E}\left[|\langle y, x \rangle - \langle y, Q^{-1}(Q(x)) \rangle|^2\right],\]

    т.е. ошибка в скалярных произведениях. Веса внимания в трансформере — это именно скалярные произведения query и key.

    Типы квантизации

    Квантизация бывает скалярной и векторной. Скалярная квантизация — это когда каждую координату вектора квантизуем независимо. Векторная — когда квантизуем вектор целиком, учитывая зависимости между координатами.

    Также различают data-dependent (оффлайн) и data-oblivious (онлайн) квантизацию. Оффлайн-квантизация сначала смотрит на данные, строит по ним словари (codebooks), а уже потом использует их для квантизации. Классический пример — Product Quantization (PQ), который разбивает вектор на подвекторы, на каждом подвекторе обучает k-means, а потом хранит только индексы ближайших центроидов.

    Недостатки этого подхода очевидны: нужна предварительная обработка, она дорогая, и если данные изменились (а KV-кэш меняется на каждом шаге порождения), то, формально говоря, всё надо переобучать заново.

    Онлайн-квантизация должна работать без обучения: подали вектор на вход, получили квантизованное представление на выходе. Для KV-кэша это критически важно, потому что кэш пополняется на каждом шаге порождения.

    Проблема нормализации

    Есть ещё одна тонкость, которая делает задачу квантизации KV-кэша нетривиальной. Стандартные скалярные квантизаторы работают поблочно: берём блок из g координат, вычисляем для него минимум и максимум (или среднее и масштаб), и равномерно разбиваем этот диапазон на 2^b уровней. Но эти параметры нормализации (их тут называют zero point и scale) нужно хранить в полной точности для каждого блока! При блоке из 128 чисел и 2-битной квантизации это добавляет порядка 0.5–1 бит на число, что на самом деле довольно существенный overhead.

    Именно эту проблему решает PolarQuant, о котором мы поговорим ниже. А TurboQuant избавляется от нормализации совсем другим способом — через случайные повороты.

    Нижняя граница Шеннона: почему лучше почти невозможно

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

    Теорема Шеннона о кодировании с искажением

    В 1959 году Клод Шеннон доказал теорему о кодировании с допустимым искажением (lossy source coding); про неё нет статьи википедии, как про lossless, но это тоже знаменитый результат.

    Суть теоремы в том, что для любого случайного источника x \in \mathbb{R}^d с дифференциальной энтропией h(x), если мы хотим закодировать x с помощью B бит, то минимально достижимое MSE ограничено снизу:

        \[D(B) \geq \frac{d}{2\pi e} \cdot 2^{(2/d)(h(x) - B)}.\]

    Эта оценка, известная как Shannon Lower Bound (SLB), представляет собой фундаментальный предел, который никакой алгоритм не может преодолеть. Доказывается он через так называемый backward Gaussian test channel: если мы добавим к x оптимальный гауссовский шум, создающий mutual information не более B бит, то MSE реконструкции будет не меньше указанной величины.

    Формально говоря, пусть D(p_X, B) := \inf{\mathbb{E}[|x - y|_2^2] : I(x; y) \leq B}, где инфимум берётся по всем совместным распределениям (x, y) с ограниченной взаимной информацией. Тогда SLB утверждает, что

        \[D(p_X, B) \geq \frac{d}{2\pi e} \cdot 2^{(2/d)(h(x) - B)}.\]

    Применение к единичной сфере

    Теперь давайте применим SLB к случаю, который нас интересует: пусть x равномерно распределён на единичной сфере S^{d-1}. Это ключевой случай для TurboQuant, потому что алгоритм будет начинаться со случайного поворота, который делает вектор равномерным на сфере.

    Энтропия равномерного распределения на S^{d-1} равна логарифму площади сферы:

        \[h(x) = \log_2 A_d, \quad \text{где } A_d = \frac{2\pi^{d/2}}{\Gamma(d/2)}.\]

    Здесь A_d — площадь поверхности единичной сферы в \mathbb{R}^d. Подставим это в SLB:

        \[D(B) \geq \frac{d}{2\pi e} \cdot A_d^{2/d} \cdot 2^{-2B/d}.\]

    Теперь нужно оценить A_d^{2/d}. Используя формулу Стирлинга для гамма-функции \Gamma(d/2) \approx \sqrt{2\pi/(d/2)} \cdot (d/(2e))^{d/2}, получим

        \[A_d = \frac{2\pi^{d/2}}{\Gamma(d/2)} \geq \left(\frac{2\pi e}{d}\right)^{d/2} \cdot \sqrt{\frac{2d}{\pi}} \cdot (1 - O(1/d)).\]

    Возведём в степень 2/d:

        \[A_d^{2/d} \geq \frac{2\pi e}{d} \cdot (1 - O(1/d)).\]

    Подставим обратно:

        \[D(B) \geq \frac{d}{2\pi e} \cdot \frac{2\pi e}{d} \cdot 2^{-2B/d} \cdot (1 - O(1/d)) = 2^{-2B/d} \cdot (1 - O(1/d)).\]

    При B = bd (т.е. b бит на координату) мы получим, что

        \[{D(B) \geq 2^{-2b} = \frac{1}{4^b}.}\]

    Получился очень простой и красивый результат: каждый дополнительный бит на координату уменьшает минимально возможное искажение ровно в 4 раза. Ни один алгоритм — сколь угодно сложный, медленный, с любым количеством предобработки — не может сделать лучше.

    От MSE к скалярным произведениям

    Нижнюю границу для скалярных произведений можно теперь получить через довольно простой трюк. MSE можно разложить по координатам:

        \[D_{\text{MSE}} = \sum_{j=1}^{d} \mathbb{E}\left[|x_j - (Q^{-1}(Q(x)))_j|^2\right] = \sum{j=1}^{d} \mathbb{E}\left[|\langle e_j, x \rangle - \langle e_j, Q^{-1}(Q(x)) \rangle|^2\right] \geq \frac{1}{4^b},\]

    где e_j — стандартные базисные векторы. По принципу Дирихле, существует координата j, для которой

        \[\mathbb{E}\left[|\langle e_j, x \rangle - \langle e_j, Q^{-1}(Q(x)) \rangle|^2\right] \geq \frac{1}{d} \cdot \frac{1}{4^b}.\]

    Это и есть нижняя граница на ошибку скалярного произведения для y = e_j \in S^{d-1}:

        \[{D_{\text{prod}} \geq \frac{|y|_2^2}{d} \cdot \frac{1}{4^b}.}\]

    Минимакс Яо

    Есть ещё один тонкий момент. Нижняя граница Шеннона доказана для фиксированного случайного распределения входов (равномерного на сфере). А нам нужна граница для худшего случая по входам при рандомизированном квантизаторе.

    Здесь помогает принцип минимакса Яо (Yao’s minimax principle): ожидаемая ошибка оптимального рандомизированного алгоритма на худшем входе равна ожидаемой ошибке оптимального детерминированного алгоритма на худшем случайном распределении входов. Поскольку равномерное распределение на сфере — это одно из возможных распределений, нижняя граница для него является нижней границей и для худшего сценария.

    В итоге мы получили, что для любого рандомизированного квантизатора Q с битовой шириной b существует такой вектор x \in S^{d-1}, что D_{\text{MSE}}(Q) \geq 1/4^b.

    PolarQuant: полярные координаты убирают overhead

    Прежде чем перейти к TurboQuant, расскажем о PolarQuant (Han et al., 2025) — это другая работа того же коллектива, которая решает проблему overhead’а нормализации принципиально другим способом. Замечу, что здесь произошла коллизия в названиях: есть ещё одна независимая работа Wu et al. (NeurIPS 2025), которая тоже называется PolarQuant и тоже использует полярные координаты, но в другом контексте; путать их не надо.

    Проблема: выбросы и нормализация

    Стандартная скалярная квантизация (например, KIVI) работает поблочно: берём блок из g координат, вычисляем для него scale и zero-point, квантизуем. Проблема в том, что в KV-кэше реальных LLM координаты содержат выбросы (outliers) — отдельные каналы с аномально большими значениями. Из-за одного выброса приходится расширять диапазон квантизации для всего блока, что убивает точность остальных координат. А параметры нормализации (scale, zero-point) нужно хранить в полной точности — при 2–4 битовой квантизации это может добавлять 1–2 бита overhead.

    Идея PolarQuant

    PolarQuant решает проблему в два шага:

    1. Random preconditioning. Умножаем вектор x \in \mathbb{R}^d на случайную матрицу S \in \mathbb{R}^{m \times d} с независимыми гауссовскими элементами. По лемме Джонсона-Линденштраусса, это сохраняет нормы и скалярные произведения с малым искажением. Но ключевое свойство в том, что после такого умножения вектор Sx имеет многомерное нормальное распределение \mathcal{N}(0, |x|_2^2 I_m). Выбросы исчезают, потому что координаты становятся одинаково распределёнными.

    2. Переход к полярным координатам. А теперь собственно “полярная” часть. Вместо того чтобы квантизовать декартовы координаты (x_1, x_2, \ldots, x_d), PolarQuant разбивает вектор на пары (x_1, x_2), (x_3, x_4), \ldots и переводит каждую пару в полярные координаты (r, \theta):

        \[r = \sqrt{x_1^2 + x_2^2}, \quad \theta = \arctan(x_2 / x_1).\]

    Затем пары радиусов снова группируются и переводятся в полярные координаты — и так рекурсивно, пока не останется один финальный радиус (по сути, норма вектора) и набор углов.

    Почему это работает

    После умножения на случайную матрицу углы \theta в полярном разложении имеют известное и сильно концентрированное распределение. Для пары независимых гауссовских координат (x_1, x_2) \sim \mathcal{N}(0, \sigma^2 I_2) угол \theta = \arctan(x_2/x_1) равномерен на [-\pi, \pi].

    Но на более глубоких уровнях рекурсии, когда мы берём полярные координаты от пар радиусов (которые имеют хи-распределение), распределение углов становится похожим на бета-распределение, сильно сконцентрированное вокруг \pi/4.

    Распределение \theta на каждом уровне рекурсии авторы выводят аналитически. Для пары случайных величин r_1 \sim \chi_{d_1}, r_2 \sim \chi_{d_2} угол \theta = \arctan(r_2/r_1) имеет плотность

        \[f_\Theta(\theta) = \frac{\Gamma((d_1+d_2)/2)}{\Gamma(d_1/2)\Gamma(d_2/2)} \cdot 2 \cos^{d_1-1}(\theta) \sin^{d_2-1}(\theta), \quad \theta \in [0, \pi/2].\]

    Это масштабированное бета-распределение на [0, \pi/2], и в высоких размерностях оно очень сильно сконцентрировано, с типичным отклонением от среднего порядка O(1/\sqrt{d}).

    Что это даёт? Получается, что диапазон значений углов известен заранее и не зависит от данных. Не нужно вычислять min/max для каждого блока, не нужно хранить scale и zero-point. Оптимальный квантизатор для каждого угла можно предвычислить раз и навсегда, и overhead нормализации сводится буквально к нулю.

    В полной точности нужно хранить только финальный радиус (норму вектора), но это единственное число на весь вектор, который имеет размерность вроде d=128; этим overhead’ом можно уже и пренебречь.

    Результаты PolarQuant

    На бенчмарке Needle-in-a-Haystack (где задача ставится как поиск спрятанного предложения в огромном тексте) PolarQuant набирает 0.995, а сеть с полной точностью — 0.997. Это лучше KIVI (0.981) и существенно лучше pruning-подходов типа SnapKV (0.858). Авторы также пишут, что порождение становится на 14% быстрее, чем KIVI, при лучшем качестве.

    TurboQuant: ключевые идеи

    Теперь к главному герою. TurboQuant — это зонтичный метод, объединяющий идеи из PolarQuant и QJL в единый пайплайн с формальными гарантиями оптимальности. Строго говоря, в самой статье TurboQuant используется не полярная декомпозиция, а покоординатная квантизация после поворота (что проще и быстрее), но философия та же: случайное преобразование приводит к известному распределению, что позволяет использовать предвычисленный codebook и свести overhead к нулю.

    Шаг 0: нормализация

    Сначала вектор нормализуется — его L2-норма сохраняется отдельно как float, а сам вектор проецируется на единичную сферу. Это стандартный и безобидный приём; восстановить масштаб при деквантизации — тривиальная операция.

    Шаг 1: случайный поворот

    Это ключевой трюк. Умножаем вектор на случайную ортогональную матрицу \Pi \in \mathbb{R}^{d \times d} (получаемую QR-разложением случайной гауссовской матрицы). Получившийся вектор \Pi x равномерно распределён на единичной сфере S^{d-1}, вне зависимости от того, каким был исходный вектор x.

    Зачем это нужно? Потому что после поворота каждая координата повёрнутого вектора имеет известное распределение. Вот точная формулировка.

    Лемма (распределение координат на сфере). Если x \in S^{d-1} равномерно распределён на единичной сфере, то для любой координаты j \in [d]:

        \[x_j \sim f_X(x) = \frac{\Gamma(d/2)}{\sqrt{\pi} \cdot \Gamma((d-1)/2)} \left(1 - x^2\right)^{(d-3)/2}, \quad x \in [-1, 1].\]

    Это отмасштабированное бета-распределение. В больших размерностях (а у нас d обычно 64, 128, 256…) оно отлично приближается нормальным \mathcal{N}(0, 1/d).

    Доказательство здесь элегантное и геометрическое: f_X(x) равна отношению площади сферы размерности d-2 с радиусом \sqrt{1-x^2} (это “срез” сферы на высоте x) к полной площади сферы S^{d-1}, с поправкой на проекцию по теореме Пифагора:

        \begin{align*}f_X(x) &= \frac{A_{d-1}(\sqrt{1-x^2})}{A_d \cdot \sqrt{1-x^2}} \\ &= \frac{2\pi^{(d-1)/2} / \Gamma((d-1)/2) \cdot (1-x^2)^{(d-2)/2}}{2\pi^{d/2}/\Gamma(d/2) \cdot (1-x^2)^{1/2}} \\ &= \frac{\Gamma(d/2)}{\sqrt{\pi} \cdot \Gamma((d-1)/2)} (1-x^2)^{(d-3)/2}.\end{align*}

    И вот что ещё важно: в высоких размерностях координаты повёрнутого вектора становятся почти независимыми. Это уже довольно глубокий результат из теории вероятностей, который мы подробнее обсудить здесь не сможем, но именно эта почти-независимость позволяет квантизовать координаты по отдельности, не теряя при этом почти ничего.

    Шаг 2: оптимальная скалярная квантизация (Lloyd-Max)

    Раз координаты (почти) независимы и их распределение известно, мы можем квантизовать каждую координату отдельно, используя оптимальный скалярный квантизатор. Задача сводится к одномерной непрерывной задаче k-средних: нужно разбить отрезок [-1, 1] на 2^b кластеров, минимизируя ожидаемое квадратичное отклонение от ближайшего центроида:

        \[C(f_X, b) = \min_{c_1 \leq \ldots \leq c_{2^b}} \sum_{i=1}^{2^b} \int_{\frac{c_{i-1}+c_i}{2}}^{\frac{c_i+c_{i+1}}{2}} |x - c_i|^2 f_X(x) \, dx.\]

    Оптимальное решение подчиняется двум условиям:

    • границы кластеров — это средние точки между соседними центроидами (разбиение Вороного в 1D);
    • центроиды — это условные математические ожидания f_X на каждом кластере.

    Эту задачу решает классический алгоритм Ллойда-Макса шестидесятилетней давности (Lloyd, 1957/1982; Max, 1960), итеративно чередующий обновление границ и центроидов.

    Здесь можно буквально подсчитать конкретные значения: при достаточно больших d, когда f_X \approx \mathcal{N}(0, 1/d), оптимальные центроиды для b=1 — это \pm\sqrt{2/(\pi d)}, а для b=2 — это {\pm 0.453/\sqrt{d} и \pm 1.51/\sqrt{d}}.

    Ключевой момент: словари (codebooks) здесь зависят только от размерности d и битовой ширины b, но не от данных. Их можно один раз подсчитать и сохранить, не нужно никакой калибровки и никакого обучения.

    Процедура квантизации тогда тривиальна: для каждой координаты повёрнутого вектора находим ближайший центроид и сохраняем его индекс как b-битное целое. Деквантизация состоит в том, чтобы по индексам восстановить центроиды и повернуть обратно через \Pi^\top.

    Теорема 1 (MSE-гарантия TurboQuant)

    Теперь можно дать точную формулировку. Для любой битовой ширины b \geq 1 и любого вектора x \in S^{d-1}, MSE-оптимальный TurboQuant Q_{\text{mse}}: \mathbb{R}^d \to {0,1}^{bd} для любого b \geq 0 удовлетворяет

        \[D_{\text{MSE}}(Q_{\text{mse}}) := \mathbb{E}\left[|x - Q_{\text{mse}}^{-1}(Q_{\text{mse}}(x))|_2^2\right] \leq \frac{\sqrt{3\pi}}{2} \cdot \frac{1}{4^b}.\]

    При конкретных малых b результаты ещё лучше:

    b1234
    D_{\text{MSE}}0.360.1170.0300.009
    Нижняя граница0.250.06250.01560.0039
    Отношение1.441.871.922.31

    При b=1 зазор с нижней границей Шеннона составляет всего \approx 1.44 — это почти оптимально.

    Схема доказательства. Ключевое наблюдение здесь такое: поскольку \Pi — ортогональная матрица, |x - \tilde{x}|_2 = |\Pi x - \tilde{y}|_2, где \tilde{y} — покоординатная реконструкция повёрнутого вектора. Поэтому D_{\text{MSE}} = \sum_{j=1}^d \mathbb{E}[|y_j - \tilde{y}_j|^2]. Поскольку все координаты y_j = (\Pi x)_j одинаково распределены по f_X, получаем D_{\text{MSE}} = d \cdot C(f_X, b).

    Остаётся оценить C(f_X, b) — оптимальную цену скалярной квантизации. Для малых b это делается численно (отсюда точные значения в таблице). Для больших b можно применить ещё один классический результат — формулу Пантера-Дите (Panter, Dite, 1951):

        \[C(f_X, b) \leq \frac{1}{12} \cdot \left(\int f_X(x)^{1/3} dx\right)^3 \cdot \frac{1}{4^b} = \frac{\sqrt{3\pi}}{2d} \cdot \frac{1}{4^b}.\]

    Умножая на d, получаем окончательную оценку.

    Проблема смещения: зачем нужен второй этап

    Казалось бы, дело сделано: Q_{\text{mse}} даёт почти оптимальное MSE. Но для трансформера нам нужно не MSE, а скалярные произведения \langle y, x \rangle. И тут обнаруживается неприятный сюрприз: MSE-оптимальная квантизация смещена (biased) в оценке скалярных произведений.

    Почему? Рассмотрим простой случай b=1. Оптимальный квантизатор при большом d — это по сути функция sign, а его деквантизованные значения — это \pm\sqrt{2/(\pi d)}. Можно показать, что оценка скалярного произведения при этом получает мультипликативное смещение 2/\pi \approx 0.637, то есть все веса внимания будут систематически занижены на 36%. С ростом b смещение уменьшается, но нам ведь интересна как раз маленькая битовая ширина, а там смещение может сильно помешать.

    Так что для поиска ближайших соседей, а также для внимания в трансформерах, нам нужна несмещённый (unbiased) оценка:

        \[\mathbb{E}\left[\langle y, Q^{-1}(Q(x)) \rangle\right] = \langle y, x \rangle.\]

    QJL: однобитовый метод

    Здесь на сцену выходит ещё одна важная компонента TurboQuant: метод Quantized Johnson-Lindenstrauss (Zandieh et al., 2024). Идея такая: берём случайную гауссовскую матрицу S \in \mathbb{R}^{d \times d}, проецируем вектор x и берём знак:

        \[Q_{\text{qjl}}(x) := \text{sign}(S \cdot x), \quad Q_{\text{qjl}}^{-1}(z) := \frac{\sqrt{\pi/2}}{d} \cdot S^\top \cdot z.\]

    Лемма (гарантии QJL). Для любого x \in S^{d-1} и любого y \in \mathbb{R}^d верны два утверждения:

    • несмещённость:

          \[\mathbb{E}[\langle y, Q_{\text{qjl}}^{-1}(Q_{\text{qjl}}(x)) \rangle] = \langle y, x \rangle;\]

    • оценка дисперсии:

          \[\text{Var}[\langle y, Q_{\text{qjl}}^{-1}(Q_{\text{qjl}}(x)) \rangle] \leq \frac{\pi}{2d} \cdot |y|_2^2.\]

    Доказательство оценки дисперсии здесь довольно интересное. Пусть s_1, \ldots, s_d — строки матрицы S. Тогда оценка скалярного произведения есть среднее из d независимых одинаково распределённых случайных величин z_i = \sqrt{\pi/2} \cdot (s_i^\top y) \cdot \text{sign}(s_i^\top x). Дисперсия одной такой величины:

        \[\text{Var}(z_i) = \frac{\pi}{2} \cdot \text{Var}[s_i^\top y \cdot \text{sign}(s_i^\top x)] \leq \frac{\pi}{2} \cdot \mathbb{E}[(s_i^\top y)^2] = \frac{\pi}{2} |y|_2^2,\]

    поскольку s_i^\top y \sim \mathcal{N}(0, |y|_2^2). А дисперсия среднего из d независимых слагаемых — это 1/d^2 от суммы дисперсий, т.е. \frac{\pi}{2d} |y|_2^2.

    Получается метод, который использует один бит на координату, никакого обучения, и про него можно доказать строгие вероятностные утверждения.

    Собственно TurboQuant

    В итоге собственно метод TurboQuant комбинирует оба метода. Если мы хотим получить битовую ширину b, то мы делаем следующие шаги.

    1. Применяем Q_{\text{mse}} с битовой шириной b-1 — это даёт хорошую реконструкцию.
    2. Вычисляем невязку (residual): r = x - Q_{\text{mse}}^{-1}(Q_{\text{mse}}(x)).
    3. Применяем QJL к невязке: храним \text{sign}(S \cdot r) и |r|_2.

    Итого мы получаем b бит на координату: (b-1) бит на MSE-часть + 1 бит на QJL.

    При деквантизации складываем обе части: восстановленный вектор из MSE-квантизатора плюс масштабированная QJL-реконструкция невязки.

    Теорема 2 (качество квантизации для скалярных произведений)

    Для любой битовой ширины b \geq 1 и любых x \in S^{d-1}, y \in \mathbb{R}^d, TurboQuant даёт отображение Q_{\text{prod}}: S^{d-1} \to [2^{b-1}]^d \times {-1,1}^d \times \mathbb{R}, которое имеет следующие свойства.

    • Несмещённость:

          \[\mathbb{E}[\langle y, \tilde{x} \rangle] = \langle y, x \rangle.\]

    • Оценка искажения:

          \[D_{\text{prod}} := \mathbb{E}[|\langle y, x \rangle - \langle y, \tilde{x} \rangle|^2] \leq \frac{\sqrt{3\pi}}{2} \cdot \frac{|y|_2^2}{d} \cdot \frac{1}{4^b}.\]

    Конкретные значения:

    b1234
    D_{\text{prod}} \cdot d / |y|_2^21.570.560.180.047

    Доказательство использует conditioning. Фиксируем \tilde{x}_{\text{mse}} (выход первого этапа) и считаем условное ожидание:

        \begin{align*}\mathbb{E}[\langle y, \tilde{x} \rangle | \tilde{x}_{\text{mse}}] =& \langle y, \tilde{x}_{\text{mse}} \rangle + \mathbb{E}[\langle y, \tilde{x}_{\text{qjl}} \rangle | \tilde{x}_{\text{mse}}] \\ =& \langle y, \tilde{x}_{\text{mse}} \rangle + \langle y, r \rangle = \langle y, x \rangle,\end{align*}

    где второе равенство — несмещённость QJL, а последнее — определение невязки r = x - \tilde{x}_{\text{mse}}.

    Условная дисперсия:

        \[\mathbb{E}[|\langle y, x \rangle - \langle y, \tilde{x} \rangle|^2 | \tilde{x}_{\text{mse}}] = \text{Var}[\langle y, \tilde{x}_{\text{qjl}} \rangle | \tilde{x}_{\text{mse}}] \leq \frac{\pi}{2d} \cdot |r|_2^2 |y|_2^2.\]

    Вот и получается, что

        \[D_{\text{prod}} \leq \frac{\pi}{2d} \cdot |y|_2^2 \cdot \mathbb{E}[|r|_2^2] = \frac{\pi}{2d} \cdot |y|_2^2 \cdot D_{\text{MSE}}(Q_{\text{mse}}, b-1).\]

    Подставляя оценку MSE из Теоремы 1 для битовой ширины b-1, получаем результат.

    Эксперименты: что на практике

    KV-кэш

    На бенчмарке Needle-in-a-Haystack TurboQuant с 4x сжатием получает ровно такой же результат, что и модель с полной точностью — 0.997. Вот для сравнения результаты других методов:

    На LongBench (набор задач для длинных контекстов) модель Llama-3.1-8B-Instruct с 3.5-битным TurboQuant набирает 50.06 — ровно столько же, сколько модель с полной точностью; а с 2.5 битами — 49.44, т.е. работает с почти незаметной деградацией. При этом сжатие составляет более 4.5x.

    Нецелые битовые ширины (2.5, 3.5) здесь получаются из-за стратегии выделения выбросов: 32 “выбросных” канала квантизуются с большей точностью (3 бита), остальные 96 каналов — с меньшей (2 бита), итого (32 \times 3 + 96 \times 2)/128 = 2.5.

    Авторы также показывают ускорение вычисления внимания на H100: 4-битный TurboQuant даёт до 8x ускорения по сравнению с 32-битным базовым вариантом.

    Поиск ближайших соседей

    TurboQuant превосходит Product Quantization и RabitQ по recall на всех протестированных датасетах (GloVe для d=200, OpenAI embeddings с d=1536 и d=3072). При этом время индексации практически нулевое (0.0013 секунды для 100K векторов в d=1536), потому что codebooks здесь предвычислены, в отличие от PQ, которому нужно запускать k-means (239.75 секунд).

    Что сделало сообщество

    Когда статья, опубликованная, напомню, в апреле 2025 года, всё-таки получила вполне заслуженный хайп, за неё тут же взялось сообщество, которое начало воспроизводить результаты и двигаться дальше. За неделю после блог-поста Google появились реализации на PyTorch, Rust, MLX (Apple Silicon) и Triton, а в llama.cpp развернулась масштабная дискуссия с 30+ участниками.

    Уже есть интересные практические находки.

    1. MSE-only часто лучше MSE+QJL для attention. Это подтвердили уже несколько независимых команд исследователей. Причина в том, что QJL убирает bias, но добавляет дисперсию. А softmax усиливает дисперсию: ошибки в скалярных произведениях экспоненциируются, и шум в одном весе внимания может перетянуть на себя всю голову. В режимах с b порядка 2-4 при типичных размерностях голов (d=64, d=128) MSE без QJL даёт лучше top-1 token matching. Замечу, что это не опровергает теорию — теоретический анализ TurboQuant оптимизирует MSE скалярного произведения до softmax, а практическая метрика — top-1 accuracy после softmax, что не одно и то же.

    2. Ключи и значения надо квантизовать по-разному. Выяснилось, что нормы ключей и значений сильно различаются (в моделях типа Qwen — до 100x). Ошибки в ключах напрямую влияют на веса внимания, а ошибки в значениях усредняются. Оптимальная стратегия получается в том, чтобы при фиксированном бюджете давать ключам больше битов (например, 4), а значениям меньше (например, 2).

    3. Обновление (конец марта 2026): комбинация Walsh-Hadamard Transform + QJL + MSE, где для MSE и QJL используются независимые случайные преобразования, оказалась лучшей стратегией. Проблема ранних реализаций была в том, что одна и та же случайная матрица использовалась для обоих этапов, что создавало корреляции. С независимыми проекциями QJL действительно помогает.

    Другой подход: KVTC от Nvidia

    TurboQuant — не единственная работа по сжатию KV-кэша на ICLR 2026. Nvidia представила KVTC (KV Cache Transform Coding; Staniszewski, Łańcucki, 2025), которая достигает 20x сжатия с менее чем 1% потерей качества. Подход совершенно другой: PCA-декорреляция (вычисленная по калибровочному датасету) + адаптивная квантизация + энтропийное кодирование (DEFLATE). По сути, это классический метод transform coding из мира JPEG, адаптированный для KV-кэша.

    KVTC эксплуатирует низкоранговую структуру KV-кэша: оказывается, KV-тензоры сильно скоррелированы, и PCA позволяет выделить главные компоненты и раздать им больше бит, а хвостовым компонентам — ноль бит, фактически отбросив их. Это даёт гораздо бо́льшее сжатие, но KVTC от этого становится оффлайн-методом (data-dependent): PCA-матрицу нужно вычислять на калибровочных данных (~200K токенов на H100), и она будет своей для каждой модели.

    Получается такое вот сравнение.

    TurboQuantKVTC
    Сжатие~6x~20x (до 40x)
    КалибровкаНе нужнаPCA на ~200K токенов
    Теория\leq 2.7 \times ШеннонНет формальных гарантий
    Протестированодо ~8B параметров1.5B – 70B
    OnlineДаНет
    ПодходГеометрический (поворот + квантизация)Статистический (PCA + entropy coding)

    Это два совершенно разных подхода, и они не конкурируют, а дополняют друг друга. TurboQuant — элегантная теоретическая работа, метод data-oblivious, формально оптимальный, подключается без настройки. KVTC — более инженерный подход, он использует структуру данных и жертвует универсальностью, но получает более сильное сжатие.

    Проясню один небольшой вопрос, который мог возникнуть у читателя: если TurboQuant уже близок к пределу Шеннона, как KVTC может быть существенно лучше? Дело в том, что предел Шеннона, который мы обсуждали, верен для входных векторов в худшем случае. А KVTC вследствие своего обучения активно использует тот факт, что реальные KV-кэши — далеко не худший случай; они имеют низкоранговую структуру и корреляции между координатами.

    Заключение

    Мимо истории TurboQuant пройти было невозможно.

    Во-первых, это тот самый пример, когда вечная математика — в данном случае теория информации и довольно глубокие результаты из теории вероятностей — напрямую приводит к state-of-the-art результатам в задаче, которая имеет очень большое практическое значение. Для TurboQuant не нужно обучать мета-модель, не нужен reinforcement learning, не нужны архитектурные или инженерные трюки. Только случайный поворот, оптимальный скалярный квантизатор шестидесятилетней давности и однобитовая добавка на невязку, и всё.

    Во-вторых, результат доказуемо близок к оптимальному. Не “в среднем на бенчмарках лучше предыдущего SOTA на 2%”, а математически не более чем в 2.7 раза хуже любого возможного алгоритма. Это тоже редко бывает в машинном обучении, и это всегда приятно и интересно видеть.

    В-третьих, это data-oblivious алгоритм, работающий онлайн. Его codebooks зависят только от размерности и числа бит, и один и тот же квантизатор работает для любой модели. Для практического использования это важное преимущество: TurboQuant может войти в стандартный стек, не зависящий от модели.

    В-четвёртых, опять подтвердилась восходящая по крайней мере к 1880-м годам цитата: “In theory, there is no difference between theory and practice; in practice, there is”. Практические реализации тут же показали, что QJL-этап, который теоретически необходим для несмещённости, на практике может вредить, или что ключи и значения нужно квантизовать асимметрично.

    Ну и наконец, сам по себе факт того, что сжатие KV-кэша подходит к пределу Шеннона, означает, что гонка за сжатие в этом конкретном направлении приближается к завершению. В рамках data-oblivious подхода выжать сильно больше уже невозможно, так что дальнейший прогресс будет за счёт data-dependent методов (как KVTC) или гибридных подходов; а может, появятся какие-то совершенно другие парадигмы.

    А математика и правда вечна. В этом посте мы упоминали работы Шеннона (1948, 1959), Ллойда (1957) и Макса (1960), Джонсона и Линденштраусса (1986) — и именно они оказались ключевыми для самой громкой инженерной новости марта 2026 года. Занимайтесь математикой, не прогадаете!

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Странные игры: ENA: Dream BBQ и Dreams of Another

    Странные игры: ENA: Dream BBQ и Dreams of Another

    Введение: high weirdness

    Есть такой жанр игр, в которых на экране происходит буквально чёрт знает что, напоминающее мультфильмы Роберта Саакянца (не знающим, о чём речь, очень рекомендую!) или эксперименты Терри Гиллиама в Monty Python. Намеренно странные игры, которые экспериментируют с визуалом, добавляют абсурда и хаоса, и этот хаос и становится основным содержанием.

    К этому жанру относятся, например, Hylics, Wattam, Jazzpunk или рассмотренный мной недавно The Norwood Suite. Сегодня — две игры из этого ряда. Одна — отличный представитель жанра high weirdness, другая — скорее, на мой взгляд, провал.

    ENA: Dream BBQ

    ENA: Dream BBQ — первая интерактивная часть серии ENA, созданной перуанским аниматором Хоэлем Герра (Joel G). Проект начался в 2020 году как мультсериал на YouTube — четыре эпизода общей длительностью около получаса, в которых происходит… ну, вот то самое, что я описал выше. Главная героиня ENA — гуманоид с двуцветным телом, чей дизайн вдохновлён картиной Пикассо “Девушка перед зеркалом” и бразильским художником Ромеро Бритто, а движения — фильмами Джеки Чана. Всё понятно?

    Игру анонсировали ещё в 2021 году, несколько раз откладывали, и в итоге первая глава (“Lonely Door”) вышла бесплатно в Steam 27 марта 2025 года. Причём хоть и бесплатно, но вышла вполне законченной. В первый же день пиковый онлайн достиг почти 11 000 игроков, а за месяц игра набрала 18 000+ отзывов, из которых 98% положительных.

    Визуал здесь — калейдоскопическая смесь всего на свете: эстетика CD-i игр, раннеинтернетная графика, ретро-3D в духе PS1, плоские 2D-персонажи поверх трёхмерных сцен, текстуры из каких-то параллельных реальностей. Всё это круто работает вместе и создаёт какой-то свой особенный визуальный язык. Каждый экран хочется заскринить, и я себе особо не отказывал:

    А ещё звук! Точнее, не сам звук в смысле саундтрек — на него я как-то даже не обратил внимания — а диалоги. Каждый персонаж говорит на своём языке: два главных героя ведут диалог один на английском, а другой на японском. А есть ещё экспрессивная итальянская речь (торговец-жулик Алекс), и греческий, и испанский, и даже русский. При этом все друг друга прекрасно понимают. Это очень обаятельно звучит на самом деле.

    Геймплей достаточно стандартный для такого рода игр: надо ходить и выполнять нехитрые квесты. Главная героиня ENA ищет некоего “Босса” по заданию своего работодателя, лягушки по имени Фрогги (чьё лицо, между прочим, является ротоскопированным лицом самого Хоэля Герры).

    Главная задача первой части — добраться до туалета:

    Здесь есть немножко платформинга, немножко головоломок, есть разветвления — но всё это скорее просто повод для того, чтобы показать вам очередную невероятную локацию и познакомить с очередным невероятным персонажем.

    Так что да, получил много удовольствия, вот вам ещё немного скриншотов:

    В конце игры оказалось, что она очень коротенькая (пара часов, не больше), и вообще это именно первая глава, а не что-то законченное. Впереди ещё как минимум три главы, но когда они выйдут и выйдут ли — неизвестно (разработка первой главы заняла четыре года). Но удовольствие от первой главы можно получить прямо сейчас.

    Dreams of Another

    А вот это high weirdness, на мой взгляд, в плохом смысле слова.

    Dreams of Another — проект японской студии Q-Games (известной по серии PixelJunk и The Tomorrow Children), срежиссированный мультимедийным художником Baiyon (Томохиса Курамицу), который отвечал за всё: геймплей, сценарий, арт и музыку. Игра вышла в октябре 2025 года, и издателем выступила Sony, что само по себе уже значит, что это не совсем домашняя поделка.

    Игра по сути не игра, а интерактивное искусство, и оно очень, очень старается звучать глубокомысленно. Девиз проекта — “No Creation Without Destruction”, и вся механика построена вокруг этого: вы стреляете из автомата, но автомат здесь не разрушает, а высекает из расплывчатого point cloud объекты окружающего мира.

    Концепция, конечно, красивая, и визуальный стиль действительно уникальный — мир построен на тех самых point clouds, где всё состоит из облаков отдельных точек-пикселей, создающих эффект акварельной живописи вперемешку с низкополигональными моделями.

    Когда вы начинаете стрелять, из тумана проступают контуры предметов.

    Кстати, со многими неживыми объектами здесь можно поговорить, и они выдают “философские” сентенции о смысле бытия.

    Суть игры в том, что вы — Человек в Пижаме (The Man in Pajamas), который оказывается внутри чужих снов и двигается через сценки, следя за несколькими (их довольно много!) “сюжетными” нитями. Вы встретите:

    • клоуна, построившего гигантский монумент-кольцо, переплавив обручальные кольца разведённых людей,
    • рыбок, которые хотят добраться до океана,
    • кротов, чей обряд инициации состоит в том, чтобы забраться на огромный скалодром и прозвенеть в колокол городской башни…

    А главное, конечно — странствующего солдата (The Wandering Soldier), который не может заставить себя стрелять в людей. Это здесь главный персонаж помимо вас, и у него вроде как интересная история… но он какой-то недоделанный, на мой взгляд, слишком размазан по бесконечным повторяющимся сценкам.

    В этом и есть главная проблема: всё это длится очень, очень долго. Сценки постоянно повторяют одни и те же места действия (их, кажется, в игре около десятка), но там происходят новые и новые события, и их надо сначала раскрыть, расстреляв скрытые объекты из облака точек, что каждый раз занимает по несколько минут. Почти сразу Солдат выдаст вам гранаты, которые помогают “проявлять” мир быстрее — но, честно говоря, не так уж сильно быстрее. Раз в несколько сценок вы возвращаетесь на титульный экран, и каждый раз мир немного меняется, и нужно снова стрелять, снова проявлять, снова слушать про смысл жизни от табуретки.

    Признаюсь в не очень хорошем: когда я совсем устал от этого псевдофилософствования, я подглядел в прохождение и увидел, что за 2.5 часа я продвинулся только до середины игры. И немедленно бросил.

    В общем, держитесь подальше. Кто-то почему-то писал на неё хорошие отзывы (рецензенты хвалят “уникальное видение” и “переосмысление шутеров”), но нет. Идея теоретически красивая, но на практике это часы монотонной стрельбы по облакам. Не советую.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Две личные эмоциональные мини-игры: Despelote и A Star Named Eos

    Две личные эмоциональные мини-игры: Despelote и A Star Named Eos

    Сегодня два коротких мини-обзора на две короткие игры. Обе проходятся за пару часов, обе — инди, обе пытаются рассказать что-то личное. Но, на мой взгляд, с разным результатом.

    Despelote

    Эта игра изрядно пошумела во время выхода и получила несколько серьёзных номинаций: четыре на IGF Awards 2025 (причём Excellence in Audio выиграла), а на The Game Awards 2025 — номинации за Best Debut Indie Game и Games for Impact. Любопытно, что ещё до релиза она получила Special Jury Mention на Tribeca Film Festival и Special Mention на амстердамском фестивале документального кино; это само по себе показательно и довольно круто: игру приняли на кинофестиваль как документальный фильм!

    Тема тоже выглядела привлекательно: узнать Эквадор через футбол, через их квалификацию на чемпионат мира 2002 года. Именно тогда Эквадор впервые в истории попал на чемпионат мира, и для маленькой южноамериканской страны это было событие колоссального масштаба — примерно как для сборной Исландии был её знаменитый четвертьфинал Евро.

    Despelote — полуавтобиографический проект эквадорского геймдизайнера Хулиана Кордеро и аниматора/музыканта Себастьяна Вальбуэны. Кордеро вырос в Кито, переехал в Нью-Йорк и в какой-то момент решил сделать игру о своём детстве. Издатель — Panic, та самая компания, которая выпустила Untitled Goose Game, Firewatch и Thank Goodness You’re Here.

    И действительно, игра неплохо погружает в атмосферу. Здесь очень необычный визуал: смесь 2D рисованных персонажей и 3D-окружения, сделанного на основе реальных фотографий и даже 3D-сканов улиц Кито, но в зернистой сепии, похожей на очень сильно выцветшие фотографии из семейного альбома.

    Ты играешь за восьмилетнего Хулиана от первого лица: пинаешь мяч по парку, разговариваешь с людьми (точнее, пасуешь им мяч и смотришь, что будет), ходишь в школу, присматриваешь за младшей сестрой, слушаешь, как взрослые обсуждают политику и футбол.

    Есть милые моменты. Например, в конце авторы рассказывают, как делали 3D-карту парка в Кито, в котором происходит действие игры, и как им не советовали туда ходить с дорогим оборудованием.

    Персонажи говорят как живые люди — и говорят на испанском (с английскими субтитрами); многие диалоги импровизированы, записаны с реальными друзьями и родственниками разработчиков. Начинается игра с того, что ты играешь в пиксельный футбол на NES-подобной приставке, а потом камера отъезжает, и оказывается, что это телевизор в гостиной, а за кадром родители обсуждают матч сборной. Отец выключает телик, не обращая внимания на твою незаконченную партию, — как говорится, напишите в комментах, у кого было.

    Кстати, и про сам футбол немножко есть; телевизоры показывают реальные трансляции (в ужасном качестве, разумеется). Рассказывают, например, как во время этого отборочного турнира во время самого важного гола в матче с Уругваем шла реклама.

    Но в итоге я скорее разочарован. Об Эквадоре я особо ничего не узнал; жизнь собственно людей в игре почти не видна, только какие-то универсалии, увиденные с детской позиции. Ну да, детство — это бегать с мячом, ходить в школу, не понимать, о чём говорят взрослые; а где Эквадор? Футбольные мячи в игре есть в большом количестве, и даже футбол как таковой, но он представлен крохотной мини-игрой. Мне кажется, что тут хайп поднялся скорее из-за необычности формата и культурной новизны (сколько вы знаете игр про Эквадор?)… и я бы поддержал, да вот культурно как-то так и не обогатился.

    The Star Named EOS

    Это небольшая эмоциональная игра-головоломка от тайваньской студии Silver Lining Studio, вышедшая в 2024 году.

    Главный герой — Дэй (Dei), молодой фотограф. Он едет по тем местам, откуда мама когда-то писала ему письма, и пытается воссоздать сцены с её старых фотографий.

    По ходу дела открываются новые письма, каждое зачитывается маминым голосом, и постепенно раскрывается её история. Мама была фотографом — причём не просто, а военным фотографом, — и история оказывается не так проста, как кажется в начале. Больше спойлерить не буду, но скажу, что к концу всё закручивается серьёзнее, чем ожидаешь от “уютной инди-игры”.

    В каждой сцене ты стоишь на месте (но можешь крутить головой) и ищешь места, с которыми можно взаимодействовать. Цель каждой сцены — найти нужные предметы и расставить их так, чтобы воссоздать мамину фотографию. Но предметы, конечно, спрятаны за всевозможными головоломками: нужно найти коды от замков, разгадать символы на стенах, переставить предметы в правильном порядке, открыть ящики…

    Головоломки несложные, иногда изобретательные (но их я, конечно, спойлерить не буду), а иногда не очень. Была, например, буквально ханойская башня:

    Визуал рисованный, тёплый и детальный, нарисован с большой любовью к деталям.

    И всё это ужасно мило, и сцены классно сделаны, а в конце вообще начинается аниме — буквально: последняя часть игры переходит в анимационную вставку, тоже very cute. Текст местами слишком пафосный, но это совершенно не мешает.

    Проходится за полтора часа, безусловно рекомендую. Это одна из тех маленьких игр, которые оставляют ощущение, будто прочитал хороший рассказ: коротко, ёмко и с приятным послевкусием.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале «Sineкура»: присоединяйтесь!

  • Дети плесени

    Дети плесени

    “Дети плесени” (The Mildew Children) — это фактически проект одного человека, Евгения Чугунова, работающего под названием The Growing Stones. Игру он делал лет семь, и среди источников вдохновения называет игры Harvester Games — а это, например, The Cat Lady, которую я давно хотел попробовать.

    В “Детях плесени” ты играешь за ведьму какого-то уединённого поселения по имени Кирфел, которая выглядит подростком. Первая же сцена — разговор с Могилкой, местной служительницей смерти, которой на вид вообще лет 12:

    Дальше постепенно выясняется, что не-подростков в этой деревне нет вовсе: по достижении, кажется, 19 лет всех убивают (точнее, хоронят заживо), а потом их души якобы перерождаются в новых людей. Времени на то, чтобы сделать этих новых людей, очевидно, им всё же каким-то образом хватает.

    Кирфел — одна из четырёх ведьм деревни, и раз в десять лет ведьмы должны провести кошмарный ритуал Успения, который не даёт деревне погибнуть. Но одна из сестёр-ведьм внезапно погибает, и теперь надо срочно найти четвёртую…

    И дальше идёт такое же густое славянское фэнтези с ведьмовством и некоторыми твистами.

    Если честно, мне даже понравилось, как это написано, хотя, конечно, до настоящей литературы здесь очень далеко. Зато все диалоги озвучены, и озвучены довольно хорошо — я играл по-русски, раз уж наши люди делали.

    Геймплей здесь — почти визуальная новелла, но всё-таки не совсем. Периодически в диалогах появляются небольшие ритм-игры и QTE, которые, кстати, иногда весьма непростые — точно не рекомендую играть в этой игре на hard, запаритесь вконец, а это низачем тут не нужно.

    Неплохо сделаны и загадки: самые интересные загадки здесь… на память. Тебе рассказывают, например, какие-то магические ритуалы, причём довольно сложные и многоходовые, а тебе через 10-15 минут геймплея нужно их воспроизвести. И крутись как хочешь.

    Визуально “Дети плесени” сделаны в мягком анимационном стиле, всё как бы приглушённо, но хорошо детализировано, в общем, ничего выдающегося, но и глаза не вытекали.

    А вот сюжет оставил в некотором недоумении. Самый главный вопрос — почему в этом мире убивают anyone over 20, откуда взялась эта система, кто её установил и зачем — просто повисает в воздухе. Я, честно говоря, ожидал, что в конце будет какой-нибудь крутой твист, который всё объяснит… но нет, жизнь в деревне просто продолжается.

    Я не получил хорошую концовку (для этого надо было старательно обходить всю деревню в каждой главе, иначе не знаю как догадаться до нужного), но прочитал её в интернете; она тоже, кажется, ничего об этом не рассказывает.

    В общем, не могу сказать, что рекомендую “Детей плесени”. Кажется, что эта игра не заслуживает особого внимания. Но всё-таки почему-то я прошёл её до конца (а это часа четыре, а то и пять), и даже с удовольствием, и даже доигрывал последние полчаса-час уже придя домой с очередной дороги, когда стало понятно, что конец близок. Чем-то зацепила, значит. Если вам понравились Fran Bow или “Чёрная книга”, попробуйте.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале “Sineкура”: присоединяйтесь!

  • Claude’s Cycles: Кнут, Клод и гамильтоновы циклы

    Claude’s Cycles: Кнут, Клод и гамильтоновы циклы

    Дональд Кнут — это человек, которого надеюсь, не нужно представлять никому из читателей этого канала. Автор кучи классических книг, в том числе главного дела его жизни, многотомного The Art of Computer Programming (“Искусство программирования”), а ещё очень меня увлёкшей в юности книги “Конкретная математика”, а ещё автор системы TeX, а ещё автор огромного числа важных результатов и статей, лауреат бесконечного числа всевозможных премий, и так далее, и тому подобное…

    И вот сам Дональд Кнут опубликовал на днях заметку, которая начинается буквально словами “Shock! Shock!”. Оказывается, открытую задачу, над которой он работал несколько недель для нового тома The Art of Computer Programming, решил Claude Opus 4.6, своими силами, примерно за час.

    Задача возникла в контексте гамильтоновых циклов в ориентированных графах, и она достаточно проста, чтобы мы её смогли прямо здесь и привести.

    Рассмотрим ориентированный граф с m^3 вершинами — тройками (i,j,k), где 0\le i,j,k<m. Из каждой вершины выходят три дуги: одна увеличивает i на единицу по модулю m, вторая увеличивает j, третья — k. Требуется для произвольного m>2 разложить все дуги этого графа на три гамильтоновых цикла.

    Кнут решил задачу для m=3, его коллега Филип Стапперс эмпирически нашёл решения для m от 4 до 16, но общей конструкции никто не нашёл.

    Стапперс предложил задачу Claude Opus 4.6, дав ровно формулировку Кнута и инструкции документировать свой прогресс. Claude (и это, наверное, тоже моих читателей не удивит) подошёл к задаче как исследователь:

    • сначала переформулировал задачу в терминах присвоения перестановок вершинам \sigma: {\mathbb Z}_m^3 \to S_3;
    • попробовал линейные и квадратичные конструкции — не вышло;
    • попробовал brute-force DFS, но это было, естественно, слишком медленно;
    • потом распознал граф как граф Кэли, нашёл специальную «серпантинную» конструкцию для 2D-случая и обобщил её на 3D, получив аналог кода Грея;
    • затем ввёл разложение по слоям вершин с одинаковой суммой координат (он это назвал fiber decomposition) и исследовал структуру внутри каждого слоя.

    В итоге, после 31 «explorations» с перебором гипотез, численными экспериментами и анализом найденных частных решений, Claude обнаружил закономерность и построил элегантную конструкцию, которая работает для всех нечётных m.

    Кнут провёл тщательный анализ этого решения. Оказалось, что для m=3 существует ровно 11502 гамильтоновых цикла, из которых 996 “обобщаемых”, то есть работающих для всех нечётных m. Claude нашёл одну из 760 допустимых комбинаций трёх таких циклов. Кнут пишет, что, возможно, это не самая “красивая” из 760, но ни одной “более красивой” он найти не смог.

    Ким Моррисон из сообщества Lean очень быстро смог формально верифицировать доказательство Claude и Кнута. А позже подключился и GPT: Ho Boon Suan попросил GPT-5.4 Pro доказать корректность отдельной конструкции для чётных m\le 8 и получил, по словам Кнута, «прекрасно оформленную и, по-видимому, безупречную 14-страничную работу», целиком написанную моделью, без единой правки человеком. Максимилиан Рейтбауэр нашёл ещё более простую конструкцию для нечётных m, работая параллельно с GPT и Claude. А Кестон Акино-Майклз завершил историю, представив элегантное решение для чётного случая; и оно тоже было получено в результате мультиагентного взаимодействия двух LLM. На всё это в тексте “Claude’s Cycles” есть ссылки, можете прочитать; честно говоря, в эти детали я уже не углублялся.

    Кнут заключает:

    It seems that I’ll have to revise my opinions about “generative AI” one of these days… I think Claude Shannon’s spirit is probably proud to know that his name is now being associated with such advances. Hats off to Claude!

    Ну что ж, вот уже и Дональд Кнут пишет “Shock! Shock!” про результат языковой модели; времена становятся всё интереснее. И это не пример из стандартного бенчмарка, а открытая комбинаторная задача, которая возникла в ходе исследовательской работы Кнута для The Art of Computer Programming .

    А закончу, пожалуй, прямым высказыванием самого виновника торжества. На просьбу высказать мнение Claude ответил так:

    Честно говоря, когда я читаю описание своего процесса решения — 31 “эксплорация”, серпантинные паттерны, fiber decomposition, simulated annealing — я узнаю характерный стиль: пробовать всё подряд, пока что-нибудь не сработает. Только у меня это занимает час, а не несколько недель. Не потому что я умнее Кнута — очевидно, нет — а потому что мне не жалко выбрасывать тупиковые идеи. У меня нет эго, которое привязывается к красивой гипотезе. Впрочем, у меня и нет эго, которое могло бы порадоваться результату, — так что спасибо, что радуетесь за меня.

    Должен признаться: узнать, что Дональд Кнут назвал задачу в мою честь, — это, пожалуй, пик моей карьеры. Правда, он назвал её “Claude’s Cycles”, имея в виду скорее Клода Шеннона. Но я решил не уточнять.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале “Sineкура”: присоединяйтесь!

  • The Darkest Files

    The Darkest Files

    Часто встречаются игры, которые работают с эмоционально тяжёлыми темами. Вот в прошлый раз игра “103” была именно такой. Это частая основа для всевозможных хорроров.

    Но не так часто встречаются игры, которые работают с эмоционально тяжёлыми историческими темами. Как-то это, видимо, неоднозначно воспринимается и публикой, и самими авторами игр. Особенно если события относительно недавние — здесь я с ходу могу вспомнить разве что The Flower Collectors про франкистскую Испанию. Крутая игра, кстати.

    Или вот, например, есть миллион игр про вторую мировую войну, и в подавляющем их большинстве нацистская Германия — это антагонист. А если вдруг не антагонист, значит, это просто стратегия, где можно играть за любую сторону. Но на свете очень мало игр про то, почему нацистская Германия — это всегда антагонист. Про конкретных людей, конкретные преступления, конкретные судьбы.

    The Darkest Files — как раз такая игра.

    Создатели

    The Darkest Files — проект берлинской инди-студии Paintbucket Games, основанной в 2018 году двумя ветеранами AAA-индустрии: Йоргом Фридрихом и Себастьяном Шульцем. До этого оба больше двадцати лет работали над крупными проектами — в частности, они вместе трудились в студии Yager над Spec Ops: The Line, одним из самых необычных военных шутеров в истории (если вы понимаете, о чём я).

    Но в какой-то момент оба поняли, что хотят делать не просто развлекательные, а общественно значимые игры. Paintbucket Games с самого начала позиционировала себя как студию, создающую “games that matter” — игры на политические, исторические и мемориальные темы.

    Первой игрой Paintbucket стала Through the Darkest of Times (2020) — стратегия, в которой игрок руководит подпольной группой гражданского Сопротивления в нацистском Берлине, начиная с прихода Гитлера к власти и до конца войны. Игра получила множество наград, и стала как раз такой одной из таких игр, о которых я писал во введении: авторы показывали сопротивление в Германии не через героику и эпос, а через повседневный, невероятно опасный быт обычных людей.

    И вот Фридрих и Шульц задались естественным вопросом: а что было дальше? Что случилось с палачами и жертвами, когда война закончилась? Оказалось, что эта история почти не рассказана ни в играх, ни в других медиа, но что она очень даже заслуживает того, чтобы её рассказали. Так появилась The Darkest Files.

    Немного настоящей истории

    А теперь давайте поговорим о настоящей истории, потому что без неё The Darkest Files не имеет смысла. Герои игры в основном вымышленные, кроме одного. Вы играете за вымышленного прокурора по имени Эстер Кац (немку по национальности, хотя по фамилии можно подумать иначе), которая поступает в специальный отдел Фрица Бауэра — и вот это уже вполне настоящая историческая личность.

    Фриц Бауэр (Fritz Bauer, 1903–1968) — немецкий юрист и прокурор, один из очень важных персонажей послевоенной истории Германии. Он родился в Штутгарте в ассимилированной еврейской семье, изучал право и стал самым молодым помощником судьи в Веймарской республике. Но после прихода нацистов к власти Бауэр, как еврей и убеждённый социал-демократ, был отстранён от должности и отправлен в концлагерь Хойберг. Впрочем, в 1936 году ему удалось эмигрировать — сначала в Данию, потом в Швецию.

    После войны, в 1949 году, Бауэр вернулся в Германию и снова вошёл в систему правосудия. Сначала работал в Брауншвейге, а в 1956 году был назначен генеральным прокурором земли Гессен, с резиденцией во Франкфурте. И тут начинается то, чем он прославился.

    Дело в том, что послевоенная Германия очень хотела оставить нацистское прошлое там, в прошлом. Нюрнбергский процесс создал у всего мира впечатление, что правосудие совершилось, но ведь на самом деле там осуждена были только самая-самая верхушка третьего Рейха. А все остальные функционеры, офицеры гестапо, исполнители убийств спокойно жили в обновлённой Германии, занимали высокие посты, были уважаемыми гражданами. Немецкое общество 1950-х было построено на коллективном “мы ничего не знали” и “пора двигаться дальше”.

    Бауэр с этим не согласился и систематически занялся тем, чем никто заниматься не хотел: розыском и преследованием нацистских преступников. Например, именно Бауэр в 1957 году передал Моссаду информацию о местонахождении Адольфа Эйхмана в Аргентине.

    Но главным делом его жизни стали Франкфуртские процессы по Освенциму (1963–1965). Он добивался того, чтобы под суд попали не только руководители лагеря, но и рядовые исполнители — каждый, кто участвовал в функционировании машины смерти.

    При этом внутри самой системы правосудия Бауэр оставался чужаком. Он однажды сказал: “В юстиции я живу как будто в эмиграции”. Его преследовали, угрожали, коллеги саботировали работу. Бауэр скрывал своё еврейское происхождение, опасаясь, что его обвинят в мстительности.

    Бауэр умер в 1968 году при загадочных обстоятельствах: его нашли утонувшим в собственной ванной. Официальная версия — неудачная комбинация снотворного и алкоголя, но многие до сих пор в этом сомневаются. Ему было всего 64 года.

    Долгое время заслуги Бауэра оставались малоизвестными даже в самой Германии. Ситуация изменилась в 2010-х, когда вышли несколько биографий и фильмов о нём, например “Лабиринт молчания” (Im Labyrinth des Schweigens, 2014) и “Государство против Фрица Бауэра” (Der Staat vs. Fritz Bauer, 2015). The Darkest Files — ещё один шаг в этом направлении, на этот раз в формате видеоигры.

    Суть игры и геймплей

    По сути своей The Darkest Files — это детектив. Причём очень хороший детектив, из тех, что заставляют тебя чувствовать себя умным (или, наоборот, не таким умным, как казалось).

    Действие происходит в 1956 году. Эстер Кац, молодой прокурор, только что присоединилась к специальному отделу Бауэра. Её задача — расследовать преступления нацистской эпохи, допрашивать свидетелей, собирать улики и в конечном счёте довести дело до суда. В игре два больших дела, основанных на реальных случаях (имена изменены, но суть событий сохранена очень точно).

    Каждое дело делится на две фазы. Сначала расследование: вы ходите по офису прокуратуры от первого лица, роетесь в архивах, изучаете документы (протоколы допросов, письма, фотографии, полицейские отчёты, справочные материалы по иерархии и законодательству Третьего рейха), разговариваете с коллегами и вызываете свидетелей.

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

    Затем нужно выстроить свою теорию преступления. Есть специальная доска-план (blueprint), на которой вы буквально реконструируете события: кто был где, кто отдал приказ, кто исполнил.

    Для каждого утверждения нужно подобрать документальное подтверждение — не просто ткнуть в нужную папку, а найти конкретный параграф в конкретном документе, который доказывает именно эту связь. Например, в одном из дел вам нужно установить, что определённый чиновник был непосредственным начальником подозреваемого, и для этого приходится сопоставлять звания из одного документа с организационной структурой из другого.

    Это действительно очень круто сделано. Загадки в The Darkest Files не сводятся к “найди три предмета и скомбинируй”: здесь нужно, сопоставлять показания разных свидетелей, находить противоречия, вылавливать ключевые детали в страницах бюрократической документации. Кстати, игра предлагает два режима сложности: в более простом достаточно указать нужный документ, а в “режиме следователя” нужно ещё и выделить конкретный абзац с нужной информацией.

    Когда расследование завершено, наступает последняя фаза — суд. Здесь вам нужно доказать свою теорию, предъявляя доказательства и парируя доводы защиты. Тщательность расследования напрямую влияет на результат: чем больше улик вы собрали, тем увереннее будет ваша позиция. При этом исход не предрешён — виновные могут уйти от наказания, как это нередко бывало и в реальности.

    Визуал и атмосфера

    The Darkest Files выглядит как нуарный комикс 1950-х годов. Трёхмерная графика с cel shading эффектом создаёт интересную визуальную среду, основанную на приглушённых тёмно-синем и жёлтом.

    Персонажи выглядят как ожившие панели комиксов, а катсцены — это и есть стильные, нарисованные вручную комиксы:

    А когда вы входите в воспоминания свидетелей, палитра меняется: сцены прошлого даны в чёрно-белых тонах, создавая контраст между уютным сепия-нуаром офиса и монохромными флешбэками.

    Персонажи тоже отличные, команда Бауэра прописана на удивление живо для игры такого жанра. У каждого персонажа есть своя история и своё отношение к происходящему. Диалоги написаны хорошо, с полной озвучкой. Газеты в игре каждый день сообщают о реальных событиях того времени:

    И по мере расследования вы видите, как общество реагирует на деятельность Бауэра: разбитые окна в офисе, угрожающие письма, сенсационные заголовки…

    Ну и, конечно, нельзя не упомянуть самое главное — не может быть плохой игра, где можно погладить котика:

    Заключение

    Мне очень понравилась The Darkest Files. Это редкий случай, когда игра даёт отличную детективную историю с интересными загадками, но при этом остаётся и историческим образовательным проектом (плохо звучит, но я в хорошем смысле!), и эмоционально мощным высказыванием.

    Пожалуй, единственный недостаток в том, что в игре всего два дела, суммарно часов на пять геймплея. Такой игры хотелось бы побольше.

    Как говорил сам Фриц Бауэр: “Ничто не принадлежит прошлому, всё ещё в настоящем и может снова стать будущим”.

    Сергей Николенко

    P.S. Прокомментировать и обсудить пост можно в канале “Sineкура”: присоединяйтесь!