Практика эксплуатации AI-агентов

Теневой режим AI-агента: проверка автоматизации без воздействия на бизнес-системы

Уровень: средний Чтение: до 8 минут Результат: проверяемые предложения на реальных событиях

Зачем нужен теневой режим

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

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

Архитектура безопасного контура

  1. Рабочая система публикует событие или его разрешённую копию.
  2. Отдельный потребитель передаёт событие теневому агенту.
  3. Агент получает только инструменты чтения и формирует структурированное предложение.
  4. Предложение записывается в отдельный журнал, недоступный рабочим обработчикам.
  5. После фактического действия сотрудника компаратор связывает обе записи и рассчитывает метрики.

Критическое свойство такой схемы — запрет записи обеспечивается не текстовой инструкцией модели, а инфраструктурой: отдельными учётными данными, сетевыми правилами и отсутствием команд изменения в реестре инструментов.

Шаг 1. Зафиксируйте контракт предложения

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

Ниже приведён пример контракта, а не универсальная схема:

{
  "event_id": "string",
  "observed_at": "RFC3339 timestamp",
  "proposed_action": "route",
  "proposed_value": "billing",
  "confidence": 0.82,
  "reason_codes": ["mentions_invoice"],
  "policy_version": "routing-v3",
  "agent_version": "shadow-2026-07",
  "input_fingerprint": "sha256:..."
}

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

Шаг 2. Отделите предложения от команд

Конфигурация должна явно запрещать выполнение действий. Следующий YAML — безопасный пример структуры; имена адаптера и переменных условны:

mode: shadow

input:
  source: event_mirror
  consumer_group: agent-shadow-routing
  start_position: latest

tools:
  allow:
    - ticket.read
    - customer.read_summary
  deny:
    - ticket.update
    - message.send
    - refund.create
    - customer.update

output:
  type: append_only_jsonl
  path: ./shadow-data/proposals.jsonl

execution:
  apply_actions: false
  max_tool_calls: 4
  timeout_seconds: 20

privacy:
  fields_allowlist:
    - event_id
    - ticket.subject
    - ticket.category
    - ticket.created_at
    - customer.service_tier
  redact_unknown_fields: true

Даже при apply_actions: false не передавайте процессу рабочие ключи записи. Флаг может быть неверно обработан кодом; отсутствие полномочий остаётся независимым барьером.

Шаг 3. Подайте копию реальных событий

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

Перед подключением проверьте конфигурацию локально. Эти команды только создают каталог для результата, проверяют YAML и ищут потенциально опасные разрешения; они не обращаются к бизнес-системам:

mkdir -p ./shadow-data
chmod 700 ./shadow-data

python -c "import yaml; yaml.safe_load(open('shadow.yaml')); print('YAML: OK')"

if grep -En 'apply_actions:[[:space:]]*true|message\.send|ticket\.update|refund\.create' shadow.yaml
then
  echo "Проверка не пройдена: обнаружено действие с записью"
  exit 1
fi

Команда с модулем yaml предполагает, что PyYAML уже установлен. Не устанавливайте зависимости непосредственно в рабочее окружение без принятой в вашей организации процедуры.

Сам запуск зависит от реализации агента. Безопасный шаблон команды выглядит так:

agent-runner \
  --config ./shadow.yaml \
  --mode shadow \
  --output ./shadow-data/proposals.jsonl

agent-runner здесь — условное имя исполняемого файла. Подставьте команду своего раннера и убедитесь, что он поддерживает режим без применения действий.

Шаг 4. Докажите отсутствие воздействия

Не считайте отсутствие видимых ошибок доказательством безопасности. До длительного запуска выполните четыре проверки:

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

Для последнего пункта используйте встроенную проверку политик вашего раннера. Пример ожидаемого интерфейса:

agent-runner policy check \
  --config ./shadow.yaml \
  --tool ticket.update

# Ожидаемый результат:
# DENY: tool is not allowed in shadow mode

Это пример ожидаемого поведения, а не утверждение о конкретном продукте. Если раннер не умеет проверять политику отдельно, проведите такую проверку на уровне адаптера инструментов и прав сервисной учётной записи.

Шаг 5. Запишите фактическое действие

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

{
  "event_id": "evt-1042",
  "actual_action": "route",
  "actual_value": "billing",
  "acted_at": "2026-07-29T09:15:00Z",
  "actor_type": "human"
}

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

Шаг 6. Сравните решения

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

Для решения вида «выбрать очередь» достаточно вычислить:

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

Пример локальной проверки двух JSONL-файлов с помощью jq:

jq -s '
  (.[0] | map({key: .event_id, value: .}) | from_entries) as $p
  | .[1]
  | map(
      select($p[.event_id] != null)
      | {
          event_id,
          proposed: $p[.event_id].proposed_value,
          actual: .actual_value,
          match: ($p[.event_id].proposed_value == .actual_value)
        }
    )
' ./shadow-data/proposals.jsonl ./shadow-data/actual.jsonl

Команда читает файлы и выводит сравнение в терминал; исходные данные она не изменяет.

Как проверить результат

Успешный технический запуск должен удовлетворять следующим условиям:

  1. На каждое принятое событие приходится не более одного финального предложения заданной версии.
  2. Повторная доставка события не создаёт противоречивых записей.
  3. В аудит-логах бизнес-систем нет операций записи от учётной записи агента.
  4. Предложения содержат версии агента и политики, поэтому результаты воспроизводимы.
  5. Несопоставленные события учитываются отдельно, а не исчезают из отчёта.
  6. Расхождения можно просмотреть без раскрытия лишних персональных данных.

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

Типовые ошибки

Запрет записи существует только в системном промпте
Модель может ошибиться, а код — неверно обработать её ответ. Уберите инструменты записи и отзовите права на уровне API.
Теневой потребитель подтверждает сообщения основной очереди
Используйте зеркальный поток или отдельную группу потребителей, не влияющую на рабочую обработку.
Предложение сравнивают с устаревшим справочником
Сохраняйте версии правил и справочных данных, действовавшие в момент решения.
Повторное событие принимают за второе независимое решение
Добавьте идемпотентный ключ из event_id, типа решения и версии агента.
Все расхождения объявляют ошибками агента
Фактическое действие тоже может быть ошибочным. Отдельно организуйте экспертный разбор спорной выборки по заранее заданным критериям.
В журнал предложений попадает полный вход
Храните разрешённые признаки, отпечаток входа и коды причин. Не дублируйте чувствительные данные без необходимости.
Сотрудники видят предложения во время эксперимента
Это меняет их поведение и лишает сравнение независимости. До завершения выбранного периода скройте теневые ответы от исполнителей.

Ограничения теневого режима

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

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

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

Критерии готовности к следующему этапу

Рассматривать ограниченный пилот с подтверждением человеком стоит только после того, как:

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

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

Краткий итог

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

Другие практические материалы собраны в разделе «Руководства», а определения используемых понятий — в глоссарии Agent Lab Journal.