3,583 papers
arXiv:2610.17616 74 13 окт. 2026 г. FREE

StateHarness: агент ведёт рабочие записи проекта и проверяет последствия правок перед завершением

КЛЮЧЕВАЯ СУТЬ
Агент поправил функцию, тесты в файле зелёные, он рапортует о готовности. А второй вызывающий модуль, импорты и README остались со старым кодом. Метод StateHarness позволяет довести большую правку до конца без забытых хвостов: переименование функции, смена формата данных, удаление файла. Фишка: завершить работу нельзя, пока в таблице связей есть строка «открыто». Агент ведёт четыре коротких записи вместо одной бесконечной ленты действий. Из них собирается сводка, которую он перечитывает перед каждым важным решением. Хвосты в импортах и документации закрываются заметно лучше.
Адаптировать под запрос
⚡

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)

📋 Дайджест исследования

Ключевая суть

Агент поправил функцию, тесты в файле зелёные, он рапортует о готовности. А второй вызывающий модуль, импорты и README остались со старым кодом. Метод StateHarness позволяет довести большую правку до конца без забытых хвостов: переименование функции, смена формата данных, удаление файла. Фишка: завершить работу нельзя, пока в таблице связей есть строка «открыто». Агент ведёт четыре коротких записи вместо одной бесконечной ленты действий. Из них собирается сводка, которую он перечитывает перед каждым важным решением. Хвосты в импортах и документации закрываются заметно лучше.

Принцип работы

Работа идёт по трём точкам сверки. Перед правкой: агент ищет по репозиторию все места, которые могут сломаться. Это вызовы, импорты, тесты, документация, конфиги. Всё найденное считается кандидатами, а не доказанными зависимостями. Каждый кандидат получает статус: «открыто», «сделано» или «проверено, менять не нужно (причина)». Во время работы: перед каждым решением агент перечитывает короткую сводку. В ней текущая задача, последние события, открытые связи и список провальных подходов. Перед финишем: проход по таблице связей. По каждой строке либо доделай, либо запиши, почему менять не нужно. Агент не может молча пропустить хвост — ему придётся письменно объяснить, почему он его бросает. Четыре записи: задача и гипотеза, журнал находок и решений, таблица связей, правила обращения (что не сработало). Это как бортовой журнал вместо памяти пилота. Забыть пункт можно, а вот пропустить строку в журнале уже сложнее.

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

Агент живёт в потоке: прочитал файл, поправил, запустил тест, снова прочитал. Всё выясненное лежит в длинной ленте. Через 50 шагов ранняя находка тонет, и агент читает те же файлы по кругу. Простое увеличение истории не спасает. Важно не сколько помнишь, а вытащишь ли нужное в нужный момент. Модель при этом хорошо ведёт структурированные заметки и следует чек-листу, когда он перед глазами. Метод меняет задачу с «помнить всё» на «записать коротко и вернуть вовремя». Заметка о связи живёт, пока не получит статус. Завершение возможно только через проход по заметкам. Прикол: выигрыш виден не в самой правке, а вокруг неё. Целевая правка стала лучше лишь слегка. Зато импорты и документацию агент теперь не бросает. Честно про минусы. На цепочках исправлений ошибок выросло число сломанных ранее проходивших тестов. Расход токенов, вызовов и времени тоже заметно больше. Доказательная база слабая: одна модель, пять задач в одном бенчмарке, 37 цепочек в другом, абляций нет. Для мест вызова эффекта не нашли. Ручной шаблон авторы не проверяли. В статье записи обновляют хуки (автоматические перехватчики шагов), а поиск и мониторинг делает код.

Когда применять

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

Мини-рецепт

1. Заведи файл записей: положи в репозиторий PROJECT_STATE.md с четырьмя разделами: ЗАДАЧА, ЖУРНАЛ, СВЯЗИ, ПРАВИЛА ОБРАЩЕНИЯ.
2. Вшей правило в инструкцию агента: вставь шаблон в CLAUDE.md, AGENTS.md или системный промпт. Скажи, что файл обновляется по ходу работы, а не в конце.
3. Заставь искать до правки: перед сменой сигнатуры, имени или формата данных агент ищет вызовы, импорты, тесты, доки и конфиги. Найденное он записывает в СВЯЗИ как кандидатов.
4. Раздай статусы: у каждой строки одно из трёх: «открыто», «сделано», «проверено, менять не нужно (причина)».
5. Запусти тесты по затронутому: после правок перезапусти тесты по изменённым файлам. Результат идёт в ЖУРНАЛ.
6. Поставь стоп-кран на зацикливание: третий раз читает один файл или повторяет записанный провал? Пусть остановится и перечитает ЖУРНАЛ целиком.
7. Закрой финиш: не завершать, пока есть «открыто». В конце агент выдаёт итоговую таблицу связей.
8. Подстрой под размер задачи: окно последних событий 5–10 записей, перечитывание записей каждые 10–15 шагов. Для мелочи оставь только СВЯЗИ и протокол завершения.

