Что нужно для того, чтобы доверить ИИ исправление реальных проблем

Источник: Command Line•

Что нужно для того, чтобы доверить ИИ исправление реальных проблем

Статья «Что нужно для того, чтобы доверить ИИ исправление реальных проблем» была впервые опубликована на Source.

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

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

И именно здесь демонстрация перестает быть просто демонстрацией.

Поскольку агент «знает, как исправить», возникает вопрос: должна ли система позволить ему закрыть BGP-сессию на устройстве, через которое проходит реальный клиентский трафик? «Чтение» — это то, что можно перепроверить. «Запись» — это действие, которое уже совершено. В тот момент, когда агент может изменить рабочую среду, любое свойство, к которому вы относились легкомысленно на этапе чтения, становится потенциальным источником риска и влияния на клиентов.

Безопасная автономность требует многоуровневого подхода.

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

Что мы вообще подразумеваем под «агентом»?

Спросите 10 разработчиков, и вы получите 10 ответов — и большинство из них будут примерами («Ну, это как агент для написания кода»), а не определениями. Это нормально; мы все еще находимся на относительно ранних этапах развития агентного ИИ. Но эта расплывчатость скрывает то, что здесь действительно важно.

Агент — это не модель. Модель — это блестящая, недетерминированная часть в центре. Агент — это детерминированное программное обеспечение, обернутое вокруг нее: часть, которая решает, о чем спрашивать модель, что ей позволено делать с ответом, к каким инструментам она может получить доступ и что произойдет, если она ошибется. Модель предоставляет интеллект. Агент предоставляет суждение о том, насколько можно доверять этому интеллекту и к чему ему позволено прикасаться.

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

Сделать агента безопасным — это не столько создание более умной модели в центре, сколько создание лучшей детерминированной оболочки вокруг нее.

Конкретно, обвязка, которую мы используем вокруг модели во время выполнения, представляет собой преимущественно детерминированный рабочий процесс с несколькими узкими, проверенными по схеме шагами модели внутри. Именно это превращает «модель однажды что-то придумала» в «эти шаги выполняются одинаково каждый раз». Вам пока не нужны все ее механизмы — это другой уровень. Пока просто удерживайте в голове эту картину: детерминированный рабочий процесс, внутри которого модель находится на коротком поводке.

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

Авторизация важнее интеллекта

«Святой Грааль» агентной разработки — это агент, который может исследовать проблему, найти решение и выполнить его без участия человека на каждом этапе. Но достижение этого в продакшене означает внедрение безопасности на каждом шаге. Больше автономности не должно означать меньше контроля.

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

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

Сложная часть автономности — это авторизация, а не интеллект.

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

Ментальная модель: четыре уровня границ

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

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

Уровень 1: У агента никогда не бывает больше прав, чем у вас

Агент не получает собственную мощную учетную запись. Он действует от имени человека, который его вызвал, в рамках реальных разрешений этого человека. Там, где невозможно избежать использования сервисной идентификации, она получает более узкие права из двух возможных. Идентификация является составной: человек плюс агент, и побеждает более строгий вариант. Политики доступа принадлежат командам, которые владеют каждым инструментом, определяются для каждого инструмента и изменяются через обычный pull request (PR) с обязательным рецензентом из команды инструмента. Слияние PR предоставляет доступ; откат PR отзывает доступ.

Уровень 2: Один интерфейс инструмента, а не «голая» оболочка

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

Формулировка «MCP против CLI» — это ложная дихотомия.

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

Уровень 3: Читайте свободно, делайте паузу перед записью

Диагностика выполняется самостоятельно. Все, что изменяет рабочую среду, останавливается и ожидает участия человека. Это звучит очевидно, но на практике удивительно сложно обеспечить соблюдение этого правила, так как велик соблазн пропустить «безопасно выглядящие» операции записи. Мы этого не делаем. Ограничитель — это код в движке исполнения, а не строка в промпте, и доверие на его обход зарабатывается для каждой процедуры и каждого типа действий отдельно — оно никогда не предоставляется модели только потому, что модель «умная».

Уровень 4: Агент, который учится перестать быть агентом

Когда мы впервые сталкиваемся с инцидентом, агент анализирует его от начала до конца, что является дорогостоящим и недетерминированным процессом. Но большинство инцидентов не являются новыми. Когда один и тот же путь рассуждений срабатывает достаточное количество раз, мы кристаллизуем его в детерминированный сценарий (playbook), который выполняется без единого вызова модели. Агент становится механизмом обнаружения новых проблем, а не постоянным «налогом» на старые. Меньше «живых» рассуждений означает одновременно более низкую стоимость, более высокую воспроизводимость и меньшую поверхность как для галлюцинаций, так и для атак.

Почему одного уровня никогда не бывает достаточно

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

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

# errdisabled- recovery.yaml (фрагмент) steps: - id: parse-status type: ai-extract # LLM парсит неструктурированный вывод CLI в типизированный JSON prompt: "Извлеките интерфейс, статус, vlan из вывода CLI." schema: interface: string status: enum[connected, errdisabled, notconnect] vlan: int - id: validate type: assert # детерминированный: отклонить все, что не соответствует схеме rule: "status in [connected, errdisabled, notconnect]" - id: decide type: condition # детерминированный: модель не участвует в принятии решения when: "status == 'errdisabled'" then: recover-interface # шаг ЗАПИСИ -> ожидает одобрения человека else: no-action

Это паттерн, который мы называем «детерминированный скелет, вероятностное наполнение». Языковая модель — это семантический парсер. Она никогда не принимает решений и никогда не обладает учетными данными, которые выполняют изменения.

Детерминированный скелет, вероятностное наполнение.

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

Итак, давайте пройдемся по контрфактическим сценариям, уровень за уровнем.

  • Уберите идентификацию, и агент будет работать с правами «бога». Сгаллюцинированная конфигурация будет применена с полномочиями, которых на самом деле не было ни у одного человека в этом процессе.
  • Уберите интерфейс инструментов и дайте ему «голую» оболочку, и не будет способа даже обозначить «применение BGP-конфигурации» как отдельное, авторизуемое и аудируемое действие. Это будет просто еще одна команда, к которой невозможно привязать RBAC или шлюз одобрения.
  • Уберите шлюз изменений, и выдуманный ASN попадет на устройство, потому что конфигурация выглядела нормально и никто не остановился, чтобы спросить.
  • Уберите время / кристаллизацию, и вы будете платить полную цену за недетерминированные рассуждения при каждом рутинном инциденте вечно, что означает, что вы используете самый рискованный режим исполнения даже для проблем, которые решили месяцы назад.

Каждое удаление ломает систему, и каждое ломает её по-своему. Нет единой точки, которую можно усилить, чтобы закрыть все четыре аспекта. Именно это на самом деле означает эшелонированная защита, и именно поэтому продукт — это стек, а не какой-то один уровень.

В этой области растет консенсус относительно того, что политика — это то, что должна обеспечивать среда выполнения (runtime), а не то, что вы просите модель соблюдать. Мы направили этот инстинкт на физическую инфраструктуру. Разница здесь в том, что когда наша среда выполнения ошибается, радиус поражения — это не плохой pull request. Это клиентский трафик, и это неприемлемо.

Вывод

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

Стек — это и есть автопилот.

О чём эта статья

Ещё в разделе «Разработка ПО»

Все →

Ещё от Microsoft