From a049db066eaa857c597f82f11cb18d584bd5d369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B4=AB=E5=BD=B1233?= Date: Wed, 24 Jun 2026 16:20:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=87=8D=E5=A4=8D=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E5=BC=BA=E5=8C=96=20=E2=80=94=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=BB=93=E6=9E=9C=E5=90=AB=E5=8E=BB=E9=87=8D=E6=96=87?= =?UTF-8?q?=E5=AD=97=E7=AB=8B=E5=8D=B3=E8=A7=A6=E5=8F=91=20+=20=E9=98=88?= =?UTF-8?q?=E5=80=BC=203=E2=86=922?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前: 仅检查同工具连续成功 ≥3 次,且只数 success 次数 现在: 1. 工具结果文本含「⚠️ 重复添加」「已跳过」「duplicate」→ 立即触发 2. 同工具连续成功 ≥2 次 → 也触发 3. 注入 ⛔ system 消息 + 缩减剩余轮次到当前+1 --- src/renderer/services/agent-engine.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/renderer/services/agent-engine.ts b/src/renderer/services/agent-engine.ts index 9f9f92c..2eff11f 100644 --- a/src/renderer/services/agent-engine.ts +++ b/src/renderer/services/agent-engine.ts @@ -1489,18 +1489,19 @@ async function handleObserving( logInfo('进度锚点已注入', `第 ${ctx.loopCount} 轮, ${recentRecords.length} 条记录`); } - // ── 通用「同工具重复成功」检测 — 任何工具连续成功多次后自动提醒停止 ── - const recentSuccess = ctx.allToolRecords.filter(r => r.status === 'success').slice(-3); - if (recentSuccess.length >= 3) { - const allSameTool = recentSuccess.every(r => r.name === recentSuccess[0].name); - if (allSameTool) { - ctx.messages.push({ - role: 'system', - content: `⚠️ 你已连续 ${recentSuccess.length} 次调用「${recentSuccess[0].name}」工具且全部成功。如果任务已完成,直接输出最终回答,不要再重复调用。`, - }); - logInfo(`同工具重复检测: ${recentSuccess[0].name} ×${recentSuccess.length},注入终止信号`); - ctx.maxLoops = Math.min(ctx.maxLoops, ctx.loopCount + 2); - } + // ── 通用重复调用检测:工具结果含去重信号 或 同工具连续成功 2+ 次 ── + const lastToolContents = ctx.messages.filter(m => m.role === 'tool').slice(-3).map(m => m.content || ''); + const hasDedupSignal = lastToolContents.some(c => c.includes('⚠️ 重复添加') || c.includes('已跳过') || c.includes('duplicate')); + const recentSuccess = ctx.allToolRecords.filter(r => r.status === 'success').slice(-2); + const allSameTool = recentSuccess.length >= 2 && recentSuccess.every(r => r.name === recentSuccess[0].name); + if (hasDedupSignal || allSameTool) { + ctx.messages.push({ + role: 'system', + content: `⛔ 检测到重复的工具调用${hasDedupSignal ? '(系统已跳过重复内容)' : ''}。「${recentSuccess[0]?.name || 'memory'}」操作已经完成,立即输出最终回答,绝对不要再调用任何工具。`, + }); + logInfo(`重复调用检测: ${recentSuccess[0]?.name || 'memory'}${hasDedupSignal ? ' (去重信号)' : ''},注入⛔终止信号`); + ctx.maxLoops = Math.min(ctx.maxLoops, ctx.loopCount + 1); + // 不要 transition 到 REFLECTING,直接在这里就已经注入了信号,下一轮 THINKING 会看到 } // ── 中途幻觉检测 — 每轮检查模型是否在无工具调用时声称完成了操作 ──