增强上传图片视觉分析并输出真实Agent分析流程
This commit is contained in:
parent
023c2fb754
commit
955b577bc5
@ -92,15 +92,19 @@ async function generateAgentConversation(
|
||||
: "用户本轮没有上传图片。";
|
||||
|
||||
const systemPrompt = `你是一个真实执行中的 AI 生图/修图 Agent。
|
||||
请根据用户需求和分析结果,给出“正在执行前”的简短汇报。
|
||||
请根据用户需求和本轮输入图片,给出“执行前”的分析汇报。
|
||||
|
||||
要求:
|
||||
1) 不要说“我无法看到图片”;按系统提供的信息做合理分析。
|
||||
2) 必须看起来是本轮真实分析结果,避免空泛套话。
|
||||
1) 不要说“我看不到图片”或“无法访问图片”,必须基于给定图片做真实分析。
|
||||
2) 语气自然、专业,不要模板腔,不要空话。
|
||||
3) 不暴露内部实现、模型路由、算法细节。
|
||||
4) 输出 4-7 行 Markdown,语气专业自然。
|
||||
5) 如果是图像任务,包含以下小节标题:需求理解、分析结论、执行计划、交付说明。
|
||||
6) 每一行尽量具体,不要重复。`;
|
||||
4) 输出 Markdown,控制在 8-14 行。
|
||||
5) 有图片时,必须包含以下小节标题且按顺序输出:
|
||||
- 需求理解
|
||||
- 图片分析
|
||||
- 执行计划
|
||||
- 输出设置
|
||||
6) “图片分析”要结合每张参考图差异,给出风格/构图/材质/光影等具体观察。`;
|
||||
|
||||
const prompt = [
|
||||
`【用户原始需求】${state.text || "(无文本)"}`,
|
||||
@ -108,18 +112,43 @@ async function generateAgentConversation(
|
||||
`【图片信息】${imageInfo}`,
|
||||
state.context ? `【画布上下文】${compactText(state.context, 300)}` : "",
|
||||
history ? `【最近对话】\n${history}` : "",
|
||||
"请输出本轮执行前汇报:",
|
||||
state.hasImage
|
||||
? "请先做本轮图片分析,再输出执行前汇报。"
|
||||
: "请输出本轮执行前汇报。",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n");
|
||||
|
||||
const { text } = await generateText({
|
||||
model,
|
||||
system: systemPrompt,
|
||||
prompt,
|
||||
temperature: 0.35,
|
||||
maxTokens: 420,
|
||||
} as any);
|
||||
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,
|
||||
system: systemPrompt,
|
||||
prompt,
|
||||
temperature: 0.35,
|
||||
maxTokens: 420,
|
||||
};
|
||||
|
||||
const { text } = await generateText(requestPayload as any);
|
||||
|
||||
const cleaned = text.trim();
|
||||
if (cleaned.length < 10) {
|
||||
|
||||
@ -167,7 +167,7 @@ export async function analyzeIntent(params: {
|
||||
|
||||
// 尝试使用 Qwen3 VL 进行深度分析(传入历史对话)
|
||||
try {
|
||||
const llmResult = await analyzWithLLM(text, hasImage, historyMessages, context);
|
||||
const llmResult = await analyzWithLLM(text, hasImage, imageUrls, historyMessages, context);
|
||||
if (llmResult) {
|
||||
console.log("[Smart Analyzer] LLM analysis result:", llmResult);
|
||||
return llmResult;
|
||||
@ -201,6 +201,7 @@ function quickKeywordMatch(text: string, hasImage: boolean): AnalysisResult {
|
||||
async function analyzWithLLM(
|
||||
text: string,
|
||||
hasImage: boolean,
|
||||
imageUrls?: string[],
|
||||
historyMessages?: HistoryMessage[],
|
||||
context?: string
|
||||
): Promise<AnalysisResult | null> {
|
||||
@ -254,14 +255,37 @@ ${historyText}
|
||||
|
||||
console.log("[Smart Analyzer] Calling Qwen3 VL for analysis with", historyMessages?.length || 0, "history messages");
|
||||
|
||||
// 调用模型分析
|
||||
const { text: responseText } = await generateText({
|
||||
model,
|
||||
system: ANALYZER_SYSTEM_PROMPT,
|
||||
prompt: userMessage,
|
||||
temperature: 0.1,
|
||||
maxTokens: 300,
|
||||
} as any);
|
||||
const visionImages = (imageUrls || [])
|
||||
.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,
|
||||
system: ANALYZER_SYSTEM_PROMPT,
|
||||
prompt: userMessage,
|
||||
temperature: 0.1,
|
||||
maxTokens: 300,
|
||||
};
|
||||
|
||||
const { text: responseText } = await generateText(requestPayload as any);
|
||||
|
||||
// 解析JSON响应
|
||||
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user