增强上传图片视觉分析并输出真实Agent分析流程

This commit is contained in:
Your Name 2026-02-08 22:35:11 +08:00
parent 023c2fb754
commit 955b577bc5
2 changed files with 76 additions and 23 deletions

View File

@ -92,15 +92,19 @@ async function generateAgentConversation(
: "用户本轮没有上传图片。"; : "用户本轮没有上传图片。";
const systemPrompt = `你是一个真实执行中的 AI 生图/修图 Agent。 const systemPrompt = `你是一个真实执行中的 AI 生图/修图 Agent。
请根据用户需求和分析结果,给出“正在执行前”的简短汇报。 请根据用户需求和本轮输入图片,给出“执行前”的分析汇报。
要求: 要求:
1) 不要说“我无法看到图片”;按系统提供的信息做合理分析。 1) 不要说“我看不到图片”或“无法访问图片”,必须基于给定图片做真实分析。
2) 必须看起来是本轮真实分析结果,避免空泛套话。 2) 语气自然、专业,不要模板腔,不要空话。
3) 不暴露内部实现、模型路由、算法细节。 3) 不暴露内部实现、模型路由、算法细节。
4) 输出 4-7 行 Markdown,语气专业自然。 4) 输出 Markdown,控制在 8-14 行。
5) 如果是图像任务,包含以下小节标题:需求理解、分析结论、执行计划、交付说明。 5) 有图片时,必须包含以下小节标题且按顺序输出:
6) 每一行尽量具体,不要重复。`; - 需求理解
- 图片分析
- 执行计划
- 输出设置
6) “图片分析”要结合每张参考图差异,给出风格/构图/材质/光影等具体观察。`;
const prompt = [ const prompt = [
`【用户原始需求】${state.text || "(无文本)"}`, `【用户原始需求】${state.text || "(无文本)"}`,
@ -108,18 +112,43 @@ async function generateAgentConversation(
`【图片信息】${imageInfo}`, `【图片信息】${imageInfo}`,
state.context ? `【画布上下文】${compactText(state.context, 300)}` : "", state.context ? `【画布上下文】${compactText(state.context, 300)}` : "",
history ? `【最近对话】\n${history}` : "", history ? `【最近对话】\n${history}` : "",
"请输出本轮执行前汇报:", state.hasImage
? "请先做本轮图片分析,再输出执行前汇报。"
: "请输出本轮执行前汇报。",
] ]
.filter(Boolean) .filter(Boolean)
.join("\n\n"); .join("\n\n");
const { text } = await generateText({ const imageInputs = state.imageUrls
.filter((url) => /^https?:\/\//i.test(url))
.slice(0, 4)
.map((url) => ({ type: "image" as const, image: url }));
const requestPayload = state.hasImage && imageInputs.length > 0
? {
model,
system: systemPrompt,
messages: [
{
role: "user" as const,
content: [
{ type: "text" as const, text: prompt },
...imageInputs,
],
},
],
temperature: 0.35,
maxTokens: 520,
}
: {
model, model,
system: systemPrompt, system: systemPrompt,
prompt, prompt,
temperature: 0.35, temperature: 0.35,
maxTokens: 420, maxTokens: 420,
} as any); };
const { text } = await generateText(requestPayload as any);
const cleaned = text.trim(); const cleaned = text.trim();
if (cleaned.length < 10) { if (cleaned.length < 10) {

View File

@ -167,7 +167,7 @@ export async function analyzeIntent(params: {
// 尝试使用 Qwen3 VL 进行深度分析(传入历史对话) // 尝试使用 Qwen3 VL 进行深度分析(传入历史对话)
try { try {
const llmResult = await analyzWithLLM(text, hasImage, historyMessages, context); const llmResult = await analyzWithLLM(text, hasImage, imageUrls, historyMessages, context);
if (llmResult) { if (llmResult) {
console.log("[Smart Analyzer] LLM analysis result:", llmResult); console.log("[Smart Analyzer] LLM analysis result:", llmResult);
return llmResult; return llmResult;
@ -201,6 +201,7 @@ function quickKeywordMatch(text: string, hasImage: boolean): AnalysisResult {
async function analyzWithLLM( async function analyzWithLLM(
text: string, text: string,
hasImage: boolean, hasImage: boolean,
imageUrls?: string[],
historyMessages?: HistoryMessage[], historyMessages?: HistoryMessage[],
context?: string context?: string
): Promise<AnalysisResult | null> { ): Promise<AnalysisResult | null> {
@ -254,14 +255,37 @@ ${historyText}
console.log("[Smart Analyzer] Calling Qwen3 VL for analysis with", historyMessages?.length || 0, "history messages"); console.log("[Smart Analyzer] Calling Qwen3 VL for analysis with", historyMessages?.length || 0, "history messages");
// 调用模型分析 const visionImages = (imageUrls || [])
const { text: responseText } = await generateText({ .filter((url) => /^https?:\/\//i.test(url))
.slice(0, 4)
.map((url) => ({ type: "image" as const, image: url }));
// 调用模型分析(有图时携带图片,确保真实视觉分析)
const requestPayload = hasImage && visionImages.length > 0
? {
model,
system: ANALYZER_SYSTEM_PROMPT,
messages: [
{
role: "user" as const,
content: [
{ type: "text" as const, text: userMessage },
...visionImages,
],
},
],
temperature: 0.1,
maxTokens: 360,
}
: {
model, model,
system: ANALYZER_SYSTEM_PROMPT, system: ANALYZER_SYSTEM_PROMPT,
prompt: userMessage, prompt: userMessage,
temperature: 0.1, temperature: 0.1,
maxTokens: 300, maxTokens: 300,
} as any); };
const { text: responseText } = await generateText(requestPayload as any);
// 解析JSON响应 // 解析JSON响应
const jsonMatch = responseText.match(/\{[\s\S]*\}/); const jsonMatch = responseText.match(/\{[\s\S]*\}/);