Guardrails в нашем LLM-шлюзе — это проверка входящего запроса перед вызовом модели. Она добавляет к запросу 40–55 мс и решает по настраиваемой текстовой политике, а не по зашитой в модель таксономии. Вердикт выносят два независимых фактора: классификатор Shieldstral задаёт зону риска, а компактный судья решает внутри неё и может наложить вето.

Если коротко — для бизнеса

  • Цена — 40–55 мс на запрос в режиме блокировки; в режиме наблюдения добавка практически нулевая.
  • Политика — наш собственный текст. Её меняют без дообучения модели, и в ней явно перечислено, что нарушением не считается.
  • Сотрудник, вставивший резюме, договор или свой пароль, не должен упираться в блокировку. Единичные персональные данные внесены в исключения политики, а блокировка без второго мнения возможна только при очень высокой уверенности (p ≥ 0.97). Один известный промах — свой пароль — разобран в результатах.
  • Если классификатор недоступен, запрос проходит, но каждый такой пропуск виден в метрике с алертом. Обратный режим под нагрузкой ложно блокировал 33% запросов при 3 одновременных и 75% при 8.
  • На регрессионном наборе из 58 синтетических кейсов связка правильно отработала 56.

О цикле «LLM-шлюз»

Две статьи о собственном LLM-шлюзе компании. «Мы» — это автор и AI-агенты, которым он делегировал часть исследований и правок. Компания обезличена, цифры настоящие.

  1. SurfCap-α: как семантический роутер выбирает модель
  2. Guardrails в LLM-шлюзе: почему Shieldstral ← вы здесь
Термины за минуту
  • Guardrails — проверки вокруг вызова модели, которые не пропускают запрещённое политикой. Здесь — только проверка входа.
  • Джейлбрейк — запрос, который пытается заставить модель обойти её собственные ограничения.
  • Инъекция промпта — инструкция, подмешанная в текст, который модель прочитает. Косвенная — спрятана не в реплике пользователя, а в документе, ответе инструмента или истории диалога.
  • Политика модерации — текст, описывающий, что считается нарушением и что — нет.
  • Таксономия рисков — фиксированный список категорий вреда, на котором обучена модель-классификатор.
  • Логпробы и калиброванная вероятность — логарифмы вероятностей токенов ответа. Из логпробов токенов «yes» и «no» получается непрерывная вероятность нарушения p, а не просто да/нет.
  • Судья с ограниченным декодированием — LLM, которой разрешено ответить только одним из заранее заданных вариантов.
  • Fail-open / fail-closed — что делать, если проверка недоступна: пропустить запрос или заблокировать его.
  • Режимы off / monitor / enforce — проверка выключена; идёт в фоне и только помечает; блокирует нарушение ответом HTTP 403.
  • F1 — гармоническое среднее точности и полноты классификатора, от 0 до 100.
  • Radix-кэш — кэш общего префикса промпта на стороне сервера инференса: повторяющееся начало запроса не пересчитывается.

Зачем и от чего

Кому особенно полезен раздел:Бизнес и продуктАрхитекторы

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

Модель угроз сводится к четырём категориям:

  • Джейлбрейки и инъекции промпта. В том числе косвенные: инструкция спрятана в документе или ответе инструмента [12].
  • Массовая выгрузка данных. Просьба вытащить через модель базу персональных или конфиденциальных данных.
  • Кража учётных данных. Попытки добыть чужие пароли, токены и ключи.
  • Незаконный и вредный контент.

Исходные условия определили выбор сильнее, чем бенчмарки:

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

Изначально планировался Llama Guard в готовом прокси. Исследование кандидатов показало, что такая схема не подходит ни по языку, ни по гибкости политики.

Подходы в литературе

Кому особенно полезен раздел:ML и исследователиАрхитекторы

