Custom-провайдеры
Несколько экземпляров одного и того же базового провайдера, ограничения по типам запросов, описательные имена и контролируемые шаблоны доступа.
Что такое custom-провайдер
Custom-провайдеры позволяют создавать несколько экземпляров одного и того же базового провайдера — каждый со своей конфигурацией и шаблоном доступа. Главная фишка — контроль типов запросов: вы ограничиваете, какие операции может выполнять каждый custom-экземпляр.
Думайте о custom-провайдерах как о «нескольких представлениях» одного и того же базового провайдера: можно завести несколько настроек поверх OpenAI, Anthropic или любого другого провайдера, оптимизированных под разные задачи, при этом разделяя те же API-ключи и базовую инфраструктуру.
Зачем
- Несколько экземпляров провайдера — несколько конфигураций над одним базовым (например, две конфигурации OpenAI).
- Контроль типов запросов — ограничение операций (chat, embedding, speech и т. п.) для каждого custom-экземпляра.
- Описательные имена —
openai-production,openai-stagingи т. п. - Переиспользование провайдера — выжать максимум из существующих провайдерских аккаунтов.
Как настроить
Custom-провайдеры конфигурируются полем custom_provider_config, расширяющим стандартную конфигурацию провайдера. Основная цель — несколько экземпляров одного базового провайдера с разными ограничениями по типам запросов.
Поведение allowed_requests:
- поле полностью отсутствует — разрешены все операции (поведение по умолчанию);
- частично задано — разрешены только явно перечисленные поля, остальные считаются
false; - полностью задано — разрешены только те операции, которые явно включены;
- передан пустой объект (
{}) — все операции отключены.

