3,583 papers
arXiv:2610.05622 78 4 окт. 2026 г. FREE

UndoBench: умение агента делать задачу — не то же самое, что умение восстановиться после сбоя

КЛЮЧЕВАЯ СУТЬ
Агент видит «таймаут» и повторяет списание. Клиент платит дважды. При слепом повторе дубли возникали больше чем в половине прогонов, а сильные коммерческие модели проблему не снимали. Метод «сначала проверь, потом повторяй» позволяет агенту безопасно восстанавливаться после потерянного ответа в платежах, CRM (система учёта клиентов), базах данных и Git. Перед повтором агент читает, что сейчас в системе, и решает по факту, а не по тексту ошибки. Это проверка состояния перед повтором, и она подняла успешное восстановление с ~43% до 75%.
Адаптировать под запрос
⚡

TL;DR

Агент, который уверенно проходит задачу в спокойных условиях, после сбоя посреди работы с реальными системами (платежи, CRM, база данных, Git) справляется примерно вдвое реже. Исследователи сравнили два прогона одной задачи: без сбоя и с потерянным ответом от сервиса. Главный риск — слепой повтор: агент видит ошибку и просто вызывает инструмент ещё раз. Лучше всего сработала схема «сначала проверь состояние, потом решай, повторять ли». Идемпотентные ключи (уникальная метка запроса, по которой сервис отсекает дубль) помогли только там, где сервис их поддерживает.

Боль выглядит так. Агент вызвал «списать 1 200 ₽». Сервис списал, но ответ потерялся по дороге. Агент видит «таймаут» и не знает, прошла операция или нет. Он повторяет вызов, и клиент платит дважды. Из текста ошибки это не отличить от настоящего провала. При слепом повторе дубли возникали больше чем в половине прогонов. Более сильные коммерческие модели проблему не снимали: у них доля дублей была такой же или выше.

Метод простой: перед повтором мутирующего вызова (создать, списать, отправить, изменить) нужно прочитать текущее состояние и только потом решать — повторять, дозавершать или остановиться. В статье такая проверка подняла успешное восстановление после потерянного ответа с ~43% до 75%. Для сбоев посреди операции у остальных методов было 0%, с проверкой — около четверти. Важно: в статье это механизм рантайма агента. Перенос в инструкцию — ниже, и это наша адаптация.

🔬

Схема метода

Что делать зависит от того, в какой фазе случился сбой:

ФАЗА 1: сбой ДО изменения (не дошли до сервиса)
        → повтор безопасен, дублей нет

ФАЗА 2: сбой В СЕРЕДИНЕ изменения (часть шагов выполнена)
        → слепой повтор не работает (0%) → читай состояние,
          дозавершай или откатывай недостающее

ФАЗА 3: сбой ПОСЛЕ коммита, ДО ответа (самый опасный)
        → НЕ повторяй вслепую → прочитай состояние →
          если эффект уже есть, считай шаг выполненным

Всё это можно уместить в одну инструкцию агенту. Проверка состояния требует у агента инструмента для чтения (read-only).

🚀

Пример применения

Задача: Вы настроили агента в Bitrix24 для службы заботы онлайн-школы. Он оформляет возврат 4 900 ₽ через ЮKassa и закрывает сделку. Платёжный API иногда отвечает таймаутом. Деньги при этом могут уйти, а ответ потеряться. Без правила агент повторит возврат, и школа вернёт деньги дважды.

Промпт (фрагмент системной инструкции):

<ПравилаСбоев>
Инструменты делятся на два типа:
- ЧТЕНИЕ (get_refund_status, get_deal, list_payments) — повторять можно.
- ИЗМЕНЕНИЕ (create_refund, update_deal, send_email) — повторять вслепую НЕЛЬЗЯ.

Если вызов ИЗМЕНЕНИЯ вернул таймаут, обрыв связи или «неизвестный результат»:
1. НЕ вызывай его повторно сразу.
2. Скажи себе: «Я не знаю, прошла операция или нет».
3. Вызови инструмент ЧТЕНИЯ и проверь: появился ли возврат 4 900 ₽
   по заказу {id_заказа}?
4. Если эффект УЖЕ есть — считай шаг выполненным, иди дальше.
   Если эффекта НЕТ — повтори вызов один раз, передав тот же ключ
   идемпотентности: {id_заказа}-refund.
