新增: 工具失败连败升级与熔断停靠

- 同工具连败三级提示:再败软提示,三败强制换路并引导检索经验
- 连拦五次强制安全停靠,不给无视熔断的余地
- 连击按会话计数防参数抖动绕过,成功即清零
This commit is contained in:
lxy
2026-10-13 13:29:15 +08:00
parent 9142e30714
commit 8c4aa5dc5b
2 changed files with 184 additions and 10 deletions
+19 -1
View File
@@ -39,7 +39,7 @@ use df_storage::models::AiProviderRecord;
// ProviderAcquire 已随 stream_round 迁至 stream_relay.rs。
use crate::state::{AppState, LlmConcurrency};
use super::audit::{process_tool_calls, ToolExecPolicy};
use super::audit::{process_tool_calls, take_tool_fail_park, ToolExecPolicy};
use super::event_bus::emit_ai_chat_event;
// compress_via_llm 已随压缩逻辑迁至 context_lifecycle.rs(maybe_auto_compress 内调用)。
use super::conversation::{save_conversation, TokenAccumulator};
@@ -2417,6 +2417,24 @@ async fn process_round_tools(
return ToolsOutcome::Exit;
}
// B5d 工具连败熔断终局:同会话失败记忆拦截连击达阈且期间无成功 → 强制停靠。
// 拦截计数在 audit 层(execute_with_heartbeat)累积,停靠在 loop 层执行:guard 复位
// 与 emit_task_parked 正典序列只有本层触达,audit 层只判定不执行。停靠即终局,
// 不再给模型无视 blocked 提示继续重试的机会(实证:拦截后模型仍原样重试 10+ 次)。
if take_tool_fail_park(conv_id) {
tracing::warn!(
conv_id = %conv_id,
"[ai] 工具连续失败熔断:失败记忆拦截连击达阈,任务强制停靠"
);
guard.reset().await;
crate::commands::ai::emit_task_parked(
app_handle, conv_id,
"工具连续失败熔断(同一调用被失败记忆反复拦截仍重试),任务安全停靠;已完成进度已保存,调整思路后重发消息可继续",
"circuit_breaker",
);
return ToolsOutcome::Exit;
}
// AC-2 ①:单轮工具调用数超限 → 注入软提示(机制化,非静默,弱模型能感知)。
// 治单轮并行调用爆炸:LLM 看不到自己发了多少调用,必须在消息流里显式警告。
if is_tool_call_over_limit(round_tool_call_count) {