Skip to content

Возможность маршрутизации моделей

Возможность маршрутизации моделей позволяет плагину выбрать, где должен выполняться подходящий запрос модели, до того как хост сопоставит модель с провайдером и выберет учётные данные.

Используйте её, когда тело запроса, заголовки, query-параметры или исходная клиентская модель должны выбрать один из вариантов:

  • исполнитель самого плагина-маршрутизатора;
  • исполнитель другого плагина;
  • встроенный путь провайдера, например codex, antigravity, xai или claude.

Поле возможности

json
{
  "capabilities": {
    "model_router": true
  }
}

Если маршрутизатор может отправлять запросы в собственный исполнитель, также объявите возможность исполнителя:

json
{
  "capabilities": {
    "model_router": true,
    "executor": true,
    "executor_model_scope": "static",
    "executor_input_formats": ["claude"],
    "executor_output_formats": ["claude"]
  }
}

Исходный код:

  • sdk/pluginapi/types.go: ModelRouter, ModelRouteRequest, ModelRouteResponse, ModelRouteTargetKind
  • sdk/pluginabi/types.go: model.route
  • internal/pluginhost/model_router.go: приоритет маршрутизаторов, проверка цели и доступность встроенных провайдеров
  • sdk/api/handlers/handlers.go: входной путь запроса до обычного определения провайдера и выбора учётных данных

Примеры:

  • examples/plugin/claude-web-search-router/go/main.go
  • examples/plugin/claude-web-search-router/go/fallback.go

Методы

МетодНазначение
model.routeВозвращает решение маршрутизации для текущего клиентского запроса.

Когда выполняется

Хост вызывает включённые маршрутизаторы моделей до обычного сопоставления модели с провайдером и выбора учётных данных. Плагины с более высоким приоритетом выполняются первыми. Если маршрутизатор возвращает Handled: false, невалидную цель или недоступную цель, хост пропускает этот результат и пробует следующий маршрутизатор. Если ни один маршрутизатор не обработал запрос, продолжается обычный путь хоста.

Запрос всё ещё находится в исходном клиентском протоколе. Например, Claude-совместимый запрос приходит с SourceFormat: "claude", а сырое тело Claude-запроса находится в Body.

Запрос

json
{
  "Plugin": {},
  "PluginID": "claude-web-search-router",
  "SourceFormat": "claude",
  "RequestedModel": "claude-sonnet-4-6",
  "Stream": true,
  "Headers": {},
  "Query": {},
  "Body": "base64-client-body",
  "Metadata": {},
  "AvailableProviders": ["antigravity", "codex", "xai"]
}

Важные поля:

ПолеОписание
PluginIDЛокальный ID плагина-маршрутизатора в хосте.
SourceFormatИсходный протокол клиента, например openai, claude или gemini.
RequestedModelКлиентская модель до определения провайдера и выбора учётных данных.
StreamОжидает ли клиент потоковый вывод.
Headers / QueryВходящие заголовки и query-параметры.
BodyСырое тело клиентского запроса. В RPC JSON кодируется как base64.
MetadataСнимок контекста запроса, созданный по мере возможности. Рассматривайте его как доступные только для чтения JSON-подобные данные.
AvailableProvidersКлючи встроенных провайдеров, для которых сейчас зарегистрированы учётные данные. Проверяйте их перед возвратом TargetKind: "provider".

Ответ

Не обрабатывать:

json
{
  "Handled": false
}

Маршрутизировать в исполнитель того же плагина:

json
{
  "Handled": true,
  "TargetKind": "self",
  "Reason": "matched_web_search"
}

Маршрутизировать в исполнитель другого плагина:

json
{
  "Handled": true,
  "TargetKind": "executor",
  "Target": "search-executor",
  "Reason": "matched_search_executor"
}

Маршрутизировать во встроенный провайдер:

json
{
  "Handled": true,
  "TargetKind": "provider",
  "Target": "codex",
  "TargetModel": "gpt-5.4-mini",
  "Reason": "matched_codex_web_search"
}

Типы целей

TargetKindTargetTargetModelПоведение
selfИгнорируется плагином; хост использует ID текущего плагина-маршрутизатора.Игнорируется.Выполняет исполнитель самого плагина-маршрутизатора.
executorID целевого плагина.Игнорируется.Напрямую выполняет исполнитель другого плагина.
providerКлюч встроенного провайдера.Необязательная замена модели.Продолжает путь через встроенный AuthManager и исполнитель провайдера.

Прямые маршруты в исполнитель плагина выполняются без выбора записи учётных данных. Целевой исполнитель должен объявить возможность исполнителя, разрешать статическое выполнение через executor_model_scope: "static" или "both" и поддерживать форматы запроса/ответа для текущего запроса.

Маршруты провайдеров должны указывать провайдера, который есть в AvailableProviders. Если TargetModel пустой, хост сохраняет исходную клиентскую модель. Если целевому провайдеру нужно нативное имя модели, задайте TargetModel явно вместо пересылки клиентского имени модели.

Пример конфигурации

Пример claude-web-search-router использует ModelRouter, чтобы обнаруживать встроенные запросы Claude Code web_search и направлять их во встроенные провайдеры с поддержкой web search или в собственный исполнитель плагина для Tavily.

yaml
plugins:
  enabled: true
  dir: "plugins"
  configs:
    claude-web-search-router:
      enabled: true
      priority: 20
      route: fallback
      antigravity_model: "gemini-3.1-flash-lite"
      codex_model: "gpt-5.4-mini"
      xai_model: "grok-4.3"
      tavily_api_keys:
        - "tvly-xxxxxxxx"
      require_web_search_only: true

Поведение маршрутов примера:

МаршрутЦель
antigravity_googleTargetKind: "provider", Target: "antigravity", TargetModel: antigravity_model
codex_web_searchTargetKind: "provider", Target: "codex", TargetModel: codex_model
xai_web_searchTargetKind: "provider", Target: "xai", TargetModel: xai_model
tavilyTargetKind: "self", исполнитель плагина сам обрабатывает Tavily.
fallbackTargetKind: "self", исполнитель плагина оркестрирует резервные варианты (fallback) по нескольким бэкендам.

Замечания по разработке

  • Возвращайте Handled: false для запросов, которые плагин не распознаёт, чтобы нижестоящие маршрутизаторы и обычный путь хоста могли продолжить обработку.
  • Держите model.route быстрым. Он должен классифицировать запрос и выбрать цель, а не выполнять полный upstream-запрос.
  • Используйте AvailableProviders перед возвратом цели встроенного провайдера.
  • Используйте self, когда исполнитель плагина должен оркестрировать резервные варианты (fallback), вызывать host.model.* или использовать внешний сервис плагина.
  • Используйте provider, когда запрос должен продолжить путь через управляемый хостом выбор учётных данных, логирование запросов, учёт использования и встроенный исполнитель.
  • model_router включается через флаг возможности и метод model.route. Повышение версии схемы плагина не требуется.

Лицензия MIT.