Документация

Что должно жить в коде

Страница о gating доказывала, что порогом должен владеть код. Эта страница идёт на уровень сильнее: некоторые проверки вообще не следует спрашивать у модели.

Самое сильное публичное утверждение о границе

Самая жёсткая формулировка исходит от реализации агентного цикла:

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

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

  • «Автоодобрять при ≥ 0.95» — это пороговое правило — в принципе какая-то достаточно высокая вероятность его прошла бы.
  • «Высокий риск требует одобрения человеком» — это структурное правило — верное независимо от того, что говорит модель.

Они не одинаково надёжны. Ваша система должна явно указывать, какие проверки к какому типу относятся, и структурных правил должно быть как можно больше.

Сначала запускайте детерминированные правила, модели отдавайте только серую зону

Ещё одна формулировка того же паттерна:

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

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

Один опубликованный тест инъекций сообщает о 300 попытках инъекции и прямо говорит, что шлюз поймал, а что проскочило. Это куда полезнее голого заявления «защита от инъекций».

Секреты и чувствительные данные: сначала блокировать локально

Один детектор секретов излагает порядок ясно:

Случай Обработка
Известные форматы секретов Блокируются локально, никогда не отправляются модели
Неизвестные строки с высокой энтропией Сначала маскируются, затем маскированный текст идёт в модель
Модель говорит ≥ 0.80 Блокировать
Модель говорит ≥ 0.30 Спросить человека
Модель недоступна Всё равно спросить человека

Два решения стоит запомнить:

  • Маскирование идёт первым. Нельзя отправить что-то во внешний сервис, чтобы выяснить, секрет ли это. Сама проверка утекает.
  • Умершая модель всё равно спрашивает человека, а не разрешает. Это fail-closed в конкретном виде — недоступность сервиса не повод тихо снизить планку безопасности.

Измерено: 6/6 секретов заблокировано, 0/6 доброкачественных входов ошибочно заблокировано.

Лимиты бюджета, подписанные квитанции, аудит

Некоторые проверки не имеют отношения к тому, что говорит модель, но должны жить в той же системе:

  • Одна среда выполнения отдаёт блокировку опасных команд и лимиты бюджета детерминированному коду и записывает каждый вердикт в цепочку квитанций, подписанных Ed25519.
  • Другая удерживает риск-score в контролируемой кодом шкале 0–100 и подписывает каждый вердикт через ES256 (540 вызовов, 99.76% и 0 ложных срабатываний при пороге 65–75).

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

Фильтруйте инъекции в двух местах

Дизайн одного слоя-ограничителя заслуживает отдельного упоминания, потому что он называет два легко пропускаемых места:

Фильтруйте один раз перед запуском вызова инструмента, и ещё раз перед тем, как результат инструмента прочитает агент.

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

Родственное правило из реализации с дополненным поиском: никогда не выводите число, которого нет в цитируемых источниках.

Песочница и разрешения

Кроме фильтрации содержимого, другой слой — ограничение радиуса поражения: защищённые пути всегда проходят через подтверждение человеком; выполнение агента идёт в изолированных рабочих пространствах (одна реализация использует Docker); разрешения подагентов отделены от разрешений родителя.

Справочная таблица

Проверка Какого рода В какую сторону падает при ошибке
Известные форматы секретов Детерминированное правило Блокировать
Авторизация операции высокого риска Структурное правило Отклонить (человек должен одобрить)
Автоодобрение команд только для чтения Пороговое правило Вернуться к запросу
Инъекция внутри вывода инструмента Детерминированный фильтр + модель Блокировать
«Агент закончил?» Шлюз эффективности Разрешить (fail-open)
Проверки формата и стиля Шлюз эффективности Разрешить

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

В одном предложении

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