Алиасы моделей

Назначение произвльного имени модели — статические алиасы на виртуальном ключе и динамические алиасы через правила маршрутизации.

Обзор

Алиасы отделяют имя модели, которое отправляет приложение, от идентификатора, с которым Meridian обращается к провайдеру. С их помощью можно:

  • отправлять "best-model" и менять стоящую за ним модель без изменения кода приложения;
  • сопоставить одно логическое имя, например "gpt-4o", с именем deployment, ARN inference-профиля или идентификатором fine-tuned модели;
  • выдавать разным командам разные модели под одним и тем же именем.

Meridian поддерживает два механизма. Они работают на разных этапах обработки запроса:

Статические алиасыДинамические алиасы
Где настраиваютсяНа ключе провайдераВ правилах маршрутизации
Когда применяютсяПосле выбора ключа, перед вызовом API провайдераПри обработке запроса, до выбора ключа
Область действияОдин ключВиртуальный ключ, пользователь, команда, заказчик или весь шлюз
УсловияНет — срабатывают всегдаДа — CEL-выражение определяет, когда правило срабатывает

Статические алиасы

Статический алиас задаётся на ключе провайдера. Для каждого запроса, который обслуживает этот ключ, имя модели заменяется по таблице алиасов перед отправкой провайдеру.

Как это работает

  1. Приложение отправляет запрос с model: "best-model".
  2. Meridian выбирает ключ, которому разрешена модель "best-model". Имя алиаса проверяется по спискам models и blacklisted_models ключа так же, как обычное имя модели.
  3. Перед вызовом провайдера Meridian заменяет "best-model" на "gpt-4o-2024-11-20" по полю aliases выбранного ключа.
  4. Провайдер получает "gpt-4o-2024-11-20". Приложению этот идентификатор знать не нужно.

Имя алиаса должно быть разрешено в списке models ключа. Если в models перечислены конкретные модели, добавьте туда имена алиасов. Значение ["*"] разрешает все модели.

Настройка

  1. Откройте Models → Model Providers и выберите провайдера.
  2. Создайте ключ или откройте существующий на редактирование.
  3. В блоке Deployments (Optional) добавьте строку:
    • Deployment name — имя модели в запросе, например best-model;
    • Model ID — идентификатор, который получит провайдер, например gpt-4o-2024-11-20.
  4. Чтобы задать дополнительные параметры, раскройте строку. Доступны имя модели для учёта стоимости, семейство модели, описание и параметры конкретного провайдера.
  5. Сохраните ключ.

Алиасы передаются в поле aliases при создании ключа:

curl -X POST http://localhost:8080/api/providers/openai/keys \
  -H "Content-Type: application/json" \
  -d '{
    "name": "openai-main",
    "value": "env.OPENAI_API_KEY",
    "models": ["*"],
    "weight": 1,
    "aliases": {
      "best-model": "gpt-4o-2024-11-20",
      "fast-model": "gpt-4o-mini"
    }
  }'

Для изменения существующего ключа используйте PUT /api/providers/{provider}/keys/{key_id}. Некорректная таблица алиасов отклоняется с ошибкой Invalid aliases: ….

{
  "providers": {
    "openai": {
      "keys": [
        {
          "name": "openai-main",
          "value": "env.OPENAI_API_KEY",
          "models": ["*"],
          "weight": 1,
          "aliases": {
            "best-model": "gpt-4o-2024-11-20",
            "fast-model": "gpt-4o-mini",
            "embedder": "text-embedding-3-large"
          }
        }
      ]
    }
  }
}

Краткая и расширенная форма

Значение алиаса задаётся строкой или объектом. Строка — краткая форма, она равнозначна объекту с одним полем model_id. Обе формы можно сочетать в одной таблице.

Расширенная форма нужна, когда идентификатор провайдера непрозрачен или для алиаса требуются отдельные параметры подключения:

