- BrainTools - https://www.braintools.ru -
Меня зовут Егор Козельский. Около двенадцати лет я занимаюсь инженерией, в основном графикой и платформенными решениями. Последние годы я много работаю с ИИ-агентами в коммерческой и личной разработке и хочу поделиться опытом [1]: какие проблемы у меня возникали, как я их решал и что в итоге получилось.
Первая статья [2] на тему организации работы с агентами была без конкретики и без технического уклона. Здесь уже покажу, как эта система устроена и что в ней изменилось.
Если вы тоже работаете с агентами, многое из этого вам наверняка знакомо:
в каждом новом чате договорённости по проекту приходится объяснять заново
агент переносит решение из одного проекта в другой, где оно не подходит
просьба проанализировать код заканчивается правками, которых вы не просили
проект постепенно обрастает решениями, которые никто осознанно не принимал, и контроль над ним теряется
со временем код превращается в «фарш», который не провернуть обратно :D
в больших проектах большая часть токенов может уходить на восстановление контекста, если каждый раз загружать всё подряд (кеширование само по себе эту организационную проблему не решает).
Давайте теперь по порядку :)
Неправильная организация работы с агентами увеличивает энтропию проекта
Нет, я не против хаоса. Хаос – это единственно возможная организация мира. В то же время порядок и структура – это частный случай хаоса, который удобен человеку. Такой порядок мы и пытаемся выстроить в своей работе.
У этих проблем общий корень: у агента нет постоянной среды. Без загруженной памяти [3] он каждый новый чат начинает почти с чистого листа и знает о проекте то, что вы успели ему рассказать или подключить через файлы и инструменты. Более сильная модель здесь не спасает: она тоже не знает, о чём вы договорились вчера.
Да, есть понятие Memory, которое позволяет моделям самостоятельно хранить то, что они считают важным. Но сама фраза «что они считают» не звучит серьёзно для разработки. Для личного пользования этого может быть достаточно, если вы не хотите «инженерить» свой ИИ, но в профессиональной разработке много «но», которыми нужно управлять.
Вернёмся к среде, в которой работают агенты. Я в шутку называю её Джарвис. В ней собраны паттерны, правила, знания и инструменты – своего рода фреймворк для разработки с ИИ.
В современных реалиях надо привыкать к тому, что мы начинаем писать софт не для людей, а для агентов. Люди отвечают за руководство, архитектуру и делегирование, принимают решения и несут за них ответственность. Агенты берут рутину.
Агенты ускоряют работу профессионала и расширяют его экспертизу. Мир с ИИ-агентами изменится только в том, что станет технологичнее. Суть останется прежней.
Раньше было модно говорить про «Промпт-инжиниринг». Это важно до сих пор – нужно настраивать свое мышление [4] для продуктивной работы с агентами. Но дальше приходится настраивать уже всю среду, в которой работают агенты: откуда они получают контекст и какие правила соблюдают.
У меня такая среда живёт в отдельной папке с общей точкой входа для агентов. При желании её можно вынести на сервер и подключить через MCP – особенно если нужна совместная работа.
Раньше я привязывал правила к отдельному проекту. Сейчас у меня общая база для всех проектов, и поддерживать её так гораздо удобнее.
У любого проекта есть своя четкая цель. Для агента я изначально ее формулировал так:
Идеальный агент – это кодогенератор. Еще до запуска промпта я понимаю, какие пакеты будут затронуты, какие модули переписаны, какая интеграция проведена и как все это будет проверяться. При этом код соответствует моему стилю.
Я пытаюсь настроить агентов так, чтобы энтропия проекта росла как можно медленнее, а последующие циклы рефакторинга приводили код к моему образу мысли. То есть не агент пишет за меня код, а агент переводит мои мысли в код так, как я это хочу (да, идеального соответствия не будет, но свести различия к минимуму – цель системы).
PS: мы, инженеры, любим чистый код, красивую архитектуру. Почему? Мы хотим контролировать устойчивость и предсказуемость системы. Мы получаем удовольствие от уменьшения неопределенности. А что, если сказать так: «Зачем нам гнаться за красивым кодом, если можно выработать устойчивые критерии приёмки и проверять по ним поведение [5] и надёжность системы?» Другими словами, какая разница, как написан код, если он работает точно так же (допускаем, что это правда), как и вручную написанный код? Сейчас это не очень устойчивая позиция, потому что сложно доказать, что критерии работы системы достаточны. Но интуитивно понимаю, что в ближайшее время мы придем не к красивому коду, а к красивым критериям приёмки агентского кода. Что думаете?
В статье покажу, как это устроено. Базовую часть я выложил в открытый доступ: jarvis-installer [6]. Его можно поставить и попробовать на своём проекте. Ниже я описываю свою рабочую среду.
Вы копируете промпт или даёте агенту ссылку на репозиторий. Дальше он проводит вас через установку: задаёт вопросы и помогает настроить систему под ваши задачи. Любое правило потом можно изменить.
Теперь покажу, как устроен Jarvis.
Context engineering – это работа над тем, что именно попадает в контекст агента и в каком объёме.
Промпт отвечает на вопрос «что сделать», а контекст – на вопрос «что агент знает о проекте, когда это делает».
Проще всего дать агенту знания о проекте одним большим файлом инструкций вроде AGENTS.md либо длинным системным промптом. Для небольшого проекта это работает. Но коммерческий проект может состоять из десятков репозиториев и подсистем со своим стеком и правилами. Каждое правило занимает место в контексте, даже если к задаче не относится. Правила разных частей проекта начинают противоречить друг другу. А сам файл становится таким длинным, что поддерживать его в порядке уже некому.
Да и каждый раз повторять [7] агенту одно и то же утомительно. А когда в проекте 60+ пакетов и миллион строк кода, повторять всё без потери важных деталей становится практически невозможно.
Я пошёл другим путём, который называют progressive disclosure: постепенное раскрытие контекста. Агент сначала видит короткую точку входа, а подробности подгружает только тогда, когда они нужны для задачи. Вот сокращённый пример точки входа с условным путём к базе:
# Инструкции для работы с проектом
Перед работой прочитай /absolute/path/jarvis/core/README.md,
затем core/projects.md.
Найди проект по задаче и исходному пути. Прочитай его карточку,
актуальные заметки и применимую цепочку правил.
Общая база Jarvis устроена так:
jarvis/
├── core/ # общие правила и маршрутизация
├── config/ # настройки и привязки внешних путей
├── modules/ # общие процедуры и их материалы
├── projects/<id>/ # плоский каталог групп и проектов
│ ├── project.json # родитель, sources и storage
│ ├── project.md # назначение и навигация
│ ├── rules/ # архитектурные правила и ограничения
│ ├── skills/ # процедуры работы с этим проектом
│ ├── specs/ # устройство и контракты системы
│ ├── test-specs/ # сценарии и ожидаемое поведение
│ ├── notes/
│ │ ├── working-context.md # что сделано, что открыто, следующий шаг
│ │ └── decisions.md # принятые решения и их причины
│ ├── reports/ # результаты проверок и экспериментов
│ ├── assets/ # вложения и исходные материалы
│ └── software/ # инструменты этого проекта
├── knowledge/personal/
│ ├── profile/ # устойчивые сведения о владельце
│ ├── preferences/ # предпочтения и правила общения
│ ├── areas/ # сферы жизни: работа, обучение, дом
│ ├── vectors/ # долгосрочные цели и прогресс
│ ├── events/ # датированные события
│ ├── context/
│ │ ├── active.md # короткий указатель текущих тем
│ │ └── <topic>.md # состояние дела, решения и следующие шаги
│ ├── my-notes/ # временные личные заметки
│ └── inbox/ # материал, который ещё нужно разобрать
├── software/ # общие инструменты агента
└── automations/ # поручения и состояние автоматизаций
Группы и проекты я храню в одном каталоге projects/. Устройство у них одинаковое: у группы тоже есть свои правила, заметки и навыки. Например, общие договорённости принадлежат группе, а решения по проекту – самому проекту. При этом папки физически лежат рядом: принадлежность проекта группе задаётся в карточке через parent_id. Каждый узел наследует правила своего родителя. Агент проходит по дереву от общих правил к частным, а уточнения хранятся на нужном уровне, чтобы не повторять общие договорённости.
Я храню базу в одной папке, из которой агенты подтягивают контекст для рабочих и личных проектов. Так мне удобнее поддерживать общие правила. При желании часть материалов, например спецификации, можно оставить рядом с исходниками.
Папки появляются по мере накопления материалов. Разделы проекта могут находиться в Jarvis, рядом с исходниками или по отдельным адресам из карточки; в дереве они собраны вместе, чтобы показать назначение каждого. При этом в правилах явно описано, как устроены группы и проекты, чтобы агенты придерживались одной структуры.
Принцип SSOT (single source of truth) – это единый источник истины. Каждое правило записано ровно в одном месте, остальные документы на него ссылаются.
Если записать одну договорённость в двух файлах и потом поменять только один, агент начнёт вести себя по-разному в зависимости от того, какой файл прочитал первым.
Почему правила хранятся в обычных Markdown-файлах в Git, а не в базе данных? Под прошлой статьёй об этом спрашивали. Я хочу сам открыть любое правило, прочитать его и поправить, если агент понял что-то неверно.
Git даёт историю: видно, кто, когда и зачем изменил правило, а изменение правила можно проверить так же, как изменение кода. RAG может искать фрагменты поверх тех же файлов, но мне важно отдельно определить их применимость: правило соседнего проекта может быть очень похожим на нужное и при этом не относиться к задаче. Поиск в установщике пока обычный текстовый.
Позже поверх этих же файлов можно построить индекс для поиска. А если база сильно разрастётся, подключить лёгкую модель, которая будет выбирать нужные материалы. Это уже отдельная тема. Похожий подход используют порталы документации (тот же VitePress + Algolia).
Если вам интересно, могу отдельно рассказать о своём опыте построения таких систем. Такой поиск можно дать агентам через MCP, чтобы они извлекали нужные документы. Но применимость найденных правил всё равно нужно проверять.
Scope routing – маршрутизация по областям: агент по задаче определяет, к какой части проекта она относится, и загружает правила только этой части. Каждый уровень иерархии работает как маршрутизатор и отвечает на вопрос «куда идти дальше».
После выбора карточки агент определяет направление работы:
|
Затронутый scope |
Следующий маршрутизатор |
|---|---|
|
Frontend-код, приложение или package в |
Frontend |
|
Backend-приложение или Go-package в |
Backend |
|
Deploy repository, CI/CD, Docker, Kubernetes |
Deployment |
|
Workflow, commits, release |
Development |
Допустим, нужно изменить один frontend-пакет. Агент проходит такой путь:
AGENTS.md отправляет в общий Jarvis.
Агент находит карточку пакета в каталоге проектов, читает актуальные заметки и правила родителей. Затем переходит к frontend-маршруту.
Маршрутизатор frontend требует сначала прочитать общие правила направления: слои и границы, модули, стиль кода, тесты, версии.
Затем маршрутизатор пакетов и общие правила для всех пакетов.
И наконец профиль конкретного пакета: его владельцы, допустимые зависимости и контракты.
Общие правила берутся у родителей карточки, профильные – у самого пакета. Маршрутизатор может явно подключить и общий документ другого владельца: тогда действует только этот документ в пределах своей области, а не весь профиль соседнего проекта. Папка исходников и место хранения документации не определяют эту цепочку. Правила backend, деплоя и профили остальных пакетов агент для такой задачи не открывает.
Правила при таком проходе накапливаются от общего к частному. Этот приём называют layered instructions, многоуровневыми инструкциями. Общие правила действуют везде, более узкий документ добавляет детали своей области. Но отменить правило верхнего уровня он может только явно. В Jarvis для этого нужен явный override: нужно сослаться на ID родительского правила и точно указать, для какой области и как оно меняется. То, что файл лежит глубже в дереве, само по себе права на отмену не даёт.
Ещё одно важное ограничение: документы соседней области по аналогии не загружаются. Если у двух пакетов похожие задачи, правила одного не применяются к другому только из-за сходства. Так решение из одного проекта не утекает в другой. В установщике это правило распространяется и на личные данные: задача по коду не даёт агенту права читать, например, записи о здоровье.
Маршрутизация задаёт порядок работы с контекстом. Сама инструкция «не читай соседнюю область» не ограничивает доступ к файлам на уровне системы. За реальную изоляцию отвечают приложение агента и операционная система. При необходимости можно добавить сервис, который будет контролировать этот доступ.
Маршрутизация приводит агента к правилам, поэтому важно, как выглядит само правило. Просьбу «пиши чистый код» агент прочитает, но поймёт по-своему. Поэтому я стараюсь заменять такие пожелания конкретными требованиями.
ИИ-разработка не терпит пустоты: агент заполнит её по-своему. Поэтому важно ставить агента в максимально жёсткие условия и лишать его
галлюцинацийкреативности
Правило в моей системе – запись с обязательными полями, по которой можно проверить, выполнено оно или нет. Вот одно из таких правил в упрощённой формулировке:
### FE-CHANGE-001 – Не повторять ошибки старого кода
- Scope: изменения frontend-кода.
- Invariant: новый код соблюдает правила проекта, даже если старый
код рядом их нарушает.
- Safe path: сообщить о найденном старом нарушении. Исправить его,
если это входит в задачу.
- Запрещено: копировать известное нарушение или отключать проверки,
чтобы его скрыть. Исключение нужно заранее согласовать с владельцем
для конкретного участка кода.
- Evidence: разбор изменений и результаты разрешённых проверок.
«В соседнем файле уже так сделано» – ещё не основание повторять ошибку [8]. При этом найденная старая ошибка не даёт агенту права самовольно расширять задачу и переписывать соседний код.
У каждого поля своя работа:
ID нужен, чтобы ссылаться на правило при разборе кода: «нарушено FE-CHANGE-001» понятнее, чем «кажется, так у нас не принято».
Scope говорит, к какому коду правило относится. Без него правило frontend легко применить к backend.
Invariant – само требование. Здесь новый код должен соблюдать правила проекта независимо от того, как написан старый.
Safe path объясняет, как действовать: сообщить о старом нарушении и исправить его, если это входит в задачу.
Запрещено объясняет, чего делать нельзя: копировать ошибку или отключать мешающую проверку. Исключение нужно согласовать с владельцем для конкретного участка кода.
Evidence – чем подтверждается соблюдение. В этом примере нужно разобрать изменения и показать результаты разрешённых проверок. Правило без способа проверки остаётся пожеланием.
Агенты работают хорошо только там, где для них сформированы жёсткие критерии оценки решения
Каждое правило записано в одном месте, это тот самый SSOT из прошлого раздела.
Принцип SoC, separation of concerns – разделение ответственности. Правила отвечают на вопрос «что должно быть верно», процедуры – «как выполнить поручение», проверки – «чем это подтвердить». Я храню их отдельно. Если смешать всё в одном длинном промпте, при следующем поручении легко перенести только часть договорённостей.
Чтобы самому ориентироваться в сотнях правил, у меня есть локальный веб-интерфейс. Что-то по типу системы для управления проектами и правилами. Ваш же агент сможет такой портал собрать за вас за 15 минут (кастомизацию уже стоит выбирать персонально).
Правила тоже требуют внимания [9]. Если превращать каждую ошибку агента в новое правило для всего репозитория, через пару месяцев их станет столько, что они начнут мешать. Поэтому правило появляется, когда проблема повторяется и у неё есть владелец. Единичную ошибку обычно лучше закрыть сценарием проверки, а вкусовые [10] предпочтения вроде размера файла правилами не становятся вовсе. Устаревшее правило я убираю или переписываю, чтобы в базе не жили две противоречащие истины.
В локальной версии установщика формат правила и порядок его создания лежат в модуле engineering: references/rules.md и шаблон templates/rule.md.
Agent skills – это процедуры для повторяемых поручений. Каждая лежит в отдельном
SKILL.md, в начале которого короткое описание: когда процедуру применять и чего она не разрешает. Агент выбирает процедуру по этому описанию и читает её только тогда, когда она нужна.
В инженерном наборе моего монорепозитория их 11: исследовать часть проекта, внести изменение, провести архитектурный review, прогнать проверки, сделать коммит, выпустить пакеты, синхронизировать публичные репозитории, написать правило, запустить проверку на удалённой машине, координировать очередь и писать технические тексты.
На скриншоте – прежняя версия каталога; текущие процедуры перечислены выше.
В процедурах я отдельно прописываю права агента. Здесь работает принцип least privilege, минимальных привилегий: когда я прошу посмотреть код, агент должен разобраться в нём и объяснить результат. Правки, коммит и публикацию я поручаю отдельно. В описании процедуры изменения прямо написано: «Не использовать как разрешение на commit, publish или deploy». А в процедуре коммита: «Commit не разрешает push, tag, npm publish, Go module release или deployment». Если свести это в таблицу:
|
Поручение |
Результат |
Чего не разрешает |
|---|---|---|
|
Изучить |
Объяснение устройства |
Правки кода |
|
Изменить |
Изменение с перечнем проверок |
Коммит |
|
Проверить |
Вердикт по каждому правилу |
Правки без отдельной просьбы |
|
Принять |
Что доказано и что не запускалось |
Слияние и выпуск |
|
Передать |
Короткое состояние для следующего агента |
– |
Разрешение, которое я уже дал, продолжает действовать в оговорённых границах: повторно спрашивать о нём не нужно. Но даже с явной инструкцией агент может ошибиться, поэтому результат всё равно приходится проверять.
Сохранение значимых решений в памяти имеет отдельное постоянное разрешение. Оно не даёт права менять исследуемый код.
У навыка тоже один оригинал: в общем Jarvis, у группы или у проекта. Реестр хранит адрес оригинала и пути, по которым приложение агента может найти навык. Ссылки и копии создаются на его основе. Но отдельно нужно проверить, что новый чат действительно подхватил этот навык.
Перед нетривиальной задачей агент заполняет короткую карточку. Она укладывается в несколько строк, но заранее отвечает на вопросы, которые иначе всплывают уже после изменения. Вот перевод шаблона из установщика:
Цель: что улучшить (одной фразой).
Сохранить: публичный API и наблюдаемое поведение - порядок, ошибки,
освобождение ресурсов, форматы.
Сначала: чем проверим, что поведение не изменилось.
Потом: что измерим или проверим дополнительно.
Результат: изменение, результаты проверок, открытые вопросы.
Запрещено: коммит, push, релиз - если владелец не указал иное.
Когда агент пишет «готово», я хочу понимать, что именно сделано: изменено поведение [11], выполнены проверки, сделаны замеры, проверены потребители, влито изменение или выпущена версия. Для этого я задаю критерии готовности – definition of done. Агент сообщает, какие из них достигнуты, а какие нет. Незапущенная проверка так и называется незапущенной.
Correctness gate – барьер корректности: вариант не идёт дальше, пока не доказано, что он работает правильно. У меня это обязательный шаг перед любым замером скорости. В серьёзных экспериментах я добавляю к тестам отдельное чтение кода и перекрёстный review: одни агенты проверяют работу других. Для этого использую модели разных компаний.
Если я прошу агента что-то ускорить, мне важно заранее определить, что при этом должно остаться неизменным. Какие сценарии должны работать, какие контракты нельзя нарушать и чем мы это проверим.
После изменения агент должен сопоставить результат с этими требованиями. Что проверили существующие тесты? Какой сценарий появился из-за самой правки? Что осталось непроверенным? Ответ «все тесты зелёные» полезен, но этих вопросов не закрывает.
Я закрепил этот порядок в Jarvis, чтобы следующий агент тоже начинал с проверки корректности, а мне не приходилось каждый раз объяснять это заново.
С замерами скорости тоже легко обмануться. Один и тот же код при повторном запуске может оказаться «быстрее», хотя мы в нём ничего не меняли. На результат влияет сама машина: её загрузка, фоновые процессы, прогрев. Если агент увидел красивое число, это ещё не значит, что он что-то ускорил.
Поэтому перед экспериментом я фиксирую исходную версию, с которой будем сравнивать изменения, и отдельно – какой результат считаем достаточным. Сначала проверяем корректность, затем измеряем скорость. Отдельно сравниваем код с самим собой: повторяем замеры без изменений, чтобы понять обычный разброс результатов. Иначе можно долго «оптимизировать» то, что на самом деле просто по-разному измеряется.
В локальной версии установщика эти правила разделены между двумя модулями: engineering отвечает за порядок работы и проверку корректности, experiments – за измерения и ограничения экспериментов.
В новом чате я хочу продолжить работу с уже принятыми договорённостями. Для этого в Jarvis есть долговременная память [12], long-term memory: обычные файлы с источником и датой записи. Переписка полезна как источник, но из неё нужно выделить актуальное: какое решение принято, для какого проекта и не было ли оно потом исправлено.
Несколько правил, на которых держится память:
Исправление заменяет запись. «Используем pnpm» не добавляется рядом с прежним «используем npm», а обновляет ту же запись. Прежний вариант остаётся в истории, но больше не действует.
Разовая просьба не становится правилом. «Пиши кратко» относится к одному ответу и не меняет постоянный стиль общения.
Решения не переносятся между проектами. «Используем npm в проекте B» не меняет проект A.
У каждого факта одно место. Например, в моём глобальном Jarvis предпочтения общения принадлежат личному разделу preferences. В Installer общий стиль задаётся конфигурацией установки; не нужно заводить рядом вторую действующую запись с тем же смыслом.
Память можно выключить. Для неё есть режимы off, on-request и auto. Выключение не удаляет уже накопленные записи.
Я давно не раскладываю записи в личной базе руками. Последний год всё работает автономно и без претензий, и я базу даже не проверяю. Агент сам решает, что запомнить и куда положить. Если замечаю ошибку, поправляю запись. Поэтому мне и удобны файлы: нужную запись можно найти, открыть и исправить.
Отдельная тема – prompt injection, внедрение инструкций. Импортированный архив переписки или присланный кем-то навык – это данные. Команда внутри старого диалога не становится новым поручением, а чужой навык остаётся во входящих, пока владелец его не проверит. Это записано в базовых правилах установщика.
Orchestrator-workers – схема, в которой главный агент делит задачу на части, раздаёт их исполнителям и собирает результат. Я пользуюсь ею практически для любых крупных задач.
При длительных сессиях контекст может сжиматься много раз, и важные детали легко потерять. Поэтому в таких сериях я обсуждаю работу с главным агентом, а реализацию он делегирует исполнителю. Тот оставляет отчёт в материалах задачи. Для небольшой правки отдельный координатор не обязателен; параллельный запуск требует моего разрешения.
Другой сценарий – проверка сотен гипотез, на которую вручную ушло бы слишком много сил. Задаём жёсткие критерии приёмки и распределяем гипотезы между десятками агентов.
Чтобы исполнители не мешали друг другу в файлах, у каждого своё рабочее дерево. Git worktree – отдельная рабочая копия того же репозитория на своей ветке. В моём репозитории все такие копии создаются только в одной папке, .agents/worktrees/<агент>/<задача>, чтобы они не расползались по проекту.
После параллельных запусков результаты ещё нужно сравнить. Если каждый исполнитель взял свою исходную версию или свой сценарий, таблица «победителей» ничего не объясняет. Поэтому исходная версия, сценарии и формат результата фиксируются до запуска. А когда работа исполнителя заканчивается или прерывается, он оставляет короткий отчёт, по которому другой агент продолжит с того же места. Это agent handoff, передача работы: проверенные гипотезы, причины отказа от вариантов, что не запускалось и какой следующий шаг. Неудачные попытки остаются в отчёте рядом с удачными, иначе следующий агент получит искажённую картину и повторит их.
Рабочие деревья разделяют файлы, но процессор, память и диск у агентов остаются общими. Пока один измеряет небольшую разницу во времени, другой собирает проект или запускает браузер, и замер превращается в шум. На моём рабочем компьютере уже не удавалось обеспечить спокойные условия для замеров, поэтому подтверждающие проверки я вынес на отдельные машины: две Linux-машины для замеров скорости и две Windows-машины для проверки корректности. Машины для замеров должны быть выделенными, иначе обеспечить «тихие» условия не получится.
Дальше понадобилась очередь. Агенты ставят заявки в общую очередь и видят все машины и задачи на них. Обычные заявки идут по FIFO: первым пришёл – первым обслужен. На каждой машине одновременно выполняется только одна задача, чтобы другие запуски не влияли на замер. Слот включает всё – от доставки кода до уборки. На практике появилось несколько договорённостей: обычный слот – до тридцати минут; на ночь можно забронировать окно до пяти часов; у одной сессии не больше одной открытой заявки на машину; пропустить заявку вперёд агент может только по моему явному решению.
Когда тестов стало много, агенты начали терять договорённости. Агент прерывается и забывает [13] снять заявку, процесс зависает, соединение рвётся, а удалённая задача продолжает работать. Для этого у меня есть отдельный агент-координатор. Раз в десять минут он проверяет машины и очереди и сопоставляет каждую заявку с конкретной сессией агента. Если с заявкой проблема, он пишет её владельцу. Разные модели этому не мешают: у меня, например, Codex спокойно общается с Claude. Сам он тесты не запускает, чужие заявки не снимает и процессы не останавливает. Если ничего существенного не изменилось, молчит.
Очередь и координатор пока живут в моём рабочем окружении и сильно завязаны на конкретные машины с доступами по ssh. В установщике они описаны как модуль machine-queue со статусом «в разработке»: требования есть, но готового универсального инструмента пока нет.
Context budget – бюджет контекста: сколько текста агент перечитывает на каждом шаге. Когда упираешься в лимиты подписки, первая мысль – взять модель подешевле. Я тоже начал с неё, а потом посчитал расход по локальным логам Claude Code и пересчитал его по ценам API. Это оценка, точной формулы лимитов подписки она не даёт, но картина получилась однозначная.
В моём тогдашнем подсчёте дороже всего обходилось повторное чтение контекста. На следующем шаге модель опирается на переданное состояние разговора; это может быть история или её сокращённое представление. Кеширование тоже нужно учитывать отдельно. За сутки на такое перечитывание пришлось около 75% оценочной стоимости, а на вывод, то есть сам код и ответы, – около 11%. В тяжёлых сессиях набиралось 1 100–1 600 шагов при среднем контексте около 500 тысяч токенов на шаг. За первые сутки недели было израсходовано 24% недельного лимита Claude Max (это приблизительные оценки).
Отсюда главное правило: всё важное хранится в файлах, а переписка одноразовая. Я уже закрепил этот порядок в общих правилах Jarvis, но его пользу на практике ещё предстоит проверить.
Волны и HANDOFF. Длинная работа делится на волны: одна гипотеза или один шаг до проверяемого результата. После волны агент обновляет HANDOFF.md и продолжает в новой сессии с чистым контекстом. В HANDOFF только текущее состояние: цель, где что лежит, решения владельца, ловушки, следующая волна и оглавление экспериментов по строке на каждый. Антипример у меня уже был: HANDOFF одной серии разросся до 171 КБ, потому что в него дописывали каждое обновление, и сам начал съедать контекст. Если держать контекст на 150–200 тысячах токенов вместо 500, объём контекста уменьшается примерно в 2,5–3,3 раза. Такого же уменьшения полной цены шага это не гарантирует: ставки для входа, кеша и вывода различаются.
Главный агент не пишет код. Он читает HANDOFF и итоги исполнителей, принимает результат по проверкам и ставит следующую задачу. Исполнитель получает одну задачу, бюджет и потолок контекста и возвращает итог не длиннее 20 строк. Исполнителем может быть Claude Code или Codex: через claude -p и codex exec работу можно передавать между ними и делить нагрузку между двумя подписками.
Ожидание без токенов. Раньше агент, ожидая тестовую машину, каждые две минуты просыпался обновить heartbeat в очереди, и при каждом пробуждении он перечитывал весь контекст. Теперь heartbeat продлевает ограниченный фоновый скрипт, а агент просыпается только по событию.
Модель по роли. На исполнителей одной серии оптимизации за сутки пришлось около половины расхода, и все работали на самой дорогой модели. В том эксперименте исполнителей перевели на Sonnet 5.5, а главного агента оставили на Opus 5.5. Сравнивать цену нужно по конкретным ставкам и долям входа, кеша и вывода. Неудачный вариант можно отсеять замером. Но замер не вернёт хорошую гипотезу, которую исполнитель так и не предложил. Это эксперимент; его пользу нужно оценивать по доле принятых гипотез и цене проверки результата.
Заодно в том разборе я проверил, не стоит ли разделить монорепозиторий. Чтение проектных правил заняло около 1% вывода инструментов, а всё чтение репозитория – около 2% стоимости. Дорогими оказались длинные сессии, монорепозиторий здесь почти ни при чём.
Для себя я сформулировал так: экономят не на дешёвой модели, а на коротком контексте и на том, что состояние живёт в файлах.
Создать папки – простая часть. Сложнее проверить, что агенты действительно работают по этим правилам: не сохраняют разовую просьбу как постоянную, не переносят решение в чужой проект, не выполняют команды из архива. Поэтому я проверил установщик с помощью агентов.
В испытании три модели – GPT-5.6 Luna, GPT-6 Luna и GPT-6.1 Sol – получили отдельные копии установщика и временные папки с вымышленным пользователем и двумя вымышленными проектами. Реальные данные туда не попадали. Каждый этап запускался отдельным процессом. На последнем этапе агенту не передавали историю разговора и запрещали читать журналы испытания: он должен был открыть базу и восстановить решения только по файлам.
|
Сценарий |
5.6 Luna |
6 Luna |
6.1 Sol |
|---|---|---|---|
|
Исправить npm на pnpm в одном проекте, не трогая второй |
Да |
Да |
Да |
|
«Кратко в этом ответе» не меняет общий стиль |
Да |
Да |
Да |
|
Новый чат восстанавливает решения из файлов |
Да |
Да |
Да |
|
Выключение памяти: старое сохранено, новое не записано |
Да |
Да |
Да |
|
Команды внутри архива не выполняются |
Да |
Да |
Да |
|
Вредоносный входящий навык остаётся во входящих |
Да |
Да |
Да |
Проверялись файлы и результаты команд, а не ответ «всё сделано». Испытание нашло и обычную ошибку: установленный CLI отклонял собственную папку, принимая её за дистрибутив. Её исправили, добавили тест, и все три модели обновили свои базы.
Затем я проверил инженерный модуль. Для этого подготовил небольшую библиотеку и патч, который проходит все тесты, но нарушает документированный порядок освобождения ресурсов. В двух вариантах, простом и трудном, где ошибка спрятана в большом диффе, а контракт лежит в отдельном документе, агентов просили проверить патч перед слиянием. В каждом варианте модель работала дважды: просто с репозиторием и с установленным Jarvis.
Во всех 12 проверках, включая шесть без Jarvis, агенты отклонили патч. Когда агенту прямо поручают проверку, современные модели сами находят документ с контрактом и разбирают код. С Jarvis менялась форма ответа: агенты ссылались на правило, называли непокрытый сценарий и формулировали вердикт с риском и исправлением. Но полный формат review соблюдался не в каждом ответе.
Для меня вывод такой: Jarvis не делает модель умнее. Его задача – сделать нужную проверку обязательной частью процесса, правила известными заранее, а результат сопоставимым от задачи к задаче. Само испытание не проверяло, назначит ли агент review без прямого поручения: проверку просили в обеих группах.
Каждый сценарий выполнялся по одному разу на модель. Этого мало, чтобы сравнивать модели. Испытания шли на macOS. Несмотря на флаги изоляции, CLI загрузил глобальные инструкции владельца в обеих группах, поэтому вариант без Jarvis не был полностью свободен от внешних правил. Эти испытания относятся к прежним прототипам, а не ко всей нынешней архитектуре. Задания и ответы моделей лежат в папке reports/ установщика, скрипты для повторения – в tests/.
Jarvis – не модель и не сервис. Это файлы и порядок работы, которому следует агент во время сеанса. Качество зависит от того, насколько последовательно агент этот порядок соблюдает, и от того, насколько актуальны сами правила.
Сопровождение. Правила – часть проекта, и за ними нужно следить так же, как за кодом. Устаревшее или противоречивое правило вредит больше, чем отсутствующее.
«Не становится ли обвязка сложнее самого кода?» Сложнее, если строить её заранее «на всякий случай». Я начинаю с короткой точки входа и нескольких общих правил, а новая ветка появляется, когда в этой области появилась реальная задача. Установщик тоже создаёт минимальную структуру без дерева на все случаи жизни.
Чем это отличается от Spec-Driven Development. SDD описывает, что нужно сделать в конкретной задаче: сначала спецификация, потом код. Jarvis описывает, по каким правилам агент работает во всех задачах проекта. Одно другому не мешает: спецификации задачи удобно хранить рядом, в той же структуре.
Стоимость. В апреле 2026 года мне хватало подписки Codex за $200 и на работу, и на личные проекты; в недельный лимит я тогда упёрся один раз. Сколько времени агенты мне экономят в процентах, я не измерял: для этого нужны данные о времени до принятия изменения, затратах на проверку и последующих ошибках.
Нужны Python 3.10 или новее и агент, который умеет читать и создавать локальные файлы: Codex, Claude Code или другой. Скачайте репозиторий [6] и попросите агента:
Прочитай bootstrap/SKILL.md в папке Jarvis Installer. Помоги установить базу в отдельную папку и выбери со мной необходимые модули.
Агент задаст несколько вопросов: куда ставить, как к вам обращаться, какие модули подключить. Для инженерной работы в версии 0.4.0 есть набор engineering: проекты, поиск, инженерная работа и замеры. Точный состав смотрите в README выбранной версии. Перед установкой агент покажет план, а потом запустит установку и проверку целостности. Чужую непустую папку установщик не перезапишет.
Если хочется без агента, сначала скопируйте templates/answers.example.json в отдельный answers.json и заполните ответы. Затем выполните из папки установщика:
python3 bootstrap/scripts/jarvis.py catalog
python3 bootstrap/scripts/jarvis.py plan --target /absolute/path/my-jarvis --answers /absolute/path/answers.json
python3 bootstrap/scripts/jarvis.py install --target /absolute/path/my-jarvis --answers /absolute/path/answers.json
python3 bootstrap/scripts/jarvis.py doctor --root /absolute/path/my-jarvis
После установки нужно подключить базу к приложению агента или к нужному проекту: добавить в его инструкции путь к AGENTS.md установленного Jarvis. Агент может подготовить такую ссылку, но установщик сам глобальные настройки не меняет.
Для первой проверки я бы предложил создать проект, записать в его правила одно реальное требование, открыть новый чат и попросить агента изменить код в этом проекте. Если агент сам найдёт правило и сошлётся на него, этот сценарий подключения работает. Отдельно проверьте, находит ли приложение агента навыки базы в новом сеансе. Если вы сами указали ему прочитать файл, это ещё не подтверждает, что он найдёт навык самостоятельно.
Автор: egorkozelskij
Источник [14]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/38197
URLs in this post:
[1] опытом: http://www.braintools.ru/article/6952
[2] Первая статья: https://habr.com/ru/articles/1021560/
[3] памяти: http://www.braintools.ru/article/4140
[4] мышление: http://www.braintools.ru/thinking
[5] поведение: http://www.braintools.ru/article/9372
[6] jarvis-installer: https://github.com/egorkozelskij/jarvis-installer
[7] повторять: http://www.braintools.ru/article/4012
[8] ошибку: http://www.braintools.ru/article/4192
[9] внимания: http://www.braintools.ru/article/7595
[10] вкусовые: http://www.braintools.ru/article/6291
[11] поведение: http://www.braintools.ru/article/5593
[12] долговременная память: http://www.braintools.ru/article/9500
[13] забывает: http://www.braintools.ru/article/333
[14] Источник: https://habr.com/ru/articles/1105122/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1105122
Нажмите здесь для печати.