关于 genesys-memory
Papez 是面向 AI Agent 的开源因果记忆库,核心是评分引擎、因果图和生命周期管理器。它以原生 MCP 服务的形式提供 13 个工具,适合需要长期、可解释记忆的开发者。
主要功能
- 01基于相关性、连接度和激活度的评分
- 02内存因果图与边的类型化关系
- 03记忆修正与新旧版本取代机制
- 04低分记忆的自动遗忘与修剪
- 05可选 JSON 持久化,无数据库依赖
适用场景
- 01为 AI Agent 保存跨会话的决策与上下文
- 02追溯某项决定的因果链路
- 03对过时或冲突的记忆进行修正与清理
MCP 相关
Papez 以 stdio MCP 服务形式运行,向客户端提供 memory_store、memory_recall、memory_traverse 等 13 个记忆工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx genesys-memoryOPENAI_API_KEY密钥OpenAI API key for embedding generation (optional — use GENESYS_EMBEDDER=local for no API key)ANTHROPIC_API_KEY密钥Anthropic API key for LLM-based memory processing (optional)GENESYS_EMBEDDEREmbedding provider: 'openai' or 'local' (default: openai)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Papez
AI 记忆的智能层。
Papez 不只是记住发生了什么,还会记住为什么。它将评分引擎、因果图和生命周期管理器结合起来,用于 AI Agent 记忆,并原生支持 MCP。
LoCoMo 基准测试(已认证)
| 系统 | 分数 | 协议 |
|---|---|---|
| Papez | 85.55 ± 0.37 | 固定配置:gpt-4o-mini 答题器 + 判定器,temp 0,n=1,540,类别 1–4,10 次运行(2026 年 7 月) |
| Zep | 75.14 | 可比的已发布配置 |
| Mem0 | 66.9 | 可比的已发布配置(Mem0 论文) |
供应商自行报告的 90 分以上成绩采用了不同的答题器/判定器,因此不可比较——在此固定协议下,检索的理论上限为 94.9。你可以自行复现:Astrix-Labs/locomo-harness · 完整方法 · 每次运行的结果。
托管产品: papez.ai — 你的 AI 个人记忆,可在 ChatGPT、Claude 和所有 MCP 应用间延续 · 定价 · 开发者文档 · 基准测试方法(LoCoMo 得分 85.55,经过 10 次运行认证,并已公布凭证)
这是什么
Papez 是一个用于 AI 记忆的评分引擎、因果图和生命周期管理器。记忆根据乘法公式(相关性 × 连通性 × 重新激活)评分,在因果图中相互连接,并会在变得无关时主动遗忘。
此软件包(papez)是核心库:一个支持可选 JSON 持久化的内存因果图引擎,以及一个 stdio MCP 服务。它不依赖数据库,也不提供 REST API。基于此库构建的托管产品另行提供于 api.papez.ai,其中包含 Postgres、其他存储后端以及 REST/HTTP MCP API;这些都不属于此软件包。
为什么选择 Papez
- 扁平记忆无法扩展。 将所有内容都塞进向量存储,只会让你能够回忆,却无法理解。第 500 条记忆会淹没那 5 条重要记忆。
- 不遗忘,就没有智能。 真正的记忆系统会遗忘。没有主动清理,你的 AI 就会被过时的上下文淹没。
- 无法进行因果推理。 向量相似度无法回答“我为什么选择 X?”——你需要一张图。
你的 AI 记住了一切,却什么都不理解。Papez 能解决这个问题。
快速开始
需要 Python 3.11 或更高版本。
安装软件包。基础安装不依赖任何数据库——状态保存在内存中,也可以选择持久化到 JSON 文件。
pip install papez
可选扩展:
pip install 'papez[openai]' # OpenAI embeddings
pip install 'papez[local]' # Local embeddings (sentence-transformers, no API key)
pip install 'papez[anthropic]' # LLM-based causal inference (consolidation, contradiction detection)
直接运行 stdio MCP 服务:
python3 -m papez
从源代码安装
git clone https://github.com/Astrix-Labs/papez.git
cd papez
pip install -e '.[dev]'
pytest tests/
连接到你的 AI
Claude Code
claude mcp add papez -- python -m papez
Claude Desktop
添加到你的 claude_desktop_config.json:
{
"mcpServers": {
"papez": {
"command": "python",
"args": ["-m", "papez"]
}
}
}
可靠性与重试
stdio 服务是一个本地独立进程。在负载较高时,或其前方的托管传输正在重启或重新部署时,工具调用可能会暂时失败,连接也可能短暂无响应。内存写入和读取不值得让 Agent 一轮对话崩溃,因此客户端应优雅降级,而不是将内存调用视为致命错误:
- 服务端也会优雅降级:工具异常(或缺少必需参数)会以结构化的
{"error": "...", "retryable": bool}载荷返回,而不是触发协议级 MCP 故障,因此内存暂时不可用不会导致传输崩溃。retryable标志会按以下说明提供指引——仅对读取工具为true。 - 重试幂等读取操作(
memory_recall、memory_search、memory_traverse、memory_explain、memory_stats),并采用短暂且有上限的退避策略(例如尝试 2–3 次)。除了重新激活记录外,这些操作没有值得担心的副作用。 - 遇到不确定的超时,不要盲目重试
memory_store/memory_amend——如果首次调用已静默成功,之后的重试会创建重复节点。优先继续当前轮,并在下次memory_recall时核对;或者传入稳定的source_session,以便轻松发现重复项。 - 将内存视为尽力提供的上下文,而非硬性依赖。 如果调用失败,请使用已有上下文继续,并在下一轮再试,而不是中止。图谱是持久的;漏掉一次写入可以恢复,崩溃的 Agent 轮则无法恢复。
MCP 工具
| 工具 | 描述 |
|---|---|
memory_store | 存储一条新记忆。使用 related 指定写入者提供的带类型边({id, type});related_to 是旧版参数,始终创建 caused_by 边。category 可选。可能返回 possible_conflicts(启发式提示)。 |
memory_amend | 记录一项更正:创建一条取代现有记忆的新记忆。旧记忆会保留(在回忆时衰减),而不会被删除。 |
memory_recall | 根据自然语言查询回忆记忆(向量 + 关键词 + 图谱扩散激活)。支持 verbosity: "concise",以返回轻量载荷。 |
memory_search | 按状态、类别、日期(since)、最后活跃日期(active_since)或实体筛选向量搜索。传入空查询可按时间顺序枚举(无需嵌入模型)——结合 since / active_since,无需知道要查询什么即可回答“自上次查看以来有什么新内容”。 |
memory_traverse | 从一个节点遍历因果图。返回可到达的节点及诱导子图中的边(source/target/type/weight/created_by)——其结果是 BFS 树的超集,因此可以还原路径。支持 edge_types。 |
memory_explain | 解释一条记忆的分数。包含 score_model 区块(公式 + 实时的各作用力明细 + 过时说明)和 removal_impact。 |
memory_stats | 获取内存系统统计信息 |
pin_memory | 固定一条记忆,使其永不被遗忘 |
unpin_memory | 取消固定之前固定的记忆 |
delete_memory | 永久删除一条记忆 |
list_core_memories | 列出核心记忆,可按类别筛选 |
set_core_preferences | 设置核心记忆类别的用户偏好 |
promote_to_org | 将私有记忆提升为组织可见 |
作者指定的边及更正
memory_store 的 related 参数允许作者设置边的语义,而不是由系统猜测。每个条目均为 {"id": "<node-id>", "type": "<edge-type>"},方向为
new_node --type--> target(因此,supersedes 表示新节点取代目标节点)。无效类型会在创建节点之前被拒绝——显式写入绝不会只成功一部分。related_to 仍然存在,但始终会创建 caused_by;建议优先使用 related。
要更正事实,请使用 memory_amend(node_id, content, reason=...):它会存储新版本,将其关联为 SUPERSEDES → old,并保留旧记忆以供审计。
Recall 会自动降低被取代记忆的优先级,并为其添加 superseded_by 标签。
当你使用 memory_store 存储的内容与自动关联候选项在字面上不一致(例如数字变化或出现否定词)时,结果可能包含
possible_conflicts——这些是启发式提示,并非已验证的矛盾,也绝不会被具体化为边。请用它们来判断是否需要执行 memory_amend。
简洁 Recall
memory_recall(query, verbosity="concise") 会跳过因果链增强,每条命中仅返回 id / summary / status / score / activation / is_core(若已设置,还包括 superseded_by)——对高频查找来说,令牌开销低得多。verbosity="full"(默认值)保持不变。两种模式下仍会进行重新激活写入(它们由 read_only 控制,而非 verbosity)。
请参阅 docs/scoring.md,了解 activation / decay_score 的实际含义——简而言之,它是一个保留权重,在记忆被 Recall 时会升高,而不是删除倒计时。
工作原理
每条记忆的得分由三种因素相乘得出:
decay_score = relevance × connectivity × reactivation
- 相关性会随时间衰减。旧记忆会逐渐淡化,除非得到强化。
- 连接度会奖励具有许多因果链接的记忆。枢纽记忆能够留存。
- 重新激活会提升反复被 Recall 的记忆。频率很重要。
由于公式采用乘法,记忆必须在所有三个维度上都获得分数才能留存。连接度很高但从未访问的记忆仍会衰减。频繁被 Recall 但在因果关系上孤立的记忆仍会淡化。
decay_score(每条命中中都以 activation 为别名)是保留权重,而非删除倒计时——Recall 记忆会使其升高,低分只表示“处于休眠状态”,并不意味着“注定要被删除”。只有同时满足以下所有条件才会删除:得分低、孤立、未固定、非核心、非组织级,且处于闲置状态(30 天内未存储、Recall 或重新激活,GENESYS_FORGETTING_MIN_IDLE_DAYS)。stdio 服务每 10 分钟运行一次重新评分、状态转换和清理流程(GENESYS_MAINTENANCE_INTERVAL_S;设为 0 可禁用)。完整模型及计算示例请参阅 docs/scoring.md。
STORE → ACTIVE → DORMANT → FADING → PRUNED
↑ │
└── reactivation ────┘
(only if score=0, orphan, not pinned)
记忆还可以提升为核心状态——这类记忆在结构上十分重要,会自动固定,且永不清理。
基准测试结果
请参阅本 README 顶部的已认证 LoCoMo 结果:在冻结协议下运行 10 次,得分为 85.55 ± 0.37(gpt-4o-mini 回答器和评审器、温度 0、n=1,540、类别 1–4)。类别 5——包含有争议真实答案的对抗性问题——不纳入统计,这与可比的已发布测试设置一致。
每次运行都可复现:测试工具位于 Astrix-Labs/locomo-harness,完整方法说明和各次运行结果均已发布。仓库内各场景的复现脚本位于 benchmarks/。
存储后端
此软件包提供一个存储后端:内存因果图(storage/memory.py),并可通过 GENESYS_PERSIST_PATH 选择性启用 JSON 持久化。无需数据库。
其他后端——Postgres/pgvector、FalkorDB、MongoDB 和 Obsidian vault 适配器——以及 REST API、OAuth 和多用户身份验证,均属于托管产品 api.papez.ai,不包含在此仓库中。
想为开源库使用其他存储后端?请在 storage/base.py 中实现 provider 协议,并自行提供所需组件。
配置
将 .env.example 复制为 .env,并设置:
| 变量 | 必需 | 描述 |
|---|---|---|
OPENAI_API_KEY | 除非 GENESYS_EMBEDDER=local | 嵌入 |
ANTHROPIC_API_KEY | 否 | 启用基于 LLM 的因果推断(整合、矛盾检测)。默认关闭——若未设置,因果边仅来自调用方在 memory_store 中明确声明的边,以及余弦相似度链接。 |
GENESYS_EMBEDDER | 否 | openai(默认)或 local(sentence-transformers,无需 API 密钥) |
GENESYS_PERSIST_PATH | 否 | 用于在重启后持久化状态的 JSON 文件路径(否则使用内存) |
GENESYS_USER_ID | 否 | 单租户模式下的默认用户 ID |
自动链接调优
自动链接会将新存储的记忆连接到语义相似的已有记忆。如果规则过于宽松,就会形成“毛线团”——所有内容最终都与其他内容相距约 2 跳,从而破坏遍历范围。以下三个参数用于限制它:
| 变量 | 默认值 | 描述 |
|---|---|---|
GENESYS_AUTOLINK_MIN_SIMILARITY | 嵌入器建议值 | 创建自动链接的余弦相似度下限。明确设置的值优先于嵌入器默认值。 |
GENESYS_AUTOLINK_MAX_EDGES | 3 | 单次 memory_store 最多可创建的自动链接数。限制扇出。 |
GENESYS_AUTOLINK_MAX_NODE_DEGREE | 10 | 任意单个节点作为目标时可累积的 auto_link 边数上限。仅限制扇出仍会让枢纽节点在每次存储时永久增加一条边;此参数会限制枢纽节点本身。 |
此下限会根据嵌入器调整:自动链接是永久的图结构,因此其下限高于临时的召回下限。若未设置 GENESYS_AUTOLINK_MIN_SIMILARITY,则有效下限采用嵌入器的建议值——OpenAI 为 0.6(text-embedding-3-small 的真实匹配通常聚集在约 0.5 以上),本地 sentence-transformers 为 0.45(其真实匹配通常聚集在约 0.2–0.4,但已观察到噪声对达到约 0.44,因此本地仅会自动链接近乎重复的内容)。任何未知嵌入器均回退至 0.45。自动链接还会去重:若一对节点已通过任何边连接(例如 user_explicit caused_by),则不会再创建并行的 auto_link related_to。
memory_store 上的 possible_conflicts 提示会使用自身较低的下限(GENESYS_CONFLICT_MIN_SIMILARITY,默认为召回下限)进行扫描,并使用更大的窗口(GENESYS_CONFLICT_SCAN_K,默认值为 8)——因此,提高自动链接下限不会缩小矛盾检测范围。
召回 / 相关性下限
召回过滤也遵循相同的嵌入器自适应模式:
| 变量 | 默认值 | 描述 |
|---|---|---|
GENESYS_RECALL_MIN_SIMILARITY | 嵌入器建议值(OpenAI 为 0.5 / 其他为 0.2) | 纯向量命中低于此余弦相似度下限时,会从 memory_recall 中丢弃。关键词命中不受此限制。 |
GENESYS_CORE_INJECT_MIN_SIMILARITY | 嵌入器建议值(OpenAI 为 0.45 / 其他为 0.2) | 将自动提升的核心记忆注入召回结果的下限。固定记忆始终会被注入。 |
评分参数
三力评分公式及其生命周期阈值均可通过环境变量配置(参见 engine/config.py 和
docs/scoring.md):GENESYS_ACTR_DECAY、
GENESYS_RELEVANCE_VECTOR_WEIGHT、GENESYS_RELEVANCE_KEYWORD_WEIGHT、
GENESYS_MIN_CONNECTIVITY、GENESYS_FORGETTING_THRESHOLD、GENESYS_DORMANCY_*
转换阈值,以及 GENESYS_CORE_* 晋升权重。
所有选项请参见 .env.example。
构建者
Papez 由 Rishi Meka 在 Astrix Labs 开发。它源于每次会话都要向 Claude 重新解释项目上下文所带来的困扰。其目标是构建位于你的大模型与记忆之间的智能层,并完全开源。
贡献
参见 CONTRIBUTING.md。
许可证
注意: v0.3.6 之前的 Papez 版本文档曾误标为 Apache 2.0。LICENSE 文件始终包含 AGPLv3 文本。从 v0.3.6 起,所有文档均正确标注为 AGPL-3.0-or-later,并附有贡献者许可协议。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。