# 结构化会话存储 - 任务拆分
本文档拆分的任务均支持**标记成功/失败**:每项任务有明确的完成标准,满足即为成功,否则为失败。实施时可在「状态」列更新为:`待开始` | `进行中` | `成功` | `失败`。
---
## 状态约定
| 状态 | 含义 |
|------|------|
| 待开始 | 未开始 |
| 进行中 | 正在实现或验证 |
| 成功 | 完成标准已全部满足 |
| 失败 | 未满足完成标准或已放弃 |
---
## 任务列表
### T1. 定义会话存储模型与条目类型
| 项目 | 内容 |
|------|------|
| **依赖** | 无 |
| **描述** | 定义「会话存储」的抽象:条目列表,每条为 TextEntry(Role + Content)或 SpecialEntry(Type + YAML 载荷)。确定 C# 类型(如 ConversationEntry 基类/接口、TextConversationEntry、SpecialConversationEntry)或带 kind/type 判别的 DTO;文档化存储与 ChatSession 的归属关系(每会话一份存储)。 |
| **完成标准** | 1)设计文档或代码中已定义条目类型及存储结构。
2)约定存储由谁持有(如 ChatSession 或 ConversationStore)。
3)与现有 Role、特殊消息类型可对应。 |
| **状态** | 成功 |
---
### T2. 定义特殊消息 YAML 载荷约定
| 项目 | 内容 |
|------|------|
| **依赖** | 无 |
| **描述** | 为 Form / ParameterSet / Table / ColumnMatch(及可选 WorkflowStatus)定义 YAML 载荷的字段约定(type、id、类型专用字段),并文档化;与现有 ISpecialMessage 属性可互转。 |
| **完成标准** | 1)设计文档中已描述各类型 YAML 字段。
2)与 SpecialMessage 类型可序列化/反序列化对应。 |
| **状态** | 成功 |
---
### T3. 实现 SpecialMessage 序列化/反序列化(Utils)
| 项目 | 内容 |
|------|------|
| **依赖** | T2 |
| **描述** | 实现 `SpecialMessageSerializer`:ISpecialMessage → YAML 字符串;`SpecialMessageDeserializer`:type + YAML → ISpecialMessage(Form 需 IFormRegistry)。支持 Form、ParameterSet、Table、ColumnMatch(及可选 WorkflowStatus)。 |
| **完成标准** | 1)Serialize(ISpecialMessage) 与 Deserialize(type, yaml, formRegistry?) 存在且对上述类型正确。
2)Form 在 formId 缺失时有降级行为。
3)项目可编译通过,无新增 linter 报错。 |
| **状态** | 成功 |
---
### T4. 实现会话存储(ConversationStore)及与 ChatSession 集成
| 项目 | 内容 |
|------|------|
| **依赖** | T1 |
| **描述** | 实现会话存储:支持追加 TextEntry、SpecialEntry;持有有序条目列表。ChatSession 持有该存储(或存储即 ChatSession 内字段);提供 AppendText(role, content)、AppendSpecial(type, yamlPayload) 或等价 API。 |
| **完成标准** | 1)存储可追加文本与特殊消息,顺序与调用顺序一致。
2)ChatSession 能访问并写入该存储。
3)项目可编译通过,无新增 linter 报错。 |
| **状态** | 成功 |
---
### T5. 实现 Prompt 视图:从存储生成 ChatHistory(GetHistoryForLlm)
| 项目 | 内容 |
|------|------|
| **依赖** | T4 |
| **描述** | 实现从会话存储构建「发给 LLM 的历史」:遍历存储,TextEntry 转为 ChatMessageContent(Role, Content);SpecialEntry 跳过或替换为一句短文本;可选在头部插入 System(guidePrompt)。返回 ChatHistory,供 KernelService 使用。 |
| **完成标准** | 1)存在 GetHistoryForLlm(guidePrompt?) 或等价方法,返回 ChatHistory。
2)返回结果中不包含原始 YAML 载荷;仅含 User/Assistant 文本(及可选的短占位)。
3)项目可编译通过,无新增 linter 报错。 |
| **状态** | 成功 |
---
### T6. KernelService 使用 GetHistoryForLlm 而非 session.History
| 项目 | 内容 |
|------|------|
| **依赖** | T5 |
| **描述** | 修改 AskAsync / AskStreamAsync:调用 LLM 时传入「从会话存储生成的 ChatHistory」(如 session.GetHistoryForLlm(guidePrompt)),不再直接使用 session.History 作为请求体。 |
| **完成标准** | 1)发给 LLM 的请求使用由存储派生的 History。
2)对话语义与顺序正确;无原始 YAML 进入请求。
3)项目可编译通过,无新增 linter 报错。 |
| **状态** | 成功 |
---
### T7. 实现 UI 视图:从存储构建 ChatMessages(LoadMessagesFromStore)
| 项目 | 内容 |
|------|------|
| **依赖** | T3, T4 |
| **描述** | 实现从会话存储构建 UI 列表:遍历存储,TextEntry → ChatMessageModel(文本);SpecialEntry → 反序列化得 ISpecialMessage → ChatMessageModel(对应 MessageType, SpecialContent)。替换或重命名原 LoadMessagesFromSession,使加载会话时**仅从存储**构建 ChatMessages,不解析 History。 |
| **完成标准** | 1)加载会话后,ChatMessages 仅由会话存储构建,顺序与存储一致。
2)特殊消息正确还原为卡片(Form/ParameterSet/Table/ColumnMatch);反序列化失败有降级。
3)项目可编译通过,无新增 linter 报错。 |
| **状态** | 成功 |
---
### T8. ViewModel 写入会话存储(替代写入 History)
| 项目 | 内容 |
|------|------|
| **依赖** | T4, T3 |
| **描述** | 修改 MainWindowViewModel:用户发送消息、助手回复、出现表单/参数集/表格/列匹配时,**向会话存储追加**对应 TextEntry 或 SpecialEntry;不再向 ChatSession.History 追加「带前缀的 Assistant」。添加消息的入口(AddUserMessage/AddAssistantMessage/AddFormMessage/AddParameterSetMessage/SubmitForm 中 Table 等)均改为写存储。 |
| **完成标准** | 1)用户发送、助手回复后,存储中有对应 TextEntry。
2)AddFormMessage、AddParameterSetMessage、SubmitForm 中 Table 等后,存储中有对应 SpecialEntry,顺序正确。
3)不再向 History 追加特殊消息的编码字符串。
4)项目可编译通过,无新增 linter 报错。 |
| **状态** | 成功 |
---
### T9. 会话存储的持久化与加载(可选)
| 项目 | 内容 |
|------|------|
| **依赖** | T4, T2 |
| **描述** | 实现会话存储的序列化/反序列化(如 ToYaml/FromYaml 或 JSON):存储整体可持久化;加载会话时先反序列化得到存储,再据此构建 UI。若当前仅内存会话,可先实现内存结构,持久化格式约定好接口后再接存储。 |
| **完成标准** | 1)存储可序列化为 YAML 或 JSON,并可反序列化回内存结构。
2)加载会话时从持久化数据恢复存储,再通过 UI 视图构建 ChatMessages。
3)或明确标注「仅内存、持久化后续接」,接口已预留。 |
| **状态** | 成功 |
---
### T10. 简化 EnsureFormsYamlInSystem(与 System 的衔接)
| 项目 | 内容 |
|------|------|
| **依赖** | 无 |
| **描述** | 调整 EnsureFormsYamlInSystem:不再向 System 内容追加 formsYaml、不再在 System 后插入摘要。仅保留「在需要时提供 guidePrompt」的职责;实际 System 的插入可在 GetHistoryForLlm 中完成。若调用方仍传 formsYaml,可忽略或移除参数。 |
| **完成标准** | 1)不再向 System 或 History 写入摘要/表单 YAML 块。
2)GetHistoryForLlm 或等价路径中可插入一条 System(guidePrompt);或由调用方传入。
3)现有调用 EnsureFormsYamlInSystem 的代码可编译、运行(参数可精简)。 |
| **状态** | 成功 |
---
### T12. 集成/手工验证:存储为真相源、UI 与 Prompt 为视图
| 项目 | 内容 |
|------|------|
| **依赖** | T6, T7, T8(T9 若已做则含持久化) |
| **描述** | 端到端验证:新建会话 → 发送消息、添加表单/参数集、提交表单产生 Table → 检查会话存储中按序存在对应 TextEntry 与 SpecialEntry;切换会话再切回后,从存储恢复的 UI 显示所有文本与卡片、顺序正确;调用 LLM 时使用 GetHistoryForLlm,请求中无 YAML;若已实现持久化,重启或重新加载后存储恢复正确。 |
| **完成标准** | 1)会话存储为唯一事实来源;UI 与 Prompt 均从存储派生。
2)加载会话后卡片与顺序正确;LLM 请求不含原始 YAML。
3)不再存在「向 History 写入特殊消息编码」或「System 后固定摘要」的逻辑。 |
| **状态** | 进行中 |
---
## 任务依赖关系简图
```
T1 ──→ T4 ──┬──→ T5 ──→ T6
T2 ──→ T3 ──┘ │
T4,T3 ───┼──→ T7 ──┐
T4,T3 ───┼──→ T8 ──┤
T4,T2 ────────────────┴──→ T9 ──┤
T10(独立,可与 T5 衔接) ├──→ T12
```
---
## 使用说明
- **标记成功**:当某任务的所有「完成标准」均满足时,将该项的「状态」改为 `成功`,并可在文档中补充完成日期或备注。
- **标记失败**:当某任务无法满足完成标准或需要回退时,将「状态」改为 `失败`,并建议在文档或 issue 中记录原因及后续计划。
- **不适用**:若某任务经排查不适用,可在完成标准中注明「不适用」并将状态标为 `成功`。