Перейти к содержанию

Управление провайдерами

Провайдер описывает, какой 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 принимает запросы в формате:

{
  "query": "Привет, как дела?",
  "config": {
    "model_name": "internal-llm-v2",
    "temperature": 0.7
  }
}

И отвечает:

{
  "result": {
    "text": "Привет! У меня всё хорошо.",
    "tokens_used": 15
  }
}

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 из эксплуатации, миграции на другого провайдера, или временном отключении.

Активация провайдера

  1. На странице Providers найдите провайдера в статусе DRAFT
  2. Нажмите кнопку Activate (иконка Power)
  3. Система проверит, что все обязательные поля заполнены
  4. Статус изменится на ACTIVE

Что происходит при активации: Gateway немедленно начинает принимать запросы для этого маршрута. Если к провайдеру ещё не привязан профиль безопасности — запросы будут проксироваться к LLM без проверки детекторами. Рекомендуется сначала создать и привязать профиль (шаги 3–4 из раздела Порядок настройки), а затем активировать провайдера.

Архивация провайдера

  1. На странице Providers найдите активного провайдера
  2. Нажмите кнопку Archive
  3. Подтвердите действие в диалоге

Что происходит при архивации: 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:

# В контейнере или через docker logs
grep "failed to extract prompt" /var/log/aigate/gateway.log

Наличие этого сообщения означает, что 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-запрос:

curl -X POST "http://localhost:8001/api/v1/providers/{id}/health-check?performed_by=admin"

Результат проверки:

Статус Условие Что делать
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 (что считается ошибкой).