7 мин

Автоматический откат внешних последствий агента

Автоматический откат внешних последствий агента не может отменить каждое действие. Узнайте, где заканчиваются снимки и начинаются согласования или компенсации.

Автоматический откат внешних последствий агента

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

Безопасный подход разделяет четыре механизма: снимки приложения, Git revert, восстановление базы данных и компенсирующие действия. У каждого своя граница ответственности. Для любого действия, которое выходит за границы приложения, до его выполнения агентом нужны отдельные согласование, свидетельства, правило повторной попытки и путь восстановления. Если никто не может описать этот путь одним предложением, действие не готово к выполнению без присмотра.

У отката четыре разных значения

Откат полезен, только когда команда называет состояние, которое он вернет, и состояние, которого он не коснется. Обычно это слово скрывает четыре механизма с совершенно разными гарантиями.

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

Git revert фиксирует новый коммит, изменения которого отменяют более ранний коммит. Он исправляет историю исходного кода, не удаляя ее. Он не связывается с сервисами, которые старый код вызывал во время работы.

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

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

Во время ревью дизайна я использую таблицу ответственности за последствия, потому что она требует точных ответов:

ИзменениеКто отвечает за восстановлениеТипичный механизмМожно ли стереть исходное последствие?
Созданный исходный кодПриложение или репозиторийВосстановление снимка или Git revertОбычно да, для будущих запусков
Закоммиченные строкиОператор базы данныхЛогическое исправление или восстановлениеИногда локально
Доставленное письмоПочтовый провайдер и получательПоследующее письмо или подавление ожидающего письмаНет
Проведенный платежПлатежный процессорАннулирование или возвратНет
Внешний API-запросПринимающий сервисОтмена или компенсация, зависящая от провайдераОбычно нет

Последний столбец важнее всего. Обратная операция не доказывает, что исходная исчезла. Могут остаться журналы аудита, копии у получателей, записи о расчетах, webhook и физическая работа.

Revert кода меняет программу, а не прошлое

Revert кода предотвращает или меняет будущее поведение, но не отменяет последствия, которые уже вызвала старая версия. Это верно независимо от того, использует ли команда Git, снимок платформы или откат развертывания.

Документация Git описывает git revert как создание коммитов, отменяющих изменения, внесенные предыдущими коммитами. Формулировка точна: Git применяет обратный патч к содержимому репозитория. Git ничего не знает о письмах, платежах, облачных ресурсах, заявках в поддержку или API партнеров, созданных во время работы отменяемого коммита.

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

У отката развертывания та же граница. Перенаправление трафика на предыдущую сборку восстанавливает выполняемое поведение. Запросы, уже принятые замененной сборкой, сохраняют свои последствия. Очереди задач также могут пережить развертывание и выполнить старые предположения в восстановленной версии.

Перед revert сохраните операционные свидетельства, созданные старой сборкой:

  • Идентификатор развертывания и исходный коммит
  • Идентификаторы запуска агента и намерения
  • Идентификаторы сообщений очереди и статус аренды
  • Идентификаторы внешних запросов
  • Ответы провайдера и временные метки

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

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

Восстановление базы данных решает более узкую задачу, чем обычно думают

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

Рассмотрим такую последовательность:

  1. Агент добавляет строку счета.
  2. Он вызывает платежный API.
  3. Процессор принимает списание.
  4. Коммит базы данных завершается ошибкой.

Локальный откат удаляет строку счета. Списание при этом остается. Повтор всей операции без сверки может списать с клиента деньги еще раз. Это классический сбой двойной записи: приложение пыталось сделать одно бизнес-действие атомарным в системах без общего координатора транзакций.

Изменение порядка не решает проблему. Если приложение сначала фиксирует счет, а затем вызов платежа завершается ошибкой, в базе остается неоплаченный счет. Такое состояние проще проверить, но приложению все равно нужна машина состояний, которая различает payment_pending, payment_confirmed, payment_failed и payment_unknown.

