Короткий ответ для владельца бюджета

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

Эта рекомендация относится к заказам, созданию кампаний и изменениям лимитов через управляющий API. Она не описывает повторы отдельных ставок в RTB-аукционе: у них другой жизненный цикл и временные ограничения. Базовую архитектуру закупки разбираем в гайде по programmatic, подготовку медиапредложений в разборе OpenProposal.

Почему тайм-аут оставляет неизвестность

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

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

В Amazon Builders’ Library идемпотентность рассматривается как способ безопасно повторять операции распределённого сервиса. Это инженерный принцип, применимый к рекламному управлению; статья AWS не подтверждает поддержку такого режима какой-либо российской DSP.

Что означает идемпотентность в договоре API

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

Stripe документирует такой механизм на примере собственных API. При этом поведение API v1 и v2 различается: сохранённый ответ и обработка неудачной работы устроены неодинаково. Копировать срок хранения или правила ошибок из платёжного API в рекламную интеграцию нельзя. Этот пример полезен как образец явного контракта, а не готовая спецификация для медиабаинга.

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

Один идентификатор решения, несколько попыток

Для учебного заказа вводим business_operation_id равный order-brief-42-v3. Он относится к конкретному согласованному брифу, получателю и действию. Первая и вторая попытки получают разные attempt_id, но сохраняют business_operation_id и ключ идемпотентности. Полезно также хранить хеш нормализованных параметров: сумму, валюту, аккаунт, период, перечень инвентаря и версию согласования.

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

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

Карточка операции для интегратора

Параметры, ключ, статус и подтверждение связывают решение с заказом
Параметры, ключ, статус и подтверждение связывают решение с заказом. Собственная редакционная схема AdTech Russia. Числа в учебных примерах не являются рыночными данными.

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

ПолеУчебное значение или правило
ОперацияСоздать один заказ по брифу 42, версия 3
Область ключаАккаунт рекламодателя, тип операции, согласованное решение
Неизменяемые параметрыПолучатель, сумма, валюта, даты, продукт, версия согласования
ПовторТот же ключ и те же параметры до выяснения результата
Изменение суммыНовое решение после закрытия судьбы старого
Неизвестный исходПауза на новые обязательства по этому решению, запрос статуса
Истечение храненияСверка кабинета и журнала до новой попытки
ПодтверждениеID заказа площадки, время, итоговые параметры

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

Параллельные исполнители требуют общей защиты

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

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

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

Семь испытаний перед доступом к деньгам

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

  • Потерять ответ после успешной записи: повтор должен вернуть исходный заказ либо однозначно сообщить его статус.
  • Отправить две одинаковые попытки одновременно: проверить число объектов и согласованность ответов.
  • Повторить ключ с другой суммой: ожидать документированный конфликт, не молчаливое изменение.
  • Перезапустить агента между отправкой и ответом: восстановить исходную операцию из постоянного журнала.
  • Повторить после истечения хранения ключа: убедиться, что процесс требует сверки, если сервер уже не защищает от дубля.
  • Получить серверную ошибку: проверить правила именно этого API, не считать любой 5xx доказательством отсутствия эффекта.
  • Отозвать полномочие после первой попытки: дальнейшее создание или изменение должно учитывать актуальный запрет, а чтение статуса иметь отдельно определённые права.

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

Отмена тоже может потерять ответ

Запрос отмены, подтверждение и прекращение расхода являются разными состояниями
Запрос отмены, подтверждение и прекращение расхода являются разными состояниями. Собственная редакционная схема AdTech Russia. Числа в учебных примерах не являются рыночными данными.

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

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

Российский пилот без смены DSP

Начните с одной команды существующего кабинета: например, создания кампании без её запуска. Технический руководитель описывает контракт API, медиабайер фиксирует согласование, AdOps сверяет созданные объекты, финансовый ответственный проверяет резерв и обязательства. Назначьте владельца состояния «исход неизвестен» и срок эскалации, согласованный с реальной поддержкой.

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

Самостоятельный вывод редакции: право автоматически повторять команду выдаётся после проверки контракта и восстановления состояния. Пока команда не умеет доказать единственность заказа, агенту достаточно готовить решение для оператора. Связанный разбор контроля AI-медиабаинга объясняет остальные границы полномочий; определения доступны в глоссарии.