Полгода назад по сети разошлась история про AI-агента, который слил 441 тысячу за один твит — модель приняла решение, у неё был доступ к исполнению, и никто не стоял между решением и деньгами. С тех пор каждый раз, когда речь заходит про «дать агенту управлять чем-то важным», всплывает один и тот же страх: а если он сделает глупость с реальными деньгами?
Я строю сервис, где AI-агент управляет рекламными кампаниями в Яндекс.Директе, Google Ads и VK — то есть ровно тем, где ошибка агента стоит денег напрямую. И главный вопрос проектирования был не «как научить агента управлять рекламой», а «как сделать так, чтобы он физически не мог потратить деньги без человека».
Ниже — архитектура, в которой у агента нет ни одной кнопки, которая тратит бюджет сама. Разберу, где проходит граница между тем, что агент делает свободно, и тем, что требует подтверждения, как устроен этот контур, и почему я не доверяю агенту деньги, даже когда доверяю его аналитике.
Сразу честно про рамки: сервис в открытом бета-тесте, и — тьфу-тьфу — за время разработки агент ни разу не пытался сделать ничего катастрофического. Так что это статья не про пойманный инцидент, а про архитектуру, спроектированную так, чтобы инцидент был невозможен by design. Проверять её в бою будем на бете.
Проблема доверия агенту
Сначала о том, почему это вообще нетривиально.
Современный подход к агентам — дать модели набор инструментов (tools) и позволить самой решать, какие вызывать. Через протокол MCP это делается красиво: описываешь инструменты, агент читает описания и оркестрирует их под задачу пользователя. «Проанализируй, какие кампании сливают бюджет, и оптимизируй» — агент сам ходит по метрикам, находит проблемы, принимает решения.
Проблема в последнем слове. Аналитику агенту доверить не страшно: ошибётся в выводе — поправишь. А вот исполнение решения, которое тратит деньги, — это точка невозврата. Агент, который неверно понял метрику и поднял ставку в десять раз, потратит реальный бюджет за минуты, и откатить это уже нельзя.
История с 441 тысячей — ровно про отсутствие этого барьера. Модель имела право исполнять, между её решением и деньгами никого не было. Мой вывод из неё простой: агенту можно дать думать, но нельзя дать платить в одиночку.
Граница: read свободно, write — через человека
Вся архитектура строится на одном разделении. Инструменты агента делятся на два класса по признаку «тратит ли это деньги и меняет ли что-то необратимо».

Read-инструменты агент вызывает свободно, сколько нужно: получить баланс, список кампаний, метрики эффективности, найти аномалии, сравнить площадки, построить отчёт. Всё это только читает данные — навредить невозможно, поэтому агент оркестрирует их без ограничений.
Write-инструменты — те, что меняют состояние рекламы и тратят бюджет — их ровно три, и это сознательно короткий список: управление кампанией (пауза, возобновление, архивация), изменение ставки, изменение бюджета. Плюс создание объявления. Всё, что может стоить денег, собрано в этот узкий набор, и каждый из них проходит через контур подтверждения.
В коде это разделение — не пожелание, а жёсткая проверка. Write-инструмент физически не выполнится без права на запись у API-ключа, и в описании самого инструмента для агента стоит пометка, что операция разрушительная:
annotations: { readOnlyHint: false, destructiveHint: true }, // ... requireWritePermission(authInfo); // упадёт без write-права requirePlatformAccess(authInfo, params.platform);
Причём агент обязан объяснить, зачем он это делает — параметр reason со свободным текстом обязателен, минимум пять символов. Это не формальность: обоснование показывается человеку в момент подтверждения, чтобы он видел логику агента, а не голое «изменить ставку на X».
Контур подтверждения
Теперь главное — что происходит, когда агент хочет потратить деньги.
Перед выполнением write-операции сервис проверяет сумму, которую она затронет, против порога, заданного пользователем. Ниже порога — выполняется сразу (агенту не нужно дёргать человека из-за копеечной корректировки). Выше порога — вместо выполнения создаётся подтверждение (pending approval), и действие замирает до решения человека.

