修复: 三元组相邻性归位保住工具轮
- df-ai sanitize 新增 step 0.5 reorder_interlopers_after_tool_run: 楔入 head 与 tool 响应间的异类消息(压缩摘要/用户插话/警示)移到该组响应之后,只重排不删内容,工具轮不再被剥除 - 幂等;仅处理单头+夹层+紧随连续 tool 段,其余畸形仍走剥除兜底 - 单测: 旧剥除用例改为归位保轮 + 新增幂等用例;cargo test -p df-ai --lib context 156 passed - 实证更正: 2026-08-04 报告「实证4」被推翻——已定位原始会话 b4d6b4e0,首轮裸问候即发两个 tool_calls;同步更新看板 909 状态
This commit is contained in:
@@ -16,6 +16,15 @@
|
||||
|
||||
> 注:用户贴的"你好"会话原始调用(`"project_id":"DevFlow"` + `pattern:"scan"`)在三个库中均**未检索到**,
|
||||
> 疑未落库或已清理。但同类行为在库中有大量实证,结论不依赖该单例。
|
||||
>
|
||||
> **✅ 2026-10-10 定位恢复(推翻上文"未检索到")**:该会话已实证定位——`devflow-dev.db` 会话
|
||||
> `b4d6b4e0-6901-4937-af47-d3202678406b`(标题「打招呼」,模型 `sensenova-6.7-flash-lite`,创建
|
||||
> 2026-08-04 04:00:46 UTC)。`ai_conversations.messages` blob 恰为该轮:`[user] "你好"` +
|
||||
> `[assistant] 空文本 + tool_calls=[list_project_modules, search_files]`;`ai_tool_executions`
|
||||
> 两行逐字对上截图(`{"project_id": "DevFlow"}`→`{"modules":[],"project_id":"DevFlow","total":0}`;
|
||||
> `{"pattern":"scan","path":"E:/wk-lab/devflow/src-tauri","recursive":true}`→`{"has_more":false,...,"total":0}`),
|
||||
> tool_call_id 为弱模型特征 `gen_stream_4`/`gen_stream_23`,message_id `msg_1785816059122_5`。
|
||||
> 原检索为空的可能原因:该轮未落 `ai_messages`(该会话 ai_messages 最早为 2026-08-06),仅存于 blob+executions 表。
|
||||
|
||||
## 实证 1:重复探索是系统性现象(非偶发)
|
||||
|
||||
@@ -50,6 +59,12 @@
|
||||
## 实证 4:问候本身不触发工具,但弱模型任务中失控
|
||||
|
||||
- 修正:纯"你好"第一轮模型会正常回复能力介绍(09e7abfa/1982ff08 均如此),**0 例**"问候后紧邻调工具"
|
||||
|
||||
> **⚠️ 2026-10-10 更正(实证推翻本条)**:会话 `b4d6b4e0`(标题「打招呼」)的**首轮**即是裸问候
|
||||
> 「你好」→ assistant **空文本 + 直接发 2 个 tool_calls**,无任何前置上下文。故"问候本身不触发工具"
|
||||
> 不成立——至少对 `sensenova-6.7-flash-lite` 存在**首轮问候即开工具**的实例。原"0 例"结论源于当时未
|
||||
> 检索到该会话(其轮次未落 ai_messages),属样本缺失导致的误判。据此,「工具全量暴露 + 弱模型自控弱」
|
||||
> 的诱因比原判更严重:**无需任务上下文,裸问候即可触发工具探索**。
|
||||
- 用户贴的"你好犯傻"更可能是:会话有历史上下文(scan/工程模块任务残留),模型把"你好"当继续信号,或 system prompt 全量 55 工具 + "优先使用工具"引导诱使弱模型"准备上下文"
|
||||
- 一旦进入实质任务,弱模型即进入重复探索/绕行/参数错误循环
|
||||
|
||||
|
||||
+1
-1
@@ -843,4 +843,4 @@ graph TD
|
||||
909. [~] **907 源头守静 + 无损归位(夹层根治)**(2026-10-10 devflow 接手登记,源自 907 补注遗留):现 907 修复走「未邻接即剥除」——保证不 400 但有损(夹层场景丢一轮工具交互)。
|
||||
- ✅ **① 源头守静(2026-10-10 实施完成,避让插入变体)**:df-ai 新增 `ContextManager::push_system_anchor`(context/mod.rs)——末条为悬空 `ToolCallHead` 时将 system 锚点插在**该头之前**(index=len-1),否则常规尾部追加;私有判定 `ends_with_dangling_tool_call_head`(`group==ToolCallHead`)。比原设计「推迟 push」更优:摘要/警示**不丢**,且楔入根本不产生。5 处尾部 push 全量收口(压缩成功 context_lifecycle:269 / 兜底 keyword_fallback_commit:372 / 警示 insert_system_notice helpers:44 / 主题标记 agentic/mod:1804 / 续轮 nudge :2399)。单测 `push_system_anchor_appends_on_normal_tail` + `push_system_anchor_avoids_dangling_tool_call_head` 锁定。验收:`cargo test -p df-ai --lib context` **155 passed/0 failed**;`cargo check -p devflow` EXIT 0。
|
||||
- [ ] **①-补 双取锁合并未做**:压缩失败路径 `set_compressing(false)` 与兜底提交仍两次取锁(context_lifecycle:312→:322),并发二次压缩窗口未消(低风险,留后续)。
|
||||
- [ ] **② 无损归位未做**:将 sanitize 的「剥除」升级为设计 ① 的「相邻性归位」(head 与响应间楔入的异类消息移到该组响应之后,只重排不删内容)+ 幂等单测——对**用户插话型夹层**(源头无法消除,纠偏 16 场景)是唯一无损解。落点:`src-tauri/src/commands/ai/agentic/context_lifecycle.rs:269`(LLM 成功 push)/`:372`(兜底 push)/`:312`→`:322`(双取锁)。验收:构造楔入序列断言输出合规且 head 后紧随其响应、幂等;插话场景工具结果不丢。
|
||||
- ✅ **② 无损归位(2026-10-10 实施完成)**:`crates/df-ai/src/context/sanitize.rs` 新增 step 0.5 `reorder_interlopers_after_tool_run`——楔入 assistant 头与其 tool 响应之间的异类消息(压缩摘要/用户插话/警示 system)**整体移到该组响应之后**(只重排不删内容),归位后 step1 邻接判定即认闭合,工具轮**不再被剥除**;仅对「单头 + 夹层 + 紧随该头的连续 tool 段」生效,遇下一个 tool_call 头即停(不跨单元),其余畸形仍走剥除兜底。幂等。单测替换旧剥除用例为 `sanitize_reorders_interloper_to_keep_tool_round` + 新增 `sanitize_reorder_is_idempotent`。验收:`cargo test -p df-ai --lib context` **156 passed/0 failed**。
|
||||
|
||||
Reference in New Issue
Block a user