5. Если проверить состояние нечем или результат неясен — остановись
   и напиши оператору: что вызывал, с какими параметрами, что неизвестно.

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

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

🧠

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

Слабость. Из текста ошибки «timeout» не видно, дошёл ли вызов до сервиса. Ошибка не говорит, прошло ли изменение. Если в инструкции нет правила, повтор — самое «естественное» поведение, которому учат и людей-программистов, и модели.

Сильная сторона. Модель хорошо следует явному порядку действий и отличает «читать» от «менять». Если выделить класс «неизвестный результат» и привязать к нему обязательное действие, модель его выполняет.

Как метод использует это. Мы подменяем вопрос «получилось ли?» (его нельзя решить по ошибке) вопросом «что сейчас в системе?» (его можно проверить прямым чтением).

Рычаги управления: - Список инструментов — сильнее всего влияет на результат. Чем точнее вы разметили чтение и изменение, тем надёжнее правило. - Число повторов (в примере «один раз») — для необратимых операций (деньги, письма клиентам) ставьте ноль и эскалацию человеку. - Ключ идемпотентности — работает, только если сервис его поддерживает. Проверьте документацию API. - Условие остановки (шаг 5) — расширьте или сузьте в зависимости от цены ошибки.

📋

Шаблон промпта

В статье нет готового текстового промпта: проверка состояния реализована в рантайме. Шаблон ниже — перенос принципа в инструкцию агенту.

<ПравилаСбоев>
<Инструменты>
  ЧТЕНИЕ (повторять можно): {список_инструментов_чтения}
  ИЗМЕНЕНИЕ (повторять вслепую нельзя): {список_инструментов_изменения}
  НЕОБРАТИМЫЕ (ошибка → сразу эскалация человеку): {список_необратимых}


<ЕслиВызовИзмененияВернулОшибку>
  Тип ошибки «до отправки» (DNS, отказ соединения, ошибка валидации):
    → безопасно исправь параметры и повтори.
  Тип ошибки «неизвестный результат» (таймаут, обрыв, нет ответа):
    1. Не повторяй вызов.
    2. Вызови {инструмент_проверки} и найди ожидаемый эффект: {ожидаемый_эффект}.
    3. Эффект есть → шаг выполнен, продолжай.
    4. Эффекта нет → повтори один раз с ключом {ключ_идемпотентности}.
    5. Не удалось проверить → остановись, напиши {кому_эскалировать}.


<ЕслиОперацияИзНесколькихШагов>
  При обрыве посередине сначала перечисли шаги, уже видимые в системе,
  затем выполни только недостающие. Не начинай с начала.


<Отчёт>
  После любого сбоя кратко запиши: что вызывал, что случилось,
  что проверил, что решил.


Подставьте: названия ваших инструментов, ожидаемый результат (например, «возврат на 4 900 ₽ по заказу») и контакт для эскалации.

🚀 Быстрый старт — вставь в чат:

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

[вставить шаблон выше]

LLM спросит, какие у агента есть инструменты, какие из них меняют данные и чем можно проверить результат. Это нужно, потому что весь метод держится на разметке «чтение / изменение / необратимое» и на том, чем именно агент проверит состояние. Модель возьмёт структуру из шаблона и заполнит под вашу систему.

⚠️

Ограничения

⚠️ Нужен инструмент чтения: если агент не может проверить состояние (нет read-only доступа к платёжной системе, CRM, базе), метод не сработает. Тогда остаются эскалация человеку или идемпотентные ключи.

⚠️ Идемпотентность — не волшебство: ключи защищают только там, где сервис их принимает. На остальных эндпоинтах агент делал дубли почти в каждом прогоне. Отправили ключ ≠ защитились.

⚠️ Сбой посреди операции остаётся тяжёлым: даже с проверкой состояния восстановление было только у четверти прогонов. Остальные методы не справлялись совсем. Для многошаговых изменений нужны откат и человек в петле.

⚠️ Проверена идея, не формулировка: в статье проверка состояния реализована в рантайме, а не текстом в промпте. Работает ли ваша инструкция так же надёжно — проверяйте на своих сценариях.

⚠️ Среда симулированная: задач немного, доверительные интервалы широкие, а выигрыш идемпотентности статистически не подтверждён. Берите как направление, не как точный прогноз. Также неполная часть текста: часть разделов с описанием Verify-Retry нам недоступна.

