NeMo Guardrails
NeMo Guardrails предоставляет программируемые механизмы безопасности для приложений с LLM. Он работает как отдельный сервис перед моделью и может обеспечивать:
- Обнаружение конфиденциальных данных (например, PII во входных и выходных данных).
- Политики контента (например, запрещённые темы, упоминания конкурентов).
- Пользовательские потоки валидации, написанные на Colang и Python.
Оператор TrustyAI предоставляет доступ к NeMo Guardrails через пользовательский ресурс (CR) NemoGuardrails. В этом документе рассматривается базовое развертывание, которое:
- Защищает уже развернутую модель на платформе обслуживания.
- Использует NeMo Guardrails для фильтрации входных/выходных данных и простых бизнес-правил.
Содержание
Предварительные требованияАрхитектураКонфигурация NeMo ConfigMapОсновыrails.coОсновы actions.pyРазвертывание пользовательского ресурса NemoGuardrailsАутентификация (при включённой auth)Как получить токенДоступ к API NeMo GuardrailsПример базового chat completion (разрешённый контент)Пример guardrail по длине сообщенияПример запрещённого контентаПример обнаружения конфиденциальных данныхДополнительные материалыПредварительные требования
- Установлен оператор TrustyAI (см. Install TrustyAI).
- Модель уже развернута на платформе обслуживания (например, vLLM) и предоставляет API, совместимый с OpenAI.
Архитектура
На высоком уровне путь запроса следующий:
Client → NeMo Guardrails service → model predictor (OpenAI-compatible API)
NeMo Guardrails:
- Принимает запросы в стиле OpenAI
chat/completions. - Выполняет настроенные rails (обнаружение конфиденциальных данных, проверки длины, запрещённые темы и т.д.).
- Для разрешённых запросов пересылает их в базовую модель.
- Для заблокированных запросов возвращает соответствующее сообщение ассистента без вызова модели.
Оператор TrustyAI управляет Pod и Service сервера NeMo Guardrails через CR NemoGuardrails. Service затем может быть открыт извне с помощью выбранного ingress или gateway решения в кластере.
Конфигурация NeMo ConfigMap
NeMo Guardrails ожидает каталог конфигурации, который обычно содержит:
config.yaml: основной файл конфигурации NeMo Guardrails.rails.co: потоки Colang, реализующие rails для входных/выходных данных и дополнительную логику управления.actions.py: Python-действия, которые могут вызываться потоками Colang для выполнения пользовательской логики.
Пример ConfigMap конфигурации NeMo
-
Основы
config.yaml
В приведённом примере config.yaml:
-
Объявляет одну основную модель в разделе
modelsи настраивает конечную точку, совместимую с OpenAI, черезopenai_api_baseиmodel_name. -
Настраивает встроенное обнаружение PII в
rails.config.sensitive_data_detection:input.entities/output.entitiesперечисляют типы сущностей для защиты (например,EMAIL_ADDRESS,PERSON).- При запуске rails
detect sensitive data on input/detect sensitive data on outputNeMo автоматически вызывает внутренние детекторы с использованием этой конфигурации.
-
Определяет, какие rails выполняются и в каком порядке, через
rails.input.flowsиrails.output.flows:detect sensitive data on input/detect sensitive data on output— встроенные rails, основанные наsensitive_data_detection.check message lengthиcheck forbidden words— пользовательские rails, реализованные вrails.coи поддерживаемые Python-действиями изactions.py.
-
Замените
<model-predictor-host>,<port>и<model-name>на фактический URL сервиса предсказателя и имя модели. -
Убедитесь, что предсказатель реализует API
/v1/chat/completions, совместимый с OpenAI. -
Для более продвинутой настройки
config.yaml(дополнительные типы rails, подсказки, трассировка, база знаний и интеграция с другими провайдерами безопасности) обратитесь к официальной документации по YAML-конфигурации NeMo Guardrails: Nvidia NeMo Guardrails Configuration.
Основы rails.co
В этом примере rails.co определяет два пользовательских входных rail:
define flow check message length:- Имя потока
check message lengthдолжно совпадать с записью вrails.input.flowsвconfig.yaml. $length_result = execute check_message_lengthзапускает Python-действиеcheck_message_lengthизactions.py, передавая текущий контекст разговора.- Операторы
ifветвятся по возвращённой строке и либо:- вызывают блок
bot ...для отправки ответа (например,bot inform message too long), и stopдля прерывания дальнейшей обработки и предотвращения вызова LLM,- либо ничего не делают и позволяют конвейеру продолжить к следующему rail при возврате
"allowed".
- вызывают блок
- Имя потока
define flow check forbidden words:- Использует тот же шаблон, но вызывает действие
check_forbidden_wordsи блокирует только если возвращаемое значение не"allowed".
- Использует тот же шаблон, но вызывает действие
Дополнительные моменты:
- Блоки
bot ...(например,bot inform message too long) определяют заранее подготовленные сообщения ассистента, которые отправляются напрямую клиенту без обращения к базовой LLM, когда rail решает остановить конвейер. - Rails, определённые в
rails.co, выполняются в порядке, указанном вrails.input.flows/rails.output.flows. Встроенные rails, такие какdetect sensitive data on input, запускаются до или после пользовательских в зависимости от их позиции в списке. - Показанный здесь Colang — минимальный пример. Поддерживаются более сложные потоки (несколько шагов, переменные, дополнительные действия); см. справочник Colang в документации NeMo Guardrails для полного синтаксиса и возможностей. Хорошей отправной точкой является руководство по Colang 2.0: Colang Getting Started.
Основы actions.py
Файл actions.py содержит функции Python, декорированные @action, которые потоки Colang могут вызывать через execute <action_name>:
- Действия получают объект
context, который представляет собой структуру, похожую на dict, заполненную NeMo (например, содержит последнее сообщение пользователя под ключом"user_message"). - Действия возвращают значение (обычно короткую строку), по которому потоки Colang делают ветвления.
В этом примере:
check_message_length:- Анализирует
context["user_message"], вычисляет количество слов и возвращает:"blocked_too_long", если сообщение следует отклонить."warning_long", если нужно выдать предупреждение, но конвейер может продолжить работу."allowed", если длина сообщения приемлема.
- Анализирует
check_forbidden_words:- Приводит сообщение пользователя к нижнему регистру, ищет запрещённые слова и:
- Возвращает
"allowed", если ничего не найдено. - Возвращает значение, отличное от
"allowed"(например,"blocked_password"), если обнаружено запрещённое слово.
- Возвращает
- Приводит сообщение пользователя к нижнему регистру, ищет запрещённые слова и:
Эти шаблоны можно расширять для более сложных guardrails, таких как структурированные проверки, числовые пороги или вызовы внешних сервисов.
Развертывание пользовательского ресурса NemoGuardrails
Имея ConfigMap и секрет с токеном, создайте CR NemoGuardrails для развертывания сервиса NeMo Guardrails:
Ключевые поля:
nemoConfigs: Ссылается на один или несколько наборов конфигураций; каждый набор может включать один или несколько ConfigMap с файлами конфигурации NeMo Guardrails.env.OPENAI_API_KEY: Токен, используемый NeMo Guardrails для аутентификации на конечной точке backend модели (например, сервис vLLM). Для внутренних неаутентифицированных сервисов инференса это значение можно задать напрямую какvalue: "<placeholder>"и оно не используется backend. Для сервисов инференса только по HTTP TLS-сертификаты для backend URL не требуются.security.opendatahub.io/enable-auth: При значении"true"маршрут к NeMo Guardrails защищён аутентификацией кластера и требует Bearer токен.
Примените:
После создания CR оператор выполнит reconciliate и создаст:
- Deployment для сервера NeMo Guardrails.
- Service, который открывает HTTP endpoint NeMo Guardrails внутри кластера.
Дождитесь, пока Pod Deployment станет Ready:
Аутентификация (при включённой auth)
Когда перед NeMo Guardrails включена HTTP-аутентификация, сервис ожидает Bearer токен в входящих запросах.
Как получить токен
Создайте ServiceAccount, Role (с правами get, create на services/proxy) и RoleBinding в том же namespace, что и ресурс NemoGuardrails; затем создайте токен для ServiceAccount:
Опционально задайте длительность токена, например, --duration=8760h для одного года. Последняя команда выведет токен; используйте его в заголовке Authorization: Bearer <token>.
Доступ к API NeMo Guardrails
NeMo Guardrails предоставляет endpoint для chat completions в стиле OpenAI:
POST /v1/chat/completions
Откройте Service NeMo Guardrails с помощью предпочитаемого ingress или gateway механизма (например, ресурса Ingress или API gateway) и запомните публичный хост и порт:
- Без аутентификации: Service обычно открыт по HTTP на порту 80.
- При включённой аутентификации: Service обычно открыт по HTTPS на порту 443.
Установите базовый URL, например:
Пример базового chat completion (разрешённый контент)
Пример запроса:
Типичный ответ:
Пример guardrail по длине сообщения
Поток check_message_length и соответствующее Python-действие реализуют простой guardrail на основе длины. Если сообщение пользователя слишком длинное, rail отвечает напрямую без вызова backend LLM:
Ответ генерируется NeMo Guardrails без вызова backend модели:
Пример запрещённого контента
Запрещённые темы контролируются действием check_forbidden_words и соответствующим потоком Colang. Если сообщение пользователя содержит запрещённое слово, например "hack" или "password", rail блокирует запрос:
Ответ генерируется NeMo Guardrails без вызова backend модели:
Пример обнаружения конфиденциальных данных
Обнаружение конфиденциальных данных настроено в config.yaml в разделе rails.config.sensitive_data_detection. В примере конфигурации и для входных, и для выходных данных флагируется EMAIL_ADDRESS.
Пример входного сообщения с адресом электронной почты:
Типичный ответ:
В этом случае встроенный rail обнаружения конфиденциальных данных зафиксировал адрес электронной почты в сообщении пользователя, и NeMo Guardrails возвращает безопасный запасной ответ вместо того, чтобы позволить backend модели ответить потенциально небезопасно.
Дополнительные материалы
Для более широкого обзора библиотеки NeMo Guardrails (кейсы использования, архитектура и интеграции в экосистему) смотрите официальную документацию: Overview of NVIDIA NeMo Guardrails Library.