Динамическая память и удалённый регистр правил в UniKit AI
В первом посте я рассказал, зачем написал UniKit AI. Во втором разобрал пайплайн работы - от исследования до коммита.
Сейчас финальная часть и, пожалуй, самая техническая: как устроена память фреймворка и почему она принципиально отличается от классического CLAUDE.md и его аналогов в других агентах.
Проблема статичной памяти
Напомню, с чего мы стартовали. Классический подход к правилам в AI-разработке - это CLAUDE.md. Файл грузится в контекст при старте сессии, и все правила, которые в нём лежат, сразу занимают место в контекстном окне. На маленьких проектах это терпимо. На реальных - правила для фреймворков, модулей, стиля кода, архитектурных принципов быстро съедают до 40-50 тысяч токенов контекстного окна.
Решений в классике два, и оба плохие:
- Держать все правила в CLAUDE.md - раздутый контекст, медленные ответы, дорогие токены.
- Подсовывать правила вручную через ссылки на md в промтах - автоматизация ломается, разработчик превращается в оператора файлов.
Есть еще один подход - для каждого фреймворка или модуля создавать отдельный скилл. Но и этот подход мне не нравится. Это целая куча скиллов, которые друг с другом могут быть не связаны и им все равно надо как-то прокидывать общие правила архитектуры проекта.
UniKit AI решает эту проблему динамической загрузкой правил. Скиллы грузят не все правила сразу, а только те, которые нужны конкретной задаче в конкретный момент.
Динамическая загрузка правил: как это работает в UniKit AI
Скиллы UniKit AI не читают всю память целиком. Они работают через специальный индекс - файл .unikit/memory/RULES_INDEX.md, в котором для каждого правила есть краткое описание: что это за правило, к какому фреймворку/модулю относится, когда его нужно применять.
Когда создаётся или выполняется план, агент для каждой задачи смотрит индекс и подтягивает только те правила, которые нужны именно этой задаче. Пишем UI-анимацию - подтянутся правила по UI и по DOTween. Пишем систему сохранений - подтянутся правила по сериализации и по конкретной библиотеке, которую используем. Другие правила в это время мирно лежат на диске и не занимают контекст.
Это один из главных поинтов фреймворка. Память может расти бесконечно - хоть 100 файлов правил - и это не разнесёт стартовый контекст в ноль.
Core vs stack: два типа правил
Правила в UniKit AI делятся на два типа, и лежат они в разных папках:
- Core-правила (.unikit/memory/core/)
- Stack-правила (.unikit/memory/stack/)
Core-правила - общие правила, не привязанные к конкретным модулям или фреймворкам. Архитектурные принципы, правила написания тестов, стиль кода, принципы работы с исключениями. Всё то, что применяется в проекте везде.
Stack-правила - правила для конкретных фреймворков и модулей.
Каждое stack-правило лежит в отдельном файле:
- .unikit/memory/stack/zenject.md,
- .unikit/memory/stack/unitask.md,
- .unikit/memory/stack/r3.md
- и так далее.
Такое разделение нужно как раз для индексной подгрузки: core-правила подтягиваются чаще (они универсальные), stack-правила - строго по мере необходимости, когда задача реально касается конкретного фреймворка.
Полная автономия от CLAUDE.md
Важный момент: UniKit AI никак не привязан к CLAUDE.md или аналогам в других агентах. Вся база живёт в собственной папке .unikit. Там находится информация об архитектуре проекта, артефакты исследований и планов, core- и stack-правила, патчи, накопленные через /unikit-fix.
У такой автономии есть крутой бонус - в одном проекте можно работать сразу с несколькими агентами. Например, планировать и писать код через Claude Code, а ревью делать через Codex CLI.
Оба агента будут использовать одни и те же скиллы и одну и ту же базу .unikit в рамках одного проекта. Никакой синхронизации CLAUDE.md и её аналогов не требуется.
Генерация правил через /unikit-memory
Писать правила руками с нуля - удовольствие ниже среднего. Поэтому есть отдельный скилл, который делает это за тебя:
/unikit-memory создай правила для Zenject
Скилл задействует Context7, ищет информацию по вебу, может взять на вход переданные файлы и документы - и по всему этому сформирует базовое правило в .unikit/memory/stack/. Идеально с первого раза, скорее всего, не получится - но это уже рабочая база, которую можно дорабатывать во время реального использования.
Во втором посте я упоминал /unikit-rules - скилл для быстрой записи правил руками. Он пишет в .unikit/RULES.md, и этот файл имеет более высокий приоритет, чем все правила из папки .unikit/memory. Логика такая: .unikit/RULES.md - это полигон для обкатки новых правил. Записал, прогнал на реальных задачах, убедился, что работает, - и мигрируешь в постоянную память через:
/unikit-memory --migrate-rules
Скилл сам определит, в какой файл постоянной памяти перенести правило, проверит его на пересечения с уже существующими, и если найдёт конфликт - предложит варианты решения.
Правила в .unikit/memory я называю динамической или постоянной памятью. В отличие от правил в .unikit/RULES.md, они обычно универсальные и переносимы между проектами.
И это ключевая идея: такая база знаний становится лучше с каждым проектом и превращается в универсальную библиотеку разработчика.
Удалённый регистр правил
Раз уж правила переносимы - значит, нужен механизм их синхронизации между проектами. Для этого в UniKit AI есть механизм удалённого регистра правил.
Регистр - это git-репозиторий или локальная папка, где лежат core- и stack-правила для нужного игрового движка. У каждого правила есть версия. А у регистра манифест, который описывает какие правила у него существуют.
Когда ты создаёшь новое правило через /unikit-memory, скилл сначала идёт в регистр и проверяет, есть ли там уже что-то подходящее. Если есть - предлагает скачать готовое. Если нет - генерирует с нуля.
По умолчанию в фреймворк встроен мой официальный регистр.
Правила из него уже включены в поставку npm-пакета и работают даже в офлайне. Но если есть интернет, идет подгрузка манифеста правил в git.
В регистре уже больше 100 правил для всех движков, и он будет постоянно пополняться.
Более того, я призываю сообщество помогать с наполнением правил для официального регистра - вместе мы можем собрать действительно серьёзную базу знаний для AI-разработки в геймдеве!
Свой регистр правил: git или локальная папка
Ничто не мешает сделать свой регистр. Либо свой форк/независимый git-репозиторий, либо просто локальную папку, если не хочется возиться с публикацией.
Переопределить используемый регистр можно тремя способами:
- при инициализации проекта через unikit-ai init
- через CLI: unikit-ai rules registry set <ссылка на git или путь к папке>
- через скилл /unikit-rules-registry create - он возьмёт текущие правила проекта, соберёт из них регистр в нужном формате и в конце спросит, использовать ли его в текущем проекте
Последний способ удобен, когда у тебя уже накопилась хорошая база правил в проекте и хочется вынести её в переиспользуемое хранилище. Дальше получившуюся папку можно закоммитить в свой git и переключить регистр через unikit-ai rules registry set.
Ещё есть скилл /unikit-rules-registry update - он читает изменения в правилах проекта, сравнивает с текущим регистром и если есть расхождения, переносит изменения в регистр и поднимает версию правила. Работает только с регистрами в формате локальной папки - для git-репозиториев (официального или кастомного) не применим.
Обновление правил в проекте
Чтобы подтянуть свежие версии правил из регистра в проект, достаточно выполнить CLI-команду:
unikit-ai update
Команда обновит сам фреймворк, если вышла новая версия, и правила тоже. Если у правила в регистре поднялась версия - оно обновится в проекте.
Но есть пара нюансов:
- Правила должны быть из одного регистра. Если в проекте стоит правило из одного регистра, а обновление пытается прилететь из другого - обновления не будет, даже если имена совпадают.
- Защита от перезаписи локальных правок. Если в локальной копии правила что-то менялось и хеш файла не совпадает с хешем на момент установки - обновление не произойдёт. Это защита от того, чтобы случайно не затереть свои же доработки.
Если нужно обновить принудительно, с перетиранием всего:
unikit-ai update --force
Что в итоге
Если резюмировать: динамическая память и регистр решают три проблемы, которые у меня были в классическом подходе:
- Контекст перестал быть бутылочным горлышком. Правил может быть хоть сотня - грузятся только нужные.
- База знаний стала портативной. Наработал правила на одном проекте - перенёс на следующий через регистр.
- Появилась коллективная база. Можно не изобретать правила для Zenject, UniTask или Addressables с нуля - а забрать готовые из общего регистра и доработать под себя.
Финал серии постов о UniKit
На этом серия из трёх постов про UniKit AI закрыта. За три поста мы прошли путь от "зачем это вообще нужно" до внутреннего устройства самого нетривиального механизма фреймворка.
Ссылки на другие статьи по UniKit AI:
Другие ссылки:
unity
unikit-ai
ai
gamedev