Возможность маршрутизации моделей
Возможность маршрутизации моделей позволяет плагину выбрать, где должен выполняться подходящий запрос модели, до того как хост сопоставит модель с провайдером и выберет учётные данные.
Используйте её, когда тело запроса, заголовки, query-параметры или исходная клиентская модель должны выбрать один из вариантов:
- исполнитель самого плагина-маршрутизатора;
- исполнитель другого плагина;
- встроенный путь провайдера, например
codex,antigravity,xaiилиclaude.
Поле возможности
{
"capabilities": {
"model_router": true
}
}Если маршрутизатор может отправлять запросы в собственный исполнитель, также объявите возможность исполнителя:
{
"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,ModelRouteTargetKindsdk/pluginabi/types.go:model.routeinternal/pluginhost/model_router.go: приоритет маршрутизаторов, проверка цели и доступность встроенных провайдеровsdk/api/handlers/handlers.go: входной путь запроса до обычного определения провайдера и выбора учётных данных
Примеры:
examples/plugin/claude-web-search-router/go/main.goexamples/plugin/claude-web-search-router/go/fallback.go
Методы
| Метод | Назначение |
|---|---|
model.route | Возвращает решение маршрутизации для текущего клиентского запроса. |
Когда выполняется
Хост вызывает включённые маршрутизаторы моделей до обычного сопоставления модели с провайдером и выбора учётных данных. Плагины с более высоким приоритетом выполняются первыми. Если маршрутизатор возвращает Handled: false, невалидную цель или недоступную цель, хост пропускает этот результат и пробует следующий маршрутизатор. Если ни один маршрутизатор не обработал запрос, продолжается обычный путь хоста.
Запрос всё ещё находится в исходном клиентском протоколе. Например, Claude-совместимый запрос приходит с SourceFormat: "claude", а сырое тело Claude-запроса находится в Body.
Запрос
{
"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". |
Ответ
Не обрабатывать:
{
"Handled": false
}Маршрутизировать в исполнитель того же плагина:
{
"Handled": true,
"TargetKind": "self",
"Reason": "matched_web_search"
}Маршрутизировать в исполнитель другого плагина:
{
"Handled": true,
"TargetKind": "executor",
"Target": "search-executor",
"Reason": "matched_search_executor"
}Маршрутизировать во встроенный провайдер:
{
"Handled": true,
"TargetKind": "provider",
"Target": "codex",
"TargetModel": "gpt-5.4-mini",
"Reason": "matched_codex_web_search"
}Типы целей
| TargetKind | Target | TargetModel | Поведение |
|---|---|---|---|
self | Игнорируется плагином; хост использует ID текущего плагина-маршрутизатора. | Игнорируется. | Выполняет исполнитель самого плагина-маршрутизатора. |
executor | ID целевого плагина. | Игнорируется. | Напрямую выполняет исполнитель другого плагина. |
provider | Ключ встроенного провайдера. | Необязательная замена модели. | Продолжает путь через встроенный AuthManager и исполнитель провайдера. |
Прямые маршруты в исполнитель плагина выполняются без выбора записи учётных данных. Целевой исполнитель должен объявить возможность исполнителя, разрешать статическое выполнение через executor_model_scope: "static" или "both" и поддерживать форматы запроса/ответа для текущего запроса.
Маршруты провайдеров должны указывать провайдера, который есть в AvailableProviders. Если TargetModel пустой, хост сохраняет исходную клиентскую модель. Если целевому провайдеру нужно нативное имя модели, задайте TargetModel явно вместо пересылки клиентского имени модели.
Пример конфигурации
Пример claude-web-search-router использует ModelRouter, чтобы обнаруживать встроенные запросы Claude Code web_search и направлять их во встроенные провайдеры с поддержкой web search или в собственный исполнитель плагина для Tavily.
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_google | TargetKind: "provider", Target: "antigravity", TargetModel: antigravity_model |
codex_web_search | TargetKind: "provider", Target: "codex", TargetModel: codex_model |
xai_web_search | TargetKind: "provider", Target: "xai", TargetModel: xai_model |
tavily | TargetKind: "self", исполнитель плагина сам обрабатывает Tavily. |
fallback | TargetKind: "self", исполнитель плагина оркестрирует резервные варианты (fallback) по нескольким бэкендам. |
Замечания по разработке
- Возвращайте
Handled: falseдля запросов, которые плагин не распознаёт, чтобы нижестоящие маршрутизаторы и обычный путь хоста могли продолжить обработку. - Держите
model.routeбыстрым. Он должен классифицировать запрос и выбрать цель, а не выполнять полный upstream-запрос. - Используйте
AvailableProvidersперед возвратом цели встроенного провайдера. - Используйте
self, когда исполнитель плагина должен оркестрировать резервные варианты (fallback), вызыватьhost.model.*или использовать внешний сервис плагина. - Используйте
provider, когда запрос должен продолжить путь через управляемый хостом выбор учётных данных, логирование запросов, учёт использования и встроенный исполнитель. model_routerвключается через флаг возможности и методmodel.route. Повышение версии схемы плагина не требуется.