mcpField
S
spomory

spomory

远程服务
github.com/yliuai记忆与知识15 天前更新
代码仓库

关于 spomory

Spomory 是一个 MCP 服务,可在不同 AI 客户端和会话间共享持久记忆。它以图结构检索和管理记忆,并提供保存、查找、查看及删除事实的工具。

主要功能

  1. 01跨客户端和会话共享记忆
  2. 02增量更新知识图谱
  3. 03基于图的多跳检索
  4. 04添加、更新、删除或跳过事实
  5. 05查看并导出记忆图谱
  6. 06本地或托管部署

适用场景

  1. 01跨客户端会话回忆项目细节
  2. 02在不同客户端复用个人偏好
  3. 03查看记忆图谱中的关联事实
  4. 04导出或删除已存记忆

MCP 相关

Spomory 通过 MCP 工具提供记忆操作,包括添加、搜索、删除、查看和导出信息。它既可本地运行,也可作为托管服务运行。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://api.yliuai.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://api.yliuai.com/mcp
Streamable HTTPhttps://api.yliuai.com/mcp-apikey需要授权
安装包
pypispomory0.3.1

工具

详细介绍

Spomory

English | 中文

Spomory 为 AI 客户端提供可跨会话持久保存的记忆,并在所有客户端之间共享。只需告诉其中一个客户端一次(例如项目细节、偏好或个人情况),之后任何客户端都能将其回忆起来,无需你重复说明。它是一个 MCP 服务,因此兼容所有 MCP 的客户端:Claude Desktop、Cursor、Codex CLI 和豆包均已通过真实客户端会话完成端到端验证(请参阅下文“它能做什么”);**ModelScope、Coze 和阿里云百炼(Alibaba Cloud Bailian)**也已知兼容,连接方式与其他远程 MCP 客户端相同(使用 Streamable HTTP;百炼目前尚不支持 Streamable HTTP,因此需使用 SSE)。

它以 MCP 服务的形式运行,可在你自己的设备上本地运行(免费,数据不会离开你的电脑),也可作为托管云服务运行(免费注册,记忆可在不同设备间同步)——上述每个客户端都支持这两种方式。本 README 其余部分将介绍本地使用方式(下文“开始使用”介绍的就是这种方式);开始使用云服务最快捷的方式是访问 Web 应用 spomory.yliuai.com/get-started/remote。 每个客户端各自的本地/云端配置详见 docs/mcp_quickstart.en.md(按客户端分节——Claude Desktop/Cursor/Codex CLI/豆包——每节均介绍两种连接方式)。

想先了解它的实际功能,再决定是否安装?无需注册即可在 spomory.yliuai.com体验演示——粘贴一些文本,看看它如何将文本转换为结构化事实。这些事实之后会在你连接的 Claude、Cursor、Codex CLI 及其他所有客户端间同步,并跨会话持久保存,而不是每次重置。

开始使用

需要 Python 3.11+。

1. 安装。 也可以完全跳过这一步——第 3 步的配置可以直接指向 uvx,它会按需获取并运行,无需预先安装:

pip install "spomory[llm,embedding,mcp]"

2. 为它提供一个大模型。 Spomory 使用大模型将你告诉它的内容转换为结构化事实。任何兼容 OpenAI 的 API 都可以——OpenAI、DeepSeek、Qwen 等:

export LLM_API_KEY=sk-...
export LLM_BASE_URL=https://api.deepseek.com   # optional, defaults to OpenAI
export LLM_MODEL=deepseek-chat                 # optional, defaults to gpt-4o-mini

3. 将它连接到你的客户端。 Claude Desktop、Cursor 和 Codex CLI 都需要在配置文件中添加几行,指向 spomory-mcp 命令。具体步骤、每个客户端的配置文件示例,以及我们遇到的一个实际问题(macOS 会阻止运行位于 ~/Documents 下的虚拟环境),请参阅 docs/mcp_quickstart.en.md。

没有配置文件的客户端——Doubao(豆包)、Coze、ModelScope——则通过可点击操作的“自定义连接器”表单连接(URL + 请求头,或用于本地进程的命令 + 参数 + 环境变量);请参阅同一文档中的 Doubao 部分 (现在每个客户端——Claude Desktop、Cursor、Codex CLI、Doubao——都有独立的部分,并在其下按 STDIO/HTTP/OAuth 分类)。

最容易让人踩坑的一点:配置中需要填写 spomory-mcp 的绝对路径(运行 which spomory-mcp 即可查找)——客户端启动它时不一定会设置你的 shell 的 PATH。如果 command 使用 uvx,这个问题(以及第 1 步)就都不复存在——具体 JSON 请参阅快速入门指南。

