Ваш ИИ-агент ждёт вас: превращаем запросы на подтверждение в телефонные звонки

Автономные агенты молча останавливаются и ждут, когда им нужен человек. Ничто в стеке агентов не заставит ваш телефон зазвонить. Разбираем, как связать запросы на подтверждение и сорвавшиеся запуски с настоящим звонком через Echobell.

Содержание

У каждого фреймворка для автономных агентов, вышедшего в 2026 году, одна и та же дыра. Агент часами работает без вас, упирается в действие, которое ему не разрешено выполнять самостоятельно, останавливается — и дальше не происходит ничего. Запуск не завершается ошибкой. Он не повторяется. Он висит в памяти с сериализованным объектом состояния и ждёт человека, который понятия не имеет, что его ждут. Это руководство показывает, как закрыть разрыв: превратить момент «мне нужен человек» в звонящий телефон с помощью Echobell.

Разрыв структурный, а не баг конкретного продукта. Документация OpenAI по агентам описывает процесс подтверждения точно: когда инструменту нужно подтверждение, «запуск приостанавливается, пока вы не подтвердите или не отклоните его», результат возвращает interruptions плюс возобновляемый state, а если проверка может затянуться, вам предлагают сериализовать это состояние, сохранить его и возобновить позже (OpenAI, руководство по Agents SDK). Нигде в этом процессе ничто не доходит до человека. Уведомить того, кто подтверждает, — целиком ваша задача.

При этом запуски становятся всё длиннее. AWS описывает свои frontier-агенты как способные «работать часами или днями, не требуя вмешательства» (About Amazon). Kiro Crew, вышедший 4 августа 2026 года, говорит прямо: «Запустите миграцию, и она продолжит идти через контрольные точки и повторы, пока вы на встрече или спите» — и тут же отмечает, что «запросы инструментов могут требовать подтверждения» (Kiro). Обе половины верны одновременно. Агент работает, пока вы спите, и агент останавливается, пока вы спите.

Насколько часто на самом деле случаются инциденты с агентами?

Достаточно часто: у большинства компаний такой инцидент уже был, и большинство не запускает агентов без присмотра. В опросе 418 специалистов по ИТ и безопасности, проведённом в январе 2026 года Cloud Security Alliance по заказу Token Security, 65% организаций сообщили минимум об одном инциденте с ИИ-агентами за последний год — 61% об утечке данных, 43% о нарушении работы и 35% о финансовых потерях (пресс-релиз CSA, отчёт).

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

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

Что на самом деле происходит, когда агенту нужен человек?

Он молча ждёт, и уведомление каждый фреймворк оставляет на вас. Механизм различается, результат — нет.

СтекМеханизмЧто доходит до человека
OpenAI Agents SDKneedsApproval у инструмента приостанавливает запуск и возвращает interruptions + возобновляемый stateНичего — что делать с прерыванием, решает ваше приложение
MCP-серверыelicitation/create запрашивает ввод у пользователя посреди вызова инструмента и возвращает accept, decline или cancelТо, что отрисует MCP-клиент, — в безголовом запуске на это никто не смотрит
Claude CodeСрабатывает хук Notification со значениями матчера, среди которых agent_needs_input и agent_completedТо, к чему вы подключите хук
Kiro CrewЗапросы инструментов могут требовать подтверждения, активность записывается для разбораВкладка Activity, если вы её откроете

Model Context Protocol фиксирует это прямо на уровне спецификации. Elicitation существует именно для того, чтобы сервер мог посреди запуска спросить что-то у человека, и текущая ревизия (2026-07-28) предупреждает: серверы «НЕ ДОЛЖНЫ предполагать, что запросы elicitation всегда будут успешными», и обязаны обрабатывать отказ, отмену и сбой клиента (спецификация MCP). Протокол стандартизирует вопрос. Он не стандартизирует — и не может стандартизировать — то, как привлечь внимание человека.

В этом и вся возможность. У каждого слоя стека агентов есть хорошо продуманная пауза. Ни у одного нет телефонного номера.

Какие события агента заслуживают звонка?

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

  1. Заблокированное подтверждение в запуске, который без него не продвинется. Агент простаивает, время идёт, и никакое ожидание это не разрешит. Это канонический случай.
  2. Окончательный сбой длинного запуска без присмотра. Шестичасовая миграция, умершая на втором часу, — это четыре часа, которых вы не вернёте, и вы предпочли бы узнать об этом на втором часу.