В коде это выглядит так: инструмент не исполняет действие напрямую, а сперва спрашивает у бэкенда, не превышен ли лимит, и при превышении заводит подтверждение:
const check = await checkSpendLimit({ userId, platform, amount }); if (check.exceedsThreshold) { const approval = await createApproval({ userId, actionType: 'adjust_budget', platform, description: `Изменить бюджет кампании X на ${amount} ₽`, payload, // что именно исполнить после одобрения expiresInHours: 24, }); return `Действие требует подтверждения. Ссылка: /app/approvals`; }
Ключевой момент: агент не исполняет отложенное действие — он его только предлагает. Само исполнение произойдёт, лишь когда человек нажмёт «одобрить» в личном кабинете, и уже не агент его выполнит, а отдельный серверный исполнитель, по сохранённому payload.
У подтверждения есть три свойства, каждое из которых закрывает свою дыру:
Срок годности. Подтверждение живёт заданное время (по умолчанию сутки) и потом истекает само. Это защита от ситуации, когда одобрение висит неделю, реклама за это время изменилась, а человек нажимает «да» на устаревшее решение. Истекло — деньги, зарезервированные под операцию, возвращаются.
Защита от двойного исполнения. Одобренное действие исполняется ровно один раз — на время исполнения ставится блокировка, и повторный клик или гонка двух вкладок не проведут операцию дважды:
const locked = await r.set(lockKey, '1', 'EX', 120, 'NX'); if (!locked) return { success: false, error: 'Approval is already being executed' };
Белый список исполняемого. Даже одобренное подтверждение может запустить только действие из явного списка разрешённых — три write-инструмента, и всё. Никакой одобренный payload не выполнит ничего за пределами этого списка, даже если бы кто-то попытался его подсунуть.
export const APPROVAL_EXECUTABLE_TOOL_NAMES = [ 'manage_campaign', 'adjust_bid', 'adjust_budget', ] as const;
Итог этой конструкции: между решением агента потратить деньги и фактической тратой всегда стоит человек, у него перед глазами обоснование агента, а окно на раздумье ограничено по времени. Повторить историю с 441 тысячей тут структурно невозможно — агенту просто некуда нажать, чтобы потратить бюджет самому.
Prepaid-модель: агент платит за каждое действие
Отдельный слой защиты, о котором обычно не думают, — экономический. Каждый вызов инструмента стоит денег, списываемых с предоплаченного баланса пользователя.

Чтение метрики — полрубля, поиск аномалий или отчёт — полтора, write-операция — три рубля, создание объявления — пять. Read-операции дешёвые, потому что безопасные; действия дороже, потому что значимые.
Это не только модель монетизации, но и естественный ограничитель. Агент, застрявший в цикле и дёргающий инструменты по кругу, упрётся в баланс и остановится, а не будет молотить бесконечно. А когда одобрение отклоняется или истекает, списанная за него стоимость возвращается на баланс — платишь только за то, что реально произошло.
Что агент делает хорошо: аналитика и дашборды
Теперь про то, чему агенту доверять как раз можно и нужно, — потому что статья была бы неполной, если бы создавала впечатление, что агент тут связан по рукам. Связан он ровно в одном: тратить деньги. Всё остальное — его сила.
Агент читает метрики со всех подключённых площадок сразу и отвечает на вопросы, которые иначе требуют ручного сведения трёх кабинетов: где сливается бюджет, какие кампании дают лучший ROAS, где просела конверсия за неделю. Инструмент поиска аномалий подсвечивает резкие изменения, которые легко пропустить глазами.
И то, что получается особенно наглядно, — агент собирает дашборды. Просишь «покажи сводку по рекламе за месяц» — агент собирает данные и генерирует дашборд с метриками, графиками и таблицами, который возвращается ссылкой:

Здесь агенту дана полная свобода, потому что дашборд ничего не тратит и ничего не ломает — это чтение, оформленное красиво. Виджеты четырёх типов: метрика, график (линия, столбцы, круг, область), таблица, текст. Агент сам решает, что показать под задачу, — и это ровно тот случай, где автономия модели работает на тебя без риска.
Как это подключается
Коротко про механику, чтобы было понятно, что это не игрушка.
Сервис — это MCP-сервер, который подключается к любому MCP-совместимому клиенту (Claude, например) одной строкой конфига. После подключения агент видит инструменты и может ими пользоваться от лица пользователя.
Рекламные площадки подключаются через OAuth — Яндекс.Директ, Google Ads, VK. Токены хранятся зашифрованными, у каждого API-ключа своя область прав: можно выдать ключ только на чтение, тогда write-инструменты будут недоступны в принципе, даже до контура подтверждения. То есть у осторожного пользователя агент может быть вообще лишён доступа к тратам на уровне ключа.
Три кабинета за одним интерфейсом
Отдельная сложность, которую стоит упомянуть: каждая рекламная площадка устроена по-своему, и агенту нельзя показывать этот зоопарк.
У Яндекс.Директа своё API со своей моделью кампаний, у Google Ads — совершенно другое, с иерархией аккаунтов и своими типами ставок, у VK — третье. Метрики называются по-разному, ставки задаются в разных единицах, статусы кампаний не совпадают. Если бы агент видел три разных API напрямую, ему пришлось бы держать в контексте три несовместимые модели — и ошибаться на стыках.
Поэтому каждая площадка спрятана за адаптером с единым интерфейсом. Агент вызывает list_campaigns или adjust_bid одинаково для любой площадки, а адаптер переводит это в специфику конкретного API и приводит ответ к общему формату. Добавить новую площадку — значит написать ещё один адаптер, не трогая ни агента, ни контур подтверждения.
Это та же идея, что и с границей read/write: сложность прячется внутрь, наружу торчит простой и предсказуемый интерфейс. Агенту проще, ошибок меньше, а человек в контуре видит унифицированное «изменить бюджет кампании X на Y рублей», а не сырой ответ чужого API.
Почему именно так, а не проще
Можно было сделать проще — например, дать агенту всё, но с общим дневным лимитом трат. Я сознательно не пошёл этим путём, и вот почему.
Дневной лимит защищает от масштаба катастрофы, но не от самой ошибки. Агент всё равно потратит деньги не туда, просто не больше лимита в день. А человек узнает об этом постфактум. Контур подтверждения работает иначе: он ловит ошибку до траты, и не по сумме, а по факту — любое значимое действие проходит через живой взгляд.
Вот три подхода к тому, чтобы агент не разорил, рядом:
Подход | Что защищает | Слабое место |
|---|---|---|
Ничего, полный доступ | ничего | история с 441 тысячей |
Дневной лимит трат | масштаб убытка | ошибка всё равно случается, узнаёшь постфактум |
Человек в контуре (здесь) | сам факт ошибочной траты | меньше автономии: крупное ждёт одобрения |
Первый подход — это ровно то, что привело к катастрофе с твитом. Второй кажется разумным, но он про «потерять не слишком много», а не про «не потерять». Третий — единственный, где ошибочная трата не происходит вовсе, ценой того, что агент не всесилен.
Да, это менее автономно. Агент не может сам оптимизировать кампании ночью, пока ты спишь, — крупные изменения дождутся твоего одобрения. Но это осознанный размен: я выбираю чуть меньше автономии в обмен на то, что не проснусь с пустым рекламным бюджетом. Для денег это правильный размен.
Итог
Дать AI-агенту доступ к деньгам можно — но не давать ему право тратить их в одиночку. Вся архитектура сервиса построена вокруг одной границы: агент свободно читает, анализирует и предлагает, но любое действие, которое тратит бюджет, проходит через человека — с обоснованием агента перед глазами, с ограниченным окном на решение, с исполнением из белого списка и защитой от повторов.
История с агентом, слившим 441 тысячу, была про отсутствие этого барьера. Здесь барьер — центральный элемент конструкции, а не надстройка. Агент получился полезным ассистентом по рекламе, который при этом структурно не способен разорить.
Сервис в открытой бете. Если хотите подключить своего агента к рекламным кабинетам и посмотреть, как это работает на ваших данных, — ads.synapsea.agency, тестовый доступ бесплатный. За баг-репорты, особенно про обход контура подтверждения, благодарю продлением подписки — если найдёте способ заставить агента потратить деньги без одобрения, мне очень нужно об этом знать.
Процесс разработки пишу в личном канале — https://t.me/synapseaa
А как вы относитесь к автономным агентам с доступом к деньгам — где для вас граница доверия?

