WorkingContext 写入链落地(用户轮目标钉扎+压缩后 JSON 卡片回填重锚定,含 6 单测); 工作流 DAG 摘要注入生产侧接通(AI 路径启动写入+终态回写,审批调用点透传会话)。 附知识库与记忆走查诊断(「笨/丢历史」根因:消息压缩视图丢失+知识检索四重收口), todo 登记修复分档(含随批补登 09-28 交互走查索引条目)。
6.8 KiB
aichat 知识库与记忆能力走查 — 用户反馈「笨/丢历史会话」根因诊断
日期: 2026-09-29 | 触发: 用户反馈「明显感觉丢历史会话特别严重」「感觉很笨」 方法: 双代理只读走查(知识库链路/记忆四层) + 运行时 DB 实证(devflow.db 副本只读查询) 结论处置: 会话内上下文生产侧已修复(同日实施,见文末);跨会话召回/知识检索收口登记待办
一、DB 实证(核心证据)
数据源: %APPDATA%/top.1216.devflow/devflow.db 副本(104MB,82 会话/10647 消息)。
| 指标 | 数值 | 含义 |
|---|---|---|
| compressed 消息占比 | 4758/10647 (44.7%) | 压缩是常态而非例外 |
| user 消息被压缩 | 363/892 (41%) | 四成用户请求模型看不到 |
| 最大会话 5fea6024 | 828 条消息,模型可见仅 44 条 (5%) | 26 条用户消息 0 条可见 |
| user 可见率最差大会话 Top4 | 0b0a46e5: 0/6 · 5c3bc8a0: 0/8 · 5fea6024: 0/26 · f64dee94: 0/39 | 「我说过的话他全忘了」属实 |
| compressed 原文保留 | 363 条全部非空 | 存储没丢,丢的是发送视图 |
| 四段式压缩摘要落库 | 仅 1 条 | 大量压缩走关键词兜底/旧格式,摘要质量无保障 |
定性: 丢历史会话 = 机制性视图丢失(DB 单向 compressed 标记永不回 LLM 上下文),不是存储损坏。压缩触发阈值 0.6×可用预算,长会话大半历史必然出局;摘要 ≤1024 token 替代全部被压缩内容,且 user 原话不保证进摘要。
二、知识库链路: 四重收口(管道铺好,水龙头拧死)
代码事实(走查证据,均为当前 HEAD 实核):
- 整句 LIKE 检索(最致命): 检索 query=末条用户消息全文,
idea_repo.rs:640-661用%整句%做 LIKE——知识标题是短语,整句子串匹配命中率≈0。自动注入即使有已发布知识也几乎空转。 - candidate↔published 断链: 自动提炼(
knowledge_inject.rs:441+)与 MCPinsert_knowledge产物全是status='candidate';检索只认'published'(idea_repo.rs:651)。不手动去 /knowledge 页发布,沉淀的知识(现库 962 条!)永不进对话。reuse_count排序形同虚设。 - 语义检索默认关:
vector_enabled=false(knowledge_config.rs:58),需手配 embedding provider;默认纯 LIKE,中文同义表达必漏。 - LLM 零知识工具:
tool_registry.rs73 个工具无任何 knowledge 注册;9eb2995 的 search/insert_knowledge 挂在 df-mcp(127.0.0.1:18765)只服务外部 MCP 客户端,ai-chat 自己的 agentic loop 不接。「记住这个」只会落进对话文本,会话结束即散。
次要: 注入剂量 top-3×500 字符;source_project 存而不用于检索过滤;提炼只看最后 6 条消息且每会话仅 1 次。
知识维度总评: 管道全部 wired(auto_inject 默认开),但四重收口使普通对话实际获得知识的概率趋近于零。
三、记忆能力分层盘点
| 层 | 现状 | 判定 |
|---|---|---|
| L1 轮内 | 全量历史进请求,预算≈102k token,namespace 大结果引用化 | ✅ wired |
| L2 跨轮 | 两道丢失闸门: ①单向压缩(保护最近 6 条,其余换 ≤1024 token 摘要,不可逆);②超预算视图裁剪无摘要补偿(只保最近 6 条) | ⚠️ 半残 |
| L3 跨会话 | 零召回: 新会话全空,无全局摘要/项目记忆/跨会话检索,完全隔离 | ❌ 空壳 |
| L4 跨重启 | 恢复消息(compressed 仍是压缩态)+pinned_goals;不恢复: working_context/namespace_store(重启清空)/agent_language/session_trust | ⚠️ 半残 |
空壳机制(有代码无调用方/断链):
- MemoryAdapter(
df-ai/src/memory_adapter.rs): 语义记忆 trait,全仓零调用方,注释中的 VectorMemoryAdapter 不存在。 - Persona 人设(5 内置人设+prompt 模板): 唯一实例化点在两个默认关闭的实验门内,不进正常对话链路,无持久化。
- 跨会话记忆: 无任何机制——这是「丢历史会话」主观感受的最大来源(与 DB 实证互为表里: 同会话压缩出局 + 跨会话零召回 + 重启再丢一层)。
- DB 落库截断: >8192 字符的 user/assistant 文本落库截为 前3072+后3072+省略标记(
conversation.rs:101-119)——重启后连原文都只剩骨架。
四、本次已修(同日实施批,已过编译门禁)
「上下文管理演进」07-20 设计中 T4/T5 的生产侧空壳补齐(消费侧早已落地但无数据源):
- T5 WorkingContext 写方法(df-ai/context_helpers.rs):
begin_turn(新用户轮目标钉扎)+sync_after_compress(压缩后从 T3 JSON 卡片回填决策+重锚定)+reset_all实现,6 个新单测全绿。 - T5 接线:
chat.rs:651/1978用户消息入库点 begin_turn;context_lifecycle.rs:278压缩成功分支 sync_after_compress(TODO 清零)。效果: 压缩不再裸丢目标/决策,下轮 system prompt 重锚定。 - T4 生产侧:
workflow.rs::run_workflow_inner增加 conv_id 参数,AI 路径启动写workflow_id+workflow_dag_summary,终态回写完成/失败摘要;chat.rs:896/1278审批调用点透传。休眠链路闭环。
门禁: cargo check --workspace 0 错误;cargo test -p df-ai 494 过/4 挂(4 挂均在 anthropic_compat/model_fetch_helpers,本批零触碰的存量失败,见待办)。
边界说明: 本批只解「会话内压缩后目标/决策丢失」一块。跨会话零召回、知识四重收口、重启失忆均未动,登记待办。
五、待办分档(修复方向,未实施)
P0(直接治「笨」):
- 知识检索去整句 LIKE: 分词/抽关键词后多条件 OR,或默认开语义检索(补 embedding 配置引导)。改动点
idea_repo.rs:640-661+knowledge_inject.rs:364-384。 - candidate 断链打通: 自动提炼产物到阈值 confidence/reuse 自动晋升 published(或检索纳入高置信 candidate),人工审核保留为可选。
- 视图裁剪补摘要: 超预算淘汰单元被丢弃时生成滚动补偿摘要(现在无声丢失)。
P1:
4. LLM 知识工具: tool_registry 注册 search_knowledge/insert_knowledge(复用 df-mcp 实现),让 agent 能按需查/存。
5. 跨会话召回最小闭环: 项目级记忆条目(知识表已有 source_project 字段)+会话结束时提炼进知识库(现有 auto_extract 扩为跨会话通道)。
6. 存量测试修复: anthropic_compat::anthropic_full_stream_accumulates_usage(assert usage.is_none() 失败)+model_fetch_helpers::non_chat_sensenova_u1_image_filtered 等 4 个,疑似 6bafdcd 流式 usage 语义变更后未同步测试。
P2: 7. DB 截断放宽/取消(user 原话平均 41 字,3072 截断对 user 无必要,主要风险在工具结果;可分 role 定阈值)。 8. namespace 持久化或重建(DB 原文在,重启可懒重建,免「已超出内存上限」占位)。 9. 兜底压缩路径接 sync_after_compress("")(当前取舍: 不接,防丢决策态;待版本计数漂移观察后复议)。