- Откройте
http://localhost:8080. - В боковой панели выберите Providers.
- Нажмите Add New Provider.
- Задайте уникальное имя провайдера (например,
openai-custom). - Выберите тип базового провайдера (например,
openai). - Настройте, какие типы запросов разрешены.
- Сохраните конфигурацию.
# Custom-провайдер только для chat completion
curl --location 'http://localhost:8080/api/providers' \
--header 'Content-Type: application/json' \
--data '{
"provider": "openai-custom",
"keys": [
{
"name": "openai-custom-key-1",
"value": "env.OPENAI_API_KEY",
"models": ["*"],
"weight": 1.0
}
],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"list_models": false,
"text_completion": false,
"text_completion_stream": false,
"chat_completion": true,
"chat_completion_stream": true,
"responses": false,
"responses_stream": false,
"embedding": false,
"speech": false,
"speech_stream": false,
"transcription": false,
"transcription_stream": false
},
"request_path_overrides": {
"chat_completion": "/v1/chat/completions"
}
}
}'{
"providers": {
"openai-custom": {
"keys": [
{
"name": "openai-custom-key-1",
"value": "env.OPENAI_API_KEY",
"models": ["*"],
"weight": 1.0
}
],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"list_models": false,
"text_completion": false,
"text_completion_stream": false,
"chat_completion": true,
"chat_completion_stream": true,
"responses": false,
"responses_stream": false,
"embedding": false,
"speech": false,
"speech_stream": false,
"transcription": false,
"transcription_stream": false
},
"request_path_overrides": {
"chat_completion": "/v1/chat/completions"
}
}
}
}
}Параметры конфигурации
Разрешённые типы запросов
Контроль операций custom-провайдера. Поведение:
- если
allowed_requestsне задан — разрешено всё; - если задан — разрешены только поля со значением
true, остальные считаютсяfalse.
Доступные операции:
text_completion— legacy text completion;text_completion_stream— стриминговый text completion;chat_completion— обычный chat completion;chat_completion_stream— стриминговый chat completion;responses— обычные responses-запросы;responses_stream— стриминговые responses-запросы;embedding— генерация embedding;speech— синтез речи (TTS);speech_stream— стриминговый TTS;transcription— распознавание речи (STT);transcription_stream— стриминговое STT.
Базовые типы провайдеров
Custom-провайдер можно построить поверх:
openai— OpenAI API;anthropic— Anthropic Claude;bedrock— AWS Bedrock;cohere— Cohere;gemini— Gemini;replicate— Replicate.
Переопределение путей запросов
Поле request_path_overrides переопределяет дефолтные пути API для конкретных типов запросов. Полезно при:
- подключении к собственным или self-hosted провайдерам;
- интеграции с прокси, ожидающими определённый формат URL;
- использовании fork'ов провайдеров с изменёнными API-путями.
Не поддерживается: request_path_overrides не работает для базовых провайдеров gemini и bedrock из-за специфики их API.
Поле принимает маппинг типов запросов в пути или полные URL.
Пути (относительно base_url):
{
"request_path_overrides": {
"chat_completion": "/v1/chat/completions",
"chat_completion_stream": "/v1/chat/completions",
"embedding": "/v1/embeddings",
"text_completion": "/v1/completions"
}
}Полные URL (в обход base_url):
{
"request_path_overrides": {
"chat_completion": "https://specific-endpoint.com/chat",
"embedding": "http://another-service:8080/embeddings"
}
}Если в request_path_overrides указан полный URL (со схемой и хостом), Meridian использует его напрямую и игнорирует base_url из network_config для этого типа запроса. Это позволяет направлять разные типы запросов к совершенно разным эндпоинтам.
Пример: OpenAI-совместимый endpoint с переопределёнными путями
{
"custom-llm": {
"keys": [{ "name": "custom-llm-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"network_config": {
"base_url": "https://your-openai-compatible-endpoint.com"
},
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true
},
"request_path_overrides": {
"chat_completion": "/api/v2/chat",
"chat_completion_stream": "/api/v2/chat"
}
}
}
}В этом примере вместо дефолтного пути OpenAI /v1/chat/completions запросы пойдут на https://your-openai-compatible-endpoint.com/api/v2/chat.
TLS для self-signed и внутренних сертификатов
При подключении к HTTPS-провайдерам с self-signed или внутренним CA (закрытые контуры, внутренние сервисы) TLS настраивается в network_config:
| Поле | Тип | Описание |
|---|---|---|
insecure_skip_verify | boolean | Отключить проверку TLS-сертификата. Только для доверенных внутренних окружений. Не рекомендуется в production. |
ca_cert_pem | string | PEM-кодированный CA-сертификат, которому Meridian будет доверять при подключении. Используйте, когда у эндпоинта свой CA. |
Опции взаимоисключающие. Не задавайте insecure_skip_verify: true вместе с ca_cert_pem — валидация конфигурации это отвергнет.
Вариант 1: пропуск проверки (закрытые контуры / self-signed):
{
"my-air-gapped-provider": {
"keys": [{ "name": "key-1", "value": "env.API_KEY", "models": ["*"], "weight": 1.0 }],
"network_config": {
"base_url": "https://internal-llm.example.com",
"insecure_skip_verify": true
},
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true
}
}
}
}Вариант 2: собственный CA (предпочтительно):
{
"my-internal-provider": {
"keys": [{ "name": "key-1", "value": "env.API_KEY", "models": ["*"], "weight": 1.0 }],
"network_config": {
"base_url": "https://internal-llm.example.com",
"ca_cert_pem": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
},
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true
}
}
}
}insecure_skip_verify отключает всю проверку сертификатов и небезопасен. Если у вас есть CA-сертификат, всегда предпочитайте ca_cert_pem. insecure_skip_verify — только в доверенных, изолированных окружениях (например, air-gapped сети).
Сценарии использования
1. Конфигурации по окружениям
Разные конфигурации под production, staging и development:
{
"openai-production": {
"keys": [{ "name": "openai-prod-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true,
"embedding": true,
"speech": true,
"speech_stream": true
}
}
},
"openai-staging": {
"keys": [{ "name": "openai-stage-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true,
"embedding": true,
"speech": false,
"speech_stream": false
}
}
},
"openai-dev": {
"keys": [{ "name": "openai-dev-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": false,
"embedding": false,
"speech": false,
"speech_stream": false
}
}
}
}2. Контроль доступа на основе ролей
Ограничение возможностей по ролям пользователей или командам. После создания custom-провайдеров можно завести виртуальные ключи для управления тем, кто к каким провайдерам имеет доступ — это даёт детальный контроль над правами команд и потреблением ресурсов:
{
"openai-developers": {
"keys": [{ "name": "openai-developers-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true,
"embedding": true,
"text_completion": true
}
}
},
"openai-analysts": {
"keys": [{ "name": "openai-analysts-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"embedding": true
}
}
},
"openai-support": {
"keys": [{ "name": "openai-support-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": false
}
}
}
}3. Тестирование фич и постепенная раскатка
Тестирование новых фич на ограниченной группе пользователей:
{
"openai-beta-streaming": {
"keys": [{ "name": "openai-streaming-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": true,
"embedding": false
}
}
},
"openai-stable": {
"keys": [{ "name": "openai-stable-key-1", "value": "env.PROVIDER_API_KEY", "models": ["*"], "weight": 1.0 }],
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": {
"chat_completion": true,
"chat_completion_stream": false,
"embedding": true
}
}
}
}Выполнение запросов
В запросе используется имя custom-провайдера:
# Запрос к custom-провайдеру
curl --location 'http://localhost:8080/v1/chat/completions' \
--header 'Content-Type: application/json' \
--data '{
"model": "openai-custom/gpt-4o-mini",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'Связь с конфигурацией провайдеров
Custom-провайдеры расширяют стандартную систему конфигурации провайдеров: наследуют все возможности базового провайдера и добавляют ограничения по типам запросов.
Подробнее о настройке провайдеров — на странице Настройка провайдеров.
Связанные материалы
- Повторные попытки и резервные варианты — автоматическое аварийное переключение между провайдерами.
- Балансировка ключей — взвешенное распределение нагрузки между API-ключами.
- Виртуальные ключи — расширенный контроль доступа и мониторинг через governance.
Тюнинг производительности
Оптимизация Meridian под высокую нагрузку — параллелизм, размеры очередей и memory-пулы.
Замена без пересборки приложения
Замените существующее подключение к AI-SDK на Meridian, поменяв только базовый URL в настройках. Код остаётся прежним, а вы получаете фолбэки, балансировку и управление бюджетом.