Всё остальное — на более тихий канал. «Задача успешно завершена» — обычный пуш. «Агент израсходовал 80% бюджета» — в лучшем случае срочное уведомление. «Агент запущен» — вообще не уведомление. Три типа уведомлений в Echobell — обычное, срочное и звонок — существуют ровно для такой сортировки, и раскладка событий агента по ним здесь самое важное проектное решение. Если вы уже боретесь с объёмом уведомлений, прочитайте как справиться с усталостью от оповещений, прежде чем добавлять канал, который звонит.

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

Echobell превращает вебхук или письмо в телефонный звонок — настоящий звонок со звуком и вибрацией, который пробивается через «Фокусирование» и «Не беспокоить» в iOS так же, как это сделал бы звонок от члена семьи (см. как обойти «Фокусирование» в iOS). Он стоит между агентом, который остановился, и человеком, который может снять паузу.

Шаг 1 — Создайте канал со звонком для заблокированных агентов

Создайте в приложении канал и задайте ему тип уведомления Звонок. Дайте ему однозначное имя вроде «Агент заблокирован — нужно подтверждение» и не используйте его больше ни для чего. Скопируйте URL вебхука из деталей канала; он выглядит как https://hook.echobell.one/t/<channel-token>. Относитесь к нему как к секрету — любой, у кого он есть, может заставить ваш телефон звонить (руководство по вебхукам).

Задайте шаблоны заголовка и текста так, чтобы по ним можно было действовать прямо с экрана блокировки:

Title: Агент заблокирован: {{agent}}
Body: Ожидает {{action}} в {{project}} — с {{time}} UTC

{{time}} и другие системные переменные времени всегда доступны в UTC, и передавать их не нужно.

Шаг 2 — Отправляйте вебхук из ветки подтверждения

В любом SDK, который возвращает прерывания, пауза — это обычная ветка в вашем коде. Отправьте POST на URL канала, прежде чем припарковать запуск:

let result = await run(agent, input, { stream: false });

if (result.interruptions?.length) {
  await fetch(process.env.ECHOBELL_BLOCKED_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      agent: agent.name,
      action: result.interruptions[0].rawItem.name,
      project: process.env.PROJECT_NAME,
      externalLink: `https://ops.example.com/runs/${runId}`,
    }),
  });
  await saveState(runId, result.state); // сериализуем и возобновляем после подтверждения
}

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

Шаг 3 — Используйте хуки, когда агент — это CLI, а не библиотека

Claude Code предоставляет хук Notification, матчер которого фильтрует по типу уведомления, включая agent_needs_input и agent_completed, а обработчиками хука могут быть команды оболочки или прямые HTTP-запросы (справочник по хукам). Обработчик типа command даёт контроль над формой полезной нагрузки, а это важно, потому что Echobell отрисовывает ровно те ключи JSON, которые вы отправили:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "agent_needs_input",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{agent: \"claude-code\", action: .message, project: .cwd}' | curl -sS -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_BLOCKED_URL\""
          }
        ]
      }
    ]
  }
}

Для обработчиков command вход хука приходит как JSON в stdin и содержит поля вроде session_id, cwd, hook_event_name и permission_mode. Тип обработчика http отправляет тот же JSON прямо на URL вообще без скрипта, что выглядит заманчиво, — но он ещё и ожидает, что ответ будет документом с выводом хука, а ответ Echobell таковым не является. Используйте command, если только вы не проверили, что http в вашей конфигурации ведёт себя так, как вам нужно.

Шаг 4 — Поймайте агентов, которые шлют только письма

Многие платформы для агентов, сервисы запусков по расписанию и внутренние инструменты отчитываются только по электронной почте. У каждого канала Echobell может быть свой адрес, поэтому одно правило пересылки превращает такие письма в звонки (триггеры по email, настройка звонка из письма). Триггеры по email дают from, to, subject, text и html как переменные шаблона, так что условие можно построить по теме письма, ничего не разбирая самостоятельно.

Шаг 5 — Добавьте условия, чтобы звонили только настоящие блокировки

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

blocking == true && risk == "high"

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

Шаг 6 — Протестируйте с включённым «Не беспокоить»

Вызовите канал через curl, пока на телефоне, который действительно будет принимать оповещение, включён режим «Не беспокоить»:

curl -X POST https://hook.echobell.one/t/<channel-token> \
  -H "Content-Type: application/json" \
  -d '{"agent":"test","action":"deploy to prod","project":"demo","blocking":true,"risk":"high"}'

Включите в приложении Повтор неудачного звонка, чтобы звонок, заблокированный «Фокусированием», был повторён. Непротестированный путь эскалации — это предположение.

