Files
DevFlow/docs/02-架构设计/专项设计/AI对话目标丢失诊断-2026-06-26.md
绝尘 4b754fe230 更新: 目标丢失诊断报告 G1/G2/G4 实施状态(commit 8ce18cb)
§五方向建议核对:G1 目标钉扎 / G2 探索熔断 / G4 话题标记修正 已实施,
G3 状态机收敛(文档衔接),G5 排查结论(历史脏数据,数据治理项不改代码)。
诊断→实施闭环标注。todo DAG + 待决策.md 状态核对一致(本 session 16 提交全景已同步)。
2026-06-27 00:56:55 +08:00

109 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 对话「目标丢失 / 意图丢失」诊断报告
> 日期2026-06-26
> 触发AI Chat 使用中,用户发送 Bug / 分析需求目标后,分析过程中目标丢失,系统不知道做什么、完全跑偏。
> 方法:直读对话数据库(`AppData/Roaming/top.1216.devflow/devflow-dev.db`)实测会话 + 源码机制走查。
> 性质:基于代码 + 数据库实证的机制级诊断(非模型分析猜测)。
---
## 一、现场铁证(会话 `54c8b5bd`
| 指标 | 实测值 | 含义 |
|---|---|---|
| `prompt_tokens` | **4,809,714**(约 480 万) | 远超 GLM 1M 窗口,反复触发压缩 / 裁剪 |
| 消息数 | 308 条 | 长 ReAct 链,工具结果堆积 |
| 原始目标 `[seq5]` | `分析一下 灵感模块 存在的不足 [项目: DevFlow]``status=compressed` | **目标消息已被踢出 LLM 上下文**`sanitize_messages` step0 过滤 `is_active` |
| 话题标记 `[seq0]` | `task → project`active | 系统判定「当前 project 话题」,但真实目标是 idea 域(灵感模块) |
| 尾部 `[seq287307]` | 连续 10+ 次 `search_files`,关键词 `auto-execute-mode / auto_execute / 全部接管 / autoExecute / execute-mode / execute_mode / auto-exec / 接管 / df-ai-auto`**全部 `total:0` 空结果** | 失去目标后的游荡死循环 |
**结论**原始目标是「分析灵感模块存在的不足」LLM 最终在反复搜索「自动执行模式 / 全部接管」——与目标毫无关系。目标彻底丢失。
---
## 二、根因(机制级)
### 根因 1上下文爆炸 → 目标消息物理出局(核心)
- `df-ai/src/context.rs``sanitize_messages` step0 按 `is_active()` 过滤发送视图。目标 user 消息被 F-15 压缩标 `status=compressed` 后,**不再进入 LLM 上下文**。
- 目标仅靠**压缩摘要 system 消息**「续命」。`prompt.rs::compress_prompt` 四段式(意图 / 决策 / 文件 / 约束)+ 主题词锚点保留——但摘要是 **LLM 二次生成,信息降级严重**。「分析灵感模块不足」这类具体目标,在数次压缩后语义稀释到无法指导后续动作。
- 480 万 token 的会话,目标消息经历多轮压缩,保真度无法保证。
### 根因 2话题切换标记误判反向强化错误方向
- `agentic/mod.rs:735-772``pending_topic_marker` 基于末两条 user 消息的 `IntentRecognizer` 关键词推断(双高置信 ≥0.7 才标),`insert_at(0)` 软提示 system「请以新话题为准」。
- 失效点:
- 长链里 user 消息早被压缩出局topic 推断基于**已失真历史**。
- 本例最后 active 标记是 `task→project`,与真实目标(灵感模块 / idea 域)**背离**——软提示反而告诉 LLM「现在是 project 话题」,帮倒忙。
- marker 只在 push **user 消息**时检测,工具轮次间不参与。
### 根因 3单链 ReAct无目标重锚定架构本质
- `df-ai/src/coordinator.rs`**纯空壳 TODO**B 路线占位,`AgentCoordinator::run` 直接返 `"TODO: Agent 协作结果"`)。
- `df-ai/src/planner.rs`Plan DAG + Kahn 分层 + validate 齐全,但文件头明确「纯函数零 IO 零状态」「不接入 agentic loop待 Phase B+C」。`PLANNING_ENABLED=true` 只门控**工具排序**`filter_tool_defs_planned`**不做多步规划执行**。
- agentic loop 每轮只在 push 新 user 消息时检测话题切换,**工具轮次间不重申目标**。没有「当前目标 + 进度」结构化状态LLM 每轮自行决定下一步,长链必然游荡(`[seq287307]` 实证)。
### 根因 4无探索熔断
- `[seq287307]` 连续 10+ 次空结果不中断。系统不跟踪「已搜过什么 / 连续 N 次无进展」LLM 无限换关键词。
- 这是目标丢失的**放大器**:不知道目标 → 不知道该停 → 无限游荡token 失控480 万)。
### 根因 5system prompt「聚焦准则」是文字说教非机制
- `prompt.rs:104-108` 有「聚焦准则:始终围绕用户当前请求的核心目标」——纯 prompt 文字,靠 LLM 自觉。
- 目标一旦从上下文(消息流)消失,文字准则**无锚点可抓**。没有「每轮把目标钉在 system 顶部」的机制。
---
## 三、为什么现有设计压不住
| 现有机制 | 性质 | 为什么压不住 |
|---|---|---|
| 压缩摘要F-15 | **被动**信息降级 | 摘要保真靠 LLM多轮压缩后目标语义稀释 |
| 话题切换标记 | 软提示 + 关键词推断 | 基于失真历史,本例反向误导 |
| 聚焦准则 prompt | 文字说教 | 目标消息出局后无锚点 |
| `insert_at(0)` system 锚点 | 多个堆首位 | 话题标记 + 压缩摘要 + 关键词兜底三个锚点互相稀释 |
三个 `insert_at(0)`(话题标记 `agentic/mod.rs:762`、压缩摘要 `:918`、关键词兜底 `:969`)堆在首位,互相稀释,没有一个是「权威目标」。
---
## 四、关联现状
- 当前分支 `conv-state-convergence` + `agentic/conv_state.rs`452 行状态机)已在尝试收敛对话状态,**但目标作为一等状态尚未固化进状态机**——这是未完成的工作。
- memory `devflow-aichat-session-analysis-2026-06-22` 已标的「最高杠杆 P0-2 编排规划能力弱」即此问题的上层概括。本报告是其**数据库实证版**。
---
## 五、方向建议G1/G2/G4 已实施 commit 8ce18cb2026-06-26
最高杠杆:**把「用户当前目标」从消息流提升为一等结构化状态**。
1. **目标钉扎** ✅ G1 已实施8ce18cb首轮提取用户目标为 `PerConvState.pinned_goal`run_agentic_loop 入口拼进 system_promptloop 不变量,免疫 F-15 压缩 / build_eviction_units 裁剪 / sanitize step0 is_active 过滤)。目标消息压缩出局后,结构化目标仍在。
2. **探索熔断** ✅ G2 已实施8ce18cb连续 N 次空结果无进展 → 两段式警示 + AiHelpRequired 熔断,防游荡死循环 + token 失控(实测 seq287-307 连续 10+ 次盲搜死循环的场景)。
3. **状态机收敛** — G3 文档衔接conv_state.rs / mod.rs 注释pinned_goal 内容态与 ConvState 生命周期态正交,不进 enum
4. **话题标记修正** ✅ G4 已实施8ce18cbTOPIC_MARKER_GOAL_AWARE guardpinned_goal 存在时 take 后丢弃跳过 topic marker insert消除 seq0 task→project 与真实 idea 目标背离的反向误导)。
附 G5 排查结论seq1/seq4 system 异常消息是会话早期**旧版本遗留脏数据**thinking 独白 + tool_result 被错存 system早期 timestamp非当前 compress 机制问题(摘要四段式正常),最新 systemseq0 topic marker正常。**数据治理项,不改代码**。
---
## 附:待查 Bug
- `[seq1]` 一条 LLM 内部独白("等等,`process_tool_calls` 是从 `super::audit` 导入的。让我检查一下…")被存为 `system` 消息(`status=active`)。疑似 reasoning / 思考内容泄漏进 system 消息(`stream_recv` 归位问题),进一步污染上下文。待独立排查。
---
## 证据定位(源码)
| 机制 | 位置 |
|---|---|
| 上下文压缩 / sanitize / topic 字段 | `crates/df-ai/src/context.rs` |
| 话题切换 marker 消费 | `src-tauri/src/commands/ai/agentic/mod.rs:735-772` |
| 压缩 insert_at 摘要 | `src-tauri/src/commands/ai/agentic/mod.rs:820, 918, 969` |
| 多 Agent 协调(空壳) | `crates/df-ai/src/coordinator.rs` |
| Plan 规划(未接入 loop | `crates/df-ai/src/planner.rs` |
| 意图识别(关键词) | `crates/df-ai/src/intent.rs` |
| system prompt 聚焦准则 / 压缩 prompt | `src-tauri/src/commands/ai/prompt.rs:104, 233` |
| 对话状态机(进行中) | `src-tauri/src/commands/ai/agentic/conv_state.rs` |