新增智能自动模式功能: - smart-analyzer.ts: 智能意图分析器,识别抠图/换背景/增强等8种子意图 - prompt-optimizer.ts: 提示词优化器,将简单输入转为专业提示词 - model-router.ts: 智能模型路由器,根据意图选择最佳模型 - 修改route.ts集成新模块,替换原有关键词匹配逻辑 Co-authored-by: Cursor <cursoragent@cursor.com>
756 lines
24 KiB
Markdown
756 lines
24 KiB
Markdown
# 智能图片编辑 - 实施开发指南
|
||
|
||
> 版本: v1.0
|
||
> 日期: 2025-01-31
|
||
> 目标: 在聊天对话框中实现智能图片编辑功能
|
||
|
||
---
|
||
|
||
## 一、核心流程
|
||
|
||
```
|
||
用户在对话框中发送 [图片 + 文字]
|
||
│
|
||
▼
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ POST /api/chat │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ 1. 提取用户消息 │ │
|
||
│ │ - 图片 URL (from message.parts where type='file') │ │
|
||
│ │ - 文字内容 (from message.parts where type='text') │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ 2. 智能意图分析 (如果 modelId === 'auto') │ │
|
||
│ │ - 调用 Qwen3 VL 分析用户意图 │ │
|
||
│ │ - 返回: intent, subIntent, confidence │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ 3. 提示词优化 (仅图片编辑类意图) │ │
|
||
│ │ - 根据子意图选择模板 │ │
|
||
│ │ - 填充用户参数,生成专业提示词 │ │
|
||
│ │ - 添加负面提示词 │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ 4. 模型路由 │ │
|
||
│ │ - 根据意图选择最佳模型 │ │
|
||
│ │ - 图片编辑 → alibaba-image │ │
|
||
│ │ - 视觉理解 → alibaba (Qwen3 VL) │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ 5. 调用对应模型生成 │ │
|
||
│ │ - 使用优化后的提示词 │ │
|
||
│ │ - 传入用户图片 │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ 6. 返回结果到对话框 │ │
|
||
│ │ - 编辑后的图片 (Markdown格式) │ │
|
||
│ │ - 保存到数据库 │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、需要修改/创建的文件
|
||
|
||
### 2.1 新建文件
|
||
|
||
| 文件路径 | 作用 |
|
||
|---------|------|
|
||
| `lib/ai/smart-analyzer.ts` | 智能意图分析器 |
|
||
| `lib/ai/prompt-optimizer.ts` | 提示词优化器 |
|
||
| `lib/ai/model-router.ts` | 智能模型路由器 |
|
||
|
||
### 2.2 修改文件
|
||
|
||
| 文件路径 | 修改内容 |
|
||
|---------|---------|
|
||
| `app/(chat)/api/chat/route.ts` | Auto Mode 逻辑替换 |
|
||
|
||
---
|
||
|
||
## 三、详细代码实现
|
||
|
||
### 3.1 创建 `lib/ai/smart-analyzer.ts`
|
||
|
||
```typescript
|
||
/**
|
||
* 智能意图分析器
|
||
* 使用 Qwen3 VL 分析用户输入,识别图片编辑意图
|
||
*/
|
||
|
||
import { generateText } from "ai";
|
||
import { getLanguageModelById } from "./dynamic-provider";
|
||
import { getEnabledAiModelsWithProvider } from "@/lib/db/queries";
|
||
|
||
// 分析结果类型
|
||
export interface AnalysisResult {
|
||
intent: "image_edit" | "vision" | "image_gen" | "video_gen" | "chat";
|
||
subIntent?: string;
|
||
confidence: number;
|
||
optimizedPrompt?: string;
|
||
negativePrompt?: string;
|
||
suggestedModel?: string;
|
||
needsClarification?: boolean;
|
||
clarifyingQuestions?: string[];
|
||
}
|
||
|
||
// 系统提示词 - 针对图片编辑场景优化
|
||
const ANALYZER_SYSTEM_PROMPT = `你是一个专业的图片编辑意图分析专家。请分析用户的请求,判断其意图类型。
|
||
|
||
## 意图分类(按优先级)
|
||
|
||
### 1. image_edit - 图片编辑(最高优先级,需要用户上传了图片)
|
||
子意图:
|
||
- remove_background: 抠图、去背景、透明背景、去除背景
|
||
- replace_background: 换背景、改背景、白底、场景替换、背景换成
|
||
- enhance: 变清晰、高清、锐化、降噪、提升质量、修复
|
||
- extend: 扩展、拓展、延伸、outpainting、扩图
|
||
- inpaint: 去除XX、消除、擦掉、修改XX部分、局部修改、P掉
|
||
- style_transfer: 风格化、卡通化、动漫风、油画风、改风格
|
||
- resize: 缩放、放大、缩小、调整尺寸、裁剪
|
||
- color_adjust: 调色、调整颜色、亮度、对比度、饱和度
|
||
|
||
### 2. vision - 图片理解(需要用户上传了图片)
|
||
触发词:看、识别、分析、描述、这是什么、有什么
|
||
|
||
### 3. image_gen - 图片生成(不需要上传图片)
|
||
触发词:画、绘制、生成图片、创建、设计
|
||
|
||
### 4. video_gen - 视频生成
|
||
触发词:视频、动画、动起来
|
||
|
||
### 5. chat - 普通对话(默认)
|
||
|
||
## 输出格式(严格JSON)
|
||
{
|
||
"intent": "image_edit",
|
||
"subIntent": "replace_background",
|
||
"confidence": 0.95,
|
||
"optimizedPrompt": "优化后的提示词",
|
||
"negativePrompt": "需要避免的内容",
|
||
"needsClarification": false,
|
||
"clarifyingQuestions": []
|
||
}
|
||
|
||
## 特殊规则
|
||
1. 如果用户上传了图片且有编辑类关键词 → image_edit
|
||
2. 如果用户上传了图片但意图不明确 → needsClarification: true,并提供澄清问题
|
||
3. 如果用户要求编辑但没上传图片 → needsClarification: true,提示"请上传图片"`;
|
||
|
||
/**
|
||
* 分析用户意图
|
||
*/
|
||
export async function analyzeIntent(params: {
|
||
text: string;
|
||
hasImage: boolean;
|
||
imageUrls?: string[];
|
||
}): Promise<AnalysisResult> {
|
||
const { text, hasImage, imageUrls } = params;
|
||
|
||
// 获取千问3 VL 模型
|
||
const allModels = await getEnabledAiModelsWithProvider();
|
||
const qwenModel = allModels.find(
|
||
(m) => m.provider.type === "alibaba" && m.model.supportsVision
|
||
);
|
||
|
||
// 如果没有可用的分析模型,使用回退逻辑
|
||
if (!qwenModel) {
|
||
console.log("[Smart Analyzer] No Qwen3 VL model found, using fallback");
|
||
return fallbackKeywordAnalysis(text, hasImage);
|
||
}
|
||
|
||
try {
|
||
const model = await getLanguageModelById(qwenModel.model.id);
|
||
if (!model) {
|
||
return fallbackKeywordAnalysis(text, hasImage);
|
||
}
|
||
|
||
// 构建用户消息
|
||
const userMessage = hasImage
|
||
? `用户上传了图片,请求内容:"${text}"`
|
||
: `用户请求(无图片):"${text}"`;
|
||
|
||
console.log("[Smart Analyzer] Analyzing with Qwen3 VL:", userMessage);
|
||
|
||
// 调用模型分析
|
||
const { text: responseText } = await generateText({
|
||
model,
|
||
system: ANALYZER_SYSTEM_PROMPT,
|
||
prompt: userMessage,
|
||
temperature: 0.1, // 低温度保证稳定输出
|
||
maxTokens: 500,
|
||
});
|
||
|
||
// 解析JSON响应
|
||
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
||
if (jsonMatch) {
|
||
const result = JSON.parse(jsonMatch[0]) as AnalysisResult;
|
||
console.log("[Smart Analyzer] Analysis result:", result);
|
||
return result;
|
||
}
|
||
} catch (error) {
|
||
console.error("[Smart Analyzer] Error:", error);
|
||
}
|
||
|
||
// 出错时使用回退逻辑
|
||
return fallbackKeywordAnalysis(text, hasImage);
|
||
}
|
||
|
||
/**
|
||
* 回退方案:关键词匹配
|
||
*/
|
||
function fallbackKeywordAnalysis(
|
||
text: string,
|
||
hasImage: boolean
|
||
): AnalysisResult {
|
||
const lowerText = text.toLowerCase();
|
||
|
||
// 图片编辑关键词检测
|
||
if (hasImage) {
|
||
// 抠图/去背景
|
||
if (/抠图|去背景|透明背景|去背|扣图/.test(lowerText)) {
|
||
return {
|
||
intent: "image_edit",
|
||
subIntent: "remove_background",
|
||
confidence: 0.9,
|
||
};
|
||
}
|
||
|
||
// 换背景
|
||
if (/换背景|白底|改背景|背景换成|纯色背景/.test(lowerText)) {
|
||
return {
|
||
intent: "image_edit",
|
||
subIntent: "replace_background",
|
||
confidence: 0.9,
|
||
};
|
||
}
|
||
|
||
// 图片增强
|
||
if (/变清晰|高清|锐化|降噪|提升质量|修复/.test(lowerText)) {
|
||
return {
|
||
intent: "image_edit",
|
||
subIntent: "enhance",
|
||
confidence: 0.9,
|
||
};
|
||
}
|
||
|
||
// 图像拓展
|
||
if (/扩展|拓展|延伸|扩图/.test(lowerText)) {
|
||
return {
|
||
intent: "image_edit",
|
||
subIntent: "extend",
|
||
confidence: 0.9,
|
||
};
|
||
}
|
||
|
||
// 局部修改
|
||
if (/去除|消除|擦掉|P掉|修改.*部分/.test(lowerText)) {
|
||
return {
|
||
intent: "image_edit",
|
||
subIntent: "inpaint",
|
||
confidence: 0.9,
|
||
};
|
||
}
|
||
|
||
// 风格迁移
|
||
if (/风格|卡通化|动漫风|油画风/.test(lowerText)) {
|
||
return {
|
||
intent: "image_edit",
|
||
subIntent: "style_transfer",
|
||
confidence: 0.9,
|
||
};
|
||
}
|
||
|
||
// 视觉理解
|
||
if (/看|识别|分析|描述|这是什么|有什么/.test(lowerText)) {
|
||
return { intent: "vision", confidence: 0.8 };
|
||
}
|
||
|
||
// 有图但意图不明确
|
||
return {
|
||
intent: "image_edit",
|
||
confidence: 0.5,
|
||
needsClarification: true,
|
||
clarifyingQuestions: [
|
||
"您想对这张图片做什么处理?(抠图/换背景/变清晰/其他)",
|
||
],
|
||
};
|
||
}
|
||
|
||
// 无图情况
|
||
if (/画|绘制|生成图|创建.*图/.test(lowerText)) {
|
||
return { intent: "image_gen", confidence: 0.8 };
|
||
}
|
||
|
||
if (/视频|动画|动起来/.test(lowerText)) {
|
||
return { intent: "video_gen", confidence: 0.8 };
|
||
}
|
||
|
||
// 默认对话
|
||
return { intent: "chat", confidence: 0.7 };
|
||
}
|
||
|
||
export { fallbackKeywordAnalysis };
|
||
```
|
||
|
||
### 3.2 创建 `lib/ai/prompt-optimizer.ts`
|
||
|
||
```typescript
|
||
/**
|
||
* 提示词优化器
|
||
* 将用户简单输入转换为专业的图片编辑提示词
|
||
*/
|
||
|
||
// 优化结果类型
|
||
export interface OptimizeResult {
|
||
originalPrompt: string;
|
||
optimizedPrompt: string;
|
||
negativePrompt: string;
|
||
}
|
||
|
||
// 图片编辑子意图的提示词模板
|
||
const EDIT_TEMPLATES: Record<
|
||
string,
|
||
{
|
||
template: string;
|
||
negative: string;
|
||
extractors: Record<string, RegExp>;
|
||
}
|
||
> = {
|
||
remove_background: {
|
||
template:
|
||
"去除图片背景,保留主体完整,输出透明背景PNG格式,边缘处理平滑自然,保留细节(如发丝、毛发)",
|
||
negative: "残留背景,毛边,边缘模糊,主体不完整,锯齿",
|
||
extractors: {},
|
||
},
|
||
|
||
replace_background: {
|
||
template:
|
||
"将图片背景替换为{background},保持主体完整清晰,光影自然协调,边缘过渡平滑,保留主体阴影",
|
||
negative: "残留原背景,边缘不自然,光影不协调,透视错误,主体变形",
|
||
extractors: {
|
||
background: /(?:换成|改成|替换为|变成|换为)(.+?)(?:背景|底|$)/,
|
||
},
|
||
},
|
||
|
||
enhance: {
|
||
template:
|
||
"提升图片整体清晰度和质量,保持自然色彩不失真,去除噪点,增强细节,适度锐化",
|
||
negative: "过度锐化,色彩失真,噪点增加,伪影,画质下降",
|
||
extractors: {},
|
||
},
|
||
|
||
extend: {
|
||
template:
|
||
"向{direction}方向扩展图片{amount},保持原有风格和色调一致,光影过渡自然,无明显接缝",
|
||
negative: "风格不一致,明显接缝,透视错误,内容突变",
|
||
extractors: {
|
||
direction: /向?(上|下|左|右|四周)/,
|
||
amount: /(\d+%?)/,
|
||
},
|
||
},
|
||
|
||
inpaint: {
|
||
template:
|
||
"去除/修改图片中的{target},用周围环境自然填充,保持整体风格一致,无修复痕迹",
|
||
negative: "明显修复痕迹,风格不一致,内容错误,边缘不自然",
|
||
extractors: {
|
||
target: /(?:去除|消除|擦掉|删除|P掉)(.+?)(?:,|。|$)/,
|
||
},
|
||
},
|
||
|
||
style_transfer: {
|
||
template:
|
||
"将图片转换为{style}风格,保持主体可识别性,色彩风格协调,整体效果自然",
|
||
negative: "主体变形,特征丢失,风格不统一,色彩异常",
|
||
extractors: {
|
||
style: /(?:转换为|变成|改成)(.+?)(?:风格|$)/,
|
||
},
|
||
},
|
||
|
||
resize: {
|
||
template: "调整图片尺寸为{size},保持画质清晰,比例协调",
|
||
negative: "画质损失,比例失调,模糊",
|
||
extractors: {
|
||
size: /(\d+[x×]\d+|\d+%)/,
|
||
},
|
||
},
|
||
|
||
color_adjust: {
|
||
template: "调整图片{adjustment},保持自然效果,色彩协调",
|
||
negative: "色彩失真,过度调整,不自然",
|
||
extractors: {
|
||
adjustment: /(?:调整|增加|减少|提高|降低)(.+?)(?:,|。|$)/,
|
||
},
|
||
},
|
||
};
|
||
|
||
/**
|
||
* 优化提示词
|
||
*/
|
||
export function optimizePrompt(params: {
|
||
originalPrompt: string;
|
||
intent: string;
|
||
subIntent?: string;
|
||
}): OptimizeResult {
|
||
const { originalPrompt, intent, subIntent } = params;
|
||
|
||
// 只对图片编辑类意图进行优化
|
||
if (intent !== "image_edit" || !subIntent) {
|
||
return {
|
||
originalPrompt,
|
||
optimizedPrompt: originalPrompt,
|
||
negativePrompt: "模糊,低质量,变形,水印",
|
||
};
|
||
}
|
||
|
||
const template = EDIT_TEMPLATES[subIntent];
|
||
if (!template) {
|
||
return {
|
||
originalPrompt,
|
||
optimizedPrompt: originalPrompt,
|
||
negativePrompt: "模糊,低质量,变形,水印",
|
||
};
|
||
}
|
||
|
||
// 使用模板生成优化后的提示词
|
||
let optimizedPrompt = template.template;
|
||
|
||
// 从用户输入中提取参数并填充模板
|
||
for (const [key, regex] of Object.entries(template.extractors)) {
|
||
const match = originalPrompt.match(regex);
|
||
const value = match ? match[1].trim() : getDefaultValue(key);
|
||
optimizedPrompt = optimizedPrompt.replace(`{${key}}`, value);
|
||
}
|
||
|
||
// 附加用户原始意图
|
||
optimizedPrompt = `${optimizedPrompt}。\n\n用户原始要求:${originalPrompt}`;
|
||
|
||
console.log("[Prompt Optimizer] Optimized:", {
|
||
original: originalPrompt,
|
||
optimized: optimizedPrompt,
|
||
negative: template.negative,
|
||
});
|
||
|
||
return {
|
||
originalPrompt,
|
||
optimizedPrompt,
|
||
negativePrompt: template.negative,
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 获取参数默认值
|
||
*/
|
||
function getDefaultValue(key: string): string {
|
||
const defaults: Record<string, string> = {
|
||
background: "纯白色",
|
||
direction: "四周",
|
||
amount: "50%",
|
||
target: "指定区域",
|
||
style: "卡通",
|
||
size: "原尺寸",
|
||
adjustment: "颜色",
|
||
};
|
||
return defaults[key] || "默认";
|
||
}
|
||
```
|
||
|
||
### 3.3 创建 `lib/ai/model-router.ts`
|
||
|
||
```typescript
|
||
/**
|
||
* 智能模型路由器
|
||
* 根据用户意图选择最佳模型
|
||
*/
|
||
|
||
import { getEnabledAiModelsWithProvider } from "@/lib/db/queries";
|
||
|
||
// 路由结果类型
|
||
export interface RouteResult {
|
||
id: string;
|
||
displayName: string;
|
||
providerType: string;
|
||
reason: string;
|
||
}
|
||
|
||
// 意图到模型的映射配置
|
||
const INTENT_MODEL_MAP: Record<
|
||
string,
|
||
{
|
||
providerTypes: string[];
|
||
requireVision?: boolean;
|
||
requireImageGen?: boolean;
|
||
}
|
||
> = {
|
||
// 图片编辑:优先 alibaba-image(灵魂4.5)
|
||
image_edit: {
|
||
providerTypes: ["alibaba-image", "gemini"],
|
||
requireVision: true,
|
||
requireImageGen: true,
|
||
},
|
||
|
||
// 视觉理解:优先千问3 VL(成本低效果好)
|
||
vision: {
|
||
providerTypes: ["alibaba", "gemini"],
|
||
requireVision: true,
|
||
},
|
||
|
||
// 图片生成
|
||
image_gen: {
|
||
providerTypes: ["alibaba-image", "gemini", "volcano-vision"],
|
||
requireImageGen: true,
|
||
},
|
||
|
||
// 视频生成
|
||
video_gen: {
|
||
providerTypes: ["volcano-video", "qianwen-video"],
|
||
},
|
||
|
||
// 普通对话
|
||
chat: {
|
||
providerTypes: ["alibaba", "openai"],
|
||
},
|
||
};
|
||
|
||
/**
|
||
* 路由到最佳模型
|
||
*/
|
||
export async function routeToModel(params: {
|
||
intent: string;
|
||
subIntent?: string;
|
||
hasImage: boolean;
|
||
}): Promise<RouteResult> {
|
||
const { intent, subIntent, hasImage } = params;
|
||
|
||
console.log("[Model Router] Routing for intent:", intent, subIntent);
|
||
|
||
// 获取所有可用模型
|
||
const allModels = await getEnabledAiModelsWithProvider();
|
||
|
||
// 获取意图对应的配置
|
||
const config = INTENT_MODEL_MAP[intent] || INTENT_MODEL_MAP["chat"];
|
||
|
||
// 按优先级查找匹配的模型
|
||
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,
|
||
reason: `${intent}${subIntent ? `/${subIntent}` : ""} → ${selected.model.displayName}`,
|
||
};
|
||
|
||
console.log("[Model Router] Selected:", result);
|
||
return result;
|
||
}
|
||
}
|
||
|
||
// 兜底:返回任意可用模型
|
||
const fallback =
|
||
allModels.find((m) => !m.model.isSubModel && m.model.isEnabled) ||
|
||
allModels[0];
|
||
|
||
console.log("[Model Router] Using fallback model:", fallback.model.displayName);
|
||
|
||
return {
|
||
id: fallback.model.id,
|
||
displayName: fallback.model.displayName,
|
||
providerType: fallback.provider.type,
|
||
reason: "fallback",
|
||
};
|
||
}
|
||
```
|
||
|
||
### 3.4 修改 `app/(chat)/api/chat/route.ts`
|
||
|
||
在现有的 Auto Mode 逻辑位置(约第 334-422 行),替换为以下代码:
|
||
|
||
```typescript
|
||
// ========== Smart Auto Mode Logic ==========
|
||
if (finalModelId === "auto") {
|
||
console.log("[Smart Auto Mode] Starting intelligent analysis...");
|
||
|
||
// 1. 提取用户消息内容
|
||
const lastUserMessage = message;
|
||
const textContent = lastUserMessage.parts
|
||
.filter((p) => p.type === "text")
|
||
.map((p) => (p as { type: "text"; text: string }).text)
|
||
.join(" ");
|
||
|
||
const hasImage = lastUserMessage.parts.some(
|
||
(p) => p.type === "file" || p.type === "image" || p.type === "image_url"
|
||
);
|
||
|
||
const imageUrls = lastUserMessage.parts
|
||
.filter((p): p is { type: "file"; url: string } => p.type === "file")
|
||
.map((p) => p.url);
|
||
|
||
// 2. 调用智能分析器
|
||
const { analyzeIntent } = await import("@/lib/ai/smart-analyzer");
|
||
const analysisResult = await analyzeIntent({
|
||
text: textContent,
|
||
hasImage,
|
||
imageUrls,
|
||
});
|
||
|
||
console.log("[Smart Auto Mode] Analysis result:", analysisResult);
|
||
|
||
// 3. 如果需要澄清,返回澄清问题(可选功能)
|
||
if (analysisResult.needsClarification && analysisResult.clarifyingQuestions) {
|
||
console.log("[Smart Auto Mode] Needs clarification, but proceeding with best guess...");
|
||
// 暂时不中断流程,继续使用最佳猜测
|
||
}
|
||
|
||
// 4. 如果是图片编辑类意图,优化提示词
|
||
if (analysisResult.intent === "image_edit" && analysisResult.subIntent) {
|
||
const { optimizePrompt } = await import("@/lib/ai/prompt-optimizer");
|
||
const optimizedResult = optimizePrompt({
|
||
originalPrompt: textContent,
|
||
intent: analysisResult.intent,
|
||
subIntent: analysisResult.subIntent,
|
||
});
|
||
|
||
console.log("[Smart Auto Mode] Prompt optimized");
|
||
|
||
// 替换消息中的文本为优化后的提示词
|
||
message.parts = message.parts.map((part) => {
|
||
if (part.type === "text") {
|
||
return {
|
||
...part,
|
||
text: optimizedResult.optimizedPrompt,
|
||
};
|
||
}
|
||
return part;
|
||
});
|
||
|
||
// 如果模型支持负面提示词,可以在 imageParams 中传递
|
||
// requestBody.imageParams = {
|
||
// ...requestBody.imageParams,
|
||
// negativePrompt: optimizedResult.negativePrompt,
|
||
// };
|
||
}
|
||
|
||
// 5. 路由到最佳模型
|
||
const { routeToModel } = await import("@/lib/ai/model-router");
|
||
const routeResult = await routeToModel({
|
||
intent: analysisResult.intent,
|
||
subIntent: analysisResult.subIntent,
|
||
hasImage,
|
||
});
|
||
|
||
finalModelId = routeResult.id;
|
||
console.log(`[Smart Auto Mode] ✅ Routed to: ${routeResult.displayName} (${routeResult.reason})`);
|
||
}
|
||
// ========== End Smart Auto Mode Logic ==========
|
||
```
|
||
|
||
---
|
||
|
||
## 四、测试场景
|
||
|
||
### 4.1 图片编辑场景测试
|
||
|
||
| 用户输入 | 预期意图 | 预期模型 |
|
||
|---------|---------|---------|
|
||
| [图片] + "帮我把背景换成白色" | replace_background | alibaba-image |
|
||
| [图片] + "抠图" | remove_background | alibaba-image |
|
||
| [图片] + "变清晰一点" | enhance | alibaba-image |
|
||
| [图片] + "把右边的人P掉" | inpaint | alibaba-image |
|
||
| [图片] + "转成卡通风格" | style_transfer | alibaba-image |
|
||
|
||
### 4.2 非编辑场景测试
|
||
|
||
| 用户输入 | 预期意图 | 预期模型 |
|
||
|---------|---------|---------|
|
||
| [图片] + "这是什么?" | vision | alibaba (Qwen3 VL) |
|
||
| "画一个可爱的猫" | image_gen | alibaba-image |
|
||
| "你好" | chat | alibaba (Qwen3 VL) |
|
||
|
||
---
|
||
|
||
## 五、开发步骤
|
||
|
||
### Phase 1: 基础实现 (1-2天)
|
||
|
||
1. 创建 `lib/ai/smart-analyzer.ts` - 使用关键词匹配作为主逻辑
|
||
2. 创建 `lib/ai/prompt-optimizer.ts` - 实现模板化提示词优化
|
||
3. 创建 `lib/ai/model-router.ts` - 实现基于意图的模型路由
|
||
4. 修改 `app/(chat)/api/chat/route.ts` - 集成新模块
|
||
|
||
### Phase 2: 智能升级 (2-3天)
|
||
|
||
1. 在 `smart-analyzer.ts` 中集成 Qwen3 VL 进行意图分析
|
||
2. 测试各种边界情况
|
||
3. 优化提示词模板
|
||
|
||
### Phase 3: 反馈优化 (可选)
|
||
|
||
1. 添加用户反馈机制
|
||
2. 记录用户偏好
|
||
3. 持续优化模型路由策略
|
||
|
||
---
|
||
|
||
## 六、注意事项
|
||
|
||
1. **保持向后兼容**:如果智能分析失败,自动回退到关键词匹配
|
||
2. **性能考虑**:Qwen3 分析会增加约 1-2 秒延迟,考虑是否需要
|
||
3. **错误处理**:所有新模块都需要完善的 try-catch
|
||
4. **日志记录**:添加详细日志便于调试
|
||
|
||
---
|
||
|
||
## 七、文件结构
|
||
|
||
```
|
||
lib/
|
||
└── ai/
|
||
├── smart-analyzer.ts # 智能意图分析器
|
||
├── prompt-optimizer.ts # 提示词优化器
|
||
├── model-router.ts # 智能模型路由器
|
||
├── dynamic-provider.ts # 现有模型提供器
|
||
└── providers/ # 现有模型提供商
|
||
├── alibaba-image.ts
|
||
├── gemini-image.ts
|
||
└── ...
|
||
|
||
app/
|
||
└── (chat)/
|
||
└── api/
|
||
└── chat/
|
||
└── route.ts # 修改 Auto Mode 逻辑
|
||
```
|