Skip to content

模型间路由

Supported in ADKTypeScript v1.0.0Experimental

实验性功能

模型路由是实验性功能,在未来的版本中可能发生变化。我们欢迎你的反馈

默认情况下,LlmAgent 使用单个模型。当你需要为每个请求动态选择不同模型时,可以定义路由函数来选择使用哪个模型。RoutedLlm 提供此功能,支持出错时的模型回退、模型间的 A/B 测试以及按输入复杂度的自动路由。如果选中的模型在产生任何输出之前失败,路由函数将再次被调用,并附带错误上下文,以便选择不同的模型。

RoutedLlm 作为 LlmAgentmodel 参数传入。仅在模型在路由间变化时使用 RoutedLlm。如果你还需要切换指令、工具或子智能体,请改用 RoutedAgent

路由工作原理

LlmRouter 函数接收可用模型映射和当前 LlmRequest,并返回要使用的模型键:

type LlmRouter = (
  models: Readonly<Record<string, BaseLlm>>,
  request: LlmRequest,
  errorContext?: { failedKeys: ReadonlySet<string>; lastError: unknown },
) => Promise<string | undefined> | string | undefined;

models 参数接受带有显式键的 Record<string, BaseLlm>,或 BaseLlm 实例数组。如果提供数组,则每个模型的名称将用作其键。

故障转移遵循与 RoutedAgent 相同的规则:仅当选中的模型在产生任何响应之前失败时,才会使用 errorContext 重新调用路由函数。产生响应后,错误会直接传播而不重试。路由函数可以返回 undefined 以停止重试并传播最后一个错误。

实时连接: RoutedLlm.connect() 在连接时选择模型。一旦建立实时连接,就无法在中途切换模型。

基本用法

以下示例创建一个 RoutedLlm,首先尝试主模型,如果主模型失败则回退到辅助模型。路由函数检查 errorContext.failedKeys 以避免重新选择已失败的模型:

import {
  BaseLlm,
  Gemini,
  LlmRequest,
  LlmAgent,
  RoutedLlm,
  InMemoryRunner,
} from '@google/adk';

const primaryModel = new Gemini({ model: 'gemini-flash-latest' });
const fallbackModel = new Gemini({ model: 'gemini-pro-latest' });

const router = (
  models: Readonly<Record<string, BaseLlm>>,
  request: LlmRequest,
  // errorContext is provided when a previously selected model fails
  errorContext?: { failedKeys: ReadonlySet<string>; lastError: unknown },
) => {
  if (!errorContext) {
    return 'primary'; // Try primary first
  }
  if (errorContext.failedKeys.has('primary')) {
    return 'fallback'; // Fall back if primary failed
  }
  return undefined; // No more options, propagate the error
};

const routedLlm = new RoutedLlm({
  models: { primary: primaryModel, fallback: fallbackModel },
  router,
});

// Use RoutedLlm as the model for an LlmAgent
const agent = new LlmAgent({
  name: 'my_agent',
  model: routedLlm,
  instruction: 'You are a helpful assistant.',
});

const runner = new InMemoryRunner({ agent, appName: 'my_app' });

const session = await runner.sessionService.createSession({
  appName: 'my_app',
  userId: 'user_1',
});

const run = runner.runAsync({
  userId: 'user_1',
  sessionId: session.id,
  newMessage: { role: 'user', parts: [{ text: 'Hello!' }] },
});

for await (const event of run) {
  if (event.content?.parts?.[0]?.text) {
    console.log(event.content.parts[0].text);
  }
}