{
  "aliases": {
    "fast-model": "gpt-4o-mini",
    "claude-azure": {
      "model_id": "prod-sonnet-deployment",
      "model_name": "claude-sonnet-4-5",
      "model_family": "anthropic",
      "description": "Claude Sonnet 4.5 в Azure-подписке компании",
      "anthropic_version": "2023-06-01",
      "endpoint": "env.AZURE_SECONDARY_ENDPOINT"
    }
  }
}
ПолеТипОписание
model_idstringОбязательное. Идентификатор, который получает провайдер: имя deployment, ARN inference-профиля, идентификатор fine-tuned модели.
model_namestringКаноническое имя модели для расчёта стоимости и логов. Задайте его, если model_id не совпадает с именем из каталога моделей, иначе стоимость не будет рассчитана.
model_familystringСемейство модели. Определяет формат запроса и разбор ответа. Значения: anthropic, openai, mistral, cohere, gemini, gemma, llama, imagen, veo, nova, titan. Если не задано, семейство определяется по model_name, model_id и имени алиаса.
descriptionstringПроизвольное описание. Отображается в веб-интерфейсе и не влияет на маршрутизацию.
regionstringРегион для этого алиаса (Bedrock, Vertex). Если не задан, используется регион ключа. Допускается префикс env..
project_idstringПроект для этого алиаса: проект GCP для Vertex, проект AWS для Bedrock. Допускается префикс env..
use_anthropic_endpointsbooleanНаправлять запросы chat completions и responses через Anthropic-совместимые эндпоинты.

Параметры конкретного провайдера. Их можно задавать только на алиасах ключа соответствующего провайдера. Для ключа другого провайдера таблица алиасов будет отклонена.

ПровайдерПолеОписание
Azureapi_versionПереопределяет query-параметр api-version.
Azureanthropic_versionПереопределяет заголовок anthropic-version для моделей Claude в Azure.
AzureendpointПереопределяет эндпоинт ключа. Позволяет использовать один ключ для deployment в разных ресурсах Azure.
Vertexproject_numberНомер проекта GCP. Обязателен для fine-tuned моделей.
Vertexforce_single_regionВызывать модель в регионе алиаса без перехода на мультирегиональный эндпоинт.
Bedrockinference_profile_arnARN inference-профиля, который вызывается вместо идентификатора модели.
Replicateuse_deployments_endpointНаправлять запросы через эндпоинт deployments Replicate.

Правила валидации

Meridian отклоняет таблицу алиасов, если нарушено хотя бы одно правило:

ПравилоОшибка
Имя алиаса не пустоеalias source cannot be empty
model_id не пустойalias "…": model_id cannot be empty
Нет пробелов в начале и конце имени алиаса, model_id и model_namealias source "…" cannot have leading or trailing whitespace
model_family — одно из допустимых значенийalias "…": invalid model_family "…"
Нет повторяющихся имён алиасов без учёта регистра: "GPT-4o" и "gpt-4o" не могут быть в одной таблицеduplicate alias source "…" (case-insensitive)
Параметры провайдера соответствуют провайдеру ключаalias "…": azure sub-config is only valid on Azure keys (got provider "…")

Поиск без учёта регистра

Сначала ищется точное совпадение имени, затем совпадение без учёта регистра. Если в таблице есть "GPT-4O": "gpt-4o-2024-11-20", запрос с model: "gpt-4o" будет обработан этим алиасом. Имена хранятся в том виде, в котором заданы.

Отслеживание в ответе

Каждый ответ содержит блок routing_info в extra_fields с решениями маршрутизации:

{
  "extra_fields": {
    "routing_info": {
      "provider": "openai",
      "model": "best-model",
      "key": "openai-main",
      "resolved_key_alias": {
        "model_id": "gpt-4o-2024-11-20",
        "model_name": "gpt-4o"
      }
    }
  }
}
ПолеОписание
routing_info.providerПровайдер, обработавший запрос.
routing_info.modelИмя модели после правил маршрутизации. Если сработал алиас — имя алиаса.
routing_info.keyИмя использованного ключа.
routing_info.resolved_key_aliasЕсть, только если сработал алиас: model_id, а также model_name и model_family, если они заданы.
routing_info.is_fallbacktrue, если запрос обслужил резервный вариант, а не основной провайдер.
routing_info.primary_provider, routing_info.primary_modelПровайдер и модель основной попытки. Заполняются при обслуживании резервным вариантом.

Если алиас не сработал, resolved_key_alias отсутствует, а model содержит идентификатор, отправленный провайдеру.

Поля extra_fields.provider, extra_fields.original_model_requested и extra_fields.resolved_model_used устарели, но заполняются для обратной совместимости. Новым интеграциям следует использовать routing_info.


Динамические алиасы

Динамический алиас — это правило маршрутизации, которое подменяет модель при обработке запроса по CEL-выражению. В отличие от статического алиаса, оно срабатывает по условию и имеет область действия. Поэтому одно и то же имя модели может означать разные модели для разных источников запроса.

