Refactor: Modularize tools and prompts system
This commit is contained in:
7
graph_memory_tui/core/tools/__init__.py
Normal file
7
graph_memory_tui/core/tools/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
"""
|
||||
工具定义模块
|
||||
"""
|
||||
from .memory_tools import TOOLS
|
||||
from .tool_executor import execute_tool
|
||||
|
||||
__all__ = ["TOOLS", "execute_tool"]
|
||||
323
graph_memory_tui/core/tools/memory_tools.py
Normal file
323
graph_memory_tui/core/tools/memory_tools.py
Normal file
@ -0,0 +1,323 @@
|
||||
"""
|
||||
记忆工具定义 - 优化版
|
||||
精简描述,避免过拟合,保留AI自主性
|
||||
"""
|
||||
|
||||
# 基础记忆工具
|
||||
MEMORY_TOOLS = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_recall",
|
||||
"description": "检索记忆。支持关键词、时间范围、会话过滤。返回相关实体和关系。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query_intent": {
|
||||
"type": "string",
|
||||
"description": "查询意图,支持逗号分隔多个关键词"
|
||||
},
|
||||
"seed_entities": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "种子实体(可选)"
|
||||
},
|
||||
"depth": {
|
||||
"type": "integer",
|
||||
"description": "遍历深度,默认2"
|
||||
},
|
||||
"time_range": {
|
||||
"type": "object",
|
||||
"description": "时间范围(可选)",
|
||||
"properties": {
|
||||
"days": {"type": "integer", "description": "最近N天"}
|
||||
}
|
||||
},
|
||||
"session_filter": {
|
||||
"type": "string",
|
||||
"description": "会话ID过滤(可选)"
|
||||
}
|
||||
},
|
||||
"required": ["query_intent"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_commit",
|
||||
"description": "写入记忆。将三元组写入图数据库,支持批量写入。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"triplets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"subject": {"type": "string"},
|
||||
"relation": {"type": "string"},
|
||||
"object": {"type": "string"},
|
||||
"confidence": {"type": "number"}
|
||||
},
|
||||
"required": ["subject", "relation", "object"]
|
||||
},
|
||||
"description": "三元组列表"
|
||||
},
|
||||
"entity_types": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "实体类型(可选)"
|
||||
},
|
||||
"temporal_tag": {
|
||||
"type": "string",
|
||||
"description": "时间标记(可选)"
|
||||
}
|
||||
},
|
||||
"required": ["triplets"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_purge",
|
||||
"description": "删除记忆。支持条件删除和纠错替代。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"criteria": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"subject_contains": {"type": "string"},
|
||||
"relation_type": {"type": "string"},
|
||||
"target_contains": {"type": "string"},
|
||||
"time_before": {"type": "string"},
|
||||
"session_id": {"type": "string"}
|
||||
},
|
||||
"description": "删除条件"
|
||||
},
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": ["soft", "supersede"],
|
||||
"description": "删除模式:soft=逻辑删除, supersede=纠错替代",
|
||||
"default": "soft"
|
||||
},
|
||||
"new_relation": {
|
||||
"type": "object",
|
||||
"description": "新关系(supersede模式)",
|
||||
"properties": {
|
||||
"relation": {"type": "string"},
|
||||
"target": {"type": "string"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["criteria"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_introspect",
|
||||
"description": "查看记忆状态。返回会话统计、实体热点、关系分布。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"session_id": {
|
||||
"type": "string",
|
||||
"description": "会话ID(可选)"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_archive",
|
||||
"description": "归档旧记忆。将N天前的非活跃关系标记为归档状态。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"days": {
|
||||
"type": "integer",
|
||||
"description": "归档天数,默认30"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "memory_cleanup",
|
||||
"description": "清理无效数据。物理删除已删除状态超过90天的关系和孤立节点。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dry_run": {
|
||||
"type": "boolean",
|
||||
"description": "仅预览不删除",
|
||||
"default": True
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# 人设图管理工具
|
||||
PERSONA_TOOLS = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "persona_update",
|
||||
"description": "更新人设。修改AI的角色、性格、语气等属性。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"attributes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"attribute": {"type": "string", "description": "属性名(如:扮演角色、说话风格、性格特点)"},
|
||||
"value": {"type": "string", "description": "属性值"}
|
||||
},
|
||||
"required": ["attribute", "value"]
|
||||
},
|
||||
"description": "人设属性列表"
|
||||
},
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": ["replace", "merge"],
|
||||
"description": "更新模式:replace=替换, merge=合并",
|
||||
"default": "merge"
|
||||
}
|
||||
},
|
||||
"required": ["attributes"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "persona_clear",
|
||||
"description": "清除人设。删除AI的角色设定,恢复默认身份。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"confirm": {
|
||||
"type": "boolean",
|
||||
"description": "确认清除",
|
||||
"default": True
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# 工作记忆链管理工具
|
||||
WORKING_MEMORY_TOOLS = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "task_create",
|
||||
"description": "创建任务节点。用于跟踪连续性任务。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": {
|
||||
"type": "string",
|
||||
"description": "任务ID(如:Task_001)"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "任务概述"
|
||||
},
|
||||
"info_nodes": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "关联的信息节点名称(可选)"
|
||||
}
|
||||
},
|
||||
"required": ["task_id", "description"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "task_set_state",
|
||||
"description": "设置任务状态。支持:进行中、已完成、已暂停、已取消。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": {
|
||||
"type": "string",
|
||||
"description": "任务ID"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": ["进行中", "已完成", "已暂停", "已取消"],
|
||||
"description": "任务状态"
|
||||
}
|
||||
},
|
||||
"required": ["task_id", "state"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "task_delete",
|
||||
"description": "删除任务节点。同时删除关联的信息节点。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": {
|
||||
"type": "string",
|
||||
"description": "任务ID"
|
||||
},
|
||||
"delete_info_nodes": {
|
||||
"type": "boolean",
|
||||
"description": "是否删除关联的信息节点",
|
||||
"default": True
|
||||
}
|
||||
},
|
||||
"required": ["task_id"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "task_link_info",
|
||||
"description": "关联信息节点。将记忆节点关联到任务节点。",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": {
|
||||
"type": "string",
|
||||
"description": "任务ID"
|
||||
},
|
||||
"info_node_names": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "信息节点名称列表"
|
||||
}
|
||||
},
|
||||
"required": ["task_id", "info_node_names"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# 所有工具
|
||||
TOOLS = MEMORY_TOOLS + PERSONA_TOOLS + WORKING_MEMORY_TOOLS
|
||||
307
graph_memory_tui/core/tools/tool_executor.py
Normal file
307
graph_memory_tui/core/tools/tool_executor.py
Normal file
@ -0,0 +1,307 @@
|
||||
"""
|
||||
工具执行器
|
||||
"""
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
|
||||
|
||||
def execute_tool(graph: Any, tool_name: str, arguments: dict) -> str:
|
||||
"""执行工具调用"""
|
||||
print(f"\n[工具调用] {tool_name}")
|
||||
print(f"[参数] {json.dumps(arguments, ensure_ascii=False, indent=2)}")
|
||||
|
||||
try:
|
||||
# 基础记忆工具
|
||||
if tool_name == "memory_recall":
|
||||
result = graph.recall(
|
||||
query_intent=arguments.get("query_intent", ""),
|
||||
seed_entities=arguments.get("seed_entities"),
|
||||
depth=arguments.get("depth", 2),
|
||||
time_range=arguments.get("time_range"),
|
||||
session_filter=arguments.get("session_filter")
|
||||
)
|
||||
return format_recall_result(result)
|
||||
|
||||
elif tool_name == "memory_commit":
|
||||
result = graph.commit(
|
||||
triplets=arguments.get("triplets", []),
|
||||
entity_types=arguments.get("entity_types"),
|
||||
temporal_tag=arguments.get("temporal_tag")
|
||||
)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "memory_purge":
|
||||
result = graph.purge(
|
||||
criteria=arguments.get("criteria", {}),
|
||||
mode=arguments.get("mode", "soft"),
|
||||
new_relation=arguments.get("new_relation")
|
||||
)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "memory_introspect":
|
||||
result = graph.introspect(session_id=arguments.get("session_id"))
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "memory_archive":
|
||||
result = graph.archive(days=arguments.get("days", 30))
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "memory_cleanup":
|
||||
result = graph.cleanup(dry_run=arguments.get("dry_run", True))
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
# 人设图管理工具
|
||||
elif tool_name == "persona_update":
|
||||
result = execute_persona_update(graph, arguments)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "persona_clear":
|
||||
result = execute_persona_clear(graph, arguments)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
# 工作记忆链管理工具
|
||||
elif tool_name == "task_create":
|
||||
result = execute_task_create(graph, arguments)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "task_set_state":
|
||||
result = execute_task_set_state(graph, arguments)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "task_delete":
|
||||
result = execute_task_delete(graph, arguments)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
elif tool_name == "task_link_info":
|
||||
result = execute_task_link_info(graph, arguments)
|
||||
return json.dumps(result, ensure_ascii=False, default=str)
|
||||
|
||||
return f"未知工具: {tool_name}"
|
||||
|
||||
except Exception as e:
|
||||
return f"工具执行错误: {str(e)}"
|
||||
|
||||
|
||||
def format_recall_result(result: dict) -> str:
|
||||
"""格式化检索结果"""
|
||||
lines = ["===== 记忆检索结果 ====="]
|
||||
|
||||
if result.get("entities"):
|
||||
lines.append(f"\n实体 ({len(result['entities'])} 个):")
|
||||
for e in result["entities"]:
|
||||
if e and isinstance(e, dict):
|
||||
lines.append(f" - {e.get('name', 'N/A')} (类型: {e.get('type', 'unknown')}, 提及: {e.get('mention_count', 1)}次)")
|
||||
|
||||
if result.get("relations"):
|
||||
lines.append(f"\n关系 ({len(result['relations'])} 条):")
|
||||
for r in result["relations"]:
|
||||
if r and isinstance(r, dict):
|
||||
lines.append(f" - {r.get('source', 'N/A')} --[{r.get('type', 'N/A')}]--> {r.get('target', 'N/A')}")
|
||||
created = r.get("created_at", "N/A")
|
||||
if created and created != "N/A":
|
||||
created = created[:19] if "T" in str(created) else str(created)
|
||||
session_id = r.get('session_id', 'N/A')
|
||||
session_display = session_id[:20] if session_id and session_id != 'N/A' else 'N/A'
|
||||
lines.append(f" 时间: {created}, 会话: {session_display}, 轮次: {r.get('turn_id', 0)}, 置信度: {r.get('confidence', 1.0)}")
|
||||
|
||||
if not result.get("entities") and not result.get("relations"):
|
||||
lines.append("\n(未找到相关记忆)")
|
||||
|
||||
lines.append("=" * 30)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
# 人设图管理工具实现
|
||||
def execute_persona_update(graph: Any, arguments: dict) -> dict:
|
||||
"""更新人设"""
|
||||
attributes = arguments.get("attributes", [])
|
||||
mode = arguments.get("mode", "merge")
|
||||
|
||||
if mode == "replace":
|
||||
# 先清除旧人设
|
||||
graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "扮演角色"},
|
||||
mode="soft"
|
||||
)
|
||||
graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "说话风格"},
|
||||
mode="soft"
|
||||
)
|
||||
graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "性格特点"},
|
||||
mode="soft"
|
||||
)
|
||||
|
||||
# 写入新人设
|
||||
triplets = []
|
||||
for attr in attributes:
|
||||
triplets.append({
|
||||
"subject": "AI",
|
||||
"relation": attr["attribute"],
|
||||
"object": attr["value"],
|
||||
"confidence": 1.0
|
||||
})
|
||||
|
||||
result = graph.commit(triplets=triplets)
|
||||
return {
|
||||
"status": "success",
|
||||
"mode": mode,
|
||||
"updated_attributes": len(attributes),
|
||||
"details": result
|
||||
}
|
||||
|
||||
|
||||
def execute_persona_clear(graph: Any, arguments: dict) -> dict:
|
||||
"""清除人设"""
|
||||
if not arguments.get("confirm", True):
|
||||
return {"status": "cancelled", "message": "需要确认才能清除人设"}
|
||||
|
||||
# 删除所有人设相关关系
|
||||
result1 = graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "扮演角色"},
|
||||
mode="soft"
|
||||
)
|
||||
result2 = graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "说话风格"},
|
||||
mode="soft"
|
||||
)
|
||||
result3 = graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "性格特点"},
|
||||
mode="soft"
|
||||
)
|
||||
result4 = graph.purge(
|
||||
criteria={"subject_contains": "AI", "relation_type": "语气特征"},
|
||||
mode="soft"
|
||||
)
|
||||
|
||||
total_deleted = (
|
||||
result1.get("deleted_count", 0) +
|
||||
result2.get("deleted_count", 0) +
|
||||
result3.get("deleted_count", 0) +
|
||||
result4.get("deleted_count", 0)
|
||||
)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"deleted_count": total_deleted,
|
||||
"message": "人设已清除,恢复默认身份"
|
||||
}
|
||||
|
||||
|
||||
# 工作记忆链管理工具实现
|
||||
def execute_task_create(graph: Any, arguments: dict) -> dict:
|
||||
"""创建任务节点"""
|
||||
task_id = arguments.get("task_id")
|
||||
description = arguments.get("description")
|
||||
info_nodes = arguments.get("info_nodes", [])
|
||||
|
||||
# 创建任务节点
|
||||
triplets = [
|
||||
{"subject": task_id, "relation": "is_type", "object": "TaskNode"},
|
||||
{"subject": task_id, "relation": "has_description", "object": description},
|
||||
{"subject": task_id, "relation": "HAS_STATE", "object": "State_进行中"}
|
||||
]
|
||||
|
||||
result = graph.commit(triplets=triplets)
|
||||
|
||||
# 关联信息节点
|
||||
if info_nodes:
|
||||
link_triplets = []
|
||||
for node_name in info_nodes:
|
||||
link_triplets.append({
|
||||
"subject": task_id,
|
||||
"relation": "CONTAINS_INFO",
|
||||
"object": node_name
|
||||
})
|
||||
graph.commit(triplets=link_triplets)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"task_id": task_id,
|
||||
"description": description,
|
||||
"info_nodes": info_nodes,
|
||||
"details": result
|
||||
}
|
||||
|
||||
|
||||
def execute_task_set_state(graph: Any, arguments: dict) -> dict:
|
||||
"""设置任务状态"""
|
||||
task_id = arguments.get("task_id")
|
||||
state = arguments.get("state")
|
||||
|
||||
# 删除旧状态
|
||||
graph.purge(
|
||||
criteria={"subject_contains": task_id, "relation_type": "HAS_STATE"},
|
||||
mode="soft"
|
||||
)
|
||||
|
||||
# 设置新状态
|
||||
state_node = f"State_{state}"
|
||||
result = graph.commit(
|
||||
triplets=[{"subject": task_id, "relation": "HAS_STATE", "object": state_node}]
|
||||
)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"task_id": task_id,
|
||||
"new_state": state,
|
||||
"details": result
|
||||
}
|
||||
|
||||
|
||||
def execute_task_delete(graph: Any, arguments: dict) -> dict:
|
||||
"""删除任务节点"""
|
||||
task_id = arguments.get("task_id")
|
||||
delete_info_nodes = arguments.get("delete_info_nodes", True)
|
||||
|
||||
# 查询关联的信息节点
|
||||
if delete_info_nodes:
|
||||
recall_result = graph.recall(
|
||||
query_intent=f"{task_id},CONTAINS_INFO",
|
||||
depth=1
|
||||
)
|
||||
|
||||
# 删除信息节点
|
||||
for relation in recall_result.get("relations", []):
|
||||
if relation.get("type") == "CONTAINS_INFO" and relation.get("source") == task_id:
|
||||
info_node = relation.get("target")
|
||||
graph.purge(
|
||||
criteria={"subject_contains": info_node},
|
||||
mode="soft"
|
||||
)
|
||||
|
||||
# 删除任务节点
|
||||
result = graph.purge(
|
||||
criteria={"subject_contains": task_id},
|
||||
mode="soft"
|
||||
)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"task_id": task_id,
|
||||
"deleted_info_nodes": delete_info_nodes,
|
||||
"details": result
|
||||
}
|
||||
|
||||
|
||||
def execute_task_link_info(graph: Any, arguments: dict) -> dict:
|
||||
"""关联信息节点"""
|
||||
task_id = arguments.get("task_id")
|
||||
info_node_names = arguments.get("info_node_names", [])
|
||||
|
||||
triplets = []
|
||||
for node_name in info_node_names:
|
||||
triplets.append({
|
||||
"subject": task_id,
|
||||
"relation": "CONTAINS_INFO",
|
||||
"object": node_name
|
||||
})
|
||||
|
||||
result = graph.commit(triplets=triplets)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"task_id": task_id,
|
||||
"linked_nodes": info_node_names,
|
||||
"details": result
|
||||
}
|
||||
Reference in New Issue
Block a user