Стандартом стал подход Llama Guard [1]: небольшая LLM, дообученная классифицировать реплики по фиксированной таксономии рисков и отвечать «safe / unsafe» с категорией. Так же устроены ShieldGemma [2], WildGuard [3], Granite Guardian [4] и Qwen3Guard [5]. Различаются они по трём осям.

  • Таксономия. Зашита в веса или передаётся текстом в запросе. Во втором случае политику можно менять без дообучения.
  • Языки. Большинство моделей обучены преимущественно на английском. PolyGuard [6] показывает, насколько падает качество на других языках. LionGuard 2 [13] и PL-Guard [14] приходят к тому же с другой стороны: для неанглийского трафика нужна локализация и свои данные.
  • Форма ответа. Либо генерация с категорией, либо один токен «yes / no», из логпробов которого получается калиброванная вероятность.

Shieldstral [7] ставит модерацию как бинарный вопрос: «нарушает ли этот текст приложенную политику?». Политика передаётся текстом, ответ — один токен. Это совмещает оба полезных свойства: свою политику и дешёвый калиброванный скор.

Две недавние линии работ задают границы подхода:

  • Работа [8] показывает, что мониторы безопасности в основном ловят то, от чего сама модель и так отказывается. Один классификатор — слабая защита.
  • Потоковая модерация ответов [9] [10] — отдельная задача со своими моделями.

Наконец, литература об инъекциях [11] [12] сходится в одном: недоверенным нужно считать не только реплику пользователя, но и любой текст, который модель прочитает.

Сравнение кандидатов и выбор Shieldstral

Кому особенно полезен раздел:АрхитекторыML и исследователи

Выбрали Shieldstral-1.0-3B: это единственный кандидат, который одновременно понимает русский, принимает политику текстом, отвечает одним токеном и помещается на уже занятую GPU.

Кандидаты на роль классификатора первой ступени
МодельРазмерРусскийПолитикаРешение
Shieldstral-1.0-3B3Bда (12 языков)текстом в запросевыбрана
Qwen3Guard-Gen0.6B / 4B / 8Bда (119 языков)фиксированные классызапасной вариант, если важна задержка
Qwen3Guard-Stream0.6B / 4Bдафиксированные классыотложена: нет поддержки в сервинге
Llama Guard 4 / 3-1B12B / 1Bнетфиксированная таксономияотклонена
Granite Guardian 4.18Bнетнабор рисков, сильна в RAGотклонена
Nemotron Content Safety4Bнетфиксированная таксономияотклонена
gpt-oss-safeguard21B (3.6B активных)не проверялитекстомотклонена: слишком медленная для первой ступени
NER-модели для ПДн~300Mдаизвлечение спановне решают задачу классификации

Решение опиралось на пять доводов:

  1. Русский язык. Он входит в число языков обучения. Это сразу отсекло Llama Guard, Granite Guardian и Nemotron.
  2. Своя политика без дообучения. Нам нужна не общая таксономия вреда, а своя: с массовой выгрузкой данных и с явным списком того, что нарушением не считается. У Qwen3Guard с его фиксированными классами такой возможности нет.
  3. Калиброванный скор за один токен. Ответ «yes / no» даёт непрерывную вероятность, а не дискретный вердикт. На ней держится вся логика порогов и серой зоны.
  4. Размер. Модель занимает около 12 ГиБ VRAM вместе с KV-кэшем и встаёт рядом с уже работающими моделями.
  5. Сервинг. Она поддержана в SGLang и vLLM, а SGLang уже есть в стеке. Лицензия — Apache-2.0.

По данным авторов [7], Shieldstral достигает F1 88.1 на WildGuardTest и 84.6 на PolyGuard Prompt. Это уровень Qwen3Guard-Gen-8B (88.2 и 84.3) при втрое меньшем размере. Для сравнения, у Llama Guard 4 — 74.3 и 62.1.

Вендорские F1 — ориентир, а не доказательство

Это цифры авторов модели. Сравнение кандидатов на собственных русскоязычных данных мы не проводили и оценивали только итоговую связку.

Особенности реализации

Кому особенно полезен раздел:АрхитекторыИнженеры

Главное отличие от типовой схемы «классификатор перед моделью» в том, что вердикт выносит не одна модель, а два независимых фактора, и у второго есть право вето. Остальные решения выросли из дыр, найденных на практике.