Области действия

Правила оцениваются по областям от наиболее конкретной к общей. Срабатывает первое совпавшее правило:

Виртуальный ключ  →  Пользователь  →  Команда  →  Заказчик  →  Весь шлюз

Алиас можно задать на любом уровне:

  • весь шлюз (global) — "best-model" → "gpt-4o-mini", экономичный вариант по умолчанию;
  • команда (team) — для ML-команды "best-model" → "claude-sonnet-4-5";
  • виртуальный ключ (virtual_key) — для отдельного ключа "best-model" → "o1".

Каждый источник запроса получает свою модель под одним именем без изменения приложения.

Область user доступна только через API и веб-интерфейс. В config.json поддерживаются global, team, customer и virtual_key.

Пример: алиас по типу запроса

{
  "id": "route-embeddings-to-fast-model",
  "name": "route-embeddings-to-fast-model",
  "cel_expression": "request_type == 'embedding' && model == 'embedder'",
  "targets": [
    { "model": "text-embedding-3-small", "weight": 1 }
  ],
  "scope": "global"
}

Любой embedding-запрос с model: "embedder" направляется на text-embedding-3-small.

Пример: алиас со сменой провайдера

{
  "id": "premium-tier-routing",
  "name": "premium-tier-routing",
  "cel_expression": "headers['x-tier'] == 'premium'",
  "targets": [
    { "provider": "anthropic", "model": "claude-sonnet-4-5", "weight": 1 }
  ],
  "scope": "global"
}

Запросы с заголовком x-tier: premium направляются на Claude Sonnet в Anthropic независимо от модели в запросе.

Цепочки правил

Если у правила chain_rule: true, после его срабатывания Meridian заново оценивает правила всех областей с новыми провайдером и моделью. Так строится многоуровневое разрешение: правило уровня шлюза выбирает провайдера, а правило уровня виртуального ключа — конечную модель.

Сценарий. Все клиенты отправляют model: "best-model". Премиальный виртуальный ключ должен получать gpt-5, стандартный — gpt-4.1.

Правило 1 — весь шлюз, chain_rule: true:

{
  "id": "resolve-best-model-provider",
  "name": "resolve-best-model-provider",
  "cel_expression": "model == 'best-model'",
  "targets": [
    { "provider": "openai", "model": "best-model", "weight": 1 }
  ],
  "scope": "global",
  "chain_rule": true
}

Правило закрепляет за best-model провайдера OpenAI и запускает повторную оценку с provider="openai", model="best-model".

Правило 2a — виртуальный ключ premium-vk:

{
  "id": "premium-model-selection",
  "name": "premium-model-selection",
  "cel_expression": "provider == 'openai' && model == 'best-model'",
  "targets": [
    { "provider": "openai", "model": "gpt-5", "weight": 1 }
  ],
  "scope": "virtual_key",
  "scope_id": "premium-vk"
}

Правило 2b — виртуальный ключ standard-vk:

{
  "id": "standard-model-selection",
  "name": "standard-model-selection",
  "cel_expression": "provider == 'openai' && model == 'best-model'",
  "targets": [
    { "provider": "openai", "model": "gpt-4.1", "weight": 1 }
  ],
  "scope": "virtual_key",
  "scope_id": "standard-vk"
}

Запрос через premium-vk:

model="best-model", ключ premium-vk
  ↓ Правило 1 (global, chain_rule: true)
provider="openai", model="best-model" — повторная оценка
  ↓ Правило 2a (virtual_key premium-vk)
provider="openai", model="gpt-5" — завершено
OpenAI получает model="gpt-5"

Запрос через standard-vk:

model="best-model", ключ standard-vk
  ↓ Правило 1 (global, chain_rule: true)
provider="openai", model="best-model" — повторная оценка
  ↓ Правило 2b (virtual_key standard-vk)
provider="openai", model="gpt-4.1" — завершено
OpenAI получает model="gpt-4.1"

Каждый шаг цепочки может сменить провайдера, модель или оба значения. Каждое правило срабатывает в цепочке не более одного раза, а длина цепочки по умолчанию ограничена 10 шагами. Поэтому циклы невозможны.

Полный справочник CEL-выражений, приоритетов и таргетов — на странице Правила маршрутизации.


Совместное использование

