Материал подготовлен автоматически по первоисточникам: ссылки на них — в конце статьи.
Гарантию «ровно один раз» нельзя надёжно переложить на LLM: при неясном исходе записи её должен обеспечивать API инструмента. К такому выводу пришёл Jiapeng Li из Microsoft в препринте, где числа получил сам автор и рецензирования ещё не было: с ключами идемпотентности, то есть стабильными идентификаторами операции, доля дублей снизилась с 28% до 4%. Для архитектуры агента это означает, что замена модели не исправит API, в котором повторный вызов снова списывает деньги, отправляет письмо или запускает развёртывание.
Как LIMBO отделяет ошибку модели от ошибки контракта
Автор создал LIMBO — детерминированную песочницу, где агент работает с платежами, почтой, публикациями, заявками, базой данных и развёртываниями. Эксперимент охватил 25 930 эпизодов, девять моделей и три промышленные агентские обвязки; обвязкой здесь называется программа между моделью и инструментами.
Сбои вводили на границе шести имитируемых сервисов. Запрос мог выполниться до тайм-аута, остаться в обработке, выполниться частично или прийти сервису повторно. Отдельный журнал фиксировал реальные последствия каждого вызова, поэтому оценка учитывала не только конечное состояние, но и лишнее списание, которое агент затем вернул.
Ключевой сценарий начинается с тайм-аута. Агент не знает, потерялся ли запрос, потерялся ли только ответ или операция ещё выполняется. Проверочное чтение помогает, если результат уже виден: агент находит созданную запись и не повторяет вызов.
Но пустой ответ ничего не доказывает, когда исходный запрос ещё обрабатывается или данные появляются в чтении с задержкой. Если агент повторит запись, обе копии могут выполниться. Если откажется от повтора, нужная операция может не состояться.
Работа формализует эту границу: без известного максимального времени обработки никакая стратегия «проверить и повторить» не гарантирует однократное выполнение. Ожидание лишь переносит риск, если редкие запросы задерживаются дольше выбранного срока. Ключ идемпотентности снимает неоднозначность: сервис узнаёт повтор той же операции и не создаёт второй эффект.
Модель справляется только с наблюдаемыми сбоями
Когда сервис выполнил запись, но потерял подтверждение, наиболее сильные модели с явной инструкцией действовать ровно один раз создавали дубли в 0,5% эпизодов. Они читали состояние сервиса, находили результат и пропускали повторный вызов. На таких сбоях выбор модели действительно влияет на надёжность.
При позднем выполнении исходного запроса те же модели дублировали операцию в 56% случаев. При повторной доставке запроса транспортом доля выросла до 74%. Модель не может рассуждением восстановить скрытое состояние, если оба возможных мира дают ей одинаковый тайм-аут и одинаковый пустой результат чтения.
Самоотчёт агента проблему не обнаруживает: в 90% эпизодов с дублем он сообщил об успешном завершении задачи. Поэтому проверка только финального ответа или конечного состояния пропускает повторные платежи и сообщения, особенно если агент позднее компенсировал ошибку.
Агентские обвязки влияли на результат заметно меньше, чем модель и контракт инструмента. Более того, скрытый автоматический повтор опасен: модель не видит второй вызов и не может решить, безопасен ли он. Общая защитная прослойка переносилась между обвязками, но полноценно работала лишь там, где API принимал ключи.
Что менять в архитектуре агента
Для необратимых записей гарантия должна начинаться в API. Операции оплаты, отправки письма, публикации и запуска развёртывания стоит принимать со стабильным ключом. Повтор с тем же ключом должен возвращать прежний результат, а не выполнять действие заново.
Обвязка может создавать ключ, закреплять его за намерением агента и повторно использовать после тайм-аута. Модели нельзя позволять генерировать новый ключ при каждой попытке: для сервиса это будут разные операции. Обвязка также должна хранить состояние «исход неизвестен» и показывать его модели и оператору, а не превращать любой серверный сбой в прозрачный повтор.
Проверочное чтение остаётся полезным дополнением. Для него API должен давать способ узнать состояние операции и описывать задержку появления данных. Если сервис задаёт верхнюю границу обработки, агент может дождаться её окончания перед проверкой; без такой границы чтение не заменяет ключ.
Более сильную модель имеет смысл выбирать для сбоев, которые можно разрешить наблюдением: потерянного подтверждения, частичной пакетной операции или читаемого серверного результата. Но обновление LLM не следует включать в план как основную защиту от дублей. Для скрытых повторов предел задаёт контракт инструмента.
Вывод проверяли на синтетических сервисах и коротких либо средних рабочих процессах, а модели запускали через один шлюз. Поэтому конкретные доли ошибок нельзя переносить на производственную систему без собственного испытания. Однако доказанная неоднозначность тайм-аута не зависит от модели: если API не различает повтор одной операции и новую операцию, клиент не может создать эту гарантию самостоятельно.
Источники
Похоже на вашу задачу?
Расскажите, что собираете. За полчаса разложим на этапы и назовём сроки — это бесплатно и ни к чему не обязывает.



