增强Agent真实分析对话并减少硬编码兜底
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-02-08 22:29:15 +08:00
parent e038ba3593
commit 023c2fb754
2 changed files with 77 additions and 31 deletions

View File

@ -696,11 +696,7 @@ export async function POST(request: Request) {
const needsRicherAutoReply =
isImageTask &&
!smartAutoNeedsClarification &&
(
!smartAutoFriendlyMessage ||
!smartAutoFriendlyMessage.includes("\n") ||
smartAutoFriendlyMessage.replace(/\s+/g, "").length < 20
);
!smartAutoFriendlyMessage;
if (needsRicherAutoReply) {
smartAutoFriendlyMessage = buildAutoModeFallbackMessage({

View File

@ -1,4 +1,5 @@
import { Annotation, StateGraph, START, END } from "@langchain/langgraph";
import { generateText } from "ai";
import type { AnalysisResult } from "@/lib/ai/smart-analyzer";
import type { RouteResult } from "@/lib/ai/model-router";
@ -47,38 +48,87 @@ function compactText(text: string, max = 48) {
function buildStrategicFriendlyMessage(
analysis: AnalysisResult,
state: AutoAgentStateType,
): string | null {
): Promise<string | null> {
const fallbackQuestion = analysis.clarifyingQuestions?.[0];
if (analysis.needsClarification) {
return analysis.conversationalReply || fallbackQuestion || "我先确认一下,你希望我优先调整哪一部分?";
return Promise.resolve(
analysis.conversationalReply || fallbackQuestion || "我先确认一下,你希望我优先调整哪一部分?"
);
}
if (analysis.intent === "image_gen") {
const demand = compactText(state.text);
return [
"收到,我来帮你走自动模式生成方案。",
`- 需求理解:${demand}`,
"- 执行策略:先锁定主体与场景,再控制风格/光影/构图,最后输出可继续迭代的版本。",
"- 继续优化:你可以直接说“保留A,改B”,我会按最新要求快速迭代。",
].join("\n");
}
return generateAgentConversation(analysis, state);
}
if (analysis.intent === "image_edit") {
const sourceHint = state.hasImage
? state.imageFromHistory
? "我会基于你上一轮图片继续编辑。"
: "我会基于你刚上传的图片编辑。"
: "我会先按当前上下文进行编辑。";
return [
"收到,我来帮你精准编辑这张图。",
`- 执行基准:${sourceHint}`,
"- 处理方式:只改你提到的目标区域,其他主体、构图与风格尽量保持不变。",
"- 交付方式:先出一版结果,你再告诉我细调方向(如颜色、材质、氛围、细节)。",
].join("\n");
}
async function generateAgentConversation(
analysis: AnalysisResult,
state: AutoAgentStateType
): Promise<string | null> {
try {
const { getEnabledAiModelsWithProvider } = await import("@/lib/db/queries");
const { getLanguageModelById } = await import("./dynamic-provider");
const allModels = await getEnabledAiModelsWithProvider();
return analysis.conversationalReply || null;
const candidateModel = state.hasImage
? allModels.find((m) => m.model.supportsVision && m.model.isEnabled)
: allModels.find((m) => m.model.isEnabled && !m.model.isSubModel);
if (!candidateModel) {
return analysis.conversationalReply || null;
}
const model = await getLanguageModelById(candidateModel.model.id);
if (!model) {
return analysis.conversationalReply || null;
}
const history = state.historyMessages
.slice(-6)
.map((msg) => `${msg.role === "user" ? "用户" : "助手"}: ${compactText(msg.content, 120)}`)
.join("\n");
const imageInfo = state.hasImage
? `用户本轮可用图片数量:${state.imageUrls.length || 1}。图片来源:${state.imageFromHistory ? "历史消息复用" : "本轮上传"}。`
: "用户本轮没有上传图片。";
const systemPrompt = `你是一个真实执行中的 AI 生图/修图 Agent。
请根据用户需求和分析结果,给出“正在执行前”的简短汇报。
要求:
1) 不要说“我无法看到图片”;按系统提供的信息做合理分析。
2) 必须看起来是本轮真实分析结果,避免空泛套话。
3) 不暴露内部实现、模型路由、算法细节。
4) 输出 4-7 行 Markdown,语气专业自然。
5) 如果是图像任务,包含以下小节标题:需求理解、分析结论、执行计划、交付说明。
6) 每一行尽量具体,不要重复。`;
const prompt = [
`【用户原始需求】${state.text || "(无文本)"}`,
`【意图分析】intent=${analysis.intent}; subIntent=${analysis.subIntent || "none"}; confidence=${analysis.confidence}`,
`【图片信息】${imageInfo}`,
state.context ? `【画布上下文】${compactText(state.context, 300)}` : "",
history ? `【最近对话】\n${history}` : "",
"请输出本轮执行前汇报:",
]
.filter(Boolean)
.join("\n\n");
const { text } = await generateText({
model,
system: systemPrompt,
prompt,
temperature: 0.35,
maxTokens: 420,
} as any);
const cleaned = text.trim();
if (cleaned.length < 10) {
return analysis.conversationalReply || null;
}
return cleaned;
} catch (error) {
return analysis.conversationalReply || null;
}
}
const analyzeNode = async (state: AutoAgentStateType) => {
@ -96,7 +146,7 @@ const analyzeNode = async (state: AutoAgentStateType) => {
? analysis.clarifyingQuestions?.[0]
: undefined;
const strategicMessage = buildStrategicFriendlyMessage(analysis, state);
const strategicMessage = await buildStrategicFriendlyMessage(analysis, state);
return {
analysis,