Управление провайдерами¶
Провайдер описывает, какой LLM backend вы защищаете и как до него добраться. В этом разделе описано, как создавать, настраивать и обслуживать провайдеров. Концептуальное описание сущности «Провайдер» — см. Основные понятия. Здесь приведено практическое руководство по работе с провайдерами в Admin UI и через API.
Создание провайдера¶
Перейдите на страницу Providers (/providers) и нажмите Create Provider. Форма создания содержит три секции: основная информация, метод роутинга и field mapping.
Основная информация¶
| Поле | Обяз. | Описание | Допустимые значения | Подробности |
|---|---|---|---|---|
| Название | Да | Уникальное имя провайдера | Строка 1–255 символов | Отображается в UI, логах и событиях. Рекомендуемый формат: <провайдер>-<среда> (например, openai-production, gigachat-staging). Нельзя изменить после создания — выбирайте осмысленное имя сразу. |
| Тип провайдера | Да | Тип LLM API | openai, anthropic, azure, google, cohere, huggingface, ollama, vllm, gigachat, custom |
Определяет, какие mapping presets доступны. Для нестандартных API используйте custom. Нельзя изменить после создания — при ошибке нужно создать нового провайдера. |
| Target Base URL | Да | URL целевого LLM backend | Валидный URL (http:// или https://) | Полный базовый URL, куда Gateway проксирует запросы после проверки. Должен быть доступен из сети AppSec.AIGate. Не включайте путь endpoint — он указывается отдельно в API Path. |
| API Path | Да | Путь к API endpoint | Строка, начинающаяся с / |
Конкретный путь endpoint на LLM backend. Итоговый URL запроса: Target Base URL + API Path. По умолчанию /v1/chat/completions. |
| Request Timeout (ms) | Нет | Таймаут запроса к LLM | 1000–600000 (по умолч. 30000) | Максимальное время ожидания ответа от LLM backend. Если LLM не ответил за это время — Gateway возвращает ошибку 504. Для моделей с длинной генерацией (o1, reasoning) рекомендуется 120000–300000 мс. Для embedding-моделей достаточно 5000–10000 мс. |
| Описание | Нет | Комментарий для администраторов | Текст до 1000 символов | Произвольный текст: назначение провайдера, ответственный, дата создания. Отображается только в Admin UI, не влияет на работу системы. |
Типы провайдеров и рекомендуемые presets:
| Тип | Описание | Рекомендуемый preset | Когда использовать |
|---|---|---|---|
openai |
OpenAI и совместимые API | openai_chat_completions |
Для OpenAI, а также для LocalAI, vLLM, Ollama и других OpenAI-совместимых API |
anthropic |
Anthropic Claude API | anthropic_messages |
Для Anthropic Claude (все версии) |
azure |
Azure OpenAI Service | azure_openai_chat |
Для Azure-hosted OpenAI. Отличается URL-структурой (/openai/deployments/{model}/...) |
google |
Google Gemini API | google_gemini |
Для Google Gemini / Vertex AI |
cohere |
Cohere API | cohere_chat |
Для Cohere Command и Generate |
huggingface |
HuggingFace Inference API | huggingface_inference |
Для HuggingFace hosted моделей |
ollama |
Ollama (self-hosted) | ollama_chat |
Для локальных Ollama-инстансов. Формат отличается от OpenAI в некоторых деталях |
vllm |
vLLM (self-hosted) | vllm_chat |
Для vLLM серверов. OpenAI-совместимый формат |
gigachat |
GigaChat (Сбер) | gigachat_chat |
Для GigaChat API. Требует OAuth2-авторизацию |
custom |
Любой нестандартный API | custom_simple + custom mapping |
Когда формат API не совпадает ни с одним preset. Требуется ручная настройка JSONPath |
Примеры Target Base URL и API Path для популярных провайдеров:
| Провайдер | Target Base URL | API Path | Итоговый URL |
|---|---|---|---|
| OpenAI | https://api.openai.com |
/v1/chat/completions |
https://api.openai.com/v1/chat/completions |
| Anthropic | https://api.anthropic.com |
/v1/messages |
https://api.anthropic.com/v1/messages |
| Azure OpenAI | https://your-resource.openai.azure.com |
/openai/deployments/gpt-4/chat/completions |
https://your-resource.openai.azure.com/openai/deployments/gpt-4/chat/completions |
| GigaChat | https://gigachat.devices.sberbank.ru/api/v1 |
/chat/completions |
https://gigachat.devices.sberbank.ru/api/v1/chat/completions |
| Google Gemini | https://generativelanguage.googleapis.com |
/v1/models/gemini-pro:generateContent |
https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent |
| Ollama (self-hosted) | http://ollama.internal:11434 |
/api/chat |
http://ollama.internal:11434/api/chat |
| vLLM (self-hosted) | http://vllm.internal:8000 |
/v1/chat/completions |
http://vllm.internal:8000/v1/chat/completions |
Совет
Если вы не уверены в правильности Target URL — выполните curl <Target Base URL><API Path> из сети AppSec.AIGate. Если получаете ответ (даже с ошибкой авторизации 401/403) — URL правильный и backend доступен.
Метод роутинга¶
Метод роутинга определяет, как Gateway выбирает провайдера для входящего запроса. Выбирается один из трёх методов при создании провайдера. Изменить метод после создания нельзя — при ошибке нужно создать нового провайдера и перепривязать профиль.
Метод 1: URL Pattern (рекомендуется для большинства случаев)
Gateway сопоставляет заголовок X-Original-URI с regex-паттерном.
| Поле | Описание |
|---|---|
| URL Pattern | Regex-паттерн для сопоставления URL |
| Priority | Приоритет (1-1000), выше число = выше приоритет |
Примеры URL Pattern:
| URL Pattern | Что совпадёт | Что НЕ совпадёт |
|---|---|---|
/openai/.* |
/openai/v1/chat/completions, /openai/v1/embeddings |
/anthropic/v1/messages |
/api/v1/openai/.* |
/api/v1/openai/chat |
/api/v1/anthropic/chat |
/v1/chat/completions |
Только /v1/chat/completions |
/v1/embeddings |
/llm/.* |
/llm/chat, /llm/completions |
/api/chat |
Пример конфигурации двух провайдеров с URL routing:
Провайдер "OpenAI":
URL Pattern: /openai/.*
Priority: 100
Провайдер "Anthropic":
URL Pattern: /anthropic/.*
Priority: 100
Запрос с X-Original-URI: /openai/v1/chat/completions → попадёт в "OpenAI".
Запрос с X-Original-URI: /anthropic/v1/messages → попадёт в "Anthropic".
Метод 2: Host/Domain
Gateway сопоставляет заголовок Host с паттерном хоста. Поддерживает wildcard *.
| Поле | Описание |
|---|---|
| Host Pattern | Паттерн хоста (wildcard: *.openai.com) |
| Priority | Приоритет (1-1000), выше число = выше приоритет |
Примеры Host Pattern:
| Host Pattern | Что совпадёт | Что НЕ совпадёт |
|---|---|---|
openai.company.com |
Только openai.company.com |
anthropic.company.com |
*.openai.company.com |
gpt4.openai.company.com, prod.openai.company.com |
openai.company.com (без поддомена) |
llm.company.com |
Только llm.company.com |
llm2.company.com |
Пример: Ваш Nginx раздаёт разные поддомены:
openai.company.com→ провайдер "OpenAI" (host pattern:openai.company.com).claude.company.com→ провайдер "Anthropic" (host pattern:claude.company.com).
Метод 3: HTTP Header
Gateway ищет конкретный заголовок с конкретным значением.
| Поле | Описание |
|---|---|
| Header Name | Имя HTTP заголовка (например X-LLM-Provider) |
| Header Value | Ожидаемое значение (например openai) |
| Priority | Приоритет (1-1000), выше число = выше приоритет |
Пример:
Провайдер "OpenAI":
Header Name: X-LLM-Provider
Header Value: openai
Priority: 100
Провайдер "Anthropic":
Header Name: X-LLM-Provider
Header Value: anthropic
Priority: 100
Клиент отправляет запрос с заголовком X-LLM-Provider: openai → попадает в "OpenAI".
Разрешение конфликтов (Priority):
Если входящий запрос совпадает с несколькими провайдерами, используется провайдер с наибольшим числом Priority:
Провайдер "OpenAI Default": URL Pattern: /openai/.* Priority: 100
Провайдер "OpenAI VIP": URL Pattern: /openai/vip/.* Priority: 200
Запрос: /openai/vip/chat → совпадает с обоими → выбирается "OpenAI VIP" (200 > 100)
Запрос: /openai/v1/chat → совпадает только с "OpenAI Default"
Рекомендация
Используйте URL Pattern для простых случаев, Host для мультидоменной архитектуры, Header когда клиенты управляют маршрутизацией самостоятельно.
Field Mapping (Mapping Preset)¶
Field Mapping определяет, как извлекать user prompt из запроса к LLM для анализа детекторами. Без правильного mapping Gateway не сможет извлечь текст пользователя и проанализировать его.
Как выбрать Mapping Preset:
Для стандартных провайдеров выберите готовый preset — он уже знает структуру API:
| Ваш LLM | Какой preset выбрать | Формат запроса |
|---|---|---|
| OpenAI (GPT-4, GPT-3.5) | openai_chat_completions |
{"messages": [{"role": "user", "content": "..."}]} |
| Anthropic (Claude) | anthropic_messages |
{"messages": [{"role": "user", "content": "..."}]} |
| Azure OpenAI | azure_openai_chat |
Как OpenAI, но другой URL |
| Google Gemini | google_gemini |
{"contents": [{"parts": [{"text": "..."}]}]} |
| Ollama | ollama_chat |
{"messages": [{"role": "user", "content": "..."}]} |
| vLLM | vllm_chat |
OpenAI-совместимый формат |
| Свой кастомный LLM | custom_simple + mapping ниже |
Любой формат |
Полный список preset'ов — см. Mapping Presets.
Настройка Custom Mapping (для нестандартных API):
Если ваш LLM использует нестандартный формат, выберите preset custom_simple и укажите JSONPath-пути:
| Поле | Описание | Для чего нужно |
|---|---|---|
| Prompt Path | Путь к тексту пользователя | Извлечение текста для детекторов |
| Model Path | Путь к названию модели | Логирование в событиях |
| System Prompt Path | Путь к system prompt | Анализ system prompt (если нужно) |
| Response Path | Путь к тексту ответа | Извлечение текста ответа для Response Scanning |
Пример 1: Стандартный OpenAI-совместимый API
Ваш LLM принимает запросы в формате OpenAI:
{
"model": "my-model",
"messages": [
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Привет, как дела?"}
]
}
Mapping:
- Prompt Path:
$.messages[*].content(извлечёт текст из всех messages). - Model Path:
$.model. - System Prompt Path:
$.messages[?(@.role=='system')].content. - Response Path:
$.choices[0].message.content.
В данном случае проще выбрать preset openai_chat_completions — он уже настроен.
Пример 2: Кастомный LLM с нестандартным форматом
Ваш LLM принимает запросы в формате:
И отвечает:
Mapping:
- Prompt Path:
$.query. - Model Path:
$.config.model_name. - System Prompt Path: (оставьте пустым — нет system prompt).
- Response Path:
$.result.text.
Пример 3: LLM с вложенными объектами
Ваш LLM принимает:
{
"request": {
"prompt": {
"text": "Переведи на английский",
"language": "ru"
},
"model": "translate-v1"
}
}
Mapping:
- Prompt Path:
$.request.prompt.text. - Model Path:
$.request.model. - Response Path:
$.response.text.
Совет
Если вы не уверены в JSONPath — отправьте тестовый запрос через Gateway и проверьте логи api-gateway. При неправильном mapping в логах появится предупреждение failed to extract prompt.
Жизненный цикл провайдера¶
Провайдер проходит через три состояния. Переходы между ними выполняются вручную администратором.
Создание Активация Архивация
│ │ │
▼ ▼ ▼
┌───────┐ Activate ┌──────────┐ Archive ┌───────────┐
│ DRAFT │ ────────────▶ │ ACTIVE │ ──────────▶ │ ARCHIVED │
└───────┘ └──────────┘ └───────────┘
│ │
│ Reactivate │
◀─────────────────────────┘
| Состояние | Поведение | Когда использовать |
|---|---|---|
| DRAFT | Провайдер создан, но не участвует в маршрутизации. Запросы, совпадающие с его маршрутом, получат ошибку NO_BACKEND_CONFIGURED. |
После создания — для настройки и проверки параметров до ввода в эксплуатацию. |
| ACTIVE | Провайдер активен. Gateway маршрутизирует запросы к его Target URL. Health check выполняется автоматически. | Рабочее состояние. |
| ARCHIVED | Провайдер деактивирован. Запросы не маршрутизируются. Конфигурация сохраняется для аудита. Можно реактивировать. | При выводе LLM backend из эксплуатации, миграции на другого провайдера, или временном отключении. |
Активация провайдера¶
- На странице Providers найдите провайдера в статусе DRAFT
- Нажмите кнопку Activate (иконка Power)
- Система проверит, что все обязательные поля заполнены
- Статус изменится на ACTIVE
Что происходит при активации: Gateway немедленно начинает принимать запросы для этого маршрута. Если к провайдеру ещё не привязан профиль безопасности — запросы будут проксироваться к LLM без проверки детекторами. Рекомендуется сначала создать и привязать профиль (шаги 3–4 из раздела Порядок настройки), а затем активировать провайдера.
Архивация провайдера¶
- На странице Providers найдите активного провайдера
- Нажмите кнопку Archive
- Подтвердите действие в диалоге
Что происходит при архивации: Gateway перестаёт маршрутизировать запросы к этому провайдеру. Привязанные профили остаются в системе, но перестают обрабатывать трафик. События, сгенерированные ранее, сохраняются. Конфигурация доступна для просмотра в режиме «только чтение».
Внимание
Если архивируемый провайдер — единственный активный для определённого маршрута, все запросы по этому маршруту начнут получать ошибку NO_BACKEND_CONFIGURED. Убедитесь, что трафик перенаправлен на другой провайдер, или предупредите пользователей о плановом отключении.
Редактирование провайдера¶
Нажмите на имя провайдера в таблице или кнопку Edit для открытия формы редактирования.
Что можно изменить:
| Поле | Можно изменить? | Примечание |
|---|---|---|
| Название | Да | Изменение отразится в UI, но исторические события сохранят старое имя. |
| Target Base URL | Да | Применяется немедленно. Все новые запросы будут направлены на новый URL. |
| API Path | Да | Применяется немедленно. |
| Request Timeout | Да | Применяется к новым запросам. Уже выполняющиеся запросы используют старый таймаут. |
| Описание | Да | — |
| Routing: URL Pattern / Host Pattern / Header Value | Да | Паттерн можно изменить, но сам метод роутинга (URL/Host/Header) изменить нельзя. |
| Routing: Priority | Да | Изменение приоритета может перенаправить трафик на другой провайдер. Будьте осторожны. |
| Mapping Preset | Да | Смена preset применяется немедленно. При неправильном preset детекторы получат пустой текст. |
| Custom Mapping (JSONPath) | Да | Применяется немедленно. Рекомендуется протестировать на тестовом запросе. |
| Тип провайдера | Нет | Нельзя изменить после создания. Нужно создать нового провайдера. |
| Метод роутинга (тип) | Нет | Нельзя переключить URL Pattern на Host или Header. Нужно создать нового провайдера. |
Важно
Изменения в активном провайдере применяются немедленно к новым запросам. Если вам нужно безопасно мигрировать — создайте нового провайдера, настройте и протестируйте его, затем архивируйте старого.
Тестирование провайдера¶
После создания и активации провайдера рекомендуется проверить, что маршрутизация и field mapping работают корректно.
Шаг 1: Проверка маршрутизации
Отправьте тестовый запрос через Gateway и убедитесь, что он попадает к правильному провайдеру. Флаг -v выводит заголовки ответа, среди которых Gateway возвращает информацию о выбранном провайдере:
curl -v -X POST http://localhost:8085/chat \
-H "Content-Type: application/json" \
-H "X-Original-URI: /openai/v1/chat/completions" \
-H "X-Tenant-ID: default" \
-d '{"model":"gpt-4","messages":[{"role":"user","content":"Test routing"}]}' \
2>&1 | grep -E "(HTTP/|X-Provider|X-Profile)"
Что искать в выводе:
X-Provider-ID: <uuid>— ID выбранного провайдера. Если отсутствует — маршрут не найден.X-Profile-ID: <uuid>— ID применённого профиля. Если отсутствует — профиль не привязан.HTTP/1.1 200— запрос успешно проксирован к LLM.HTTP/1.1 403— запрос заблокирован детектором (это нормально для тестов безопасности).HTTP/1.1 502— LLM backend недоступен. Проверьте Target URL.
Шаг 2: Проверка field mapping
Отправьте запрос с заведомо опасным текстом (например, с PII) и проверьте, что детектор его обнаружил:
curl -s -X POST http://localhost:8085/chat \
-H "Content-Type: application/json" \
-H "X-Original-URI: /openai/v1/chat/completions" \
-H "X-Tenant-ID: default" \
-d '{"model":"gpt-4","messages":[{"role":"user","content":"Мой email: test@example.com"}]}'
Если PII Detection включён и mapping настроен правильно — на Dashboard появится событие PII_DETECTED. Если события нет — mapping неправильный: Gateway не смог извлечь текст промпта.
Шаг 3: Проверка в логах
При проблемах с mapping проверьте логи API Gateway:
Наличие этого сообщения означает, что JSONPath из mapping preset не нашёл текст в теле запроса. Проверьте структуру запроса и соответствие preset.
Health Check провайдера¶
Health check — автоматическая проверка доступности LLM backend. Gateway периодически отправляет HTTP-запрос к Target URL и фиксирует результат. Результат отображается на странице Providers в колонке Health.
Автоматические проверки:
Система выполняет health check в фоне с настраиваемым интервалом. Конфигурация через переменные окружения:
| Переменная | Значение по умолч. | Допустимый диапазон | Описание |
|---|---|---|---|
HEALTH_CHECK_ENABLED |
true |
true / false |
Включить автоматические фоновые проверки. При false — health status обновляется только при ручном запуске. |
HEALTH_CHECK_INTERVAL_SECONDS |
60 |
10–3600 | Интервал между проверками. Для критичных production-провайдеров рекомендуется 30 сек. Для staging — 300 сек. |
HEALTH_CHECK_TIMEOUT_SECONDS |
5 |
1–30 | Таймаут ожидания ответа от backend при health check. Если backend не ответил за это время — статус UNHEALTHY. |
HEALTH_CHECK_RETRIES |
2 |
0–5 | Количество повторных попыток при ошибке, прежде чем установить статус UNHEALTHY. При 0 — одна неудачная попытка сразу даёт UNHEALTHY. |
Ручная проверка:
Нажмите кнопку Check Health (иконка пульса) на странице Providers или выполните API-запрос:
Результат проверки:
| Статус | Условие | Что делать |
|---|---|---|
| HEALTHY | Backend ответил HTTP 2xx/3xx в пределах таймаута | Провайдер работает нормально. |
| UNHEALTHY | Ошибка соединения, таймаут, или HTTP >= 500 после всех retry | Проверьте: (1) Target URL корректен, (2) backend запущен, (3) сетевая связность и firewall, (4) backend не перегружен. |
| UNKNOWN | Health check ещё ни разу не выполнялся | Нажмите Check Health для первой проверки, или дождитесь автоматической. |
Дополнительные поля в ответе API /api/v1/providers/{id}:
| Поле | Тип | Описание | Как использовать |
|---|---|---|---|
health_latency_ms |
int / null | Время ответа backend в мс | Мониторинг деградации производительности. Если latency растёт — backend перегружен. Нормальные значения для облачных API: 100–500 мс. Для self-hosted: 10–100 мс. |
health_error_message |
string / null | Текст ошибки при UNHEALTHY | Содержит конкретную причину: Connection refused, Timeout, HTTP 503 Service Unavailable. Наведите на иконку Health в UI — tooltip покажет это сообщение. |
health_checked_at |
datetime / null | Время последней проверки | Если давно — возможно, health check отключён или не работает. |
Типичные проблемы и решения¶
| Проблема | Симптом | Причина | Решение |
|---|---|---|---|
| Запросы не маршрутизируются | HTTP 400 NO_BACKEND_CONFIGURED |
Провайдер не найден для данного маршрута | Проверьте: (1) провайдер в статусе ACTIVE, (2) X-Original-URI совпадает с URL Pattern, (3) X-Tenant-ID соответствует tenant провайдера |
| Детекторы не срабатывают | Запросы проходят без событий | Field mapping не извлекает текст | Проверьте mapping preset. Отправьте запрос с PII — если событие PII_DETECTED не появилось, mapping неверный |
| Backend недоступен | HTTP 502 Bad Gateway | Target URL неправильный или backend не запущен | Выполните curl <Target URL><API Path> из сети AIGate. Проверьте Health Check. |
| Таймаут | HTTP 504 Gateway Timeout | LLM отвечает дольше, чем Request Timeout | Увеличьте Request Timeout. Для reasoning-моделей (o1) — до 300000 мс. |
| Неправильный провайдер | Запрос попадает не к тому LLM | Конфликт маршрутов, неверный Priority | Проверьте Priority всех провайдеров с перекрывающимися маршрутами. Больший Priority побеждает. |
| Health check всегда UNHEALTHY | Провайдер помечен красным, но работает | Health check URL отличается от рабочего | Health check использует Target URL + API Path. Если backend требует авторизацию — health check может получать 401 (что считается ошибкой). |