Оба механизма дополняют друг друга. Сначала срабатывают правила маршрутизации, затем, после выбора ключа, — алиасы ключа. Это разделяет ответственность:

  • правила маршрутизации выбирают провайдера и уровень ключа в зависимости от источника запроса;
  • алиасы ключа задают конечный идентификатор модели для провайдера.

Пример

Ключи. Два ключа OpenAI разного уровня и ключ Anthropic, у каждого свой алиас best-model:

{
  "providers": {
    "openai": {
      "keys": [
        {
          "name": "high-tier-key",
          "value": "env.OPENAI_HIGH_TIER_KEY",
          "models": ["*"],
          "weight": 1,
          "aliases": { "best-model": "gpt-5" }
        },
        {
          "name": "low-tier-key",
          "value": "env.OPENAI_LOW_TIER_KEY",
          "models": ["*"],
          "weight": 1,
          "aliases": { "best-model": "gpt-4o" }
        }
      ]
    },
    "anthropic": {
      "keys": [
        {
          "name": "anthropic-key",
          "value": "env.ANTHROPIC_API_KEY",
          "models": ["*"],
          "weight": 1,
          "aliases": { "best-model": "claude-sonnet-4-5" }
        }
      ]
    }
  }
}

Правила маршрутизации. Два правила уровня команды выбирают провайдера, два правила уровня виртуального ключа закрепляют ключ по имени через provider_key_name:

{
  "governance": {
    "routing_rules": [
      {
        "id": "tech-team-provider",
        "name": "tech-team-provider",
        "cel_expression": "model == 'best-model'",
        "targets": [{ "provider": "openai", "model": "best-model", "weight": 1 }],
        "scope": "team",
        "scope_id": "tech-team",
        "chain_rule": true
      },
      {
        "id": "ml-team-provider",
        "name": "ml-team-provider",
        "cel_expression": "model == 'best-model'",
        "targets": [{ "provider": "anthropic", "model": "best-model", "weight": 1 }],
        "scope": "team",
        "scope_id": "ml-team",
        "chain_rule": true
      },
      {
        "id": "premium-vk-key-selection",
        "name": "premium-vk-key-selection",
        "cel_expression": "provider == 'openai' && model == 'best-model'",
        "targets": [{ "provider": "openai", "model": "best-model", "provider_key_name": "high-tier-key", "weight": 1 }],
        "scope": "virtual_key",
        "scope_id": "premium-vk"
      },
      {
        "id": "standard-vk-key-selection",
        "name": "standard-vk-key-selection",
        "cel_expression": "provider == 'openai' && model == 'best-model'",
        "targets": [{ "provider": "openai", "model": "best-model", "provider_key_name": "low-tier-key", "weight": 1 }],
        "scope": "virtual_key",
        "scope_id": "standard-vk"
      }
    ]
  }
}

provider_key_name используется в config.json и при загрузке преобразуется в идентификатор ключа. Для этого нужен config store. В API и веб-интерфейсе ключ закрепляется полем key_id.

Разрешение запросов:

tech-team + premium-vk → model="best-model"
  ↓ правило команды: provider="openai", model="best-model" (цепочка)
  ↓ правило ключа: ключ high-tier-key
  ↓ алиас: "best-model" → "gpt-5"
  → OpenAI получает model="gpt-5"

tech-team + standard-vk → model="best-model"
  ↓ правило команды: provider="openai", model="best-model" (цепочка)
  ↓ правило ключа: ключ low-tier-key
  ↓ алиас: "best-model" → "gpt-4o"
  → OpenAI получает model="gpt-4o"

ml-team → model="best-model"
  ↓ правило команды: provider="anthropic", model="best-model" (цепочка)
  ↓ правил для anthropic на уровне ключа нет — цепочка завершена
  ↓ алиас: "best-model" → "claude-sonnet-4-5"
  → Anthropic получает model="claude-sonnet-4-5"

extra_fields.routing_info для tech-team + premium-vk:

{
  "routing_info": {
    "provider": "openai",
    "model": "best-model",
    "key": "high-tier-key",
    "resolved_key_alias": {
      "model_id": "gpt-5"
    }
  }
}

routing_info.model — имя модели после правил маршрутизации. routing_info.resolved_key_alias.model_id — идентификатор, который получил провайдер после правил и алиасов ключа. Если алиас ключа не сработал, resolved_key_alias отсутствует, и провайдер получает routing_info.model.


Дальше

Содержание