API Guardrails Runtime
HTTP-контракт проверки текста, точные действия, ограничения и обработка ошибок.
Версия и границы API
Описание включает профиль agentgateway-1.5.0-chat-webhook-v2 от 17 сентября 2026 года.
OpenAPI 3.1 фиксирует HTTP-контракт.
Прежние профили agentgateway-1.4.1-text-webhook-v1 и
agentgateway-1.5.0-text-webhook-v1 сохраняются для существующих наборов.
Значение заголовка должно точно совпадать с contentProfile загруженного набора.
Через Agentgateway новый профиль допускает потоковый ответ, вызовы инструментов и сообщения с изображениями. Сам Runtime по-прежнему получает только текст. Шлюз выделяет текстовые части и сохраняет вложения и служебные поля при передаче модели. Правила не анализируют изображение, аргументы инструментов и отдельные поля рассуждения. Текст результатов инструментов входит во входную проверку.
Универсальных маршрутов /v1/check, /evaluate, /classify, /batch и
онлайн /dry-run нет. Guardrails не принимает PDF, URL документа, произвольный JSON
памяти, набор инструментов, изображения или поток SSE. Извлечение текста и
обратное сопоставление полей выполняет вызывающий сервис.
| Метод и путь | Назначение | Аутентификация |
|---|---|---|
POST /request | Выполнить секцию request выбранной политики | Сервисный токен и заголовки контекста |
POST /response | Выполнить секцию response выбранной политики | Те же заголовки |
GET /readyz | Проверить загрузку набора политик | Не требуется |
GET /metrics | Метрики Prometheus текущего процесса | Сервисный токен |
GET /openapi.json | Замороженная схема API | В текущей реализации не требуется |
GET /docs | Просмотр OpenAPI | В текущей реализации не требуется; выполнение POST требует заголовков |
Имена стадий выбирают секцию политики. Они не заставляют Guardrails вызвать модель, сохранить документ или проверить обе стадии автоматически. Для RAG и Memory соответствие операции и стадии фиксируется в конфигурации адаптера.
Заголовки каждого вызова проверки
| Заголовок | Значение |
|---|---|
Authorization | Bearer <service-token>; отдельный секрет Guardrails, не пользовательский JWT и не ключ LLM |
Content-Type | application/json; тело — UTF-8 |
x-ap-gr-policy-id | Точный идентификатор политики в загруженном наборе, например rag-memory-text |
x-ap-gr-policy-revision | Точная строковая ревизия, например 1 |
x-ap-gr-bundle-digest | 64 шестнадцатеричных символа SHA-256 канонического набора, без sha256: |
x-ap-gr-content-profile | Точное значение contentProfile загруженного набора |
x-ap-gr-response-mode | Для профиля chat-webhook-v2 обязателен: buffered либо sse-reject. Для прежних профилей не требуется |
Заголовки авторизации и контекста должны быть непустыми и встречаться ровно
один раз. Дублирование отклоняется. Content-Encoding на входе не поддерживается.
Не копируйте эти заголовки из внешнего HTTP-запроса: они относятся к доверенной
конфигурации клиента. Неверная контрольная сумма или неизвестная ревизия не переключают
Guardrails на другую политику.
Тело POST /request
{
"body": {
"messages": [
{"role": "user", "content": "Связаться: demo@example.org"}
]
}
}Массив messages непустой. У сообщения ровно два поля: role — непустая строка
до 32 символов, content — строка. null, массив мультимодальных частей,
tool_calls, name и другие дополнительные поля не поддерживаются.
role не является утверждением о доверии или авторизации: даже сообщение с
ролью system для классификатора остаётся проверяемыми данными.
Тело POST /response
{
"body": {
"choices": [
{"message": {"role": "assistant", "content": "Связаться: demo@example.org"}}
]
}
}choices также непустой. Это нормализованный объект, а не полный ответ
Chat Completions: id, model, usage, index, finish_reason и прочие поля
передавать нельзя. Служебные данные и идентификаторы RAG/Memory храните рядом в
адаптере, не добавляйте в тело запроса Guardrails.
Три результата завершённой проверки
Все три результата возвращаются с HTTP 200. Проверять только HTTP-статус
или raise_for_status() недостаточно.
Разрешить
{"action":{"reason":"policy_pass"}}Продолжите операцию с теми же текстовыми полями, которые отправляли на проверку. Это отсутствие запрещающего результата настроенных правил, а не доказательство полной безопасности или фактической корректности текста.
Заблокировать
{
"action": {
"body": "Запрос отклонён политикой",
"status_code": 403,
"reason": "policy_denied"
}
}Остановите защищаемое действие. action.status_code — часть решения для вызывающей системы; HTTP-ответ самого Guardrails остаётся 200. В сервисе RAG/Memory
преобразуйте решение в согласованную доменную ошибку или отказ задания.
Не делайте повтор того же содержимого для «получения разрешения».
Маскировать
Для /request:
{
"action": {
"body": {"messages": [{"role": "user", "content": "Связаться: [EMAIL]"}]},
"reason": "content_redacted"
}
}Для /response:
{
"action": {
"body": {"choices": [{"message": {"role": "assistant", "content": "Связаться: [EMAIL]"}}]},
"reason": "content_redacted"
}
}Подставьте возвращённые строки вместо исходных. Число сообщений, порядок и роли
сохраняются. Если ваш клиент обнаружил несоответствие, считайте ответ ошибочным.
action.body заменяет проверяемое тело, но не весь доменный объект с его ACL,
идентификаторами и метаданными. HTTP API не отдаёт смещения замен или список
найденных сущностей: повторно искать совпадения в исходном тексте не нужно.
Потоковый ответ через Agentgateway
Control Plane включает promptGuard.streaming: Enabled. Клиент модели отправляет
обычный запрос Chat Completions с stream: true. Заголовки контекста проверки
формирует шлюз; клиент не может выбрать ими более слабый режим.
| Проверка | Обычный JSON-ответ | Потоковый ответ SSE |
|---|---|---|
| Вход: запрет | Запрос остановлен до модели | То же поведение |
| Вход: маскирование | Модель получает очищенный текст | То же поведение; вложения и вызовы инструментов сохраняются |
| Выход: запрет | Ответ заблокирован | Поток остановлен событием guardrail_blocked |
| Выход: маскирование | Клиент получает очищенный текст | При совпадении поток остановлен; исходный фрагмент не выдаётся |
Преобразование выходного маскирования в запрет — явное правило нового профиля.
Agentgateway 1.5.0 не применяет Mask к SSE. Поэтому Runtime в режиме
sse-reject возвращает Reject вместо Mask; молчаливого пропуска исходного
текста нет. Режим observe по-прежнему ничего не блокирует.
HTTP-статус уже начатого потока может быть 200, даже если дальнейшая выдача
заблокирована. Клиент должен разбирать события ошибок, отмечать ответ как
незавершённый и не выдавать накопленный текст за успешный результат.
guardrail_error означает ошибку проверки, а не совпадение с правилом.
Шлюз проверяет текст окнами. В закреплённой версии размер окна составляет
1024 байта, перекрытие — 256 байт. Короткий ответ может появиться только в конце.
Ранее выданную разрешённую часть отозвать невозможно. Проверка окон не равна
проверке смысловой связи всего ответа: правило, которому нужен полный документ,
следует выполнять с stream: false. Поддерживается один вариант ответа (n=1).
Служебные части tool_calls и отдельные поля рассуждения не становятся
проверенным пользовательским текстом; клиент должен обрабатывать их отдельно.
При входном маскировании нескольких текстовых частей одного сообщения шлюз объединяет их в одну очищенную текстовую часть. Изображения сохраняют исходные данные и порядок между собой. Байты изображений не отправляются в Runtime. Прямой PDF или произвольный файловый объект в Chat Completions этим профилем не предусмотрен: SDK-агент или узел потока сначала извлекает текст документа.
У существующей привязки новое поведение появится после повторного применения сохранённой версии политики: создаётся новое неизменяемое поколение. Изменять политику или отключать её для перехода не нужно. Дождитесь подтверждения применения на всех обслуживающих репликах шлюза.
Алгоритм клиента
- Зафиксировать таблицу «позиция сообщения → поле документа/факта» и выбранную политику.
- Проверить размер сериализованного UTF-8 JSON и число сообщений.
- Выполнить вызов с ограниченным временем ожидания. Не следовать редиректам.
- Для любого HTTP-статуса, отличного от
200, или ошибки сети запретить защищаемое действие до успешной проверки. - Для
200проверить JSON поRequestResultилиResponseResultиз OpenAPI. - Разобрать три варианта выше. Неизвестный или неполный
actionсчитать технической ошибкой. - Только после успешного разрешения/маскирования передать результат дальше. Сохранять и индексировать исходник после
maskзапрещено логикой адаптера.
Проверенный пример клиента реализует этот разбор. Быстрый запуск показывает его использование.
Технические ошибки
{
"code": "policy_unavailable",
"message": "Guardrail check could not be completed",
"traceId": "0123456789abcdef0123456789abcdef"
}Ошибка имеет плоские поля code, message, traceId. Это не формат ошибок
Control Plane или RAG/Memory. В сообщение не включаются исходный текст и
провайдерские ответы. Для диагностики используйте код и traceId.
| HTTP | Код / условие | Действие интегратора |
|---|---|---|
400 | invalid_json: невалидный UTF-8/JSON, дублирующиеся поля и другие нарушения строгого разбора | Исправить сериализацию, не повторять тот же запрос |
401 | unauthenticated: нет корректного сервисного токена | Проверить доставку секрета и адрес |
403 | untrusted_context: обязательный контекст отсутствует, пуст или продублирован | Исправить конфигурацию заголовков; это не запрет содержимого |
413 | body_too_large | Уменьшить единицу обработки по согласованному правилу; не обрезать текст молча |
415 | unsupported_media | Отправлять JSON без Content-Encoding |
422 | invalid_payload, message_limit | Исправить форму/число сообщений |
503 | policy_unavailable | Проверить политику, ревизию, контрольную сумму, профиль и готовность поколения |
503 | overloaded | Ограничить конкурентность, отложить задание с ограниченным числом повторов |
503 | stage_timeout, rule_timeout, ошибки провайдера/вердикта | Проверить бюджет и провайдера; до завершения проверки не пропускать данные |
503 | invalid_replacement, output_too_large и другие ошибки проверки | Проверить правила/лимиты; слепой повтор может не помочь |
| Нет HTTP-ответа | Таймаут, DNS, TLS, разрыв соединения | Техническая недоступность, а не pass |
503 не всегда временная ошибка. Переходите к повторам только после
классификации причины. Guardrails не предоставляет Retry-After, ключи
идемпотентности и хранилище результатов проверок. Классификатор при повторе
может дать другой ответ; результат не считается детерминированным даже при
температуре 0. Идемпотентность записи в RAG/Memory обеспечивает ваш сервис.
Как выполняются правила
Политика содержит секции request и response. В каждой — общий deadlineMs,
непустой список baseline и список additional. Сначала выполняются базовые,
затем дополнительные правила в порядке списка. Все видят исходный текст этой
проверки, а не результат предыдущего маскирования.
Тип kind | Возможности | Ограничения |
|---|---|---|
stop_list | Запрет или замена по списку строк, совпадение substring либо token | Явная чувствительность к регистру; нет скрытой нормализации Unicode |
regex | Запрет или замена по RE2 | engine: google-re2-1.1.20251105; обратные ссылки и lookbehind не поддерживаются |
external_pipeline | Вызов внешнего детектора с решением allow/deny | Только контракт agent-platform.guardrail-runtime.detector/v1, без маскирования |
llm_classifier | Проверка по версионируемой инструкции; семантический запрет | Без маскирования; uncertain, отказ модели и неверный ответ — ошибка проверки |
Готового универсального распознавателя всех персональных данных, проверки достоверности фактов и доказательства соответствия ответа источникам этот API не предоставляет. Классификатор возвращает решение по настроенной инструкции, а не категории документов, оценки уверенности или найденные сущности.
Базовые правила всегда enforce. Дополнительные допускают enforce или
observe. Наблюдаемое правило не блокирует и не меняет текст; его срабатывание
или ошибка учитываются в метриках. Общий таймаут стадии и ошибки обязательных
правил всё равно запрещают продолжение.
Запрет останавливает последующие проверки. Замены собираются и применяются после проверок; конфликтующие пересечения дают техническую ошибку. Поэтому маска email первым правилом не скрывает email от следующего LLM-классификатора. Если внешний классификатор не должен получать исходные данные, нужны две отдельные проверки: локальное маскирование, затем вызов классификатора уже с полученным текстом. Это решение адаптера, не режим внутри одной политики.
Схемы конфигурации: bundle/v1
и detector/v1.
Провайдер-классификатор настраивается отдельно от модели агента. Для профиля
openai.chat-completions.classifier/v1 нужны строгая JSON Schema, temperature: 0,
max_completion_tokens, stream: false, store: false. Одного названия
«OpenAI-compatible» недостаточно: конкретный профиль нужно проверить.
Другие поддержанные профили выбираются явно, автоматической смены протокола нет.
Лимиты
| Ограничение | Диапазон контракта | Значение учебной политики |
|---|---|---|
| JSON тела запроса и ответа | maxBodyBytes: 256–131072 байт | 32768 байт |
| Сообщения / варианты ответа | maxMessages: 1–64 | 32 |
| Совпадения детектора | maxMatches: 1–1024 | 256 |
| Одновременные проверки процесса | maxConcurrency: 1–256 | 32 |
| Очередь внутри Guardrails | queueSize: 0 | Без очереди |
| Общий бюджет стадии | deadlineMs: 1–5000 мс | 250 мс |
| Таймаут правила | timeoutMs: 1–5000 мс, не больше бюджета стадии | 20 мс |
| Файл набора политик | До 700 КиБ до и после канонизации | Зависит от файла |
Схема дополнительно ограничивает каждую строку content 131072 символами, но
более низкий байтовый лимит тела применяется раньше. Учитывайте обёртку JSON,
экранирование и многобайтовые символы. Значения среды могут отличаться от примера:
нет универсального обещания задержки, пропускной способности или размера документа.