fix: 记忆去重后强制终止循环 — 系统消息 + 缩减轮次 + 工具结果强调
问题: AI 看到 memory add 返回 duplicate 后仍继续循环调用
根因: 去重消息藏在 tool result JSON 里,AI 不读或不理解
修复 (三层防御):
1. handleObserving: 检测到 tool result 含 duplicate → 注入 system 级别终止消息
+ 缩减剩余轮次到当前+2,强制即将结束
2. formatToolResultForModel: memory 去重时返回纯文本警告而非 JSON
'⚠️ 重复添加...不要再调用 memory 工具,直接输出最终回答'
3. addEntry: 检测到重复 → 抛 DuplicateEntryError(之前已修)
This commit is contained in:
@@ -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<string, unknown> = {};
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user