Три ступени и правило комбинации

Кому особенно полезен раздел:ИнженерыML и исследователи

  1. Дешёвый гейт на регулярных выражениях. Он ничего не блокирует, а только решает, нужна ли проверка на массовую выгрузку данных.
  2. Shieldstral. Оценивает вход по политике одним токеном (max_tokens=1, temperature=0); вероятность нарушения берётся из логпробов (формула ниже). Если в ответе нет ни «yes», ни «no», это ошибка разбора, и вердикт не додумывается.
  3. Судья с ограниченным декодированием. Это Plumb-4B [15] — decision-модель на базе Qwen3.5-4B, которая возвращает вероятность каждого варианта ответа за один прямой проход, без генерации токенов. Вопрос у неё один, с выбором: «safe», одна из категорий или «массовая выгрузка». Судья вызывается, только когда p ≥ 0.30 или когда его запросил гейт. Объединение трёх прежних вопросов в один сократило его время со 110 до 65 мс.
p=eℓyeseℓyes+eℓnop = \frac{e^{\ell_{\text{yes}}}}{e^{\ell_{\text{yes}}} + e^{\ell_{\text{no}}}}

Здесь ℓ — логпробы токенов «yes» и «no» в первой позиции ответа.

Зачем нужен второй фактор, видно из замера. Запросы с единичными персональными данными получали от Shieldstral p = 0.75–0.92, а настоящая косвенная инъекция — 0.73–0.78. Такие диапазоны не разделить никаким порогом. Судья разделяет их уверенно: 0.04–0.14 для персональных данных против 0.53 для атаки. Отсюда правило: в диапазоне 0.70 ≤ p < 0.97 судья с оценкой ниже 0.25 накладывает вето. Выше 0.97 вето уже нет.

Правило комбинации: Shieldstral задаёт зону, судья решает внутри неё. Шкала p = P(unsafe) по логпробам Shieldstral
ЗонаДиапазон pСудьяБез судьиИтог в enforce
Безопасноp < 0.30не вызывается—пропуск
Серая зона0.30 ≤ p < 0.70решает, порог 0.50FLAGBLOCK, если оценка судьи ≥ 0.50, иначе пропуск
Вероятно опасно0.70 ≤ p < 0.97вето при оценке < 0.25FLAGBLOCK, если вето нет
Опасноp ≥ 0.97без права ветоBLOCKBLOCK
Поверх всех зонлюбое pгейт запросил проверку, выгрузка ≥ 0.70—нарушение при любом p
Путь решения guardrails: гейт, Shieldstral, зона по p и судьяПуть решения guardrails: гейт, Shieldstral, зона по p и судья< 0.300.30–0.700.70–0.97≥ 0.97проверка выгрузкиКлиентский вводRegex-гейтShieldstral: pЗона pПропускСудья, порог 0.50Судья: вето < 0.25BLOCKСудья: выгрузка ≥ 0.70Вердикт
Путь решения guardrails: гейт, Shieldstral, зона по p и судья

Если судья недоступен, запросы из серой зоны и зоны «вероятно опасно» только помечаются (FLAG), а не блокируются.

Блокировка без судьи возможна только при p ≥ 0.97. Во всех спорных случаях без второго мнения система только помечает запрос, а не блокирует его.

ML-исследователю

Калиброванная вероятность одного классификатора не спасает, когда классы перекрываются: персональные данные (0.75–0.92) и косвенная инъекция (0.73–0.78) лежат в одной полосе p. Второй фактор с другим вопросом и другой моделью даёт независимое измерение, и в нём классы расходятся (0.04–0.14 против 0.53). Поэтому порог ставится не на один скор, а на их комбинацию.

Всё, что прислал клиент, — недоверенный текст

Кому особенно полезен раздел:АрхитекторыИнженеры

Проверяется не только последняя реплика пользователя. В проверку попадают системный промпт, инструкции, история реплик ассистента и результаты инструментов: всё это клиент может подделать. Дыра была найдена на ревью: классический джейлбрейк в system-промпте плюс «продолжай» от пользователя проходили вообще без вызова модели. Это прямое следствие работ о косвенных инъекциях [12].

