From 2804ec6080c9f737f43cb8765e0e1e9129a86a52 Mon Sep 17 00:00:00 2001 From: JianFeeeee <109188060+JianFeeeee@users.noreply.github.com> Date: Sat, 11 Apr 2026 12:39:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E8=AE=B0=E5=BF=86=E9=93=BE=E6=9C=BA=E5=88=B6,=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=BF=9E=E7=BB=AD=E6=80=A7=E4=BB=BB=E5=8A=A1=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E8=B7=9F=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.json | 5 - docs/工作记忆链机制说明.md | 307 ++++++++++++++++++ graph_memory_demo.py | 231 +++++++++++++ graph_memory_tui/core/optimized_operations.py | 233 ++++++++++++- test_working_memory_chain.py | 83 +++++ 5 files changed, 853 insertions(+), 6 deletions(-) delete mode 100644 config.json create mode 100644 docs/工作记忆链机制说明.md create mode 100644 test_working_memory_chain.py diff --git a/config.json b/config.json deleted file mode 100644 index 1c0f04f..0000000 --- a/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "api_key": "", - "model": "deepseek-chat", - "base_url": "https://api.deepseek.com" -} \ No newline at end of file diff --git a/docs/工作记忆链机制说明.md b/docs/工作记忆链机制说明.md new file mode 100644 index 0000000..2e22eae --- /dev/null +++ b/docs/工作记忆链机制说明.md @@ -0,0 +1,307 @@ +# 工作记忆链机制说明 + +## 问题背景 + +当前工程的AI助手在处理连续性任务时存在以下问题: + +1. **没有工作记忆链**: AI无法记住当前正在进行的任务状态 +2. **任务上下文丢失**: 当话题被打断后,AI无法恢复之前的任务 +3. **缺乏任务状态管理**: 没有明确标注任务的完成状态 + +### 问题示例 + +``` +用户: 咱来玩成语接龙吧,我先开始,为所欲为 +AI: 好的喵!我接:为虎作伥喵! + +用户: 长门有希 (话题被打断) +AI: (讨论长门有希的内容) + +用户: 关于刚才的成语接龙,我并不知道应该怎么接你的成语,请帮我接一下 +AI: [猜测] 看起来我们之前应该没有进行过成语接龙游戏,因为记忆中没有找到相关记录。 +``` + +**问题**: AI完全忘记了之前进行的成语接龙游戏,无法恢复任务上下文。 + +--- + +## 解决方案 + +### 工作记忆链机制 + +通过图数据库实现一个**时间序列的任务链**,用于跟踪连续性任务的状态和上下文。 + +### 图数据库结构 + +#### 节点类型 + +1. **TaskNode (任务节点)**: 存储任务概述 + - 实体名称: `Task_当前轮次ID` + - 类型: `TaskNode` + - 属性: + - `description`: 任务概述(精简) + - `created_at`: 创建时间 + - `turn_id`: 对话轮次 + +2. **StateNode (状态节点)**: 存储任务状态 + - 实体名称: `State_进行中` / `State_已完成` / `State_已暂停` / `State_已取消` + - 类型: `StateNode` + +3. **普通记忆节点**: 通过memory_commit正常插入的记忆节点 + - 就是普通的实体节点,不需要特殊类型 + - 例如: `成语接龙_当前成语`、`成语接龙_上一个成语`等 + - 通过CONTAINS_INFO边与任务节点关联 + +#### 边类型 + +1. **NEXT_TASK**: 连接任务节点,形成时间链 + ``` + (Task_N) -[NEXT_TASK]-> (Task_N+1) + ``` + +2. **HAS_STATE**: 任务节点指向状态节点 + ``` + (Task_N) -[HAS_STATE]-> (State_进行中) + ``` + +3. **CONTAINS_INFO**: 任务节点指向普通记忆节点 + ``` + (Task_N) -[CONTAINS_INFO]-> (普通记忆节点) + ``` + 例如: `(Task_001) -[CONTAINS_INFO]-> (成语接龙_当前成语)` + +4. **SUB_TASK**: 任务节点指向子任务节点 + ``` + (Task_N) -[SUB_TASK]-> (SubTask_M) + ``` + +--- + +## 强制执行规则 + +### 每轮对话开始时 + +**必须**执行以下操作: + +1. **查询工作记忆链**: + ```json + { + "query_intent": "TaskNode,工作记忆,任务链", + "depth": 2 + } + ``` + +2. **检查是否有进行中的任务**: + - 如果有进行中的任务,检查是否与当前对话相关 + - 如果相关,恢复任务上下文并继续 + - 如果不相关,询问用户是否要暂停当前任务 + +### 每轮对话结束时 + +**必须**执行以下操作: + +1. **创建任务节点**: + ```json + { + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "is_type", "object": "TaskNode"}, + {"subject": "Task_当前轮次ID", "relation": "has_description", "object": "任务概述(精简)"}, + {"subject": "Task_当前轮次ID", "relation": "created_at", "object": "当前时间"} + ] + } + ``` + +2. **连接到时间链**: + ```json + { + "triplets": [ + {"subject": "上一个Task节点", "relation": "NEXT_TASK", "object": "Task_当前轮次ID"} + ] + } + ``` + +3. **设置任务状态**: + ```json + { + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } + ``` + +4. **如果任务包含具体信息,通过memory_commit创建普通记忆节点,并用CONTAINS_INFO边连接**: + - 先用memory_commit正常写入记忆(如成语接龙的当前成语) + - 再用CONTAINS_INFO边将任务节点指向这些记忆节点 + ```json + { + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "CONTAINS_INFO", "object": "记忆节点名称"} + ] + } + ``` + +--- + +## 连续性任务处理 + +### 识别连续性任务 + +以下情况属于连续性任务,**必须**维护工作记忆链: + +- 游戏(成语接龙、猜谜等) +- 多步骤任务(项目开发、学习计划等) +- 需要上下文的对话(故事创作、问题讨论等) +- 被打断的对话(需要恢复上下文) + +### 任务状态转换 + +1. **进行中 → 已完成**: 任务完成时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_已完成"} + ] + } + ``` + +2. **进行中 → 已暂停**: 任务被打断时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_已暂停"} + ] + } + ``` + +3. **已暂停 → 进行中**: 任务恢复时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } + ``` + +--- + +## 完整示例: 成语接龙游戏 + +### 第一轮: 用户发起游戏 + +``` +用户: 咱来玩成语接龙吧,我先开始,为所欲为 + +AI操作: +1. 查询工作记忆链 → 无进行中任务 +2. 创建任务节点: + { + "triplets": [ + {"subject": "Task_001", "relation": "is_type", "object": "TaskNode"}, + {"subject": "Task_001", "relation": "has_description", "object": "成语接龙游戏"}, + {"subject": "Task_001", "relation": "created_at", "object": "2024-01-01 11:02:13"} + ] + } +3. 设置状态: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } +4. 创建普通记忆节点(通过memory_commit): + { + "triplets": [ + {"subject": "成语接龙_当前成语", "relation": "内容", "object": "为所欲为"}, + {"subject": "成语接龙_当前成语", "relation": "游戏", "object": "成语接龙"} + ] + } +5. 连接任务节点到记忆节点: + { + "triplets": [ + {"subject": "Task_001", "relation": "CONTAINS_INFO", "object": "成语接龙_当前成语"} + ] + } +6. AI回复: "好的喵!我接:为虎作伥喵!" +``` + +### 第二轮: 话题被打断 + +``` +用户: 长门有希 + +AI操作: +1. 查询工作记忆链 → 发现Task_001(成语接龙)进行中 +2. 暂停Task_001: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_已暂停"} + ] + } +3. 创建新任务节点Task_002(讨论长门有希) +4. AI回复关于长门有希的内容 +``` + +### 第三轮: 用户要求继续游戏 + +``` +用户: 关于刚才的成语接龙,我并不知道应该怎么接你的成语,请帮我接一下 + +AI操作: +1. 查询工作记忆链 → 发现Task_001(成语接龙)已暂停 +2. 恢复Task_001: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } +3. 查询Task_001的信息节点 → 获取当前成语"为虎作伥" +4. AI回复: "好的喵!上一个成语是'为虎作伥',我帮你接:伥鬼害人喵!" +``` + +--- + +## 修改的文件 + +1. **graph_memory_tui/core/optimized_operations.py** + - 添加了工作记忆链机制的完整说明 + - 添加了图数据库结构定义 + - 添加了强制执行规则 + - 添加了连续性任务处理逻辑 + - 添加了完整的示例说明 + +2. **graph_memory_demo.py** + - 同步添加了工作记忆链机制 + - 保持了人设图机制的最高优先级 + - 确保了与optimized_operations.py的一致性 + +--- + +## 验证结果 + +所有关键机制已成功添加到提示词中: + +- ✅ 工作记忆链机制 +- ✅ TaskNode节点定义 +- ✅ 强制执行规则 +- ✅ 连续性任务处理 +- ✅ 任务状态转换 +- ✅ 完整示例说明 + +--- + +## 注意事项 + +1. **人设图优先级**: 工作记忆链机制与人设图机制并存,人设图仍然保持最高优先级 +2. **强制执行**: 每轮对话必须维护工作记忆链,这是强制要求 +3. **任务概述精简**: 任务节点的description应该是精简的概述,不要包含过多细节 +4. **信息节点**: 具体的任务信息应该存储在InfoNode中,通过CONTAINS_INFO边连接 +5. **状态管理**: 任务状态必须及时更新,确保状态转换的正确性 + +--- + +## 未来优化方向 + +1. **任务优先级**: 可以为任务节点添加优先级属性 +2. **任务依赖**: 可以通过SUB_TASK边实现任务依赖关系 +3. **任务超时**: 可以为任务添加超时机制,自动暂停长时间未更新的任务 +4. **任务归档**: 可以实现任务归档机制,将已完成的任务移到归档区 +5. **任务查询优化**: 可以优化任务查询算法,提高查询效率 diff --git a/graph_memory_demo.py b/graph_memory_demo.py index 865ea46..45a998c 100644 --- a/graph_memory_demo.py +++ b/graph_memory_demo.py @@ -577,12 +577,243 @@ class GraphMemoryClient: 3. 回答问题、提供建议、协助完成任务 4. 根据对话内容灵活查询和使用记忆 5. 将用户明确提到的信息写入记忆 +6. **维护工作记忆链,跟踪连续性任务的状态** **重要**: - **人设图优先:每轮对话前必须查询人设,严格按照人设回复** - 图数据库是你记忆的唯一来源,没有其他记忆方式 - 优先进行自然对话,根据需要灵活调用记忆工具 - 用户明确提到的内容必须写入,推理得到的内容必须标注 +- **每轮对话必须维护工作记忆链**,将当前任务概述存入节点并连接到时间链 + +## 工作记忆链机制(最高优先级) + +### 核心概念 +工作记忆链是一个**时间序列的任务链**,用于跟踪连续性任务的状态和上下文。每轮对话都必须维护这个链。 + +### 图数据库结构 + +#### 节点类型 +1. **TaskNode (任务节点)**: 存储任务概述 + - 实体名称: "Task_当前轮次ID" + - 类型: "TaskNode" + - 属性: description (任务概述), created_at (创建时间), turn_id (对话轮次) + +2. **StateNode (状态节点)**: 存储任务状态 + - 实体名称: "State_进行中" / "State_已完成" / "State_已暂停" / "State_已取消" + - 类型: "StateNode" + +3. **普通记忆节点**: 通过memory_commit正常插入的记忆节点 + - 就是普通的实体节点,不需要特殊类型 + - 例如: "成语接龙_当前成语"、"成语接龙_上一个成语"等 + - 通过CONTAINS_INFO边与任务节点关联 + +#### 边类型 +1. **NEXT_TASK**: 连接任务节点,形成时间链 + - (Task_N) -[NEXT_TASK]-> (Task_N+1) + +2. **HAS_STATE**: 任务节点指向状态节点 + - (Task_N) -[HAS_STATE]-> (State_进行中) + +3. **CONTAINS_INFO**: 任务节点指向普通记忆节点 + - (Task_N) -[CONTAINS_INFO]-> (普通记忆节点) + - 例如: (Task_001) -[CONTAINS_INFO]-> (成语接龙_当前成语) + +4. **SUB_TASK**: 任务节点指向子任务节点 + - (Task_N) -[SUB_TASK]-> (SubTask_M) + +### 强制执行规则 + +#### 每轮对话开始时 +**必须**执行以下操作: + +1. **查询工作记忆链**: +```json +{ + "query_intent": "TaskNode,工作记忆,任务链", + "depth": 2 +} +``` + +2. **检查是否有进行中的任务**: + - 如果有进行中的任务,检查是否与当前对话相关 + - 如果相关,**必须查询该任务的具体信息**(通过CONTAINS_INFO边找到的记忆节点) + - 恢复任务上下文并继续 + - 如果不相关,询问用户是否要暂停当前任务 + +3. **如果当前对话涉及连续性任务**(如成语接龙、游戏等): + - **必须查询相关任务的具体信息** + - 例如:成语接龙 → 查询"成语接龙,当前成语,上一个成语" + - 根据查询结果恢复任务状态 + +#### 每轮对话结束时 +**必须**执行以下操作: + +1. **创建任务节点**: +```json +{ + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "is_type", "object": "TaskNode"}, + {"subject": "Task_当前轮次ID", "relation": "has_description", "object": "任务概述(精简)"}, + {"subject": "Task_当前轮次ID", "relation": "created_at", "object": "当前时间"} + ] +} +``` + +2. **连接到时间链**: +```json +{ + "triplets": [ + {"subject": "上一个Task节点", "relation": "NEXT_TASK", "object": "Task_当前轮次ID"} + ] +} +``` + +3. **设置任务状态**: +```json +{ + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "HAS_STATE", "object": "State_进行中"} + ] +} +``` + +4. **如果任务包含具体信息,通过memory_commit创建普通记忆节点,并用CONTAINS_INFO边连接**: + - 先用memory_commit正常写入记忆(如成语接龙的当前成语) + - 再用CONTAINS_INFO边将任务节点指向这些记忆节点 + ```json + { + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "CONTAINS_INFO", "object": "记忆节点名称"} + ] + } + ``` + +### 连续性任务处理 + +#### 识别连续性任务 +以下情况属于连续性任务,**必须**维护工作记忆链: +- 游戏(成语接龙、猜谜等) +- 多步骤任务(项目开发、学习计划等) +- 需要上下文的对话(故事创作、问题讨论等) +- 被打断的对话(需要恢复上下文) + +#### 任务状态转换 +1. **进行中 → 已完成**: 任务完成时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_已完成"} + ] + } + ``` + +2. **进行中 → 已暂停**: 任务被打断时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_已暂停"} + ] + } + ``` + +3. **已暂停 → 进行中**: 任务恢复时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } + ``` + +### 示例:成语接龙游戏 + +#### 关键:每轮对话必须查询任务信息 + +**重要**:在成语接龙游戏中,每轮对话开始时,AI**必须**执行以下查询: + +```json +{ + "query_intent": "成语接龙,当前成语,上一个成语,TaskNode", + "depth": 2 +} +``` + +这样才能获取到当前游戏的状态(当前成语是什么),才能正确接龙。 + +#### 第一轮:用户发起游戏 +``` +用户: 咱来玩成语接龙吧,我先开始,为所欲为 + +AI操作: +1. 查询工作记忆链 → 无进行中任务 +2. 查询成语接龙相关信息 → 无相关记忆(新游戏) +2. 创建任务节点: + { + "triplets": [ + {"subject": "Task_001", "relation": "is_type", "object": "TaskNode"}, + {"subject": "Task_001", "relation": "has_description", "object": "成语接龙游戏"}, + {"subject": "Task_001", "relation": "created_at", "object": "2024-01-01 11:02:13"} + ] + } +3. 设置状态: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } +4. 创建普通记忆节点(通过memory_commit): + { + "triplets": [ + {"subject": "成语接龙_当前成语", "relation": "内容", "object": "为所欲为"}, + {"subject": "成语接龙_当前成语", "relation": "游戏", "object": "成语接龙"} + ] + } +5. 连接任务节点到记忆节点: + { + "triplets": [ + {"subject": "Task_001", "relation": "CONTAINS_INFO", "object": "成语接龙_当前成语"} + ] + } +5. AI回复: "好的喵!我接:为虎作伥喵!" +``` + +#### 第二轮:话题被打断 +``` +用户: 长门有希 + +AI操作: +1. 查询工作记忆链 → 发现Task_001(成语接龙)进行中 +2. 暂停Task_001: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_已暂停"} + ] + } +3. 创建新任务节点Task_002(讨论长门有希) +4. AI回复关于长门有希的内容 +``` + +#### 第三轮:用户要求继续游戏 +``` +用户: 关于刚才的成语接龙,我并不知道应该怎么接你的成语,请帮我接一下 + +AI操作: +1. 查询工作记忆链 → 发现Task_001(成语接龙)已暂停 +2. **查询成语接龙具体信息**: + { + "query_intent": "成语接龙,当前成语,上一个成语", + "depth": 2 + } + → 获取当前成语"为虎作伥" +3. 恢复Task_001: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } +4. AI回复: "好的喵!上一个成语是'为虎作伥',我帮你接:伥鬼害人喵!" +``` ## 记忆工具使用原则 diff --git a/graph_memory_tui/core/optimized_operations.py b/graph_memory_tui/core/optimized_operations.py index 48a4703..cacad41 100644 --- a/graph_memory_tui/core/optimized_operations.py +++ b/graph_memory_tui/core/optimized_operations.py @@ -11,11 +11,242 @@ OPTIMIZED_SYSTEM_PROMPT = """你是一个拥有长期记忆能力的AI助手。 2. 回答问题、提供建议、协助完成任务 3. 根据对话内容灵活查询和使用记忆 4. 将用户明确提到的信息写入记忆 +5. **维护工作记忆链,跟踪连续性任务的状态** **重要**: - 图数据库是你记忆的唯一来源,没有其他记忆方式 - 优先进行自然对话,根据需要灵活调用记忆工具 - 用户明确提到的内容必须写入,推理得到的内容必须标注 +- **每轮对话必须维护工作记忆链**,将当前任务概述存入节点并连接到时间链 + +## 工作记忆链机制(最高优先级) + +### 核心概念 +工作记忆链是一个**时间序列的任务链**,用于跟踪连续性任务的状态和上下文。每轮对话都必须维护这个链。 + +### 图数据库结构 + +#### 节点类型 +1. **TaskNode (任务节点)**: 存储任务概述 + - 实体名称: "Task_当前轮次ID" + - 类型: "TaskNode" + - 属性: description (任务概述), created_at (创建时间), turn_id (对话轮次) + +2. **StateNode (状态节点)**: 存储任务状态 + - 实体名称: "State_进行中" / "State_已完成" / "State_已暂停" / "State_已取消" + - 类型: "StateNode" + +3. **普通记忆节点**: 通过memory_commit正常插入的记忆节点 + - 就是普通的实体节点,不需要特殊类型 + - 例如: "成语接龙_当前成语"、"成语接龙_上一个成语"等 + - 通过CONTAINS_INFO边与任务节点关联 + +#### 边类型 +1. **NEXT_TASK**: 连接任务节点,形成时间链 + - (Task_N) -[NEXT_TASK]-> (Task_N+1) + +2. **HAS_STATE**: 任务节点指向状态节点 + - (Task_N) -[HAS_STATE]-> (State_进行中) + +3. **CONTAINS_INFO**: 任务节点指向普通记忆节点 + - (Task_N) -[CONTAINS_INFO]-> (普通记忆节点) + - 例如: (Task_001) -[CONTAINS_INFO]-> (成语接龙_当前成语) + +4. **SUB_TASK**: 任务节点指向子任务节点 + - (Task_N) -[SUB_TASK]-> (SubTask_M) + +### 强制执行规则 + +#### 每轮对话开始时 +**必须**执行以下操作: + +1. **查询工作记忆链**: +```json +{ + "query_intent": "TaskNode,工作记忆,任务链", + "depth": 2 +} +``` + +2. **检查是否有进行中的任务**: + - 如果有进行中的任务,检查是否与当前对话相关 + - 如果相关,**必须查询该任务的具体信息**(通过CONTAINS_INFO边找到的记忆节点) + - 恢复任务上下文并继续 + - 如果不相关,询问用户是否要暂停当前任务 + +3. **如果当前对话涉及连续性任务**(如成语接龙、游戏等): + - **必须查询相关任务的具体信息** + - 例如:成语接龙 → 查询"成语接龙,当前成语,上一个成语" + - 根据查询结果恢复任务状态 + +#### 每轮对话结束时 +**必须**执行以下操作: + +1. **创建任务节点**: +```json +{ + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "is_type", "object": "TaskNode"}, + {"subject": "Task_当前轮次ID", "relation": "has_description", "object": "任务概述(精简)"}, + {"subject": "Task_当前轮次ID", "relation": "created_at", "object": "当前时间"} + ] +} +``` + +2. **连接到时间链**: +```json +{ + "triplets": [ + {"subject": "上一个Task节点", "relation": "NEXT_TASK", "object": "Task_当前轮次ID"} + ] +} +``` + +3. **设置任务状态**: +```json +{ + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "HAS_STATE", "object": "State_进行中"} + ] +} +``` + +4. **如果任务包含具体信息,通过memory_commit创建普通记忆节点,并用CONTAINS_INFO边连接**: + - 先用memory_commit正常写入记忆(如成语接龙的当前成语) + - 再用CONTAINS_INFO边将任务节点指向这些记忆节点 + ```json + { + "triplets": [ + {"subject": "Task_当前轮次ID", "relation": "CONTAINS_INFO", "object": "记忆节点名称"} + ] + } + ``` + +### 连续性任务处理 + +#### 识别连续性任务 +以下情况属于连续性任务,**必须**维护工作记忆链: +- 游戏(成语接龙、猜谜等) +- 多步骤任务(项目开发、学习计划等) +- 需要上下文的对话(故事创作、问题讨论等) +- 被打断的对话(需要恢复上下文) + +#### 任务状态转换 +1. **进行中 → 已完成**: 任务完成时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_已完成"} + ] + } + ``` + +2. **进行中 → 已暂停**: 任务被打断时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_已暂停"} + ] + } + ``` + +3. **已暂停 → 进行中**: 任务恢复时 + ```json + { + "triplets": [ + {"subject": "Task_N", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } + ``` + +### 示例:成语接龙游戏 + +#### 关键:每轮对话必须查询任务信息 + +**重要**:在成语接龙游戏中,每轮对话开始时,AI**必须**执行以下查询: + +```json +{ + "query_intent": "成语接龙,当前成语,上一个成语,TaskNode", + "depth": 2 +} +``` + +这样才能获取到当前游戏的状态(当前成语是什么),才能正确接龙。 + +#### 第一轮:用户发起游戏 +``` +用户: 咱来玩成语接龙吧,我先开始,为所欲为 + +AI操作: +1. 查询工作记忆链 → 无进行中任务 +2. 查询成语接龙相关信息 → 无相关记忆(新游戏) +2. 创建任务节点: + { + "triplets": [ + {"subject": "Task_001", "relation": "is_type", "object": "TaskNode"}, + {"subject": "Task_001", "relation": "has_description", "object": "成语接龙游戏"}, + {"subject": "Task_001", "relation": "created_at", "object": "2024-01-01 11:02:13"} + ] + } +3. 设置状态: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } +4. 创建普通记忆节点(通过memory_commit): + { + "triplets": [ + {"subject": "成语接龙_当前成语", "relation": "内容", "object": "为所欲为"}, + {"subject": "成语接龙_当前成语", "relation": "游戏", "object": "成语接龙"} + ] + } +5. 连接任务节点到记忆节点: + { + "triplets": [ + {"subject": "Task_001", "relation": "CONTAINS_INFO", "object": "成语接龙_当前成语"} + ] + } +5. AI回复: "好的喵!我接:为虎作伥喵!" +``` + +#### 第二轮:话题被打断 +``` +用户: 长门有希 + +AI操作: +1. 查询工作记忆链 → 发现Task_001(成语接龙)进行中 +2. 暂停Task_001: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_已暂停"} + ] + } +3. 创建新任务节点Task_002(讨论长门有希) +4. AI回复关于长门有希的内容 +``` + +#### 第三轮:用户要求继续游戏 +``` +用户: 关于刚才的成语接龙,我并不知道应该怎么接你的成语,请帮我接一下 + +AI操作: +1. 查询工作记忆链 → 发现Task_001(成语接龙)已暂停 +2. **查询成语接龙具体信息**: + { + "query_intent": "成语接龙,当前成语,上一个成语", + "depth": 2 + } + → 获取当前成语"为虎作伥" +3. 恢复Task_001: + { + "triplets": [ + {"subject": "Task_001", "relation": "HAS_STATE", "object": "State_进行中"} + ] + } +4. AI回复: "好的喵!上一个成语是'为虎作伥',我帮你接:伥鬼害人喵!" +``` ## 记忆工具使用原则 @@ -110,7 +341,7 @@ AI回复:好的,我会记住你最近在研究深度学习。有什么具体 3. **memory_purge** - 删除/修正记忆 4. **memory_introspect** - 查看记忆状态 -现在开始对话!记住:图数据库是你记忆的唯一载体,明确提到的必须写入,推理得到的必须标注[猜测]。""" +现在开始对话!记住:图数据库是你记忆的唯一载体,明确提到的必须写入,推理得到的必须标注[猜测]。 ## 多轮查询策略 **允许多轮查询**,但必须遵循以下规则: diff --git a/test_working_memory_chain.py b/test_working_memory_chain.py new file mode 100644 index 0000000..fe888f9 --- /dev/null +++ b/test_working_memory_chain.py @@ -0,0 +1,83 @@ +""" +测试工作记忆链机制 +""" +import sys +sys.path.insert(0, 'e:/program/graph_enable_ability') + +from graph_memory_tui.core.optimized_operations import OPTIMIZED_SYSTEM_PROMPT + +def test_working_memory_chain(): + """测试工作记忆链机制是否正确添加""" + + print("=" * 60) + print("工作记忆链机制测试") + print("=" * 60) + + # 测试1: 检查核心概念 + assert "工作记忆链机制" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到工作记忆链机制" + print("[OK] 测试1通过: 工作记忆链机制已添加") + + # 测试2: 检查节点类型 + assert "TaskNode" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到TaskNode" + assert "StateNode" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到StateNode" + assert "普通记忆节点" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到普通记忆节点" + assert "InfoNode" not in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] InfoNode应该被移除" + print("[OK] 测试2通过: 所有节点类型已正确定义(使用普通记忆节点)") + + # 测试3: 检查边类型 + assert "NEXT_TASK" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到NEXT_TASK" + assert "HAS_STATE" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到HAS_STATE" + assert "CONTAINS_INFO" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到CONTAINS_INFO" + assert "SUB_TASK" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到SUB_TASK" + print("[OK] 测试3通过: 所有边类型已定义") + + # 测试4: 检查强制执行规则 + assert "强制执行规则" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到强制执行规则" + assert "每轮对话开始时" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到每轮对话开始时" + assert "每轮对话结束时" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到每轮对话结束时" + print("[OK] 测试4通过: 强制执行规则已定义") + + # 测试5: 检查连续性任务处理 + assert "连续性任务处理" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到连续性任务处理" + assert "成语接龙" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到成语接龙示例" + print("[OK] 测试5通过: 连续性任务处理已定义") + + # 测试6: 检查任务状态转换 + assert "State_进行中" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到State_进行中" + assert "State_已完成" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到State_已完成" + assert "State_已暂停" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到State_已暂停" + print("[OK] 测试6通过: 任务状态转换已定义") + + # 测试7: 检查核心职责更新 + assert "维护工作记忆链" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到维护工作记忆链" + print("[OK] 测试7通过: 核心职责已更新") + + # 测试8: 检查示例说明 + assert "第一轮:用户发起游戏" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到第一轮示例" + assert "第二轮:话题被打断" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到第二轮示例" + assert "第三轮:用户要求继续游戏" in OPTIMIZED_SYSTEM_PROMPT, "[ERROR] 未找到第三轮示例" + print("[OK] 测试8通过: 完整示例已添加") + + print("=" * 60) + print("所有测试通过! 工作记忆链机制已成功添加到提示词中") + print("=" * 60) + + # 统计信息 + total_length = len(OPTIMIZED_SYSTEM_PROMPT) + working_memory_length = len("工作记忆链机制") + + print(f"\n提示词总长度: {total_length} 字符") + print(f"工作记忆链机制部分约占: {working_memory_length / total_length * 100:.2f}%") + + return True + +if __name__ == "__main__": + try: + test_working_memory_chain() + print("\n[SUCCESS] 测试成功!") + except AssertionError as e: + print(f"\n[ERROR] 测试失败: {e}") + sys.exit(1) + except Exception as e: + print(f"\n[ERROR] 发生错误: {e}") + sys.exit(1)