Документация PostgreSQL объясняет восстановление на момент времени как восстановление базовой резервной копии и воспроизведение записей журнала предзаписи до выбранной точки восстановления. Это операторская процедура для восстановления кластера базы данных. Это не точечная отмена одного запуска агента, и она не может попросить платежный процессор или почтовый сервис вернуться к той же временной метке.

Откат базы данных в прошлое может создать еще одно расхождение. Представьте восстановление до 10:00 после сбоя. Провайдер принимал запросы до 10:07, но восстановленная база уже не содержит их записей. Агенты, увидев «отсутствующие» строки, могут заново создать все семь минут работы. Поэтому перед возобновлением работы воркеров восстановление требует этапа внешней сверки.

Паттерн outbox уменьшает один опасный разрыв. Приложение фиксирует бизнес-изменение и намерение создать последствие в одной локальной транзакции:

BEGIN;

INSERT INTO invoices (invoice_id, customer_id, status)
VALUES ('inv_2048', 'cust_91', 'payment_pending');

INSERT INTO effect_intents
  (intent_id, operation, subject_id, status)
VALUES
  ('eff_7f31', 'capture_payment', 'inv_2048', 'pending');

COMMIT;

Позднее воркер забирает eff_7f31, вызывает провайдера со стабильным значением идемпотентности и фиксирует результат. Outbox не делает внешний вызов атомарным. Он дает системе надежное свидетельство того, что работа была задумана, поэтому возможны повторные попытки и сверка.

Внешним действиям нужны компенсации, а у некоторых их нет

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

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

У платежей есть несколько состояний, которые команды часто объединяют словом «списано». Авторизация резервирует возможность потратить деньги. Capture запрашивает перевод средств в рамках этой авторизации. Void может снять авторизацию, которая еще не прошла расчет. Refund создает более позднюю финансовую запись о возврате денег после capture. У этих операций разные сроки, комиссии, права и влияние на клиента. Универсальный инструмент undo_payment скрывает сведения, нужные агенту для безопасного действия.

Другие API еще менее удобны. Запрос может заказать товар, выделить инфраструктуру, опубликовать контент, выдать доступ, отправить посылку или побудить человека начать работу. Конечная точка DELETE не доказывает обратимость. Удаление ресурса может оставить журналы аудита, скопированные данные, уведомления, зависимые ресурсы или физические последствия.

Классифицируйте компенсации по тому, чего они действительно могут достичь:

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

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

Не создавайте рекурсивную функцию «откатить откат». Представляйте историю как реестр действий. Если компенсация вызвала новую ошибку, после проверки текущего состояния выпустите еще одно явное действие. Такая история длиннее, но ее можно понять во время инцидента.

Идемпотентность предотвращает повторы, но не отменяет успех

Сначала исправьте будущее поведение
Разверните исправленное приложение и храните отдельные свидетельства в собственных инструментах для платежей и электронной почты.

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

RFC 9110 определяет идемпотентный метод запроса через то, что предполагаемый эффект нескольких одинаковых запросов совпадает с эффектом одного такого запроса. На уровне семантики протокола он относит PUT, DELETE и безопасные методы к идемпотентным. POST в общем случае не идемпотентен, хотя API может добавить такое поведение собственным контрактом.

Оговорка важна. Идемпотентный DELETE все равно может каждый раз создавать новую запись журнала, метрику или ответ. Реализация идемпотентности у провайдера также может удалять записи по истечении срока, ограничивать идентификаторы одной учетной записью, отклонять измененные параметры или кэшировать только выбранные результаты. Читайте контракт провайдера, а не делайте выводы по HTTP-методу.

Каждому намерению создать последствие нужно присвоить одно стабильное значение идемпотентности до первой попытки. Повторные попытки для того же намерения используют его снова. Новое бизнес-намерение получает новое значение. Никогда не выводите его только из изменяемых параметров, таких как клиент, сумма и дата: у двух законных покупок они могут совпасть.

Тайм-аут означает неизвестный результат, а не ошибку. Действуйте так:

  1. Пометьте попытку как outcome_unknown, не создавайте новое намерение.
  2. Запросите у провайдера статус по значению идемпотентности или ссылке на операцию.
  3. Если провайдер подтверждает успех, зафиксируйте его локально.
  4. Если он подтверждает отсутствие операции, повторите попытку с тем же значением.
  5. Если он не может ответить, приостановите операцию для сверки или проверки человеком.

