From 04a065981316d1563509bcf25adcdad81ae86d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B4=AB=E5=BD=B1233?= Date: Wed, 24 Jun 2026 15:46:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AE=B0=E5=BF=86=E5=8E=BB=E9=87=8D?= =?UTF-8?q?=E5=90=8E=E5=BC=BA=E5=88=B6=E7=BB=88=E6=AD=A2=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=20=E2=80=94=20=E7=B3=BB=E7=BB=9F=E6=B6=88=E6=81=AF=20+=20?= =?UTF-8?q?=E7=BC=A9=E5=87=8F=E8=BD=AE=E6=AC=A1=20+=20=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E5=BC=BA=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: AI 看到 memory add 返回 duplicate 后仍继续循环调用 根因: 去重消息藏在 tool result JSON 里,AI 不读或不理解 修复 (三层防御): 1. handleObserving: 检测到 tool result 含 duplicate → 注入 system 级别终止消息 + 缩减剩余轮次到当前+2,强制即将结束 2. formatToolResultForModel: memory 去重时返回纯文本警告而非 JSON '⚠️ 重复添加...不要再调用 memory 工具,直接输出最终回答' 3. addEntry: 检测到重复 → 抛 DuplicateEntryError(之前已修) --- src/renderer/services/agent-engine.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/renderer/services/agent-engine.ts b/src/renderer/services/agent-engine.ts index b3672a3..0a97524 100644 --- a/src/renderer/services/agent-engine.ts +++ b/src/renderer/services/agent-engine.ts @@ -331,6 +331,13 @@ function formatToolResultForModel(toolName: string, result: ToolResult): string }); } + case 'memory': { + if ((result as any).duplicate) { + return `⚠️ 重复添加: ${(result as any).message || '相同内容已存在'}\n✅ 记忆操作已全部完成,不要再调用 memory 工具,直接输出最终回答。`; + } + return JSON.stringify({ success: true, action: result.action, type: (result as any).type, content: (result as any).content }); + } + default: { const clean: Record = {}; for (const [k, v] of Object.entries(result)) { @@ -1482,6 +1489,21 @@ async function handleObserving( logInfo('进度锚点已注入', `第 ${ctx.loopCount} 轮, ${recentRecords.length} 条记录`); } + // ── 记忆去重检测 — 如果上一轮 memory add 返回了去重信号,强制终止循环 ── + const lastToolMsgs = ctx.messages.filter(m => m.role === 'tool').slice(-3); + for (const tm of lastToolMsgs) { + if (tm.content?.includes('"duplicate":true') || tm.content?.includes('duplicate')) { + ctx.messages.push({ + role: 'system', + content: '✅ 去重检测:你的记忆操作已经全部完成(系统检测到重复添加,说明信息已存在)。还有未完成的操作请直接完成,不要再调用 memory 工具。如果全部操作已完成,立即给出最终回答。', + }); + logInfo('记忆去重检测: 检测到重复添加,注入终止信号'); + // 缩减剩余轮次到当前+1,强制即将结束 + ctx.maxLoops = Math.min(ctx.maxLoops, ctx.loopCount + 2); + break; + } + } + // ── 中途幻觉检测 — 每轮检查模型是否在无工具调用时声称完成了操作 ── const lastAssistantMsg = [...ctx.messages].reverse().find(m => m.role === 'assistant'); if (lastAssistantMsg?.content) {