就是这样。默认情况下,数据存储在本地的 ~/.memory-core/(可通过 MEMORY_CORE_DATA_DIR 覆盖)。此外还提供了一个 Dockerfile,适用于从容器镜像部署的 MCP 目录/主机。

连接后还值得立即做两件事:将 skill/spomory/SKILL.md 复制到客户端的技能目录,让它实际调用这些工具,而不是闲置在那里;如果你已经在使用 Claude Code、Codex 或 Cursor,还可以运行 spomory-import-sessions --client claude-code(或 codex/cursor),从真实的会话历史中初始化图谱,而不是从零开始。这两项内容都在快速入门指南中介绍。

想让大模型调用也在本地运行,而不是使用云 API?将 LLM_BASE_URL 指向任意本地 OpenAI 兼容服务端——vLLM、Ollama、llama.cpp 或 MLX 都可以——并设置 EMBEDDING_PROVIDER=openai_compatible,以相同方式处理嵌入,而不是使用本地的 sentence-transformers 模型,从而完全移除 torch 依赖。详情和各引擎的示例请参阅 docs/mcp_quickstart.en.md。

功能介绍

连接后,客户端中即可使用六种工具:

工具功能
add_memory记住你告诉它的内容
search_memory回忆与问题相关的内容
forget_memory删除与你要求遗忘的内容最匹配的一项
forget_all_memory一次调用即可清除整个记忆图谱
get_graph显示某项内容周围的记忆图谱,供检查
export_memory将你存储的所有内容导出为 JSON——数据可移植

这六种工具都已通过真实的 Claude Desktop、Cursor、Codex CLI 和 Doubao 会话完成端到端验证,涵盖本地和远程场景——各客户端的“验证”具体含义请参阅 docs/mcp_quickstart.en.md。

工作原理(供好奇者了解)

使用 Spomory 并不需要了解以下内容——这里是为想知道底层实际运作方式的人准备的。

  • 可插拔的大模型 / 嵌入提供方:默认使用任何兼容 OpenAI 的 API(包括中国市场的大模型提供方)+ 本地 sentence-transformers(默认使用 bge-m3,支持中英双语)。
  • 双层增量知识图谱:实体和关系作为独立层建模;新数据只会被提取并合并进来, 不会全量重建。完全匹配的填充性输入(“thanks”“好的”“ok”……)会在到达提取大模型调用前被跳过, 因为其中不可能包含可提取的事实——这对于任何未经身份验证的端点都是相关的成本保护措施。默认使用本地 LocalGraphStore (networkx + SQLite);此外还有 PostgresGraphStore 云端实现,两者共用同一套行为契约测试。
  • HippoRAG 2 风格的检索:查询会直接与三元组匹配,而不只是与实体节点匹配;匹配到的种子节点 会通过个性化 PageRank 进行扩散,以实现多跳关联,随后组装成自然语言上下文(包含来源时间戳,因此可以回答 “我什么时候提到过 X”)。此外,排序会随着某条关系越来越久未被检索而降低其相关性;同一事实被重述的 次数越多,相关性就会相应提升(采用对数阻尼,因此不会压过 PPR 排名)——这是下方主动执行的 ADD/UPDATE/DELETE/NOOP 决策之外的一种被动信号。
  • 记忆管理:包含 ADD/UPDATE/DELETE/NOOP 操作空间,以及基于规则的默认策略(RuleBasedPolicy)和完整的 GRPO 训练 流程(memory_manager/train_grpo.py,已在真实 GPU 上实际运行并验证)。
  • 记忆护照导出 + 彻底删除:JSON-LD 风格的导出格式、物理删除和审计日志。
  • 多模态图像验证:图像描述 → 复用文本提取流程 → CLIP 交叉核验候选三元组。准确来说,这是“验证”, 而非“原生跨模态提取”。
  • 云端框架:FastAPI 用户身份验证/API 密钥/配额,以及 Stripe webhook 计费脚手架(仅为框架级别,尚未部署到生产环境)。

测量结果

使用 DeepSeek 对 LoCoMo-10(conv-26,前 150 轮)中的 84 组问答进行真实运行——没有挑选有利样本,目前还无法与更大型项目已发布的结果相媲美:

指标值
Recall@10(正确的证据轮次是否进入上下文)52.4%
准确率 — 严格子字符串匹配19.0%
准确率 — LLM 评判(标准较宽松,容忍措辞差异)44.0%

此前的一次运行(在修复将日期合并到提取出的谓词中、使“何时”类问题能够回答之前)准确率较低,但召回率较高(62.0%)——这项修复牺牲了一些检索召回率,换来了实际 +14.3 个百分点的准确率提升;我们还进一步查明了具体原因,而不只是报告准确率:日期合并指令有时会误用于没有实际内容的闲聊(“Thanks!” → “thanked on 2023-07-03”),这些低价值三元组会挤占固定的 top-10 检索窗口,让相关三元组无法进入。完整数据、分类别细分结果,以及用于发现这一问题的提取结果并排比较,见 docs/benchmark_smoke_test.md。