Такая форма ответа дает агенту достаточно сведений, чтобы отличить принятие запроса от неопределенности транспорта:

{
  "intent_id": "eff_7f31",
  "attempt": 2,
  "idempotency_key": "eff_7f31",
  "transport_status": "timeout",
  "provider_status": "unknown",
  "provider_reference": null,
  "next_action": "reconcile"
}

Значение идемпотентности должно передаваться через журналы, сообщения очереди, API-заголовки и метаданные провайдера там, где это поддерживается. Если операторы не могут искать по нему по обе стороны границы, во время восстановления им придется гадать.

Согласование должно быть на границе последствия

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

«Разберись с учетной записью этого клиента» - недостаточное согласование для списания с карты или рассылки писем всем пользователям. Действительное согласование описывает конкретную операцию: получателя, сумму и валюту, дайджест сообщения или полезной нагрузки, целевую учетную запись, инструмент, срок действия и допустимое число попыток. При изменении любого согласованного поля согласование перестает соответствовать действию.

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

Требуйте явного согласования для действий, которые:

  • Перемещают деньги или создают финансовое обязательство
  • Передают информацию человеку или внешней организации
  • Публикуют, удаляют или раскрывают данные за пределами контролируемого хранилища
  • Меняют идентификацию, доступ, владение или настройки безопасности
  • Запускают физическую работу или другой процесс, который нельзя надежно отозвать

Для однотипных действий с небольшими последствиями можно использовать ограниченное постоянное согласование. Ограничение должно указывать максимальную сумму, набор получателей, разрешенный инструмент, время истечения, частоту и общее число операций. Формулировка «одобрено для биллинга» не имеет контролируемой границы.

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

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

Контракты инструментов должны показывать полный жизненный цикл последствия

Четко определите границы отката
Создавайте приложение в чате и ограничивайте откат программным обеспечением, которым управляет Koder.ai.

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

Этот фрагмент политики достаточно мал, чтобы его обеспечить, и достаточно конкретен для ревью:

tools:
  send_email:
    effect: irreversible
    approval: required
    idempotency_field: intent_id
    evidence_field: provider_message_id
    compensation: null

  capture_payment:
    effect: compensatable
    approval: required
    idempotency_field: intent_id
    evidence_field: provider_payment_id
    compensation: refund_payment

  update_draft:
    effect: local_reversible
    approval: none
    compensation: restore_version

effect сообщает планировщику, какой класс восстановления применим. approval блокирует выполнение, пока точные аргументы не будут согласованы. Поле идемпотентности заставляет повторные попытки использовать один идентификатор. Поле свидетельства говорит операторам, что нужно сохранить. Поле компенсации указывает на отдельный инструмент, не делая вид, будто исходный вызов можно выполнить в обратную сторону.

Выполнение должно принимать неизменяемый конверт:

{
  "intent_id": "eff_7f31",
  "operation": "capture_payment",
  "arguments": {
    "invoice_id": "inv_2048",
    "amount_minor": 12900,
    "currency": "USD"
  },
  "approval": {
    "approval_id": "apr_662",
    "scope_hash": "sha256:8b4f...",
    "expires_at": "2026-07-27T18:00:00Z"
  }
}

Исполнитель вычисляет дайджест операции, сравнивает его с scope_hash, проверяет срок действия, резервирует намерение и только затем связывается с провайдером. Он сохраняет метаданные запроса до вызова, а ответ - после. Если между этими записями происходит сбой, надежно сохраненное намерение остается доступным для сверки.

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

Дайте наблюдению отдельный инструмент, например get_payment_status(intent_id). Наблюдение не должно создавать последствие. Такое разделение позволяет агенту разрешать неоднозначные результаты, не получая разрешения повторить исходное действие.

Один неудачный запуск может пересечь все границы восстановления

Сохраните возможность восстановить исходный код
Экспортируйте исходный код, если процесс восстановления требует проверки на уровне репозитория и Git revert.

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

