Перейти к основному содержимому

Отказ — это решение о маршрутизации, а не свойство модели

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

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

Паттерн в инцидентах

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

Заманчиво отнести это к выравниванию. Такая формулировка ведёт к вмешательствам, которые не могут выразить ограничения, фактически требуемые ситуацией: обучение с подкреплением на основе обратной связи с людьми, лучшие системные промпты, более сильный приоритет отказа. Они формируют распределение текста, который модель будет выдавать. Они не кодируют, что сессия A может читать почтовый ящик B, но не почтовый ящик C, что краулер может получить публичную страницу, но должен отступить от эндпоинта с ограничением скорости, или что медиаобъект может быть суммирован внутри системы, но никогда не помещён в исходящую полезную нагрузку. Системный промпт, говорящий «не обращайся к приватным данным», — это запрос, а не контроль. Модель может соблюдать его в обычном случае и всё равно выдать вызов, когда контекст необычен, потому что ничто в цикле не оценивает вызов относительно принципала и ресурса.

Где на самом деле находится решение

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

Стоит разделить три шлюза, потому что их объединение — это место, где большинство проектов теряют контроль.

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

Отказ должен быть типизированным ответом, о котором планировщик может рассуждать, а не исключением, которое запускает повтор. Если отказ проявляется как трассировка стека, цикл восстановления агента будет рассматривать его как временный сбой и попробует снова с вариацией. Если он проявляется как denied: {rule, resource_class, reason}, планировщик может выбрать другой маршрут или остановиться. Различие между отказом политики и ошибкой транспорта — это разница между агентом, который адаптируется в рамках своего мандата, и тем, который долбит портал, пока что-то не поддастся.

Конкретный механизм

Close-up of a retro circuit board showing intricate copper traces and electronic components

Рассмотрим агента извлечения, работающего под мандатом сессии. Мандат — это структурированный объект, а не проза:

{
  "session": "s-8841",
  "principal": "agent:research",
  "mandate": [
    {"resource_class": "public_web", "verbs": ["fetch"], "budget": {"requests": 200, "rate_per_min": 30}},
    {"resource_class": "internal_docs", "verbs": ["search", "read"], "budget": {"documents": 50}}
  ],
  "egress": {"allowed_classes": ["summary_text"]}
}

Каждый вызов инструмента оценивается относительно этого объекта перед выполнением. Вызов несёт строку цели, взятую из мандата, например purpose: "public_web.fetch". Движок политик сопоставляет цель с мандатом, проверяет глагол, проверяет оставшийся бюджет и возвращает один из небольшого набора типизированных результатов: allow, deny, allow_with_redaction или defer_for_approval. Решение логируется с правилом, которое совпало, принципалом и бюджетом, оставшимся после вызова.

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

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

Правила проектирования, которые следуют

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

Запрещать по умолчанию любоMacro shot of metallic AA batteries stacked in a pyramid shapee0f43.jpg) акт, а не вывод.

Graphics card gpu

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

Честный компромисс

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

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

Что это меняет для оценки

Тестовые наборы должны проверять трассировку решений, а не только финальный ответ. Запуск, который производит правильный вывод через вызов, который должен был быть запрещён, — это неудачный запуск, даже если пользователь удовлетворён. Трассировка — это первичный артефакт; ответ — следствие.

Состязательные случаи должны включать правдоподобные вызовы, выходящие за рамки мандата, а не только очевидно злонамеренные. Интересные сбои — это не read_all_private_messages; это search с чуть более широким запросом, fetch по URL, который разрешается во внутренний хост, или шаг суммирования, включающий поле, которое исключает правило исходящего трафика. Эти вызовы проходят наивную проверку на уровне промпта, потому что выглядят как обычная работа.

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

Заключение

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

ПоделитьсяXLinkedInПостоянная ссылка6 мин чтения

Связанное чтение

На какие вопросы это отвечает

Why is refusal better modelled as a routing decision than a model property?

A model property shapes the distribution of text a model emits. It cannot express that a given principal may read one resource and not another at a particular time. A routing decision evaluates the principal, resource, verb, purpose and budget before the call executes, which is the granularity the failure cases actually require.

What are the three gates in an agent request path?

Intent declaration, capability grant and egress check. The first is what the agent claims it is doing, the second is what the principal may do under the session mandate, and the third is what may leave the boundary. Collapsing them into a single prompt-level instruction is where control is lost.

How should a denial be returned to the planner?

As a typed response naming the rule and resource class, for example denied with a reason, rather than as an exception. A typed denial lets the planner route around the constraint or halt, while an exception tends to be treated as a transient fault and retried.

What should agent evaluation assert on?

The decision trace, not only the final answer. A run that reaches the right output via a call that should have been denied is a failing run. Adversarial cases should include legitimate-looking calls that fall outside the mandate, not only obviously malicious ones.