TL;DR
StateHarness — оболочка вокруг кодового агента. Она заставляет агента вести четыре вида записей: текущую задачу и гипотезу, журнал находок и решений, заметки о связях (кто вызывает, какие тесты и документы затронуты) и список подходов, которые уже не сработали. Из записей собирается короткая «сводка», которая возвращается агенту перед каждым следующим решением. Перед изменением интерфейса система ищет по репозиторию места, которые могут сломаться. Перед завершением агент проходит чек-лист по своим записям.
Боль знакома каждому, кто давал агенту большую задачу. Агент правит функцию, тесты в этом файле зелёные, и он останавливается. А импорты, документация и второй вызывающий модуль остались старыми. Через 50 шагов ранняя находка тонет в истории, и агент перечитывает те же файлы по кругу. Причина простая: история действий — это лента событий, а у проекта есть структура. «Что я уже выяснил» и «что осталось недоделанным» нигде отдельно не лежит.
Метод выносит эту память из ленты в короткие редактируемые записи и заставляет сверяться с ними в трёх точках: перед правкой, во время работы и перед финишем. Если агент зациклился, отдельная «диагностическая» сессия перечитывает весь журнал и достаёт забытое. В статье это делает код-оболочка. Идею можно перенести в инструкции агенту, но не целиком (см. «Ограничения»).
Схема метода
ЗАПИСИ (агент ведёт сам, в процессе работы):
1. Состояние задачи → текущая подзадача + гипотеза
2. Журнал событий → находки, правки, тесты, решения, причины смены курса
3. Заметки о связях → вызывающие места, тесты, доки, конфиги + статус обработки
4. Правила обращения → что не сработало; «можно / проверять / не использовать»
ЦИКЛ:
Перед правкой интерфейса → поиск затронутых мест (кандидаты, не факты)
→ агент проверяет, записывает связь и решение
Каждый шаг → сводка (фокус + последние события + предупреждения)
Сигналы сбоя → напоминание → отдельная диагностическая сессия по журналу
Перед финишем → чек-лист: запрос, связи, тесты, открытые предупреждения
(по каждому: доделать ИЛИ записать, почему менять не нужно)
Пример применения
Задача: Вы ведёте интернет-магазин на Django. Нужно переименовать функцию расчёта доставки и добавить в неё вес посылки. Она вызывается из корзины, из админки, из интеграций со СДЭК и Почтой России. Ещё она описана в README и покрыта тестами. Классическая ловушка: агент правит корзину, тесты корзины зелёные, а модуль Почты России молча остаётся со старым вызовом.
Промпт (в Claude Code, поверх инструкции из шаблона ниже):
Задача: переименуй get_delivery_price(city) в calculate_delivery(city, weight_kg)
и обнови всё, что с ней связано.
Работай по правилам из PROJECT_STATE.md.
Перед изменением сигнатуры найди все вызовы, импорты, тесты и упоминания
в документации и запиши их в раздел «Связи» со статусом.
Не завершай работу, пока в «Связях» есть строки со статусом «открыто».
В конце покажи итоговую таблицу: что затронуто, что сделано,
что сознательно не менялось и почему.
Результат: Агент создаст или обновит файл с записями. В нём будут текущая подзадача, журнал и таблица связей: корзина, админка, СДЭК, Почта России, README, тесты. Перед правкой он найдёт места вызова и отметит их как «кандидаты». После каждого места будет статус «сделано», «проверено, менять не нужно (причина)» или «открыто». Перед финишем он пройдёт по таблице и вернётся к тому, что осталось открытым. В финале придёт сводная таблица последствий. Такой формат закрывает именно те хвосты, которые чаще всего теряются: импорты и документацию.
Почему это работает
Слабость. Агент живёт в потоке: прочитал файл, поправил, запустил тест, снова прочитал. Всё, что он выяснил, лежит в длинной ленте. Чем она длиннее, тем хуже он находит нужное: забытый вызов, уже отброшенную гипотезу. Локальная правка «отрывается» от последствий, которые вылезут много шагов спустя. Простое увеличение истории не помогает: важно не сколько помнишь, а вытащишь ли нужное в нужный момент.
Сильная сторона. Модель хорошо ведёт структурированные заметки и хорошо следует чек-листу, когда он прямо перед глазами. Она умеет проверить конкретное место и объяснить, почему оно затронуто или нет.
Как метод это использует. Он превращает «помнить всё» в «записать коротко и вернуть вовремя». Заметка о связи живёт, пока не получит статус. Завершение возможно только через проход по заметкам. Поэтому хвосты не исчезают сами. Выигрыш в статье виден именно там, где нужно помнить про соседние артефакты: импорты и документация. Сама правка стала лучше лишь немного.
Рычаги управления: - Запись «что не сработало» → добавь, если агент ходит по кругу. Выпиши отброшенные гипотезы, чтобы он их не повторял. - Окно последних событий → короче окно, дешевле. Но старое придётся поднимать из журнала вручную. - Условие финиша → «нет открытых связей» можно заменить своим, например «все изменённые файлы перепрогнаны тестами». - Порог диагностики → чем раньше запускаешь разбор журнала свежей сессией, тем меньше агент крутится вхолостую. Но больше расход.
Шаблон промпта
В статье эту работу делает код-оболочка: хуки, мониторинг, поиск. Ниже ручной вариант. Это та же логика (четыре записи, сводка, поиск связей, протокол завершения), выраженная инструкцией для агента. Кладётся в CLAUDE.md, AGENTS.md или системный промпт.
Ты работаешь над изменением в живом репозитории. Твоя задача — не только
выполнить правку, но и довести до согласованного состояния всё, что она задела.
Веди файл {файл_состояния} (например PROJECT_STATE.md) с четырьмя разделами.
Обновляй его по ходу работы, а не в конце.
1. ЗАДАЧА: исходный запрос; текущая подзадача; текущая гипотеза.
При смене гипотезы замени текущую, а старую и причину смены перенеси в ЖУРНАЛ.
2. ЖУРНАЛ: важные находки, правки, результаты тестов, решения, причины смены курса.
Только добавляй, не стирай.
3. СВЯЗИ: таблица «артефакт | почему затронут | статус | комментарий».
Артефакты: вызывающий код, тесты, документация, конфиги, импорты.
Статус: открыто / сделано / проверено, менять не нужно (причина).
4. ПРАВИЛА ОБРАЩЕНИЯ: подходы, которые не сработали, и пометка:
«можно» / «проверять явно» / «не использовать».
Перед каждым важным решением перечитай ЗАДАЧУ, последние {N} записей ЖУРНАЛА,
открытые строки СВЯЗЕЙ и ПРАВИЛА ОБРАЩЕНИЯ.
Если не заглядывал в записи более {K} шагов — загляни сейчас.
Перед изменением интерфейса (сигнатура, имя, формат данных) или удалением файла:
1. Найди в репозитории все места, которые могут быть затронуты:
вызовы, импорты, тесты, документацию, конфиги.
2. Считай найденное кандидатами, а не доказанными зависимостями.
3. Проверь каждое, реши, нужна ли правка или проверка, и запиши в СВЯЗИ
с причиной и статусом.
4. После правок перезапусти тесты, покрывающие изменённые файлы, и запиши
результат в ЖУРНАЛ.
Если ты:
- в третий раз читаешь один и тот же файл,
- повторяешь подход, который уже записан как неудачный,
- не можешь вспомнить, почему принято прошлое решение,
остановись. Перечитай ЖУРНАЛ целиком, найди противоречия, забытые находки
и устаревшие допущения. Запиши вывод и следующий шаг.
Перед завершением:
1. Перечитай исходный запрос.
2. Пройди по всем строкам СВЯЗЕЙ. Для каждой:
- сделай нужную доработку, ИЛИ
- запиши, почему изменений не требуется.
3. Проверь, что тесты по затронутым артефактам запущены.
4. Не завершай, пока есть строки «открыто» или неразобранные предупреждения.
5. В финальном ответе дай итоговую таблицу СВЯЗЕЙ.
Что подставлять: {файл_состояния} — имя файла записей в репозитории. {N} — окно последних событий, обычно 5–10. {K} — через сколько шагов принудительно перечитывать записи, обычно 10–15. Для маленьких задач уменьши всё и оставь только СВЯЗИ и протокол завершения.
🚀 Быстрый старт — вставь в чат:
Вот шаблон StateHarness: инструкция для кодового агента, который ведёт записи
состояния проекта и проверяет последствия правок. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит про стек и структуру репозитория, как запускаются тесты, где лежит документация и какие типичные «хвосты» у ваших правок (импорты, конфиги, миграции). Эти вопросы нужны, потому что метод держится на конкретных категориях связей и на понятном способе проверки. Модель возьмёт паттерн из шаблона и подставит ваши реалии.
Ограничения
⚠️ Больше регрессий: на цепочках исправлений ошибок число сломанных ранее проходивших тестов выросло. Метод дописывает хвосты, но не гарантирует, что старое поведение сохранилось. Тесты на изменённых файлах придётся прогонять отдельно.
⚠️ Дороже и медленнее: по сравнению с обычным агентом ушло заметно больше токенов, вызовов инструментов и времени. Для мелких правок это лишний расход.
⚠️ Польза неравномерна: выигрыш виден в импортах и документации. Для вызывающих мест (call sites) эффекта не было. Сама целевая правка улучшилась лишь слегка.
⚠️ Ручной вариант — не то же самое: в статье записи обновляют хуки, поиск по репозиторию запускается автоматически, а сигналы сбоя отслеживает код. Инструкцией в CLAUDE.md вы получите «мягкую» версию, где агент может просто пропустить шаг. Ручной шаблон авторы не проверяли.
⚠️ Слабая доказательная база: одна модель, малое число задач (пять в одном бенчмарке, 37 цепочек в другом), нет абляций. Неизвестно, какой из элементов даёт основной эффект.
⚠️ Нет готовых промптов: в доступной части статьи формулировок инструкций нет. Шаблон выше — реконструкция по описанию.
Как исследовали
Команда взяла Claude Code как базовую линию и надела на него «оболочку» с записями, сводкой, поиском затронутых мест и диагностикой. Модель везде одна, Claude Sonnet 5. Так сравнивается именно организация работы, а не сила модели. Проверяли на трёх наборах: RefactorBench (цепочки рефакторингов), пять долгих терминальных задач LHTB и ChainSWE (37 цепочек связанных багов в одном репозитории). Дополнительно сравнивали с более тяжёлой системой LongHorizon-Harness, где работают менеджер, исполнитель и аудитор.
Результаты — не одна общая победа. На рефакторинге выполнение всей цепочки выросло с 29,4% до 35,3%. Проверки «уборки» (импорты, доки) выросли с 87,0% до 95,4%, а проверки самой правки — всего на 1,3 пункта. На LHTB средняя награда выросла с 0,427 до 0,576. На ChainSWE доля исправленных багов поднялась с 35,1% до 39,5%, «остаточный долг» упал с 60 до 43, но регрессии выросли с 16 до 23. Удивило, что выигрыш — в хвостах, а не в основной правке, и что многоролевая система стоила в разы дороже (около 208 тыс. токенов против 35 тыс.), но не оказалась лучше. Практический вывод: если агенту нужно помнить про соседние артефакты, структурированные записи дешевле, чем несколько агентов-контролёров.
Одна деталь из разборов: агент с записями запомнил, что связанные тесты раньше проходили, и перезапустил их после широкой правки. Это вскрыло регрессию, которую агент без записей пропустил.
Адаптации и экстраполяции
🔧 Техника: ручная «диагностическая сессия» → свежий взгляд на журнал
Когда агент зациклился, не продолжай тот же чат. Открой новый и дай ему только файл записей:
Вот ЗАДАЧА, ПРАВИЛА ОБРАЩЕНИЯ и полный ЖУРНАЛ работы агента. Найди: повторяющиеся подходы, устаревшие допущения, противоречия, ранние находки, которые снова стали важны. Верни одно предложение — следующий шаг, только если журнал его подтверждает.Это ручная копия того, что в статье запускает система. Свежий контекст не обременён «шумом» длинной сессии.
🔧 Техника: усиление финиша → проверка на регрессии
Поскольку регрессии выросли, добавь в
пункт: «Запусти весь набор тестов, а не только затронутые; сравни с результатом до начала работы и перечисли новые падения». Это моя добавка, в статье её нет.
Экстраполяция: тот же принцип вне кода. Для длинной работы в чате с документами (договор, презентация, отчёт) заведи таблицу «связей»: что ещё нужно обновить после правки. Например, изменили цену в договоре — обновить приложение, спецификацию и письмо клиенту. Перед «готово» модель обязана пройти по таблице.
Ресурсы
- StateHarness: Maintaining Evolving Project State for Long-Horizon Coding Agents — препринт; код по ссылке из статьи: https://anonymous.4open.science/r/StateHarness
- Авторы: Chuan Zou (University of Pennsylvania), Yujun Zhou, Xiaonan Luo, Xiangliang Zhang (University of Notre Dame)
- Бенчмарки из статьи: RefactorBench (Gautam et al., 2025), Long-Horizon Terminal-Bench (Li et al., 2026), ChainSWE (Jin et al., 2026)
- Сравнение: LongHorizon-Harness (Ma et al., 2026)