Предположим, агент создает приложение для членства, развертывает изменение, импортирует список клиентов, списывает ежегодные взносы и отправляет приветственные письма. Задача выглядит единой, но пересекает как минимум четыре границы восстановления.

В 14:00 агент развертывает код, который считает ежегодный взнос по неправильному столбцу. В 14:02 он записывает в базу 40 платежных намерений и черновиков писем. В 14:03 воркер проводит несколько платежей. В 14:04 почтовый провайдер принимает приветственные сообщения с неверным взносом. В 14:05 мониторинг останавливает воркер. Некоторые платежные вызовы завершились тайм-аутом после того, как достигли процессора, поэтому локальный статус не показывает, были ли они успешны.

Восстановление снимка кода на 13:59 останавливает ошибочный расчет в будущих запусках. Оно не меняет взнос, уже скопированный в существующие намерения. Revert Git-коммита документирует исправление исходного кода, но имеет то же ограничение.

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

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

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

Запуск завершен, только когда каждое намерение достигает конечного состояния, например succeeded, confirmed_failed, compensated или manual_exception. Фраза «Приложение откатили» описывает лишь первую часть инцидента.

Восстановление работает, только когда сохраняются свидетельства

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

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

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

Проводите тренировки восстановления с намеренно неудобными точками сбоя. Завершите воркер после того, как провайдер принял запрос, но до локальной записи успеха. Восстановите данные приложения из более раннего снимка, сохранив журнал последствий. Дайте согласованию истечь между планированием и выполнением. Сделайте API наблюдения недоступным. Тренировка пройдена, когда система останавливается, сверяет состояние и показывает неразрешенное решение, не создавая дубликат последствия.

При работе с Koder.ai считайте его снимки и откат слоем восстановления приложения, а для истории базы данных и каждого внешнего действия, которое может вызвать приложение, создайте отдельные механизмы контроля. Экспорт исходного кода, управление развертыванием и откат помогают восстановить программное обеспечение, но согласования и компенсации по-прежнему остаются в контрактах инструментов приложения.

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

FAQ

Может ли откат AI-агента отменить отправку письма?

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

Может ли автоматический откат отменить списание с банковской карты?

Обычно нет. Откат не может стереть проведенный платеж из записей процессора, системе нужно оформить возврат как новую финансовую операцию. Неподтвержденную авторизацию иногда можно аннулировать, но это все равно отдельная платежная операция, а не откат кода.

Что на самом деле отменяет Git revert?

Git revert создает новый коммит с изменениями, обратными более раннему изменению кода. Он не восстанавливает строки базы данных, не отменяет API-запросы, не удаляет доставленные сообщения и не возвращает платежи. Считайте его инструментом исправления истории исходного кода.

Отменяет ли откат базы данных внешние API-вызовы?

Транзакция базы данных может откатить незакоммиченные локальные записи. После коммита восстановление может вернуть базу данных к более раннему состоянию, но при этом убрать и другие корректные записи, а действия во внешних системах оно не отменит. Используйте его как процедуру восстановления, а не как универсальную кнопку отмены.

Ключ идемпотентности - это то же самое, что откат?

Нет. Идемпотентность не дает повторным попыткам создавать повторные последствия, если провайдер реализовал ее правильно. Она не отменяет первый успешный запрос и не гарантирует безопасность другого запроса с тем же идентификатором.

Какие действия агента должны требовать одобрения человека?

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

Что агент должен записать перед вызовом внешнего API?

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

Как агенту безопасно повторить запрос с тайм-аутом?

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

Когда компенсирующее действие можно запускать автоматически?

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

Как проверить безопасность отката для инструментов агента?

Проведите в тестовой среде сценарий, в котором после принятия запроса провайдером, но до записи агентом успеха, возникает тайм-аут. Убедитесь, что система сверяет операцию по идентификатору, не создает дубликат и фиксирует любую компенсацию. Также проверьте просроченные согласования, измененные аргументы, частичные сбои у провайдера и восстановление после возврата данных приложения из снимка.

Похожие статьи