feat(memory): 添加自动关联功能及相关配置支持

This commit is contained in:
Windpicker-owo
2025-11-05 22:15:47 +08:00
parent c5c70d3cf7
commit ae60eae6dc
5 changed files with 561 additions and 28 deletions

View File

@@ -86,6 +86,11 @@ class MemoryGraphConfig:
consolidation_similarity_threshold: float = 0.85
consolidation_time_window_hours: int = 24
# 自动关联配置
auto_link_enabled: bool = True # 是否启用自动关联
auto_link_max_candidates: int = 5 # 每个记忆最多关联候选数
auto_link_min_confidence: float = 0.7 # 最低置信度阈值
# 遗忘配置
forgetting_enabled: bool = True
forgetting_activation_threshold: float = 0.1
@@ -145,6 +150,9 @@ class MemoryGraphConfig:
consolidation_interval_hours=getattr(mg_config, 'consolidation_interval_hours', 1.0),
consolidation_similarity_threshold=getattr(mg_config, 'consolidation_similarity_threshold', 0.85),
consolidation_time_window_hours=getattr(mg_config, 'consolidation_time_window_hours', 24),
auto_link_enabled=getattr(mg_config, 'auto_link_enabled', True),
auto_link_max_candidates=getattr(mg_config, 'auto_link_max_candidates', 5),
auto_link_min_confidence=getattr(mg_config, 'auto_link_min_confidence', 0.7),
forgetting_enabled=getattr(mg_config, 'forgetting_enabled', True),
forgetting_activation_threshold=getattr(mg_config, 'forgetting_activation_threshold', 0.1),
forgetting_min_importance=getattr(mg_config, 'forgetting_min_importance', 0.8),
@@ -183,6 +191,9 @@ class MemoryGraphConfig:
consolidation_interval_hours=config_dict.get("consolidation_interval_hours", 1.0),
consolidation_similarity_threshold=config_dict.get("consolidation_similarity_threshold", 0.85),
consolidation_time_window_hours=config_dict.get("consolidation_time_window_hours", 24),
auto_link_enabled=config_dict.get("auto_link_enabled", True),
auto_link_max_candidates=config_dict.get("auto_link_max_candidates", 5),
auto_link_min_confidence=config_dict.get("auto_link_min_confidence", 0.7),
forgetting_enabled=config_dict.get("forgetting_enabled", True),
forgetting_activation_threshold=config_dict.get("forgetting_activation_threshold", 0.1),
forgetting_min_importance=config_dict.get("forgetting_min_importance", 0.8),

View File