Не воссоздаст ли это ту же усталость от оповещений, только с колоколом погромче?

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

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

Есть и аргумент со стороны безопасности за высокую планку. Тот же опрос CSA показал, что основными сигналами управления организации считают риск действия (63%) и авторизацию человеком (53%). Эти сигналы что-то значат, только если авторизация человеком действительно происходит быстро. Точка подтверждения, на которую регулярно отвечают с опозданием на восемь часов, приучает всех расширять её — именно так 13% полной автономии тихо становятся значением по умолчанию, причём по неправильным причинам.

Чего Echobell не делает

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

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

Echobell не делает:

  • Ничего не подтверждает. Это не интерфейс подтверждения, и связи с состоянием вашего агента у него нет. Он заставляет телефон звонить; подтверждать или отклонять вы всё равно идёте в ноутбук, дашборд или терминал. Никакого «нажмите 1 для подтверждения» здесь нет.
  • Не возобновляет запуск. Сериализация и восстановление состояния агента — задача вашего фреймворка. Echobell к нему не прикасается.
  • Не предоставляет политики эскалации, подтверждение приёма и графики дежурств. Нет никакого «если никто не ответил за пять минут, звоним следующему». Он звонит подписчикам канала. Если вам нужны графики дежурств и отслеживание подтверждений приёма, нужна платформа управления инцидентами — про этот класс инструментов см. сравнение альтернатив Opsgenie.
  • Не защищает ваших агентов. Ничто из описанного не решает проблему теневых агентов, слишком широких разрешений на инструменты или пробела с выводом из эксплуатации, о котором пишет отчёт CSA. Более быстрое внимание человека смягчает медленную реакцию, а не плохую архитектуру.
  • Не гарантирует доставку. Звонок зависит от push-инфраструктуры, сети и заряженного телефона. Считайте его слоем, который сокращает ожидание, а не средством контроля, на которое можно положиться безоговорочно.

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

Частые вопросы

Можно ли подтвердить действие агента прямо во время звонка?

Нет. Echobell доставляет звонок с содержимым уведомления и кликабельной ссылкой; интерактивного пути ответа обратно к вашему агенту у него нет. Реалистичный сценарий такой: звонок будит вас, externalLink ведёт на дашборд запусков или эндпоинт подтверждения, и решение вы принимаете там. Если нужно подтверждение ответом, такой эндпоинт придётся построить самостоятельно — Echobell закрывает только половину с пробуждением.

Какие события фреймворка должны вызывать вебхук?

Те, при которых запуск не может продолжиться. В OpenAI Agents SDK это непустой массив interruptions. В MCP — запрос elicitation/create, на который ваш клиент не может ответить без человека. В Claude Code — хук Notification с матчером agent_needs_input. События о завершении — это обычный или срочный канал, а не канал со звонком.

Работает ли это с безголовыми агентами в CI?

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

А что конкретно с elicitation в MCP?

Elicitation рассчитан на клиента, у которого есть пользователь, чтобы отрисовать запрос. В запуске без присмотра отрисовывать его некому, а спецификация прямо предписывает серверам обрабатывать отказ и отмену, а не рассчитывать на ответ. Разумный сценарий: обёртка MCP-клиента отправляет вебхук Echobell, когда получает запрос elicitation, на который не может ответить самостоятельно, а затем удерживает или отменяет его по вашему собственному правилу.

Безопасно ли класть вывод агента в уведомление?

Отправляйте как можно меньше. Идентификатор и ссылка лучше, чем реальный вывод агента, — используйте externalLink, чтобы указать на запись о запуске в системе, которая для этого создана. Echobell хранит содержимое уведомлений и историю только на вашем устройстве, а на сервере — лишь аккаунты, каналы и подписки (модель приватности), что хорошо для минимизации данных, но не повод отправлять больше, чем нужно.

Может ли вся моя команда получать одно и то же оповещение от агента?

Да. Поделитесь каналом, и каждый подписчик получит триггер, выбрав свой тип уведомления. Частая конфигурация: инженер, который отвечает за агента, подписывается со звонком, остальная команда — со срочными уведомлениями.

Это только для iOS?

Нет. Echobell работает на iOS и на Android через Google Play (см. релиз для Android). Поведение оповещений в стиле звонка на платформах различается, поэтому тестируйте на тех устройствах, которые дежурные носят с собой на самом деле.

Чем это отличается от связки с WebhookMCP?

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


Читайте также

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