Примеры

[ПЛОХО] : Переименуй get_delivery_price в calculate_delivery и добавь параметр weight_kg
[ХОРОШО] : Задача: переименуй get_delivery_price(city) в calculate_delivery(city, weight_kg) и обнови всё, что с ней связано. Работай по правилам из PROJECT_STATE.md. Перед изменением сигнатуры найди все вызовы, импорты, тесты и упоминания в документации и запиши их в раздел «Связи» со статусом. Не завершай работу, пока в «Связях» есть строки со статусом «открыто». В конце покажи таблицу: что затронуто, что сделано, что сознательно не менялось и почему. В первом случае агент правит корзину, тесты корзины зелёные, а модуль Почты России молча остаётся со старым вызовом. Во втором в таблице будут корзина, админка, интеграции со СДЭК и Почтой России, README и тесты. Закрыть работу, пока там висит «открыто», агент не сможет.
Источник: StateHarness: Maintaining Evolving Project State for Long-Horizon Coding Agents
ArXiv ID: 2610.17616 | Сгенерировано: 2026-10-14 23:40

Проблемы LLM

ПроблемаСутьКак обойти
Агент останавливается после локальной правки и оставляет «хвосты»Агент меняет функцию. Тесты рядом зелёные. Он считает работу законченной. Но второй вызывающий модуль, импорты и документация остались старыми. Правка оторвалась от своих последствий. Они вылезают позже, когда их трудно связать с причиной. Это касается любого изменения, которое задевает несколько файлов: переименование, смена формата, удалениеНе давай завершать по ощущению «готово». Заставь вести таблицу «что затронуто» со статусами. Запрети финиш, пока есть строки «открыто». Подробности в методе ниже
В длинной сессии ранние находки тонут, агент ходит по кругуЧерез десятки шагов история действий — длинная лента. Нужная находка или отброшенная гипотеза в ней теряется. Агент перечитывает те же файлы. Повторяет подход, который уже не сработал. Больше истории не значит лучше память. Важно, вытащит ли он нужное в нужный моментВеди короткий журнал: находки, решения, причины смены курса. Отдельно держи список «что не сработало». Перед важным решением перечитывай последние 5–10 записей и список неудач. Задай признаки застревания: «в третий раз читаю один файл», «повторяю записанную неудачу». При них — стоп и разбор всего журнала. Лучше в новой сессии, с чистым контекстом

Методы

МетодСуть
Таблица связей со статусами и запретом финиша — закрывает хвосты правкиПопроси агента вести таблицу: артефакт \| почему затронут \| статус \| комментарий. Артефакты: вызывающий код, тесты, документация, конфиги, импорты. Статусы: «открыто», «сделано», «проверено, менять не нужно (причина)». Перед изменением интерфейса агент ищет по репозиторию места, которые могут быть затронуты. Найденное — только кандидаты, не доказанные зависимости. Каждое он проверяет и записывает решение. Перед завершением проходит по всей таблице. В конце показывает её итоговый вид. Почему работает: запись живёт, пока не получит статус. Хвост не может «забыться сам». Выход из задачи идёт только через проход по записям. Модель хорошо ведёт заметки и хорошо выполняет список проверки, когда он прямо перед глазами. Статус «менять не нужно, потому что…» не даёт отмахнуться молча. Когда применять: правки, которые расходятся по многим файлам. Это переименования, смена сигнатур, удаление, миграции. Подходит и для не-кода: связанные документы, конфиги, шаблоны. Когда не работает: мелкая правка в одном месте — лишний расход. Если инструкция лежит только текстом, агент может пропустить шаг. Нужна явная проверка в конце. Замени условие финиша на своё, если нужно, например «все изменённые файлы прогнаны тестами»
📖 Простыми словами

StateHarness: Maintaining Evolving Project State for Long-Horizon CodingAgents

arXiv: 2610.17616

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

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

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

В исследовании разбирали рефакторинг магазина на Django, где изменение одной функции ломает доставку и админку, но принцип универсален. Точно так же этот подход работает для сложных ETL-пайплайнов, автоматической миграции баз данных и юридического аудита. Если задача требует больше 10 последовательных шагов, сырой контекст неизбежно сгниёт без внешнего каркаса.

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

Работа с исследованием

Адаптируйте исследование под ваши задачи или создайте готовый промпт на основе техник из исследования.

0 / 2000
~0.5-2 N-токенов ~10-30с
~0.3-1 N-токенов ~5-15с