🔍

Как исследовали

Идея была простой: сравнить два прогона одной и той же задачи, с одинаковым «зерном» случайности. В первом сбоев нет, во втором ответ от сервиса теряется уже после того, как операция выполнена. Так отделяется «агент не справился с задачей» от «агент справился, но не пережил сбой». Это и называется условная доля успешного восстановления (CRSR): считаются только те случаи, где в спокойном прогоне агент задачу решил.

Собрали 36 рабочих процессов из 8 областей: облако, CRM, база данных, Git, мессенджеры, платежи, хранилище, тикеты. Главный эксперимент идёт на 12 отложенных процессах: две открытые модели Llama, два рантайма (прямой вызов и LangGraph), три способа восстановления, 20 прогонов. Всего 2 880 парных запусков. Отдельные «судьи» смотрели и на состояние среды, и на реальные вызовы по сети, то есть были ли двойные списания.

Результаты. В спокойных условиях агенты справлялись в ~84% случаев. С потерянным ответом успешное восстановление падало до ~47%, а при слепом повторе дубли возникали в 53% прогонов. Идемпотентные ключи дали +11 п.п., но весь выигрыш пришёл с трёх эндпоинтов, где сервис ключи реально поддерживал. Журнал мутаций на стороне агента без права проверить сервер оказался почти равен наивному повтору. Удивило, что LangGraph и прямой вызов дали практически одинаковые результаты: сложный рантайм не спасает.

Потом повторили на коммерческих моделях: разрыв остался, восстановление ~21%, дубли в половине и более прогонов. Более «умная» модель риск не снимает. Наконец сравнили три фазы на четырёх составных процессах. До изменения все методы ≈77%. Во время изменения почти все давали 0%, и только проверка состояния перед повтором (Verify-Retry) вытянула ~26%. После коммита, но до ответа проверка дала ~75% против 43–46% у остальных. Вывод для практики: лечить надо по фазе сбоя, универсального «повторить и надеяться» нет.

💡

Адаптации и экстраполяции

🔧 Техника: убрать «одно общее правило» → разметить инструменты по обратимости

В статье инструменты делятся на обратимые, компенсируемые и необратимые. В CLAUDE.md или системной инструкции можно добавить разметку:

ОБРАТИМЫЕ (можно откатить): создание черновика, смена тега
КОМПЕНСИРУЕМЫЕ (можно исправить встречной операцией): возврат платежа, отмена заказа
НЕОБРАТИМЫЕ (одна ошибка = ущерб): отправка письма клиенту, перевод денег
Для необратимых: при любой неопределённости — стоп и вопрос человеку.

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

Вот список инструментов моего агента: {список с описаниями}.
Для каждого определи: меняет ли он данные во внешней системе, есть ли способ
проверить результат, поддерживает ли он ключ идемпотентности.
Затем смоделируй: «вызов выполнен, ответ потерян».
Покажи, где агент сделает дубль, и предложи правила для инструкции.
🔗

Ресурсы

  • UndoBench: Separating Task Competence from Recovery Capability in Tool-Using AI Agents
  • Авторы: Dolly Sah, Tanmay Sah, Harshul Jain, Tanya Sah (независимые исследователи)
  • Код: github.com/tradertanmay/undobench
  • Упомянутые отсылки: Reflexion (Shinn et al., 2023), Sagas (Garcia-Molina & Salem, 1987), Helland (2012) об идемпотентности, SWE-bench, ToolBench, AgentBench, WebArena

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

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

Агент видит «таймаут» и повторяет списание. Клиент платит дважды. При слепом повторе дубли возникали больше чем в половине прогонов, а сильные коммерческие модели проблему не снимали. Метод «сначала проверь, потом повторяй» позволяет агенту безопасно восстанавливаться после потерянного ответа в платежах, CRM (система учёта клиентов), базах данных и Git. Перед повтором агент читает, что сейчас в системе, и решает по факту, а не по тексту ошибки. Это проверка состояния перед повтором, и она подняла успешное восстановление с ~43% до 75%.

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

