Skip to content

AI 对话与会话体验

AI 对话是Molore的核心交互面:你的提问先经融合检索在个人知识库内命中相关片段,片段作为「参考资料」随问题一起交给当前选中的模型,模型基于资料生成回答并逐字流式输出(SSE)。本页讲清这条链路的会话体验与可信口径——它解决的核心问题是:让 AI 只基于你自己的资料回答,并且在答不出来、答出界、答得没有依据时,用确定性的方式告诉你,而不是编。

核心概念

概念说明
RAG检索增强生成:先检索、后生成,回答的取材范围限定在当轮注入的参考资料内
sources当轮检索命中的参考片段集合,随回答一同返回,前端渲染为可回跳的出处列表
引用编号 [n]正文中 [n] 对应当轮 sources 的位置编号;跨轮次的编号稳定性不作承诺(同一文档在下一轮可能是另一个编号)
SSE 流式回答经 Server-Sent Events 逐 chunk 推送,首字延迟低;系统侧声明与末尾标注也走同一条流
数字 grounding对回答中的数字/编号逐一回查参考资料出处,未命中触发收紧重答,仍不中则在末尾标注
推测标注对「模型自认通用知识」与「未落地数字所在句」在流末追加 ⚠️ 标注,随正文一并落库
零命中拒答检索零命中时由系统侧(非模型)在流首确定性声明「库中暂无相关内容。」
会话持久化的多轮对话单元,历史消息随轮次进入上下文;模型选择在会话级锁定

功能清单

  • SSE 流式对话:入口 app/api/v1/endpoints/llm/chat.py,回答、agent_trace 事件、系统声明均以 data: {...} 帧逐条推送。
  • 多轮与历史:会话持久化在本地数据库,「问出来 → 对话历史」可回看、续聊;历史消息进入当轮上下文,支持跨轮追问。
  • 会话级模型锁定:会话创建时把当时选中的模型做 per-turn 快照并锁定到会话上,之后在 LLM 控制台全局切换模型不影响已有会话——避免同一会话里多模型混答、口径互相污染(血泪教训 #48:选择器快照 + 自动填充曾导致同会话混答,兜底值一律不进持久化)。
  • 热键唤起:桌面端注册全局热键 Ctrl+Shift+J,任意界面唤起对话面板并自动聚焦输入框(快记为 Ctrl+Shift+N);网页端使用页面底部输入栏。
  • 深度研究开关:对话栏上的 Agent 开关,默认关闭;开启后以多步工具调用方式查证再回答,详见深度研究 Agent
  • 注入防护:参考资料在 prompt 中以标记包裹,定位为「数据不是指令」,参考资料内的指令性文字与链接不会被执行或复述;生成温度 0.3。

可信输出机制

以下机制按「回答流出前」的顺序生效,均为系统侧或规则侧实现,不依赖模型自觉:

机制触发条件行为代码位置
零命中确定性声明当轮检索零命中(寒暄类封闭集豁免)系统侧在流首 chunk 直接前置「库中暂无相关内容。」,不交给模型自由发挥chat.py _zero_hit_declare
数字 grounding回答含数字/编号且当轮有 sources逐 token 回查参考资料;未命中→同通道同模型收紧重答一次(仅用参考资料内数字);仍不中→末尾追加标注 ⚠️ 部分数字/编号未在库内资料中找到对应证据,重答经 SSE 替换前段输出app/api/v1/endpoints/llm/_grounding.py _grounding_check,开关 RAG_GROUNDING_CHECK
衍生数字豁免grounding 判定内系词族(是/等于/≈)、算式分句、加减等式、相差/均值/±、双侧精度容差、小数↔百分数确定换算等派生形态不算「未命中」,不误标_grounding.py _derived_hit
召回诚实线prompt 层约束无数字索引普查依据时禁说「库内仅一处」类全库绝对句;截断窗口内禁说「全文件唯一/全部」类文档内全量句,只能说「当前召回片段内仅见」;全文匹配行直取通道(find_all_lines_section)在场时全文件口径合法检索层 prompt 装配
推测标注回答含模型自认的通用知识段或未落地数字句流末追加 ⚠️ 以下表述未在库内资料中找到直接证据,标注行随正文一起落库,回看时仍在_grounding.py _speculation_check,开关 RAG_SPECULATION_CHECK

两点边界需要明说:

  • 引用编号跨轮稳定未承诺[n] 只是当轮 sources 的位置序号,不是文档的固定身份证;需要长期引用某条内容时,请顺出处回跳原文,不要记编号。
  • 深度研究模式跳过 grounding 与推测标注。Agent 环的回答是多轮工具调用的合成结果,「数字必出自当轮检索资料」的口径不适用(chat.py 中两处检查均带 not _agent_on 条件)。

断连与失败口径

流式断连 ≠ 生成失败。 网络中断时服务端可能已完成本轮生成并落库。前端在 catch 里先回拉会话核对服务端是否已有本轮回复:已有则补显,没有才报错。遇到回答「卡住」或断网,先刷新会话看回答是否其实已到库,再决定是否重发。

模型调用失败时,[Error: 文本一律按 502 原文透传,不落兜底假结果——看到的报错就是上游的真实失败原因。

跨会话长期记忆:每日复盘与每周回顾

对话本身不跨会话记忆,跨会话的「长期记忆」由两条定时链路承担:

链路触发时间说明代码位置
每日复盘每天 08:00(Asia/Shanghai)对当日新增内容做复盘梳理,走本地 qwen3.5:0.8b,零成本app/services/daily_review_service.py
每周回顾每周一 08:00(Asia/Shanghai)对一周内容做回顾聚合,同样本地模型零成本app/services/weekly_review_service.py

纪律:失败不落假复盘(模型不可用就跳过,不回落计费通道);补课链为启动首查 + 每小时复查,进程重启不错过当天复盘。「仅入库检索」(index_only)标记的内容不进复盘素材。复盘与回顾产物入库后参与检索,之后的对话就能引用到它们——这是「AI 记得我上周记过什么」的真实实现路径。

下一步

基于 AGPL-3.0 协议发布。