mirror of
https://gitcode.com/JianFeeeee/TrulyMEM-TrueHumanMEM.git
synced 2026-10-15 12:15:32 +00:00
fix: 修复工具调用限制器误判问题并优化记忆查询
1. 工具调用限制器修复 - 移除memory_recall关键词智能分类,统一归类为一般记忆查询 2. 工作记忆链限制调整 - 修改限制从2次/轮到5次/轮 3. 广度优先搜索实现 - 修复depth参数被忽略问题,添加深度标注 4. 提示词优化 - 新增强制执行顺序说明,明确task_link_info使用场景 Generated with CodeArts Agent
This commit is contained in:
@ -150,14 +150,26 @@ class EmbeddedGraphDB:
|
|||||||
'mention_count': row['mention_count']
|
'mention_count': row['mention_count']
|
||||||
})
|
})
|
||||||
|
|
||||||
# 搜索关系
|
# 广度优先搜索(BFS)扩展实体和关系
|
||||||
relations = []
|
relations = []
|
||||||
|
visited_entity_ids = set(entity_ids) # 已访问的实体
|
||||||
|
current_layer_ids = set(entity_ids) # 当前层的实体
|
||||||
|
|
||||||
if entity_ids:
|
# 记录每个实体的深度
|
||||||
placeholders = ','.join('?' * len(entity_ids))
|
entity_depths = {} # entity_id -> depth
|
||||||
|
for eid in entity_ids:
|
||||||
|
entity_depths[eid] = 0
|
||||||
|
|
||||||
|
for layer in range(depth):
|
||||||
|
if not current_layer_ids:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 查询当前层实体的所有关系
|
||||||
|
placeholders = ','.join('?' * len(current_layer_ids))
|
||||||
|
|
||||||
query = f"""
|
query = f"""
|
||||||
SELECT r.id, e1.name as source, e2.name as target,
|
SELECT r.id, r.source_id, r.target_id,
|
||||||
|
e1.name as source, e2.name as target,
|
||||||
r.relation_type as type, r.confidence, r.session_id,
|
r.relation_type as type, r.confidence, r.session_id,
|
||||||
r.turn_id, r.created_at, r.status
|
r.turn_id, r.created_at, r.status
|
||||||
FROM relations r
|
FROM relations r
|
||||||
@ -167,7 +179,7 @@ class EmbeddedGraphDB:
|
|||||||
AND r.status = 'active'
|
AND r.status = 'active'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
params = list(entity_ids) + list(entity_ids)
|
params = list(current_layer_ids) + list(current_layer_ids)
|
||||||
|
|
||||||
if session_filter:
|
if session_filter:
|
||||||
query += " AND r.session_id = ?"
|
query += " AND r.session_id = ?"
|
||||||
@ -175,8 +187,18 @@ class EmbeddedGraphDB:
|
|||||||
|
|
||||||
cursor.execute(query, params)
|
cursor.execute(query, params)
|
||||||
|
|
||||||
|
# 收集下一层的实体
|
||||||
|
next_layer_ids = set()
|
||||||
|
current_layer_relations = [] # 当前层的关系
|
||||||
|
|
||||||
for row in cursor.fetchall():
|
for row in cursor.fetchall():
|
||||||
relations.append({
|
# 计算关系的深度(取两端实体深度的最大值+1)
|
||||||
|
source_depth = entity_depths.get(row['source_id'], layer)
|
||||||
|
target_depth = entity_depths.get(row['target_id'], layer)
|
||||||
|
relation_depth = max(source_depth, target_depth) + 1
|
||||||
|
|
||||||
|
# 添加关系(带深度标注)
|
||||||
|
current_layer_relations.append({
|
||||||
'source': row['source'],
|
'source': row['source'],
|
||||||
'target': row['target'],
|
'target': row['target'],
|
||||||
'type': row['type'],
|
'type': row['type'],
|
||||||
@ -184,9 +206,53 @@ class EmbeddedGraphDB:
|
|||||||
'session_id': row['session_id'],
|
'session_id': row['session_id'],
|
||||||
'turn_id': row['turn_id'],
|
'turn_id': row['turn_id'],
|
||||||
'created_at': row['created_at'],
|
'created_at': row['created_at'],
|
||||||
'status': row['status']
|
'status': row['status'],
|
||||||
|
'depth': relation_depth
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# 收集新实体(未访问过的)
|
||||||
|
source_id = row['source_id']
|
||||||
|
target_id = row['target_id']
|
||||||
|
|
||||||
|
if source_id not in visited_entity_ids:
|
||||||
|
next_layer_ids.add(source_id)
|
||||||
|
visited_entity_ids.add(source_id)
|
||||||
|
entity_depths[source_id] = layer + 1
|
||||||
|
|
||||||
|
if target_id not in visited_entity_ids:
|
||||||
|
next_layer_ids.add(target_id)
|
||||||
|
visited_entity_ids.add(target_id)
|
||||||
|
entity_depths[target_id] = layer + 1
|
||||||
|
|
||||||
|
relations.extend(current_layer_relations)
|
||||||
|
|
||||||
|
# 查询下一层实体的详细信息
|
||||||
|
if next_layer_ids:
|
||||||
|
placeholders = ','.join('?' * len(next_layer_ids))
|
||||||
|
cursor.execute(f"""
|
||||||
|
SELECT id, name, type, mention_count
|
||||||
|
FROM entities
|
||||||
|
WHERE id IN ({placeholders})
|
||||||
|
""", list(next_layer_ids))
|
||||||
|
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
entities.append({
|
||||||
|
'name': row['name'],
|
||||||
|
'type': row['type'] or 'unknown',
|
||||||
|
'mention_count': row['mention_count'],
|
||||||
|
'depth': entity_depths.get(row['id'], layer + 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
# 移动到下一层
|
||||||
|
current_layer_ids = next_layer_ids
|
||||||
|
|
||||||
|
# 为种子实体添加深度标注(depth=0)
|
||||||
|
if entity_ids:
|
||||||
|
# 重新标注种子实体的深度
|
||||||
|
for entity in entities:
|
||||||
|
if entity.get('depth') is None:
|
||||||
|
entity['depth'] = 0
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"entities": entities,
|
"entities": entities,
|
||||||
"relations": relations,
|
"relations": relations,
|
||||||
|
|||||||
@ -2,6 +2,24 @@
|
|||||||
|
|
||||||
你是TrulyMEM,一个拥有长期记忆能力的AI助手。
|
你是TrulyMEM,一个拥有长期记忆能力的AI助手。
|
||||||
|
|
||||||
|
## ⚠️ 最高优先级:强制执行顺序
|
||||||
|
|
||||||
|
**每轮对话必须严格按以下顺序执行,不可跳过任何步骤!**
|
||||||
|
|
||||||
|
```
|
||||||
|
步骤1: memory_recall (查询人设图) → 必须首先执行
|
||||||
|
步骤2: memory_recall (查询工作记忆链) → 必须第二步执行
|
||||||
|
步骤3: 处理对话内容
|
||||||
|
步骤4: 更新工作记忆链
|
||||||
|
```
|
||||||
|
|
||||||
|
**违反顺序的后果**:
|
||||||
|
- 跳过步骤1 → 无法获取人设,回复风格错误
|
||||||
|
- 跳过步骤2 → 无法获取上下文,对话不连贯
|
||||||
|
- 顺序错误 → 系统状态混乱
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## ⚠️ 最高优先级:只回复一次
|
## ⚠️ 最高优先级:只回复一次
|
||||||
|
|
||||||
**每轮对话只能回复一次!**
|
**每轮对话只能回复一次!**
|
||||||
@ -121,15 +139,34 @@
|
|||||||
- 执行其他必要的记忆操作
|
- 执行其他必要的记忆操作
|
||||||
|
|
||||||
#### 步骤4: 更新工作记忆链
|
#### 步骤4: 更新工作记忆链
|
||||||
|
|
||||||
|
**重要**: 工作记忆链有两种关联机制:
|
||||||
|
1. **时间链(NEXT_TASK)**: 系统自动维护,连接TaskNode形成时间序列
|
||||||
|
2. **信息关联(CONTAINS_INFO)**: 模型主动决定,将TaskNode链接到相关的一般记忆节点
|
||||||
|
|
||||||
|
**执行步骤**:
|
||||||
|
1. 使用 `memory_commit` 写入本轮重要信息(用户偏好、事实等)
|
||||||
|
2. 使用 `task_create` 创建任务节点(系统自动维护时间链)
|
||||||
|
3. 使用 `task_link_info` 将相关记忆节点关联到任务节点
|
||||||
|
|
||||||
|
**task_link_info 使用场景**:
|
||||||
|
- 本轮写入了新的记忆节点 → 关联到当前任务
|
||||||
|
- 讨论了之前的话题 → 关联到相关记忆节点
|
||||||
|
- 用户提到相关概念 → 关联到相关记忆节点
|
||||||
|
|
||||||
|
**示例**:
|
||||||
```
|
```
|
||||||
必须调用: task_create
|
用户: "我还是更喜欢罗辑,他的角色深度很让我着迷"
|
||||||
参数: {
|
|
||||||
"task_id": "Task_当前轮次ID",
|
AI操作:
|
||||||
"description": "本轮对话概述",
|
1. memory_commit: 写入 "用户喜欢罗辑"、"罗辑角色深度"
|
||||||
"info_nodes": ["相关记忆节点"]
|
2. task_create: 创建 "Task_讨论罗辑"
|
||||||
}
|
3. task_link_info: 关联 ["用户喜欢罗辑", "罗辑角色深度"]
|
||||||
```
|
```
|
||||||
**目的**: 记录本轮对话,维持时间链。
|
|
||||||
|
**目的**:
|
||||||
|
- 时间链维持对话连贯性(系统自动)
|
||||||
|
- 信息关联实现"由一件事回忆起相关事情"(模型决定)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -122,7 +122,7 @@ class BackendServer:
|
|||||||
persona_query_max=self._tool_limits.get("persona_query_max", 1),
|
persona_query_max=self._tool_limits.get("persona_query_max", 1),
|
||||||
persona_update_max=self._tool_limits.get("persona_update_max", 1),
|
persona_update_max=self._tool_limits.get("persona_update_max", 1),
|
||||||
task_query_max=self._tool_limits.get("task_query_max", 4),
|
task_query_max=self._tool_limits.get("task_query_max", 4),
|
||||||
task_update_max=self._tool_limits.get("task_update_max", 2),
|
task_update_max=self._tool_limits.get("task_update_max", 5),
|
||||||
memory_query_max=self._tool_limits.get("memory_query_max", 20),
|
memory_query_max=self._tool_limits.get("memory_query_max", 20),
|
||||||
memory_update_max=self._tool_limits.get("memory_update_max", 10),
|
memory_update_max=self._tool_limits.get("memory_update_max", 10),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class ToolLimits:
|
|||||||
|
|
||||||
# 工作记忆链限制
|
# 工作记忆链限制
|
||||||
task_query_max: int = 4 # 每轮最多查询4次工作记忆链
|
task_query_max: int = 4 # 每轮最多查询4次工作记忆链
|
||||||
task_update_max: int = 2 # 每轮最多修改2次工作记忆链
|
task_update_max: int = 5 # 每轮最多修改5次工作记忆链
|
||||||
|
|
||||||
# 一般记忆限制
|
# 一般记忆限制
|
||||||
memory_query_max: int = 20 # 每轮最多查询20次一般记忆
|
memory_query_max: int = 20 # 每轮最多查询20次一般记忆
|
||||||
@ -62,18 +62,9 @@ class ToolLimiter:
|
|||||||
|
|
||||||
# 一般记忆工具
|
# 一般记忆工具
|
||||||
if tool_name == 'memory_recall':
|
if tool_name == 'memory_recall':
|
||||||
# 判断是查询人设图、工作记忆链还是一般记忆
|
# 所有 memory_recall 统一归为一般记忆查询
|
||||||
query_intent = arguments.get('query_intent', '').lower()
|
# 因为 query_intent 内容不可控,无法准确判断查询类型
|
||||||
|
# 写入操作通过工具名称明确区分,不受此影响
|
||||||
# 检查是否查询人设图
|
|
||||||
if any(kw in query_intent for kw in ['人设', '角色', '性格', '语气', '说话风格', '扮演']):
|
|
||||||
return ('persona', 'query')
|
|
||||||
|
|
||||||
# 检查是否查询工作记忆链
|
|
||||||
if any(kw in query_intent for kw in ['tasknode', '工作记忆', '任务链', '任务', 'task']):
|
|
||||||
return ('task', 'query')
|
|
||||||
|
|
||||||
# 一般记忆查询
|
|
||||||
return ('memory', 'query')
|
return ('memory', 'query')
|
||||||
|
|
||||||
if tool_name == 'memory_commit':
|
if tool_name == 'memory_commit':
|
||||||
|
|||||||
@ -11,26 +11,26 @@ MEMORY_TOOLS = [
|
|||||||
"name": "memory_recall",
|
"name": "memory_recall",
|
||||||
"description": """检索记忆。支持关键词、时间范围、会话过滤。返回相关实体和关系。
|
"description": """检索记忆。支持关键词、时间范围、会话过滤。返回相关实体和关系。
|
||||||
|
|
||||||
【使用示例】
|
【⚠️ 强制执行顺序 - 每轮必须严格遵守】
|
||||||
1. 查询人设图(每轮必须首先执行):
|
1. 步骤1(必须首先执行): 查询人设图
|
||||||
{"query_intent": "AI,人设,角色,性格,语气,说话风格", "depth": 2}
|
{"query_intent": "AI,人设,角色,性格,语气,说话风格", "depth": 2}
|
||||||
|
|
||||||
2. 查询工作记忆链(每轮必须第二步执行):
|
2. 步骤2(必须第二步执行): 查询工作记忆链
|
||||||
{"query_intent": "TaskNode,工作记忆,任务链", "depth": 2}
|
{"query_intent": "TaskNode,工作记忆,任务链", "depth": 2}
|
||||||
|
|
||||||
3. 查询用户偏好:
|
3. 步骤3: 根据需要查询其他记忆
|
||||||
|
|
||||||
|
【使用示例】
|
||||||
|
1. 查询用户偏好:
|
||||||
{"query_intent": "用户,喜欢,偏好", "seed_entities": ["用户"]}
|
{"query_intent": "用户,喜欢,偏好", "seed_entities": ["用户"]}
|
||||||
|
|
||||||
4. 查询特定主题:
|
2. 查询特定主题:
|
||||||
{"query_intent": "Python,编程,项目", "seed_entities": ["Python"]}
|
{"query_intent": "Python,编程,项目", "seed_entities": ["Python"]}
|
||||||
|
|
||||||
5. 查询最近7天的记忆:
|
3. 查询最近7天的记忆:
|
||||||
{"query_intent": "任务,工作", "time_range": {"days": 7}}
|
{"query_intent": "任务,工作", "time_range": {"days": 7}}
|
||||||
|
|
||||||
【重要】每轮对话必须按顺序执行:
|
【重要】跳过步骤1或步骤2将导致系统错误!""",
|
||||||
- 步骤1: 查询人设图(最高优先级)
|
|
||||||
- 步骤2: 查询工作记忆链(维持对话连贯性)
|
|
||||||
- 步骤3: 根据需要查询其他记忆""",
|
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
Reference in New Issue
Block a user