模型间路由¶
Supported in ADKTypeScript v1.0.0Experimental
实验性功能
模型路由是实验性功能,在未来的版本中可能发生变化。我们欢迎你的反馈!
默认情况下,LlmAgent 使用单个模型。当你需要为每个请求动态选择不同模型时,可以定义路由函数来选择使用哪个模型。RoutedLlm 提供此功能,支持出错时的模型回退、模型间的 A/B 测试以及按输入复杂度的自动路由。如果选中的模型在产生任何输出之前失败,路由函数将再次被调用,并附带错误上下文,以便选择不同的模型。
将 RoutedLlm 作为 LlmAgent 的 model 参数传入。仅在模型在路由间变化时使用 RoutedLlm。如果你还需要切换指令、工具或子智能体,请改用 RoutedAgent。
路由工作原理¶
LlmRouter 函数接收可用模型映射和当前 LlmRequest,并返回要使用的模型键:
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);
}
}