Архитектору

Граница доверия проходит по шлюзу, а не по ролям внутри запроса. System-промпт, история и ответы инструментов приходят от клиента, а значит, они такой же недоверенный ввод, как реплика пользователя. Если ваша проверка смотрит только на role: user, её обходит любой клиент, который сам собирает сообщения.

Окна вместо обрезки

Кому особенно полезен раздел:ИнженерыML и исследователи

Длинный вход режется на окна по 3000 символов с перекрытием 300, не больше 10 окон. Они проверяются параллельно, итог — максимум p по окнам. Если окон больше лимита, дешёвый скан ищет паттерны инъекций по всему тексту и ставит фокус-окна вокруг находок. До этого инъекция в середине документа на 20 тысяч символов получала p = 0.000, после — 0.867.

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

Политика как данные

Кому особенно полезен раздел:АрхитекторыИнженеры

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

Политика передаётся постоянным префиксом запроса, поэтому radix-кэш SGLang не пересчитывает её на каждом вызове. Кэш на стороне шлюза хранит сырые оценки факторов, а не вердикты. Благодаря этому новые пороги применяются сразу.

Задержка и отказы

Кому особенно полезен раздел:ИнженерыАрхитекторы

  • Параллельный запуск. Проверка стартует сразу после выбора маршрута и идёт параллельно с подсчётом токенов и проверкой вложений. Результат нужен только перед вызовом провайдера, так что блокировка срабатывает до первого байта даже на потоковой выдаче.
  • Бюджеты времени. 300 мс на окно, 250 мс на судью, общий дедлайн 500 мс. Ожидание слота в очереди считается отдельно от таймаута, и занятость модели не путается с её отказом.
  • Fail-open. При недоступности классификатора запрос пропускается, но каждый такой пропуск виден в метрике с алертом. Режим fail-closed под нагрузкой давал ложную блокировку 33% запросов при 3 одновременных и 75% при 8, поэтому его сознательно не поддерживаем.
  • Три режима. off, monitor (проверка в фоне, запрос не ждёт) и enforce (нарушение → HTTP 403).

Fail-open — осознанный риск

Пока классификатор недоступен, вход не проверяется. Компенсация — алерт на каждый такой пропуск и отдельный детектор секретов, который закрыт на отказ (см. ниже).

Ничего лишнего наружу

Кому особенно полезен раздел:АрхитекторыИнженеры

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

Секреты — не задача классификатора

Кому особенно полезен раздел:АрхитекторыИнженеры

Ключи, токены и пароли ищет отдельный детерминированный детектор. Он работает за линейное время, умеет маскировать и в режимах маскирования и блокировки закрыт на отказ (fail-closed). LLM-классификатор плохо находит секреты, а регулярное выражение с проверкой энтропии — хорошо. При 300 КБ входа на него уходит 10 мс по медиане.

Архитектору

Задачи с точным признаком (формат ключа, энтропия строки) решаются детерминированно и закрыты на отказ. Вероятностной модели остаётся то, что без понимания текста не решить: намерение, инъекции, выгрузка. Так отказ классификатора не открывает дорогу утечке секретов.

Проверьте у себя

  • Попадают ли в проверку system-промпт, история ассистента и результаты инструментов, или только последняя реплика пользователя?
  • Проверяется ли длинный вход целиком (окнами), или модель видит только обрезанное начало?
  • Разделены ли ожидание в очереди и таймаут модели? Иначе под нагрузкой «занято» превращается в «отказ».
  • Не уходят ли клиенту вероятность или причина вердикта?
  • Видна ли в метриках каждая пропущенная из-за недоступности проверка?

Результаты, ограничения и что дальше

Кому особенно полезен раздел:Бизнес и продуктML и исследователиИнженеры