@@ -17,12 +17,13 @@ from typing import Any, Dict, List, Optional, Set, Tuple
from src.memory_graph.config import MemoryGraphConfig
from src.memory_graph.core.builder import MemoryBuilder
from src.memory_graph.core.extractor import MemoryExtractor
from src.memory_graph.models import Memory, MemoryNode, MemoryType, NodeType
from src.memory_graph.models import Memory, MemoryEdge, MemoryNode, MemoryType, NodeType, EdgeType
from src.memory_graph.storage.graph_store import GraphStore
from src.memory_graph.storage.persistence import PersistenceManager
from src.memory_graph.storage.vector_store import VectorStore
from src.memory_graph.tools.memory_tools import MemoryTools
from src.memory_graph.utils.embeddings import EmbeddingGenerator
import uuid
logger = logging.getLogger(__name__)
@@ -851,6 +852,376 @@ class MemoryManager:
logger.error(f"记忆整理失败: {e}", exc_info=True)
return {"error": str(e), "merged_count": 0, "checked_count": 0}
async def auto_link_memories(
self,
time_window_hours: float = None,
max_candidates: int = None,
min_confidence: float = None,
) -> Dict[str, Any]:
"""
自动关联记忆
使用LLM分析记忆之间的关系自动建立关联边。
Args:
time_window_hours: 分析时间窗口(小时)
max_candidates: 每个记忆最多关联的候选数
min_confidence: 最低置信度阈值
Returns:
关联结果统计
"""
if not self._initialized:
await self.initialize()
# 使用配置值或参数覆盖
time_window_hours = time_window_hours if time_window_hours is not None else 24
max_candidates = max_candidates if max_candidates is not None else self.config.auto_link_max_candidates
min_confidence = min_confidence if min_confidence is not None else self.config.auto_link_min_confidence
try:
logger.info(f"开始自动关联记忆 (时间窗口={time_window_hours}h)...")
result = {
"checked_count": 0,
"linked_count": 0,
"relation_stats": {}, # 关系类型统计 {类型: 数量}
"relations": {}, # 详细关系 {source_id: [关系列表]}
}
# 1. 获取时间窗口内的记忆
time_threshold = datetime.now() - timedelta(hours=time_window_hours)
all_memories = self.graph_store.get_all_memories()
recent_memories = [
mem for mem in all_memories
if mem.created_at >= time_threshold
and not mem.metadata.get("forgotten", False)
]
if len(recent_memories) < 2:
logger.info("记忆数量不足,跳过自动关联")
return result
logger.info(f"找到 {len(recent_memories)} 条待关联记忆")
# 2. 为每个记忆寻找关联候选
for memory in recent_memories:
result["checked_count"] += 1
# 跳过已经有很多连接的记忆
existing_edges = len([
e for e in memory.edges
if e.edge_type == EdgeType.RELATION
])
if existing_edges >= 10:
continue
# 3. 使用向量搜索找候选记忆
candidates = await self._find_link_candidates(
memory,
exclude_ids={memory.id},
max_results=max_candidates
)
if not candidates:
continue
# 4. 使用LLM分析关系
relations = await self._analyze_memory_relations(
source_memory=memory,
candidate_memories=candidates,
min_confidence=min_confidence
)
# 5. 建立关联
for relation in relations:
try:
# 创建关联边
edge = MemoryEdge(
id=f"edge_{uuid.uuid4().hex[:12]}",
source_id=memory.subject_id,
target_id=relation["target_memory"].subject_id,
relation=relation["relation_type"],
edge_type=EdgeType.RELATION,
importance=relation["confidence"],
metadata={
"auto_linked": True,
"confidence": relation["confidence"],
"reasoning": relation["reasoning"],
"created_at": datetime.now().isoformat(),
}
)
# 添加到图
self.graph_store.graph.add_edge(
edge.source_id,
edge.target_id,
edge_id=edge.id,
relation=edge.relation,
edge_type=edge.edge_type.value,
importance=edge.importance,
metadata=edge.metadata,
)
# 同时添加到记忆的边列表
memory.edges.append(edge)
result["linked_count"] += 1
# 更新统计
result["relation_stats"][relation["relation_type"]] = \
result["relation_stats"].get(relation["relation_type"], 0) + 1
# 记录详细关系
if memory.id not in result["relations"]:
result["relations"][memory.id] = []
result["relations"][memory.id].append({
"target_id": relation["target_memory"].id,
"relation_type": relation["relation_type"],
"confidence": relation["confidence"],
"reasoning": relation["reasoning"],
})
logger.info(
f"建立关联: {memory.id[:8]} --[{relation['relation_type']}]--> "
f"{relation['target_memory'].id[:8]} "
f"(置信度={relation['confidence']:.2f})"
)
except Exception as e:
logger.warning(f"建立关联失败: {e}")
continue
# 保存更新后的图数据
if result["linked_count"] > 0:
await self.persistence.save_graph_store(self.graph_store)
logger.info(f"已保存 {result['linked_count']} 条自动关联边")
logger.info(f"自动关联完成: {result}")
return result
except Exception as e:
logger.error(f"自动关联失败: {e}", exc_info=True)
return {"error": str(e), "checked_count": 0, "linked_count": 0}
async def _find_link_candidates(
self,
memory: Memory,
exclude_ids: Set[str],
max_results: int = 5,
) -> List[Memory]:
"""
为记忆寻找关联候选
使用向量相似度 + 时间接近度找到潜在相关记忆
"""
try:
# 获取记忆的主题
topic_node = next(
(n for n in memory.nodes if n.node_type == NodeType.TOPIC),
None
)
if not topic_node or not topic_node.content:
return []
# 使用主题内容搜索相似记忆
candidates = await self.search_memories(
query=topic_node.content,
top_k=max_results * 2,
include_forgotten=False,
optimize_query=False,
)
# 过滤:排除自己和已关联的
existing_targets = {
e.target_id for e in memory.edges
if e.edge_type == EdgeType.RELATION
}
filtered = [
c for c in candidates
if c.id not in exclude_ids
and c.id not in existing_targets
]
return filtered[:max_results]
except Exception as e:
logger.warning(f"查找候选失败: {e}")
return []
async def _analyze_memory_relations(
self,
source_memory: Memory,
candidate_memories: List[Memory],
min_confidence: float = 0.7,
) -> List[Dict[str, Any]]:
"""
使用LLM分析记忆之间的关系
Args:
source_memory: 源记忆
candidate_memories: 候选记忆列表
min_confidence: 最低置信度
Returns:
关系列表,每项包含:
- target_memory: 目标记忆
- relation_type: 关系类型
- confidence: 置信度
- reasoning: 推理过程
"""
try:
from src.llm_models.utils_model import LLMRequest
from src.config.config import model_config
# 构建LLM请求
llm = LLMRequest(
model_set=model_config.model_task_config.utils_small,
request_type="memory.relation_analysis"
)
# 格式化记忆信息
source_desc = self._format_memory_for_llm(source_memory)
candidates_desc = "\n\n".join([
f"记忆{i+1}:\n{self._format_memory_for_llm(mem)}"
for i, mem in enumerate(candidate_memories)
])
# 构建提示词
prompt = f"""你是一个记忆关系分析专家。请分析源记忆与候选记忆之间是否存在有意义的关系。
**关系类型说明:**
- 导致: A的发生导致了B的发生因果关系
- 引用: A提到或涉及B引用关系
- 相似: A和B描述相似的内容相似关系
- 相反: A和B表达相反的观点对立关系
- 关联: A和B存在某种关联但不属于以上类型一般关联
**源记忆:**
{source_desc}
**候选记忆:**
{candidates_desc}
**任务要求:**
1. 对每个候选记忆,判断是否与源记忆存在关系
2. 如果存在关系,指定关系类型和置信度(0.0-1.0)
3. 简要说明判断理由
4. 只返回置信度 >= {min_confidence} 的关系
**输出格式JSON**
```json
[
{{
"candidate_id": 1,
"has_relation": true,
"relation_type": "导致",
"confidence": 0.85,
"reasoning": "记忆1是记忆源的结果"
}},
{{
"candidate_id": 2,
"has_relation": false,
"reasoning": "两者无明显关联"
}}
]
```
请分析并输出JSON结果"""
# 调用LLM
response, _ = await llm.generate_response_async(
prompt,
temperature=0.3,
max_tokens=1000,
)
# 解析响应
import json
import re
# 提取JSON
json_match = re.search(r'```json\s*(.*?)\s*```', response, re.DOTALL)
if json_match:
json_str = json_match.group(1)
else:
json_str = response.strip()
try:
analysis_results = json.loads(json_str)
except json.JSONDecodeError:
logger.warning(f"LLM返回格式错误尝试修复: {response[:200]}")
# 尝试简单修复
json_str = re.sub(r'[\r\n\t]', '', json_str)
analysis_results = json.loads(json_str)
# 转换为结果格式
relations = []
for result in analysis_results:
if not result.get("has_relation", False):
continue
confidence = result.get("confidence", 0.0)
if confidence < min_confidence:
continue
candidate_id = result.get("candidate_id", 0) - 1
if 0 <= candidate_id < len(candidate_memories):
relations.append({
"target_memory": candidate_memories[candidate_id],
"relation_type": result.get("relation_type", "关联"),
"confidence": confidence,
"reasoning": result.get("reasoning", ""),
})
logger.debug(f"LLM分析完成: 发现 {len(relations)} 个关系")
return relations
except Exception as e:
logger.error(f"LLM关系分析失败: {e}", exc_info=True)
return []
def _format_memory_for_llm(self, memory: Memory) -> str:
"""格式化记忆为LLM可读的文本"""
try:
# 获取关键节点
subject_node = next(
(n for n in memory.nodes if n.node_type == NodeType.SUBJECT),
None
)
topic_node = next(
(n for n in memory.nodes if n.node_type == NodeType.TOPIC),
None
)
object_node = next(
(n for n in memory.nodes if n.node_type == NodeType.OBJECT),
None
)
parts = []
parts.append(f"类型: {memory.memory_type.value}")
if subject_node:
parts.append(f"主体: {subject_node.content}")
if topic_node:
parts.append(f"主题: {topic_node.content}")
if object_node:
parts.append(f"对象: {object_node.content}")
parts.append(f"重要性: {memory.importance:.2f}")
parts.append(f"时间: {memory.created_at.strftime('%Y-%m-%d %H:%M')}")
return " | ".join(parts)
except Exception as e:
logger.warning(f"格式化记忆失败: {e}")
return f"记忆ID: {memory.id}"
async def maintenance(self) -> Dict[str, Any]:
"""
执行维护任务
@@ -885,17 +1256,22 @@ class MemoryManager:
)
result["consolidated"] = consolidate_result.get("merged_count", 0)
# 2. 自动遗忘
# 2. 自动关联记忆(发现和建立关系)
if self.config.auto_link_enabled:
link_result = await self.auto_link_memories()
result["linked"] = link_result.get("linked_count", 0)
# 3. 自动遗忘
if self.config.forgetting_enabled:
forgotten_count = await self.auto_forget_memories(
threshold=self.config.forgetting_activation_threshold
)
result["forgotten"] = forgotten_count
# 3. 清理非常旧的已遗忘记忆(可选)
# 4. 清理非常旧的已遗忘记忆(可选)
# TODO: 实现清理逻辑
# 4. 保存数据
# 5. 保存数据
await self.persistence.save_graph_store(self.graph_store)
result["saved"] = True

View File

@@ -42,6 +42,7 @@ class EdgeType(Enum):
ATTRIBUTE = "属性关系" # 任意节点 → 属性
CAUSALITY = "因果关系" # 记忆 → 记忆
REFERENCE = "引用关系" # 记忆 → 记忆(转述)
RELATION = "关联关系" # 记忆 → 记忆(自动关联发现的关系)
class MemoryStatus(Enum):

View File

@@ -387,9 +387,81 @@ class GraphStore:
for node_id, mem_ids in data.get("node_to_memories", {}).items():
store.node_to_memories[node_id] = set(mem_ids)
# 5. 同步图中的边到 Memory.edges保证内存对象和图一致
try:
store._sync_memory_edges_from_graph()
except Exception:
logger.exception("同步图边到记忆.edges 失败")
logger.info(f"从字典加载图: {store.get_statistics()}")
return store
def _sync_memory_edges_from_graph(self) -> None:
"""
将 NetworkX 图中的边重建为 MemoryEdge 并注入到对应的 Memory.edges 列表中。
目的:当从持久化数据加载时,确保 memory_index 中的 Memory 对象的
edges 列表反映图中实际存在的边(避免只有图中存在而 memory.edges 为空的不同步情况)。
规则:对于图中每条边(u, v, data),会尝试将该边注入到所有包含 u 或 v 的记忆中(避免遗漏跨记忆边)。
已存在的边(通过 edge.id 检查)将不会重复添加。
"""
from src.memory_graph.models import MemoryEdge
# 构建快速查重索引memory_id -> set(edge_id)
existing_edges = {mid: {e.id for e in mem.edges} for mid, mem in self.memory_index.items()}
for u, v, data in self.graph.edges(data=True):
# 兼容旧数据edge_id 可能在 data 中,或叫 id
edge_id = data.get("edge_id") or data.get("id") or ""
edge_dict = {
"id": edge_id or "",
"source_id": u,
"target_id": v,
"relation": data.get("relation", ""),
"edge_type": data.get("edge_type", data.get("edge_type", "")),
"importance": data.get("importance", 0.5),
"metadata": data.get("metadata", {}),
"created_at": data.get("created_at", "1970-01-01T00:00:00"),
}
# 找到相关记忆(包含源或目标节点)
related_memory_ids = set()
if u in self.node_to_memories:
related_memory_ids.update(self.node_to_memories[u])
if v in self.node_to_memories:
related_memory_ids.update(self.node_to_memories[v])
for mid in related_memory_ids:
mem = self.memory_index.get(mid)
if mem is None:
continue
# 检查是否已存在
if edge_dict["id"] and edge_dict["id"] in existing_edges.get(mid, set()):
continue
try:
# 使用 MemoryEdge.from_dict 构建对象
mem_edge = MemoryEdge.from_dict(edge_dict)
except Exception:
# 兼容性:直接构造对象
mem_edge = MemoryEdge(
id=edge_dict["id"] or "",
source_id=edge_dict["source_id"],
target_id=edge_dict["target_id"],
relation=edge_dict["relation"],
edge_type=edge_dict["edge_type"],
importance=edge_dict.get("importance", 0.5),
metadata=edge_dict.get("metadata", {}),
)
mem.edges.append(mem_edge)
existing_edges.setdefault(mid, set()).add(mem_edge.id)
logger.info("已将图中的边同步到 Memory.edges保证 graph 与 memory 对象一致)")
def remove_memory(self, memory_id: str) -> bool:
"""
从图中删除指定记忆

