Refactor: Modularize tools and prompts system

This commit is contained in:
JianFeeeee
2026-04-11 16:50:33 +08:00
parent 4be27fdac7
commit 01bf67aa66
18 changed files with 1388 additions and 1911 deletions

View File

@ -0,0 +1,7 @@
"""
工具定义模块
"""
from .memory_tools import TOOLS
from .tool_executor import execute_tool
__all__ = ["TOOLS", "execute_tool"]

View 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

View 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
}