Что должно жить в коде
Страница о 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) |
| Проверки формата и стиля | Шлюз эффективности | Разрешить |
Средний столбец — это и есть суть: чем ближе к верху, тем меньше должна быть задействована модель.
В одном предложении
Проверка, которую может переопределить вероятность, в конце концов будет ею переопределена. Сначала решите, какие проверки нельзя переопределять; только потом настраивайте пороги.