优化: 弱模型治理收尾(AC-2探索预算:单轮上限+目录去重+禁绕行 + AC-5失败画像:合法目标回灌+相近锚点提示)
This commit is contained in:
@@ -219,6 +219,14 @@ pub const STALL_BREAKER_GOAL_REMIND: bool = true;
|
||||
/// 「最小样本 6」+「单点 3 次」阈值有意义,又不至于扫太长历史稀释近期漂移信号。
|
||||
pub const STALL_BREAKER_SAMPLE_SIZE: usize = 12;
|
||||
|
||||
/// AC-2 ①:单轮工具调用数上限(默认 8)。
|
||||
///
|
||||
/// 治弱模型单轮一次性发超多工具调用(实证 09e7abfa:同一目录列 3 次 + run_command 绕行,
|
||||
/// 单轮十几个 grep/read 并行爆炸)。LLM 看不到"自己本轮发了多少调用",必须在消息流里
|
||||
/// 显式警告才能感知(机制优先 prompt 说教)。超限即 insert 一条 system 软提示到
|
||||
/// conv.messages(非静默),下轮 build_for_request 时 LLM 可见,促其聚焦关键操作。
|
||||
pub const MAX_TOOL_CALLS_PER_ROUND: usize = 8;
|
||||
|
||||
/// L1 断路器:连续同类工具失败熔断阈值(治 kms 会话 53 轮 0 产出死循环)。
|
||||
///
|
||||
/// 背景:agent 无止损,某工具反复同类失败(权限拒绝/路径错误等)仍每轮重试,
|
||||
@@ -312,7 +320,7 @@ pub mod command_lock;
|
||||
pub(crate) mod helpers;
|
||||
pub(crate) use helpers::try_continue_agent_loop;
|
||||
pub(crate) use helpers::infer_goal_from_tool_calls;
|
||||
pub(crate) use helpers::{tool_call_signature, is_repetitive_exploration, is_pure_greeting};
|
||||
pub(crate) use helpers::{tool_call_signature, is_repetitive_exploration, is_pure_greeting, is_tool_call_over_limit};
|
||||
|
||||
// ============================================================
|
||||
// 单 Provider 流式结果 + fallback 辅助
|
||||
@@ -1887,6 +1895,8 @@ pub(crate) async fn run_agentic_loop(
|
||||
if !has_tool_calls { converged = true; break; }
|
||||
let _ = converged;
|
||||
|
||||
// AC-2 ①:记录本轮工具调用数(供超限警告判定;process_tool_calls 会 move 走 tool_calls_acc)。
|
||||
let round_tool_call_count = tool_calls_acc.len();
|
||||
// 处理工具调用(Low 自动执行 / Medium+High 待审批)
|
||||
let pending_count = process_tool_calls(&session_arc, tool_calls_acc, &tools_arc, &db, &app_handle, &conv_id).await;
|
||||
// DIRAUTH 审批链已闭环。原 eprintln 诊断降级为 tracing::debug,
|
||||
@@ -1904,6 +1914,12 @@ pub(crate) async fn run_agentic_loop(
|
||||
return;
|
||||
}
|
||||
|
||||
// AC-2 ①:单轮工具调用数超限 → 注入软提示(机制化,非静默,弱模型能感知)。
|
||||
// 治单轮并行调用爆炸:LLM 看不到自己发了多少调用,必须在消息流里显式警告。
|
||||
if is_tool_call_over_limit(round_tool_call_count) {
|
||||
insert_tool_call_over_limit_warning(&session_arc, &conv_id, iteration, round_tool_call_count).await;
|
||||
}
|
||||
|
||||
// L1 断路器:连续同类工具失败熔断(治 agent 无止损死循环,机制非 prompt 说教)。
|
||||
// count_recent_failures 读末尾连续 Tool 消息,失败包按结构化信号归一 key 入滚动窗口计数。
|
||||
if CIRCUIT_BREAKER_ENABLED {
|
||||
@@ -2472,6 +2488,33 @@ async fn fetch_goal_summary(session_arc: &Arc<Mutex<AiSession>>, conv_id: &str)
|
||||
format!("(当前目标: {})", goal_summary)
|
||||
}
|
||||
|
||||
// ── insert_tool_call_over_limit_warning: AC-2 ① 单轮工具调用数超限软提示 ──
|
||||
// 机制化(非 prompt 说教):超限即 insert system 警告到 conv.messages 首位(对齐 G2
|
||||
// insert_stall_warning 模式),下轮 build_for_request 时 LLM 可见,促其聚焦关键操作。
|
||||
async fn insert_tool_call_over_limit_warning(
|
||||
session_arc: &Arc<Mutex<AiSession>>,
|
||||
conv_id: &str,
|
||||
iteration: usize,
|
||||
count: usize,
|
||||
) {
|
||||
let warn_text = format!(
|
||||
"⚠ 本轮工具调用达 {} 个,超过单轮上限 {} 个。请聚焦关键操作,减少并行调用,勿重复探索同一区域。",
|
||||
count, MAX_TOOL_CALLS_PER_ROUND
|
||||
);
|
||||
let mut session = session_arc.lock().await;
|
||||
if session.per_conv.contains_key(conv_id) {
|
||||
let conv = session.conv(conv_id);
|
||||
conv.messages.insert_at(0, ChatMessage::system(&warn_text));
|
||||
tracing::info!(
|
||||
conv_id = %conv_id,
|
||||
iteration,
|
||||
count,
|
||||
limit = MAX_TOOL_CALLS_PER_ROUND,
|
||||
"[ai] AC-2 单轮工具调用数超限:注入软提示"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── emit_fatal_error: 致命错误统一 emit AiError(扁平抽自原 Fatal/Exhausted 双分支重复代码) ──
|
||||
// emit+publish 双写 Tauri 事件总线。error_type=Network 对齐原 Fatal 分支(鉴权/4xx归类)。
|
||||
async fn emit_fatal_error(app_handle: &AppHandle, conv_id: &str, error: &str) {
|
||||
|
||||
Reference in New Issue
Block a user