# 智能对话系统完整技术文档 (v2.1) ## 1. 核心架构概述 本系统采用 **“三层记忆结构”** 来解决 LLM 在游戏中的长对话、API 成本控制与数据持久化问题。 ### 1.1 三层记忆模型 | 层级 | 名称 | 职责 | 存储位置 | 关键特性 | | :--- | :--- | :--- | :--- | :--- | | **L1** | **工作记忆 (Working Memory)** | 维持 API 短期对话上下文 | `DeepSeekService` / `DoubaoService` | 滚动修剪 (Rolling Window),限制 Token 消耗 | | **L2** | **全局存档 (Full Chat Log)** | 永久记录所有原始对话 | `LLMChatManager` | 只增不减,用于 UI 历史回看和存盘 | | **L3** | **语义记忆 (Semantic Memory)** | 提炼关键信息,对抗遗忘 | `ContextMemoryManager` | 定期调用 AI 总结,动态注入 System Prompt | --- ## 2. 详细实现案例分析 (Case Study) 为了更直观地理解系统运作,我们以一个更适合技术展示的场景为例:对话内容尽量“业务化”,突出 L1/L2/L3 的分工、成本控制与抗遗忘效果。 **场景设定**: * **角色**: NPC “ECHO-7”(地堡安保与引导 AI)。 * **玩家**: “Alex”。 * **参数配置**: * `Max Context Window` (L1): **4 条** (极小值,用于演示滚动遗忘)。 * `Summary Threshold` (L3): **2 条** (每 2 句对话触发一次总结)。 ### 2.1 阶段一:初次相遇 (初始化) **系统状态**: * **System Prompt**: `"你是地堡安保与引导 AI(ECHO-7)。语气专业简洁;优先给出可执行的下一步建议;不要编造不存在的系统状态。"` * **L1 (Working Memory)**: `[System]` * **L3 (Summary)**: `""` (空) **对话发生**: 1. **User**: "你好,我是 Alex。现在要去修复供电系统。" 2. **AI**: "已记录。建议先前往配电室,确认主断路器状态;如果你能提供当前所在区域,我可以给出更短路线。" **此时内部数据**: * `fullChatLog` (L2): 包含上述 2 条消息。 * `messagesSinceLastSummary`: 2 (达到阈值,触发总结任务)。 ### 2.2 阶段二:触发语义总结 (L3 介入) **后台处理 (用户无感知)**: 1. `ContextMemoryManager` 抓取最近 2 条对话。 2. **发送无状态请求 (Stateless Request)** 给 LLM: * *Prompt*: "请将以下对话提炼为可用于后续对话的关键信息,要求:用第三人称、尽量短、只保留稳定事实与当前目标。对话:User: 你好,我是 Alex... AI: 已记录... 建议先前往配电室..." 3. **LLM 返回总结**: `"玩家名为 Alex;当前目标是修复供电系统;已建议前往配电室检查主断路器,并可在提供所在区域后给出更短路线。"` 4. **动态更新 System Prompt**: * 新 Prompt: `"你是地堡安保与引导 AI(ECHO-7)。语气专业简洁;优先给出可执行的下一步建议;不要编造不存在的系统状态。\n\n[前情提要]: 玩家名为 Alex;当前目标是修复供电系统;已建议前往配电室检查主断路器,并可在提供所在区域后给出更短路线。"` ### 2.3 阶段三:对话继续与滚动遗忘 (L1 介入) **对话继续**: 3. **User**: "我现在在仓储区。" 4. **AI**: "从仓储区出门右转进入维护走廊,沿主干道前进到第二个分岔口左转即可到配电室。到达后先确认主断路器与备用电源指示灯。" **此时 L1 (Working Memory) 状态**: * 总消息数: 1(System) + 2(Round 1) + 2(Round 2) = 5 条。 * **触发滚动压缩** (Max=4): * 最早的 `User: "你好,我是 Alex。现在要去修复供电系统。"` 被移除。 * 次早的 `AI: "已记录。建议先前往配电室..."` 被保留 (或是移除,取决于具体修剪逻辑)。 **关键点**: 虽然 L1 里的“自我介绍 + 目标”原始消息被删除了,但 **System Prompt 里已经注入了 “玩家名 + 当前目标 + 已给建议” 的语义记忆**。 ### 2.4 阶段四:验证记忆 (最终效果) 5. **User**: "我叫什么?以及我现在要做什么?" 6. **AI**: "你是 Alex。你当前的目标是修复供电系统;我建议你前往配电室检查主断路器,并根据指示灯确认是否需要切换到备用电源。" -> **成功!** AI 通过 L3 的语义记忆(System Prompt)回答了 L1 工作记忆中已经丢失的问题。 --- ## 3. 逻辑流程图 (Mermaid) ### 3.1 完整消息处理管线 此图展示了一条用户消息如何穿过三层系统,并触发存档和总结。 ```mermaid sequenceDiagram participant U as User (UI) participant M as LLMChatManager (L2) participant S as LLM Service (L1) participant Mem as ContextMemory (L3) participant API as DeepSeek API participant Disk as SaveManager Note over U, Disk: 阶段一:处理用户消息 U->>M: Send("我现在在仓储区") M->>M: Add to fullChatLog M->>Disk: SaveGame() M->>Mem: OnMessageAdded() M->>S: SendMessage("我现在在仓储区") Note over S, API: 阶段二:L1 滚动压缩 S->>S: Add to History S->>S: TrimHistory (若 > MaxWindow) S->>API: POST Request (带 History) API-->>S: Reply ("给出到配电室的路线与检查步骤") Note over M, Disk: 阶段三:处理 AI 回复 S-->>M: Callback("给出到配电室的路线与检查步骤") M->>M: Add to fullChatLog M->>Disk: SaveGame() M->>Mem: OnMessageAdded() M-->>U: Update UI Note over Mem, S: 阶段四:L3 异步总结 (若达到阈值) Mem->>Mem: Check Threshold Mem->>S: SendStatelessMessage(SummaryPrompt) S->>API: POST Request (无历史,仅总结) API-->>S: Summary Text S-->>Mem: Return Summary Mem->>Mem: Update currentSummary Mem->>Disk: SaveGame() Mem->>S: UpdateSystemPrompt(NewPrompt) Note right of S: System Prompt 更新为:
[原设] + [新总结] ``` --- ## 4. 模块与接口详解 ### 4.1 服务层 (DeepSeekService / DoubaoService) 负责与 LLM API 直接交互,维护 **L1 工作记忆**。 * **滚动压缩逻辑**: * 参数: `maxContextWindow` (例如 20 条)。 * 机制: 每次发送前,若历史记录超限,则移除最早的对话(Index 1+),但**始终保留 System Prompt (Index 0)**。 * **Prompt 动态更新**: * `UpdateSystemPrompt(string)`: 允许外部(L3 层)动态修改当前运行时的系统提示词。 * **无状态请求**: * `SendStatelessMessage(...)`: 发送不带历史记录的一次性请求,专用于 L3 层的总结任务,避免污染 L1 上下文。 ### 4.2 管理层 (LLMChatManager) 作为中央枢纽,维护 **L2 全局存档**。 * **存档同步**: * 在游戏启动 (`RestoreState`) 时,恢复 `fullChatLog`,并调用 `activeService.SetHistory()`,让 AI 瞬间“想起”最近的对话。 ### 4.3 记忆层 (ContextMemoryManager) 系统的“海马体”,维护 **L3 语义记忆**。 * **自动阈值同步**: * `Start()` 时读取 `maxContextWindow`,将总结阈值 (`summaryThreshold`) 设为其一半。 * *目的*: 确保在 L1 层发生滚动遗忘之前,L3 层已经完成了关键信息的固化。 --- ## 5. 存档数据结构示例 存档文件 `savegame.json` 中的实际内容示例: ```json { "keys": [ "ChatSystem", "ContextMemory" ], "values": [ // L2: 完整的对话流水账 "{\"logs\":[{\"role\":\"user\",\"content\":\"你好,我是Alex。现在要去修复供电系统。\"}, {\"role\":\"assistant\",\"content\":\"已记录。建议先前往配电室检查主断路器;如提供所在区域可给出更短路线。\"}]}", // L3: 提炼后的语义总结 "{\"summary\":\"玩家名为Alex;当前目标是修复供电系统;已建议前往配电室检查主断路器,并可在提供所在区域后给出更短路线。\",\"counter\":2}" ] } ``` --- ## 6. 配置指南 ### 6.1 如何配置新角色 1. 在场景中找到挂载 `DeepSeekService` 的物体。 2. 在 Inspector 中修改 **System Prompt** (例如 "你是地堡安保与引导 AI")。 3. **注意**: 即使开启记忆系统,AI 也会基于这个 Prompt 进行总结拼接,不会覆盖你的人设。 ### 6.2 性能调优 * **Max Context Window**: 建议 **20-50**。太小会导致 AI 说话逻辑不连贯,太大会增加 API 费用。 * **Summary Threshold**: 默认自动设为 Window 的一半。手动修改需谨慎。 ### 6.3 调试建议 * 开启 `DeepSeekService` 的 `Enable Debug Key` 可在运行时通过特定口令越权调试。 * 查看 Console 中的 `[Memory]` 日志可监控总结任务的触发与完成。