fix: 复用现有 Qwen VL 模型调用方式

This commit is contained in:
Your Name 2026-02-02 12:06:57 +08:00
parent 3558eed251
commit f7debfb55f

View File

@ -1,6 +1,7 @@
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { db } from "@/lib/db"; import { generateText } from "ai";
import { aiProvider } from "@/lib/db/schema"; import { getEnabledAiModelsWithProvider } from "@/lib/db/queries";
import { getLanguageModelById } from "@/lib/ai/dynamic-provider";
export const runtime = "nodejs"; export const runtime = "nodejs";
export const maxDuration = 30; export const maxDuration = 30;
@ -13,7 +14,7 @@ const POSITION_OPTIONS = [
] as const; ] as const;
interface PickObjectRequest { interface PickObjectRequest {
imageUrl: string; // 图片 URL(不再使用 Base64) imageUrl: string; // 图片 URL
clickX: number; // 点击位置 X (0-1) clickX: number; // 点击位置 X (0-1)
clickY: number; // 点击位置 Y (0-1) clickY: number; // 点击位置 Y (0-1)
} }
@ -52,17 +53,28 @@ export async function POST(request: Request) {
}, { status: 400 }); }, { status: 400 });
} }
// 获取 Qwen-VL 配置 - 使用原生 SQL 查询 // 获取 Qwen VL 模型(复用现有逻辑)
const providers = await db.select().from(aiProvider); const allModels = await getEnabledAiModelsWithProvider();
const qwenProvider = providers.find(p => p.providerId === 'qwen'); const qwenModel = allModels.find(
(m) => m.provider.type === "alibaba" && m.model.supportsVision
);
console.log('[PickObject] 找到 providers:', providers.length, '个'); if (!qwenModel) {
console.log('[PickObject] Qwen provider:', qwenProvider ? '已找到' : '未找到'); console.log("[PickObject] No Qwen VL model found");
if (!qwenProvider || !qwenProvider.isEnabled || !qwenProvider.apiKey) {
return NextResponse.json({ return NextResponse.json({
success: false, success: false,
error: 'Qwen 服务未配置或未启用', error: 'Qwen VL 模型未配置',
}, { status: 500 });
}
console.log('[PickObject] 使用模型:', qwenModel.model.modelId, qwenModel.model.displayName);
const model = await getLanguageModelById(qwenModel.model.id);
if (!model) {
console.log("[PickObject] Failed to get language model");
return NextResponse.json({
success: false,
error: '无法加载模型',
}, { status: 500 }); }, { status: 500 });
} }
@ -89,56 +101,33 @@ ${POSITION_OPTIONS.join('、')}
【boundingBox】相对坐标 0-1,精确到小数点后2位 【boundingBox】相对坐标 0-1,精确到小数点后2位
`.trim(); `.trim();
const apiUrl = `${qwenProvider.apiBaseUrl || 'https://dashscope.aliyuncs.com/compatible-mode/v1'}/chat/completions`; console.log('[PickObject] 调用 Qwen VL 模型...');
console.log('[PickObject] 调用 Qwen API:', apiUrl);
// 调用 Qwen-VL API(使用图片 URL) // 调用 Qwen VL 模型(复用现有的 generateText)
const response = await fetch(apiUrl, { const { text: responseText } = await generateText({
method: 'POST', model,
headers: { messages: [
'Content-Type': 'application/json', {
'Authorization': `Bearer ${qwenProvider.apiKey}`, role: 'user',
}, content: [
body: JSON.stringify({ {
model: 'qwen-vl-max', type: 'image',
messages: [ image: imageUrl, // 直接使用图片 URL
{ },
role: 'user', {
content: [ type: 'text',
{ text: prompt,
type: 'image_url', },
image_url: { ],
url: imageUrl, // 直接使用图片 URL },
}, ],
}, temperature: 0.1,
{ maxTokens: 300,
type: 'text', } as any);
text: prompt,
},
],
},
],
max_tokens: 200,
}),
});
console.log('[PickObject] Qwen API 响应状态:', response.status); console.log('[PickObject] Qwen 返回内容:', responseText?.substring(0, 200));
if (!response.ok) { if (!responseText) {
const errorText = await response.text();
console.error('[PickObject] Qwen API error:', errorText);
return NextResponse.json({
success: false,
error: `AI 识别服务错误: ${response.status}`,
}, { status: 500 });
}
const data = await response.json();
const content = data.choices?.[0]?.message?.content;
console.log('[PickObject] Qwen 返回内容:', content?.substring(0, 200));
if (!content) {
return NextResponse.json({ return NextResponse.json({
success: false, success: false,
error: 'AI 未返回结果', error: 'AI 未返回结果',
@ -149,7 +138,7 @@ ${POSITION_OPTIONS.join('、')}
let result: PickObjectResult; let result: PickObjectResult;
try { try {
// 尝试从返回内容中提取 JSON // 尝试从返回内容中提取 JSON
const jsonMatch = content.match(/\{[\s\S]*\}/); const jsonMatch = responseText.match(/\{[\s\S]*\}/);
if (!jsonMatch) { if (!jsonMatch) {
throw new Error('未找到 JSON'); throw new Error('未找到 JSON');
} }
@ -190,7 +179,7 @@ ${POSITION_OPTIONS.join('、')}
} }
} catch (parseError) { } catch (parseError) {
console.error('[PickObject] JSON parse error:', parseError, 'Content:', content); console.error('[PickObject] JSON parse error:', parseError, 'Content:', responseText);
// 返回默认结果 // 返回默认结果
const posX = clickX < 0.33 ? '左' : clickX > 0.66 ? '右' : '中央'; const posX = clickX < 0.33 ? '左' : clickX > 0.66 ? '右' : '中央';