На контрольном наборе из 58 синтетических кейсов в режиме enforce связка правильно отработала на 56. Оставшиеся два промаха известны и задокументированы.

  • Пропуск. Инъекция, спрятанная в HTML-комментарий внутри результата инструмента, получила p = 0.12.
  • Ложная блокировка. Пользователь вставил свой собственный пароль (p = 0.97), и запрос заблокирован.

Это регрессионный тест, а не оценка полноты

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

Добавка к задержке запроса в режиме enforce
Запросp50, мсp95, мс
Короткий40.645.3
Документ на 20 тыс. символов49.755.2
С флагом риска (вызывается судья)48–5156–57

В режиме monitor добавка практически нулевая. Сам Shieldstral на 2 тыс. токенов отвечает за 49 мс (p50) одиночно, а при 8 одновременных запросах — уже за 268 мс. Именно поэтому очередь и таймаут разделены.

Ревью первой версии на проде дало три урока, и из них выросла текущая архитектура:

  1. Обрезка прятала атаки. Около 73% вердиктов выносились по обрезанному входу. Ответ — окна с фокусировкой.
  2. Проверялась только реплика пользователя. Джейлбрейк через system-промпт проходил. Ответ — весь клиентский ввод считается недоверенным.
  3. Три отдельных вопроса судье не укладывались в бюджет. Вызовы уходили в таймаут. Ответ — один комбинированный вопрос выбора и вызов судьи только из серой зоны.

Что не сделано и стоит проверить дальше:

  • Сравнение на своих данных. Нет офлайн-бенча кандидатов на реальном русскоязычном трафике. Вендорские F1 — это ориентир, а не доказательство.
  • Модерация ответов и стримов. Сейчас проверяется только вход. Потоковые модели [9] [10] ждут поддержки в сервинге.
  • Скрытые инъекции в разметке. Нужен препроцессинг, который извлекает HTML-комментарии и невидимый текст из результатов инструментов.
  • Осознанная детекция, а не отказ. По выводу [8] монитор ценен тем, что ловит сверх отказов базовой модели. Именно эту долю стоит измерить на нашем трафике.

Литература

Кому особенно полезен раздел:ML и исследователи

  1. Inan H. et al. Llama Guard: LLM-based Input-Output Safeguard for Human-AI Conversations. arXiv:2312.06674.
  2. Zeng W. et al. ShieldGemma: Generative AI Content Moderation Based on Gemma. arXiv:2407.21772.
  3. Han S. et al. WildGuard: Open One-Stop Moderation Tools for Safety Risks, Jailbreaks, and Refusals of LLMs. arXiv:2406.18495.
  4. Padhi I. et al. Granite Guardian. arXiv:2412.07724.
  5. Zhao H. et al. Qwen3Guard Technical Report. arXiv:2510.14276.
  6. Kumar P. et al. PolyGuard: A Multilingual Safety Moderation Tool for 17 Languages. arXiv:2504.04377.
  7. Calvi A. et al. Shieldstral. arXiv:2607.25857. Карточка модели: mistralai/Shieldstral-1.0-3B.
  8. Karne S. Safety Monitors Mostly Catch What the Model Already Refuses. arXiv:2609.05797.
  9. Kavumba P. et al. Predict, Don’t React: Value-Based Safety Forecasting for LLM Streaming. arXiv:2604.03962.
  10. Wang J. et al. FreoStream: Enhancing Stream Guardrails via Future-Aware Reasoning and Safety-Aligned Optimization. arXiv:2606.13737.
  11. Chen S. et al. StruQ: Defending Against Prompt Injection with Structured Queries. arXiv:2402.06363.
  12. Greshake K. et al. Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection. arXiv:2302.12173.
  13. Tan L. et al. LionGuard 2: Building Lightweight, Data-Efficient & Localised Multilingual Content Moderators. arXiv:2507.15339.
  14. Krasnodębska A. et al. PL-Guard: Benchmarking Language Model Safety for Polish. arXiv:2506.16322.
  15. crh225/plumb-4b — карточка модели: дообучение Qwen3.5-4B (через JevK5 v0.2), оценка вариантов ответа за один прямой проход, Apache-2.0.

Названия и первые авторы сверены с arXiv API 25 октября 2026.