LongMemEval(xiaowu0162/longmemeval-cleaned 的 oracle 变体,500 个问题中的前 10 个):

指标值
Recall@10100%(10/10)
准确率 — 严格子字符串匹配30%
准确率 — LLM 评判80%

这里的局限性与数据本身同样重要:

  1. 仅 10 个问题,并非完整的 500 个——每个问题平均会导入约 27 轮对话(约 27 次实际提取调用,加上一次生成调用和一次评判调用);此环境中的 LLM API 调用需要经过代理,实际延迟较高;完整数据集需要数十小时才能跑完。这是真实运行,并非模拟,但样本量很小,不应将结果视为可推广到完整数据集。
  2. 这 10 个问题恰好全都是 temporal-reasoning 类型——数据集还包含 multi-session 类型;load_longmemeval(limit=10) 按文件顺序取前 10 条,没有进行分层抽样,因此该样本并不代表整个数据集。
  3. Recall@10 = 100% 很大程度上是 oracle 变体设计造成的结果,并不能有力证明检索能力——oracle 变体会预先筛选每个问题的候选内容,只保留相关会话(没有干扰会话),这比真实部署中的记忆存储(包含数百或数千条无关对话轮次)容易得多。这与完整的(非 oracle)LongMemEval 基准测试并非同一任务,不应直接与其他产品在难度更高的变体上报告的数据进行比较。
  4. 严格匹配准确率(30%)远低于 LLM 评判准确率(80%),与 LoCoMo 结果中观察到的模式一致——子字符串匹配会系统性地低估内容正确但措辞不同的答案。

原始数据: benchmarks/results/longmemeval_oracle_subset.json; 运行脚本为 benchmarks/run_longmemeval_subset.py。

贡献者指南:从源代码构建

以下内容适用于希望深入研究内部实现、运行测试套件,或使用 MCP 服务运行所需依赖组之外的其他依赖组(GPU 训练、云 API 骨架、多模态验证)的贡献者。如果你只想使用 Spomory,则无需了解这些内容——请参阅上文的“开始使用”。

项目结构
src/
├── memory_core/
│   ├── graph/            # entity/relation models, storage adapters (local SQLite / cloud Postgres), incremental writes
│   ├── retrieval/        # query→triple matching, personalized PageRank, context assembly
│   ├── memory_manager/   # action space, reward functions, GRPO training script, policy inference
│   ├── multimodal/       # image captioning + CLIP verification
│   ├── mcp_server/       # MCP Server (the distribution entry point)
│   ├── export/           # memory passport export format + true delete
│   ├── llm/              # pluggable LLM/embedding providers
│   ├── audit.py          # deletion audit log
│   └── usage.py          # retention/usage tracking
└── cloud_api/            # FastAPI cloud service skeleton (auth, quotas, billing)
benchmarks/                # LoCoMo/LongMemEval evaluation harness + multimodal comparison experiments
tests/                     # 94+ tests, from unit tests to real LLM/GPU/Postgres end-to-end verification
docs/                      # per-epic design notes, verification reports, runbooks (see index below)
设置开发环境

前置条件:Python 3.11+、uv (没有 uv?可以用 python -m venv + pip install -e 替代下面的 uv 命令)。

git clone <this repo's URL> memory-core && cd memory-core
uv venv --python 3.11 .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

# Pick dependency groups as needed — they can be combined, no need to install everything:
uv pip install -e ".[dev]"                 # required to run tests/lint
uv pip install -e ".[llm,embedding]"       # required for the "minimal working memory system" (see the demo below)
uv pip install -e ".[mcp]"                 # extra: connecting to Claude Desktop/Cursor
uv pip install -e ".[rl]"                  # extra: GRPO training (requires a GPU + CUDA)
uv pip install -e ".[cloud]"               # extra: cloud API / Postgres backend
uv pip install -e ".[multimodal]"          # extra: image + CLIP verification

