You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
结构化会话存储 - 需求分析
1. 文档信息
| 项目 |
说明 |
| 功能名称 |
结构化会话存储(Structured Conversation Store) |
| 版本 |
3.0 |
| 适用范围 |
所有会话(不区分 Ask/Workflow) |
| 依赖 |
ChatSession、MainWindowViewModel、特殊消息类型(Form/ParameterSet/Table/ColumnMatch)、LLM 调用链 |
2. 背景与目标
2.1 背景
- 现状问题:当前以「LLM 用的 ChatHistory」为唯一事实来源。引入特殊消息(表单、参数集、表格、列匹配等)后,若把特殊消息编码进同一条 History(如 Content 前缀+YAML),会导致:
- 真相源混合了「该发给模型的对话」与「仅供 UI 展示的卡片」;
- 每次调用 LLM 前必须解析、过滤;加载会话时要从字符串反推卡片;
- 扩展新类型或改格式时,解析约定与两端逻辑都要一起改,维护成本高。
- 共识:应有一份独立的、全结构化的会话存储,作为 UI 与 Prompt 构建的共同真相源;LLM History 仅作为从该存储派生出的视图,不再承担「存储真相」的职责。
2.2 目标
- 结构化存储为唯一事实来源:引入一套会话级的结构化存储(以下简称「会话存储」或「Store」),其中每条记录均为结构化条目(文本消息 = 角色 + 文本;特殊消息 = 类型 + YAML 载荷)。该存储按时间顺序记录会话中发生的所有消息与卡片,不依赖 ChatHistory 的形态。
- UI 与 Prompt 均为视图:
- UI:从会话存储按序生成界面所需的列表(如
ChatMessages),文本即文本气泡,特殊消息即卡片(还原 SpecialContent)。
- Prompt 构建:从同一份会话存储生成「发给 LLM 的历史」——仅包含需参与对话的文本(及可选的简短占位),再转为后端所需的
ChatHistory。
二者均不直接依赖「混入特殊消息的 History」作为真相源。
- 可持久化、可恢复:会话存储可序列化(如 YAML/JSON)并持久化;加载会话时先恢复该存储,再据此构建 UI 与 Prompt,保证顺序与内容一致。
- 与 System/摘要解耦:不向 System 消息写入或追加摘要;不在 System 后固定插入观察摘要;不因 Ask 模式做上述注入。
3. 用户与利益相关方
| 角色 |
诉求 |
| 用户 |
切换会话或重新打开后,能看到完整对话流及曾出现的表单、参数卡、表格、列匹配等卡片,顺序与当时一致。 |
| 会话列表/详情 |
进入某会话时,从持久化/内存中的会话存储恢复,保证 UI 与行为一致。 |
| 开发/维护 |
真相源单一、结构清晰;扩展新消息类型仅改存储条目类型与两种视图逻辑,无需解析字符串约定。 |
4. 功能需求
4.1 会话存储的条目类型
- 文本消息:角色(User / Assistant / System)+ 文本内容。用于用户输入、助手回复及可选的 System 引导词。
- 特殊消息:类型(Form / ParameterSet / Table / ColumnMatch / WorkflowStatus 等)+ YAML 载荷(对 AI 更友好、可读性好)。载荷含 type、id 及类型专用字段,可序列化/反序列化,用于恢复 UI 卡片。
4.2 特殊消息类型与载荷内容(YAML)
| 类型 |
载荷需包含内容 |
恢复时说明 |
| Form |
formId、title、status、fields、submitLabel 等 |
恢复时可根据 formId 从 FormRegistry 取 FormDefinition,还原表单卡片及已填/已提交状态。 |
| ParameterSet |
title、items(name、valueText、description、fieldType、options 等) |
直接反序列化还原 ParameterSetMessage。 |
| Table |
title、columnNames、rows/totalRowCount/maxPreviewRows |
直接反序列化还原 TableDataMessage。 |
| ColumnMatch |
title、requiredColumns、previewColumns、mappings |
直接反序列化还原 ColumnMatchMessage。 |
| WorkflowStatus |
title、steps 等 |
可选,恢复为只读展示卡片。 |
4.3 顺序与唯一性
- 所有条目在存储中严格按发生顺序排列,形成一条时间线。
- 新增用户输入、助手回复、出现的卡片等,均追加到存储末尾,不修改已有条目(除业务上允许的「更新同一卡片」策略外,若需支持再单独约定)。
4.4 视图行为
- UI 视图:遍历会话存储,对每条条目——文本消息 → 生成对应
ChatMessageModel(User/AI + 文本);特殊消息 → 反序列化载荷为 ISpecialMessage,生成带 MessageType 与 SpecialContent 的 ChatMessageModel。结果用于填充 ChatMessages 等界面列表。
- Prompt 视图:遍历同一份会话存储,仅取「需要参与 LLM 对话」的条目(如 User、Assistant 文本);对特殊消息可跳过或替换为一句简短描述(如「[已展示表单:加载散点]」)。将结果转为
ChatHistory(或当前后端所需格式)供 AskAsync / AskStreamAsync 使用。不把原始 YAML 载荷发给模型。
4.5 持久化与加载
- 持久化:会话存储可序列化为 YAML 或 JSON(建议 YAML,对人与 AI 更友好),随会话一起持久化;若当前仅内存会话,则内存中的存储即为真相源。
- 加载:加载会话时先反序列化得到会话存储,再基于该存储构建 UI 视图与(在调用 LLM 时)Prompt 视图;不依赖「从 ChatHistory 反推卡片」。
5. 非功能需求
| 类型 |
要求 |
| 单一事实来源 |
UI 与 Prompt 仅从会话存储派生,不另设混合了编码约定的 History 作为真相源。 |
| 可序列化 |
存储及每条特殊消息载荷均有稳定、可逆的序列化格式(YAML),便于持久化与跨版本兼容。 |
| 顺序一致 |
存储中的顺序与用户看到的时间线一致;恢复后顺序不变。 |
| 可维护性 |
新增消息类型时,仅扩展存储条目类型与两种视图逻辑,无需改字符串解析约定。 |
6. 约束与假设
- 不注入 System:不在 System 消息内容中追加或合并摘要;System 后不再固定插入观察摘要 Assistant 消息。
- LLM History 非真相源:
ChatHistory 仅作为「调用 LLM 时由会话存储生成的视图」,不作为持久化或 UI 恢复的真相源。
- Form 恢复:特殊消息 Form 恢复时依赖 FormRegistry 提供 FormDefinition;若 formId 不存在可降级为占位或只读文本。
- 会话列表:「恢复卡片」指用户进入某会话时,从该会话的存储恢复 UI;若列表仅展示标题/摘要,不展开历史,则恢复发生在打开该会话时。
7. 验收标准(高层)
- 存在独立的会话存储,其中所有条目均为结构化(文本 = 角色+内容,特殊消息 = 类型+YAML 载荷);存储为 UI 与 Prompt 构建的唯一事实来源。
- 加载会话后,UI 仅从该会话的存储构建,能按序还原所有文本与卡片;调用 LLM 时使用的历史仅从同一份存储投影得到(仅文本或文本+短占位),且不包含原始 YAML 载荷。
- 持久化格式为会话存储的序列化形式(如 YAML 文档);不依赖「混入特殊消息的 ChatHistory」作为持久化真相源。