lovart3/lib/ai/model-router.ts
Your Name 8763e8d53f feat: 智能图片编辑系统 - 意图分析、提示词优化、模型路由
新增智能自动模式功能:
- smart-analyzer.ts: 智能意图分析器,识别抠图/换背景/增强等8种子意图
- prompt-optimizer.ts: 提示词优化器,将简单输入转为专业提示词
- model-router.ts: 智能模型路由器,根据意图选择最佳模型
- 修改route.ts集成新模块,替换原有关键词匹配逻辑

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-01-31 23:15:11 +08:00

232 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 智能模型路由器
* 根据用户意图选择最佳AI模型
*
* 核心逻辑:图片编辑场景优先使用 alibaba-image (灵魂4.5)
*/
import { getEnabledAiModelsWithProvider } from "@/lib/db/queries";
// 路由结果类型
export interface RouteResult {
id: string;
displayName: string;
providerType: string;
modelId: string;
reason: string;
}
// 意图到模型的映射配置
// providerTypes 按优先级排序,第一个是首选
const INTENT_MODEL_MAP: Record<
string,
{
providerTypes: string[];
requireVision?: boolean;
requireImageGen?: boolean;
description: string;
}
> = {
// 图片编辑:优先 alibaba-image(灵魂4.5,支持提示词扩展)
image_edit: {
providerTypes: ["alibaba-image", "gemini"],
requireVision: true,
requireImageGen: true,
description: "图片编辑",
},
// 视觉理解:优先千问3 VL(成本低效果好)
vision: {
providerTypes: ["alibaba", "gemini"],
requireVision: true,
description: "图片理解",
},
// 图片生成:优先灵魂4.5
image_gen: {
providerTypes: ["alibaba-image", "gemini", "volcano-vision"],
requireImageGen: true,
description: "图片生成",
},
// 视频生成
video_gen: {
providerTypes: ["volcano-video", "qianwen-video"],
description: "视频生成",
},
// 普通对话:优先千问3
chat: {
providerTypes: ["alibaba", "openai", "local"],
description: "对话",
},
};
// 子意图的特殊路由配置(覆盖默认配置)
const SUB_INTENT_OVERRIDES: Record<
string,
{
providerTypes?: string[];
reason?: string;
}
> = {
// 抠图:alibaba-image 效果最好
remove_background: {
providerTypes: ["alibaba-image", "gemini"],
reason: "抠图首选灵魂4.5",
},
// 换背景:alibaba-image 支持场景生成
replace_background: {
providerTypes: ["alibaba-image", "gemini"],
reason: "换背景首选灵魂4.5",
},
// 图片增强
enhance: {
providerTypes: ["alibaba-image", "gemini", "volcano-vision"],
reason: "增强首选灵魂4.5",
},
// 风格迁移:gemini 可能更有创意
style_transfer: {
providerTypes: ["gemini", "alibaba-image"],
reason: "风格迁移优选Gemini",
},
};
/**
* 路由到最佳模型
*/
export async function routeToModel(params: {
intent: string;
subIntent?: string;
hasImage: boolean;
}): Promise<RouteResult> {
const { intent, subIntent, hasImage } = params;
console.log("[Model Router] Routing:", { intent, subIntent, hasImage });
// 获取所有可用模型
const allModels = await getEnabledAiModelsWithProvider();
console.log("[Model Router] Available models:", allModels.length);
// 获取意图对应的配置
let config = INTENT_MODEL_MAP[intent] || INTENT_MODEL_MAP["chat"];
// 检查是否有子意图的特殊配置
if (subIntent && SUB_INTENT_OVERRIDES[subIntent]) {
const override = SUB_INTENT_OVERRIDES[subIntent];
if (override.providerTypes) {
config = { ...config, providerTypes: override.providerTypes };
}
}
// 按优先级查找匹配的模型
for (const providerType of config.providerTypes) {
const candidates = allModels.filter((m) => {
// 匹配 provider 类型
if (m.provider.type !== providerType) return false;
// 检查能力要求
if (config.requireVision && !m.model.supportsVision) return false;
if (config.requireImageGen && !m.model.supportsImageGen) return false;
// 排除子模型(只选主模型)
if (m.model.isSubModel) return false;
// 必须启用
if (!m.model.isEnabled) return false;
return true;
});
if (candidates.length > 0) {
// 优先选择默认模型
const defaultModel = candidates.find((c) => c.model.isDefault);
const selected = defaultModel || candidates[0];
const result: RouteResult = {
id: selected.model.id,
displayName: selected.model.displayName,
providerType: selected.provider.type,
modelId: selected.model.modelId,
reason: subIntent
? `${config.description}/${subIntent} → ${selected.model.displayName}`
: `${config.description} → ${selected.model.displayName}`,
};
console.log("[Model Router] ✅ Selected:", result);
return result;
}
}
// 兜底逻辑:返回任意可用的图片编辑模型
const fallbackCandidates = allModels.filter(
(m) =>
!m.model.isSubModel &&
m.model.isEnabled &&
(m.model.supportsImageGen || m.model.supportsVision)
);
if (fallbackCandidates.length > 0) {
const fallback = fallbackCandidates[0];
console.log("[Model Router] Using fallback (with image capability):", fallback.model.displayName);
return {
id: fallback.model.id,
displayName: fallback.model.displayName,
providerType: fallback.provider.type,
modelId: fallback.model.modelId,
reason: `fallback (${config.description})`,
};
}
// 最终兜底:返回任意可用模型
const anyModel = allModels.find((m) => !m.model.isSubModel && m.model.isEnabled);
if (anyModel) {
console.log("[Model Router] Using any available model:", anyModel.model.displayName);
return {
id: anyModel.model.id,
displayName: anyModel.model.displayName,
providerType: anyModel.provider.type,
modelId: anyModel.model.modelId,
reason: "fallback (any)",
};
}
// 如果没有任何模型,抛出错误
throw new Error("No available models for routing");
}
/**
* 获取意图的推荐模型列表(用于 UI 展示)
*/
export function getRecommendedModelsForIntent(intent: string): string[] {
const config = INTENT_MODEL_MAP[intent];
return config ? config.providerTypes : INTENT_MODEL_MAP["chat"].providerTypes;
}
/**
* 检查模型是否适合指定意图
*/
export function isModelSuitableForIntent(
providerType: string,
intent: string,
supportsVision: boolean,
supportsImageGen: boolean
): boolean {
const config = INTENT_MODEL_MAP[intent];
if (!config) return true; // 未知意图,允许任何模型
// 检查 provider 类型是否匹配
if (!config.providerTypes.includes(providerType)) {
return false;
}
// 检查能力要求
if (config.requireVision && !supportsVision) return false;
if (config.requireImageGen && !supportsImageGen) return false;
return true;
}