embedding 依赖组会在首次使用时从 HuggingFace 下载默认模型 BAAI/bge-m3 (约 2.2GB)——请确保可以访问 huggingface.co (如果你位于 Great Firewall 后方,运行 export HF_ENDPOINT=https://hf-mirror.com 即可通过镜像访问)。你也可以通过 export EMBEDDING_MODEL=<any sentence-transformers model name> 换用更小的模型。

运行最简示例(不使用 MCP,直接调用 Python)

安装 dev + llm + embedding,并设置好“开始使用”中的三个环境变量后,这个脚本会直接运行完整的“写入记忆 → 检索记忆”流程(逻辑与 mcp_server/server.py 中的 add_memory/search_memory 工具相同,只是直接调用库,而不是通过 MCP 协议层):

# demo.py
from memory_core.graph.local_store import LocalGraphStore
from memory_core.graph.incremental import IncrementalIngestor
from memory_core.llm.openai_compatible import OpenAICompatibleProvider
from memory_core.llm.local_sentence_transformer import SentenceTransformerProvider
from memory_core.memory_manager.policy import RuleBasedPolicy
from memory_core.retrieval.ppr import personalized_pagerank, rank_entities
from memory_core.retrieval.query_match import match_query_to_triples
from memory_core.retrieval.ranker import build_context

store = LocalGraphStore("demo.sqlite3")          # a local file; delete it to reset
llm = OpenAICompatibleProvider()                 # reads LLM_API_KEY etc. from the environment
embedder = SentenceTransformerProvider()         # downloads bge-m3 on first run

# 1. Write a memory: the LLM extracts triples, incrementally merged into the graph
ingestor = IncrementalIngestor(store, llm, policy=RuleBasedPolicy())
result = ingestor.ingest("I do AI research at CAS, mostly in Python.", source_id="demo")
print(f"added {result.new_entities} entities, {result.new_relations} relations")

# 2. Retrieve: match the query against triples -> PPR diffusion -> assemble a natural-language context
query = "Where do I work?"
entities, relations = store.all_entities(), store.all_relations()
entities_by_id = {e.id: e for e in entities}
matches = match_query_to_triples(query, relations, entities_by_id, embedder, top_k=10)
seed_ids = {r.relation.subject_id for r in matches} | {r.relation.object_id for r in matches}
scores = personalized_pagerank(entities, relations, seed_entity_ids=list(seed_ids))
ranked_ids = [eid for eid, _ in rank_entities(scores)]
print(build_context(relations, entities_by_id, ranked_ids, top_k=10))
python demo.py

以下是使用 DeepSeek 进行实时运行的实际输出,输入内容与上方完全一致(并非编造,也未清理——这是实际返回的内容):

added 3 entities, 2 relations
I do AI research at CAS (recorded at 2026-09-05 10:40:00).I do AI research mostly in Python (recorded at 2026-09-05 10:40:00).

具体措辞以及实体/关系数量取决于大模型自身的提取结果,并会因运行而异;但只要环境变量设置正确,非空输出就表示整个流程端到端正常运行。 retrieval/ranker.py 会检测关系文本是中文还是其他语言,并相应地渲染(中文不加空格 + 中文时间戳标签,其他语言使用空格分隔单词 + 英文时间戳标签),因此,英文输入不再像这个演示的早期版本那样,输出为一整串连在一起的单词。

测试
pytest                    # everything
pytest -m "not slow"      # skip tests that download models / train — runs in seconds

大多数“耗时较长”的测试都没有使用模拟对象——它们会进行真实调用(真实的大模型 API、真实的本地嵌入模型、真实的 CLIP 模型),因此需要设置相应的环境变量(LLM_API_KEY 等)或已有已下载的模型缓存。

文档索引

文档内容
mcp_quickstart.en.md (中文)MCP 服务安装、配置、连接 Claude Desktop/Cursor/Codex CLI/Doubao,以及实际使用中的注意事项
graph_store_interface.en.md (中文)存储适配器接口设计
export_format.en.md (中文)“记忆护照”导出格式
dataset_format.en.md (中文)GRPO 训练数据格式,以及真实数据集的生成方式
methodology.en.md (中文)技术方法:已验证的内容与仍待验证的内容
benchmark_smoke_test.en.md (中文)LoCoMo 基准测试的真实结果及失败案例分析
memory_manager_eval.en.md (中文)基于规则与经过 GRPO 训练的策略对比,包括调试过程
multimodal_verification.en.md (中文)图像 + CLIP 验证实验结果
gpu_training_runbook.en.md (中文)GPU 训练环境设置记录(包括实际遇到的问题)
postgres_setup.en.md (中文)云 Postgres 后端部署记录
leaderboard_submission.en.md (中文)第三方排行榜调研
mvp_scope.en.md (中文)MVP 范围定义
privacy_policy_draft.en.md (中文) / product_copy_memory_passport.en.md (中文)隐私政策草案 / 面向外部的产品文案
eng_note_cjk_rendering_bug.en.md (中文)工程说明:CJK 渲染错误的实际发现→修复→验证过程

以上每篇文档现在都有中文版和英文版。

已知限制

  • 语音输入的多模态验证(ASR + 音频嵌入)尚未实现。
  • GRPO 训练数据集(140 个真实样本)和训练步数仍然较少;memory_manager_eval.md 如实记录了这些因素对训练效果的限制。
  • 云 API/计费功能目前仅有基础框架,尚未接入真实的生产环境。

许可证

请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。