优化: 弱模型工具行为治理(项目/任务清单补id + 缓存命中警告 + read_symbol 提示)
This commit is contained in:
@@ -67,7 +67,7 @@ pub(crate) use finalize::audit_finalize;
|
||||
// cache(audit/cache.rs):高危工具去重缓存 + 只读工具缓存。
|
||||
// 第三批从本文件抽离,行为零变更。
|
||||
mod cache;
|
||||
pub(super) use cache::{find_cached_readonly_result, pending_placeholder_for};
|
||||
pub(super) use cache::{cache_hit_warning, find_cached_readonly_result, pending_placeholder_for};
|
||||
|
||||
// data_change(audit/data_change.rs):AR-11 数据变更联动刷新。
|
||||
// 第四批从本文件抽离,行为零变更。pub(crate) use 保持 emit_data_changed 对 crate 内可见
|
||||
@@ -586,13 +586,17 @@ pub(crate) async fn process_tool_calls(
|
||||
let mut low_risk_uncached: Vec<(ToolCallDraft, serde_json::Value, RiskLevel)> = Vec::with_capacity(low_risk.len());
|
||||
for (draft, args, risk_level) in low_risk {
|
||||
let cached = find_cached_readonly_result(session_arc, conv_id, &audit_repo, &draft.name, &args).await;
|
||||
if let Some(cached_content) = cached {
|
||||
if let Some((cached_content, hit_count)) = cached {
|
||||
// 缓存命中:直接 push tool_result + 审计(decided_by=cache_hit 标记缓存来源),
|
||||
// 不走真执行 + 不重emit Started/Completed(避免误导前端工具又执行了一次)。
|
||||
// AC-1 根治:弱模型不知道结果来自缓存,仍死循环重调同参工具。此处给回填的
|
||||
// tool_result 前置「重复调用拦截」警告头(机制化提示,LLM 能看到 tool_result),
|
||||
// 命中次数递增威慑,告知勿再重复调用相同参数的工具。
|
||||
let warned_content = format!("{}{}", cache_hit_warning(&draft.name, hit_count), cached_content);
|
||||
// emit Completed 携带缓存结果供前端折叠卡片展示(与 find_cached_high_risk_result 一致)。
|
||||
let ev = AiChatEvent::AiToolCallCompleted {
|
||||
id: draft.id.clone(),
|
||||
result: serde_json::Value::String(cached_content.clone()),
|
||||
result: serde_json::Value::String(warned_content.clone()),
|
||||
conversation_id: Some(conv_id.to_string()),
|
||||
};
|
||||
let _ = app_handle.emit("ai-chat-event", ev.clone());
|
||||
@@ -600,18 +604,20 @@ pub(crate) async fn process_tool_calls(
|
||||
// 短 lock 段:push tool_result(纯写,无 await)
|
||||
{
|
||||
let mut session = session_arc.lock().await;
|
||||
session.conv(conv_id).messages.push(ChatMessage::tool_result(&draft.id, &cached_content));
|
||||
session.conv(conv_id).messages.push(ChatMessage::tool_result(&draft.id, &warned_content));
|
||||
}
|
||||
audit_tool_call(
|
||||
&audit_repo, conv_id, &draft.id, &draft.name, &draft.args,
|
||||
"completed", risk_level, Some(cached_content), Some("cache_hit"),
|
||||
"completed", risk_level, Some(warned_content), Some("cache_hit"),
|
||||
current_message_id,
|
||||
).await;
|
||||
tracing::info!(
|
||||
conv_id = %conv_id,
|
||||
tool = %draft.name,
|
||||
tc_id = %draft.id,
|
||||
"[ai] 只读工具缓存命中,跳过真执行(治 LLM 死循环重调)"
|
||||
hit_count,
|
||||
"[ai] 只读工具缓存命中(第 {} 次),已加警告头回填,跳过真执行(治 LLM 死循环重调)",
|
||||
hit_count
|
||||
);
|
||||
} else {
|
||||
low_risk_uncached.push((draft, args, risk_level));
|
||||
|
||||
Reference in New Issue
Block a user