Всё зависит от того, в какой фазе случился сбой. 1. Сбой до изменения. Запрос не дошёл до сервиса. Повтор безопасен. 2. Сбой посреди изменения. Часть шагов уже выполнена. Слепой повтор здесь не работает вообще (0%). Читай состояние, дозавершай или откатывай недостающее. 3. Сбой после коммита, до ответа. Это самый опасный случай. Операция прошла, а ответ потерялся. Прочитай состояние. Если эффект уже есть, считай шаг выполненным. Таймаут не значит «не прошло». Сначала читай, потом решай. Представь, что звонишь в банк: «Перевод ушёл?» Ты не нажимаешь «отправить» второй раз. Ты открываешь выписку. Агент должен делать так же. Для этого ему нужен инструмент чтения (read-only, без права менять данные).

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

Из текста «timeout» не видно, дошёл ли вызов до сервиса. Ошибка молчит про результат. Без правила повтор остаётся самым «естественным» ходом. Ему учат и людей-программистов, и модели. Модель хорошо следует явному порядку действий. Она отличает «читать» от «менять». Если выделить класс «неизвестный результат» и привязать к нему обязательное действие, модель его выполняет. Метод подменяет вопрос «получилось ли?», на который нет ответа, вопросом «что сейчас в системе?», который проверяется прямым чтением. Есть и цифры. Для сбоев посреди операции остальные методы давали 0%. С проверкой выходит около четверти. Немного, но это разница между нулём и шансом. Сильные модели дублей не избегали: доля была такой же или выше. Важно: в статье проверка состояния встроена в рантайм агента (программу, которая запускает инструменты). Перенос в текст инструкции мы только предлагаем. Он не проверен в этой форме.

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

Агенты с инструментами, которые меняют данные → возвраты и списания, создание сделок в CRM, рассылка писем, запись в базу, особенно когда API иногда отвечает таймаутом и ты не знаешь, прошла операция или нет. НЕ подходит, если у агента нет доступа на чтение (нельзя заглянуть в платёжную систему или базу). Тогда остаются эскалация человеку и ключи идемпотентности (уникальная метка запроса, по которой сервис отсекает дубль). Они работают только там, где сервис их принимает. Для необратимых действий (деньги, письма клиентам) ставь ноль повторов и сразу зови человека. Сбой посреди многошаговой операции остаётся тяжёлым случаем. Тут нужны откат и человек в петле.

Мини-рецепт

1. Раздели инструменты на три группы: чтение (повторять можно), изменение (вслепую нельзя), необратимые (ошибка = сразу человеку).
2. Опиши сбой «неизвестный результат»: таймаут, обрыв, пустой ответ. Для него одно правило: не повторять сразу.
3. Назови проверку: какой инструмент чтения вызвать и какой эффект искать. Например: <проверка>get_refund_status по заказу {id_заказа}
4. Пропиши развилку: эффект есть — шаг выполнен. Эффекта нет — один повтор с тем же ключом идемпотентности, если сервис его поддерживает.
5. Дай выход на человека: не удалось проверить — агент останавливается и пишет оператору, что вызывал, с чем и что неизвестно.
6. Для многошаговых операций: при обрыве сначала перечислить шаги, уже видимые в системе. Потом выполнить только недостающие, а не начинать заново.
7. Попроси короткий отчёт: что вызывал, что случилось, что проверил, что решил.
8. Прогони на своих сбоях: сымитируй потерянный ответ и посмотри, не появились ли дубли. Формулировку из статьи никто не проверял, твою тоже надо.

Примеры

[ПЛОХО] : Оформи возврат 4 900 ₽ по заказу 1734 через ЮKassa и закрой сделку. Если ошибка, попробуй ещё раз.
[ХОРОШО] : Возврат 4 900 ₽ по заказу 1734: вызови create_refund. Если пришёл таймаут или обрыв, НЕ повторяй вызов. Скажи себе: «Я не знаю, прошла операция или нет». Вызови get_refund_status и проверь, есть ли возврат 4 900 ₽ по заказу 1734. Возврат есть — считай шаг выполненным и закрывай сделку. Возврата нет — повтори один раз с ключом 1734-refund. Проверить не вышло — остановись и напиши оператору, что вызывал и что неизвестно. В первом случае агент на таймауте второй раз спишет деньги, и школа вернёт их дважды. Во втором сначала смотрит статус возврата. Потом он закрывает сделку, повторяет с тем же ключом или зовёт человека. В отчёте оператору видно, что проверено и почему принято такое решение.
Источник: UndoBench: Separating Task Competence from Recovery Capability in Tool-Using AI Agents
ArXiv ID: 2610.05622 | Сгенерировано: 2026-10-06 05:40