View File

@@ -73,38 +73,84 @@ class MemoryTools:
"""
return {
"name": "create_memory",
"description": "创建一个新的记忆。记忆由主体、类型、主题、客体(可选)和属性组成。",
"description": """创建一个新的记忆节点。
⚠️ 记忆创建原则(必须遵守):
1. **价值判断**:只创建具有长期价值的关键信息,避免记录日常闲聊、礼貌用语、重复信息
2. **细粒度原则**:每条记忆只包含一个明确的事实/事件/观点,避免泛化
3. **原子性**:如果一句话包含多个重要信息点,拆分成多条独立记忆
4. **具体性**:记录具体的人、事、物、时间、地点,避免模糊描述
❌ 不应创建记忆的情况:
- 普通问候、感谢、确认等礼貌性对话
- 已存在的重复信息
- 临时性、一次性的琐碎信息
- 纯粹的功能操作指令(如"帮我查一下"
- 缺乏上下文的碎片化信息
✅ 应该创建记忆的情况:
- 用户的个人信息(姓名、职业、兴趣、联系方式等)
- 重要事件(项目进展、重大决定、关键行动等)
- 长期偏好/观点(喜好、价值观、习惯等)
- 人际关系变化(新朋友、合作关系等)
- 具体计划/目标(明确的待办事项、长期目标等)
📝 拆分示例:
- ❌ "用户喜欢编程最近在学Python和机器学习" → 过于泛化
- ✅ 拆分为3条
1. "用户喜欢编程"(观点)
2. "用户正在学习Python"(事件)
3. "用户正在学习机器学习"(事件)
记忆结构:主体 + 类型 + 主题 + 客体(可选)+ 属性""",
"parameters": {
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "记忆的主体,通常是'''用户'或具体的人名",
"description": "记忆的主体,通常是'用户'或具体的人名(避免使用''",
},
"memory_type": {
"type": "string",
"enum": ["事件", "事实", "关系", "观点"],
"description": "记忆类型:事件时间绑定的动作)、事实稳定状态)、关系人际关系)、观点主观评价)",
"description": "记忆类型:\n- 事件时间绑定的具体动作(如'完成项目''学习课程'\n- 事实稳定的客观状态(如'职业是工程师''住在北京'\n- 关系人际关系(如'认识了朋友''同事关系'\n- 观点主观评价/偏好(如'喜欢Python''认为AI很重要'",
},
"topic": {
"type": "string",
"description": "记忆的主题,即发生的事情或状态",
"description": "记忆的核心主题,必须具体且明确(如'学习PyTorch框架'而非'学习编程'",
},
"object": {
"type": "string",
"description": "记忆的客体,即主题作用的对象(可选",
"description": "记忆的客体/对象,作为主题的补充说明(如主题是'学习',客体可以是'PyTorch框架'",
},
"attributes": {
"type": "object",
"description": "记忆的属性,如时间、地点、原因、方式等",
"description": "记忆的具体属性(尽量填写以增加记忆的信息密度)",
"properties": {
"时间": {
"type": "string",
"description": "时间表达式,如'今天''昨天''3天前''2025-11-05'",
"description": "具体时间表达式,如'2025-11-05''今天下午''最近一周''3天前'",
},
"地点": {
"type": "string",
"description": "具体地点(如果相关)"
},
"原因": {
"type": "string",
"description": "事件发生的原因或动机(如果明确)"
},
"方式": {
"type": "string",
"description": "完成的方式或途径(如果相关)"
},
"结果": {
"type": "string",
"description": "事件的结果或影响(如果已知)"
},
"状态": {
"type": "string",
"description": "当前状态(如'进行中''已完成''计划中'"
},
"地点": {"type": "string", "description": "地点"},
"原因": {"type": "string", "description": "原因"},
"方式": {"type": "string", "description": "方式"},
},
"additionalProperties": True,
},
@@ -112,7 +158,7 @@ class MemoryTools:
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "记忆的重要性0-1之间的浮点数默认0.5",
"description": "记忆的重要性评分0.0-1.0\n- 0.3-0.4: 次要信息\n- 0.5-0.6: 一般信息\n- 0.7-0.8: 重要信息(用户明确表达的偏好、重要事件)\n- 0.9-1.0: 关键信息(核心个人信息、重大决定、强烈偏好)\n默认0.5",
},
},
"required": ["subject", "memory_type", "topic"],
@@ -129,27 +175,42 @@ class MemoryTools:
"""
return {
"name": "link_memories",
"description": "关联两个已存在的记忆,建立因果或引用关系。",
"description": """手动关联两个已存在的记忆
⚠️ 使用建议:
- 系统会自动发现记忆间的关联关系,通常不需要手动调用此工具
- 仅在以下情况使用:
1. 用户明确指出两个记忆之间的关系
2. 发现明显的因果关系但系统未自动关联
3. 需要建立特殊的引用关系
关系类型说明:
- 导致A事件/行为导致B事件/结果(因果关系)
- 引用A记忆引用/基于B记忆知识关联
- 相似A和B描述相似的内容主题相似
- 相反A和B表达相反的观点对比关系
- 关联A和B存在一般性关联其他关系""",
"parameters": {
"type": "object",
"properties": {
"source_memory_description": {
"type": "string",
"description": "源记忆的描述用于查找对应的记忆",
"description": "源记忆的关键描述用于搜索定位,需要足够具体)",
},
"target_memory_description": {
"type": "string",
"description": "目标记忆的描述用于查找对应的记忆",
"description": "目标记忆的关键描述用于搜索定位,需要足够具体)",
},
"relation_type": {
"type": "string",
"description": "关系类型,如'导致''''因为''所以''引用''基于'",
"enum": ["导致", "", "相似", "相反", "关联"],
"description": "关系类型从上述5种类型中选择最合适的",
},
"importance": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "关系的重要性0-1之间的浮点数默认0.6",
"description": "关系的重要性0.0-1.0\n- 0.5-0.6: 一般关联\n- 0.7-0.8: 重要关联\n- 0.9-1.0: 关键关联\n默认0.6",
},
},
"required": [
@@ -170,13 +231,25 @@ class MemoryTools:
"""
return {
"name": "search_memories",
"description": "搜索相关的记忆。支持语义搜索、图遍历和时间过滤。",
"description": """搜索相关的记忆,用于回忆和查找历史信息。
使用场景:
- 用户询问之前的对话内容
- 需要回忆用户的个人信息、偏好、经历
- 查找相关的历史事件或观点
- 基于上下文补充信息
搜索特性:
- 语义搜索:基于内容相似度匹配
- 图遍历:自动扩展相关联的记忆
- 时间过滤:按时间范围筛选
- 类型过滤:按记忆类型筛选""",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索查询,描述要查找的记忆内容",
"description": "搜索查询(用自然语言描述要查找的内容,如'用户的职业''最近的项目''Python相关的记忆'",
},
"memory_types": {
"type": "array",
@@ -184,33 +257,33 @@ class MemoryTools:
"type": "string",
"enum": ["事件", "事实", "关系", "观点"],
},
"description": "要搜索的记忆类型,可多选",
"description": "记忆类型过滤(可选,留空表示搜索所有类型)",
},
"time_range": {
"type": "object",
"properties": {
"start": {
"type": "string",
"description": "开始时间'3天前''2025-11-01'",
"description": "开始时间'3天前''上周''2025-11-01'",
},
"end": {
"type": "string",
"description": "结束时间'今天''2025-11-05'",
"description": "结束时间'今天''现在''2025-11-05'",
},
},
"description": "时间范围过滤(可选)",
"description": "时间范围(可选,用于查找特定时间段的记忆",
},
"top_k": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"description": "返回结果数量默认10",
"description": "返回结果数量1-50默认10。根据需求调整\n- 快速查找3-5条\n- 一般搜索10条\n- 全面了解20-30条",
},
"expand_depth": {
"type": "integer",
"minimum": 0,
"maximum": 3,
"description": "遍历扩展深度0表示不扩展默认1",
"description": "图扩展深度0-3默认1\n- 0: 仅返回直接匹配的记忆\n- 1: 包含一度相关的记忆(推荐)\n- 2-3: 包含更多间接相关的记忆(用于深度探索)",
},
},
"required": ["query"],