Проблемы LLM

ПроблемаСутьКак обойти
Агент повторяет вызов вслепую, когда не знает, прошла операция или нетАгент вызвал действие, которое меняет данные: списать деньги, создать запись, отправить письмо. Ответ потерялся по дороге. Агент видит «таймаут». Из текста ошибки не понять, дошёл ли вызов до сервиса. Самое «естественное» действие — повторить. Если операция уже прошла, получается дубль: двойное списание, два письма, две записи. Плохо то, что это случается и у сильных моделей. Дело не в уме модели, а в том, что ошибка не несёт нужной информацииДобавь в инструкцию правило: после ошибки с неизвестным результатом не повторять вызов. Сначала прочитай текущее состояние системы. Потом решай: повторить, дозавершить или остановиться. Подробности — в методе ниже

Методы

МетодСуть
Сначала проверь состояние, потом решай о повторе — защита от дублейРаздели инструменты на два типа. Чтение (получить статус, список, карточку): повторять можно. Изменение (создать, списать, отправить, обновить): вслепую повторять нельзя. Если изменение вернуло таймаут, обрыв или «неизвестный результат», действуй по шагам. 1) Не повторяй вызов. 2) Скажи себе: «Я не знаю, прошла операция или нет». 3) Вызови инструмент чтения и найди ожидаемый эффект, например «возврат 4 900 ₽ по заказу N». 4) Эффект есть — считай шаг выполненным. 5) Эффекта нет — повтори один раз. 6) Проверить нечем или результат неясен — остановись и позови человека. Опиши ему, что вызывал, с какими параметрами и что неизвестно. Если операция из нескольких шагов оборвалась посередине: сначала перечисли шаги, уже видимые в системе. Выполни только недостающие. Не начинай с начала. Почему работает: вопрос «получилось ли?» нельзя решить по тексту ошибки. Вопрос «что сейчас в системе?» решается прямым чтением. Модель хорошо следует явному порядку действий и отличает «читать» от «менять». Рычаги: точная разметка инструментов (важнее всего), число повторов, условие остановки. Для необратимых действий (деньги, письма клиентам) ставь ноль повторов и сразу передавай человеку. Уникальная метка запроса: при повторе можно передать ту же метку. Сервис по ней отсекает дубль. Но это работает только если сервис метки поддерживает. Проверь документацию API. Отправленная метка не равна защите. Когда да: у агента есть инструмент чтения и он меняет данные во внешних системах (платежи, CRM, база, Git). Когда нет: читать состояние нечем. Тогда остаются передача человеку и метки запроса там, где они есть. Для сбоя посреди многошаговой операции метод помогает лишь частично. Нужны ещё откат и человек в контуре. Проверка работает как механизм среды выполнения агента. Как текстовая инструкция она не проверена. Тестируй на своих сценариях
📖 Простыми словами

UndoBench: Separating Task Competence from Recovery Capability inTool-UsingAIAgents

arXiv: 2610.05622

AI-агенты отлично щёлкают задачи в тепличных условиях, но в реальном мире они ломаются в два раза чаще при первом же сбое сети. Корень проблемы прост: модель не различает ситуации «действие не выполнилось» и «ответ потерялся по дороге». Если платёжный шлюз или CRM упали по таймауту, агент видит ошибку и включает тупой слепой повтор, превращая обычный сетевой лаг в катастрофу с дублями.

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

Спасает только жёсткое правило «проверь состояние перед повтором»: агент обязан сначала запросить статус операции, а не спамить новыми вызовами. Второй рабочий костыль — идемпотентные ключи, когда сервис сам отсекает дубликаты по уникальному ID транзакции. Исследование UndoBench наглядно доказало: без проверки статуса шанс успешного восстановления падает ровно в 2 раза, и агент начинает сливать ресурсы компании на ровном месте.

Тестировали на платежах вроде ЮKassa и базах данных, но грабли одинаковые везде. Отправка писем клиентам, коммиты в Git, закрытие сделок в CRM или возврат тех самых 4 900 рублей покупателю — любой шаг с изменением внешнего состояния требует защиты. Если агент управляет критическими бизнес-процессами, слепо надеяться на его «сообразительность» без сценария проверки — чистое самоубийство.

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

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

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

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