mcpField
M
memkeeper

memkeeper

本地服务
github.com/teflon07记忆与知识411 周前更新

关于 memkeeper

memkeeper 是面向 AI Agent 的本地优先记忆引擎,将持久上下文保存在单个 SQLite 文件中。它支持词法检索和设备端语义检索,并通过 MCP 跨会话使用。

主要功能

  1. 01单文件 SQLite 存储
  2. 02BM25/FTS 词法搜索
  3. 03设备端语义检索
  4. 04交叉编码器重排
  5. 05人工整理的持久记忆

适用场景

  1. 01跨会话回忆 Agent 事实
  2. 02检索项目决策和偏好
  3. 03将记忆数据保留在本机

MCP 相关

stdio MCP 服务提供 `remember` 和 `search` 工具,供客户端在会话中保存和检索记忆。`hook retrieve` 命令还可将相关记忆注入 Claude Code 提示词。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"teflon07-memkeeper": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/teflon07/memkeeper:0.5.3"
]
}
}
}
启动命令docker run -i --rm ghcr.io/teflon07/memkeeper:0.5.3

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/teflon07/memkeeper:0.5.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

memkeeper 标志

大多数软件只有金鱼般的记忆。这个不一样。

CI 状态 最新版本 许可证:MIT OR Apache-2.0 memkeeper MCP 服务在 Glama 上的质量评分

memkeeper

AI Agent 的本地优先记忆。一个快速、可嵌入的记忆引擎,可完全在你的设备上存储、 排序和检索 Agent 的持久上下文,无需网络连接或大模型调用。

Memkeeper 是 AI Agent 所依托的开源、本地优先控制平面:持久记忆、项目上下文、协调任务交接以及默认拒绝的权限,全都可确定地在你自己的设备上运行。本仓库的核心是记忆引擎。

ℹ️ 生成的发行版镜像。 本仓库由私有开发仓库生成并以发行版形式发布。main 分支可能会 重新生成,因此请固定到带标签的发行版(或发行版资源),而不是任意的 main 提交——带标签的发行版是稳定的。请参阅 CONTRIBUTING.md 了解如何贡献;目前最适合的方式是提交问题、安全 报告和设计反馈。

  • 本地优先。 单个 SQLite 数据库。无需服务、云端或遥测。
  • 提示词时快速检索。 确定性的 BM25/FTS 检索,可选用 ONNX 语义嵌入和交叉编码器重排器。
  • 专为持久性而设计。 原子写入、带架构版本的存储,以及保留模型,可将反复出现且信号强的记忆提升到持久层。

memkeeper 演示:存储两条记忆,然后进行一次语义搜索;尽管查询与已存储记忆没有共同关键词,仍能找到正确的记忆

真实的 CLI 输出,经由 scripts/mkfmt 格式化以便阅读。搜索查询与找到的记忆没有共同关键词。

状态:预发布版(v0.5.3)。API 和线协议在 1.0 之前可能会发生变化。

快速开始

# Install the latest release binary (macOS arm64 / Linux x86_64) to ~/.local/bin.
# It's self-contained — nothing else to install.
curl -fsSL https://raw.githubusercontent.com/teflon07/memkeeper/main/install.sh | bash

# Optional, one-time: fetch on-device semantic models. Lexical search works without it.
memkeeper pull-models

# Create a store, remember something, search it back.
memkeeper init
memkeeper remember --json '{"content":"memkeeper stores memories in a local SQLite database"}'
memkeeper search   --json '{"query":"where are memories stored","limit":3}'

安装就这么简单:一个独立二进制文件,无需运行时网络连接、大模型或 API 密钥。 如果不想把脚本通过管道传给 shell?可从 发行版页面下载二进制文件并验证其 .sha256,或从源代码构建。省略 --store 时,存储默认位于 ~/.memkeeper/store.sqlite;--json 的值也可以是 @<file> 或 -(标准输入),而不是内联字符串,从而避免 shell 引号问题 (在 Windows PowerShell 中尤其方便)。

从 v0.2.x 升级

v0.3.0 引入了从架构 5 升级到架构 6;v0.4.0 到 v0.5.3 保持 架构 6 不变。迁移具有事务性,但 v0.2.x 无法打开架构 6 存储。请停止所有长时间运行的 memkeeper 进程,并保留架构 5 备份,直到确认升级成功。

安装当前版本前,请使用 v0.2.x 二进制文件备份存储:

STORE=~/.memkeeper/store.sqlite
memkeeper backup --store "$STORE" --output "$STORE.schema5.bak" --json

安装当前版本,显式运行迁移,并在重启任何长时间运行的进程前验证结果:

curl -fsSL https://raw.githubusercontent.com/teflon07/memkeeper/main/install.sh | bash
memkeeper init --store "$STORE" --json
memkeeper doctor --store "$STORE" --json

init 可以安全地重复运行。如果需要回滚,请先恢复架构 5 备份,再启动旧版二进制文件。

在你的 Agent 中使用(MCP)

memkeeper 使用 MCP(基于 stdio 的 JSON-RPC 2.0),因此任何 MCP 客户端—— Claude Code、Cursor 等——都能在会话期间读取和写入记忆。将 客户端的 MCP 配置指向原生二进制文件(无需 Python,也无需额外依赖):

{ "mcpServers": { "memkeeper": { "command": "memkeeper", "args": ["mcp"] } } }

Agent 会调用 remember 来记录持久事实,并在之后的不同会话中调用 search 来回忆, 检索效果与 CLI 相同。

memkeeper 通过 MCP 工作:Agent 连接后调用 remember 存储一条事实,然后在之后的会话中调用 search,通过语义检索将其回忆起来

真实的 memkeeper mcp JSON-RPC 请求与响应往返,通过 scripts/mcpfmt 格式化以便阅读。

应存储什么

memkeeper 保存自包含的记忆:事实、决策、偏好和经验教训。每次 remember 都会写入一条可独立成立的记忆,并保留其上下文和意图(存储“用户喜欢在披萨上放菠萝”,而不只是“菠萝”)。原子化意味着每条记忆表达一个想法,而不是删减成一个关键词。检索、去重、取代和实体图在这种粒度下效果最佳。

应避免两个极端:

  • **过于简短:**只有一个关键词或片段,丢失了要点。
  • **过于冗长:**一整篇文档。精选记忆层不进行分块,嵌入器每条记录只会读取约 512 个 token 的开头,因此加载较长文件 (例如整个 Markdown 库)会导致这些记录的语义召回效果较弱(词法 BM25 仍会索引全文)。若要导入整篇文档, 不要将它们存储为记忆——请使用文档存储, 这是 memkeeper 独立的 RAG 层,会将文件分块并嵌入到隔离空间中 (memkeeper-ingest 附加组件可通过这种方式导入整个文件夹)。或者提炼文档要点,并将其作为记忆存储。

捕获记忆

memkeeper 提供的是需要你主动填充的精选记忆,而不是自动记录对话转录。记忆有两种添加方式:

  • 直接添加——通过 CLI 或脚本运行 memkeeper remember --json '{"content":"…"}'。
  • 通过 Agent 添加——原生 MCP 服务允许 MCP 客户端(Claude 和其他 Agent)在会话期间调用 remember,以便在持久事实出现时及时捕获。若已确认的记忆提及实体或陈述了关系,MCP 工具会要求 Agent 在同一次调用中加入有界的图投影。memkeeper 会验证并原子化提交记忆、精确别名和有类型的关系。唯一的记忆 ID 就是关系的证据。

memkeeper 不会为此运行第二个大模型或后台提取器。MCP 宿主 Agent 会在进行常规 remember 调用时提供结构化的图字段。原始 CLI 调用者也可以显式提供相同的 graph 对象。

在检索方面,memkeeper hook retrieve 是一个 Claude Code UserPromptSubmit 钩子客户端,会将相关记忆注入提示词——因此 Agent 无需显式搜索也能回忆。它负责检索;记忆捕获仍需通过 remember 主动完成。

语义检索(默认)

memkeeper 有三种检索模式。本地语义检索是默认模式,也是推荐的完全在设备上运行的模式。 请预先选择一种模式——嵌入后端会记录在存储中,因此更改后端意味着需要重新嵌入(reindex --embed),而不是简单切换。

memkeeper 检索:确定性的 BM25/FTS 基础检索无需任何模型,即可返回精确关键词匹配;加载 ONNX 模型后,即使语义查询与目标记忆没有共同关键词,也能找到正确的记忆

确定性基础检索(零模型、零网络)以及在此基础上进行的语义检索 + 重排——使用同一个存储和同一条查询路径。通过 scripts/mkfmt 获取的实际输出。

模式网络设置
本地语义检索(默认)无安装二进制文件,然后运行 pull-models
仅词法检索无开箱即用;只需跳过 pull-models
设备外语义检索通过 API 生成嵌入设置 MEMKEEPER_EMBED_PROVIDER=openai + base URL + key

隐私: 设备外语义检索会将记忆的文本发送给嵌入服务提供商进行向量化。只有在可以接受的情况下才使用此模式;两种在设备上运行的模式绝不会将记忆内容发送到任何地方。

本地语义检索(默认)

发布版二进制文件已支持语义检索(ONNX 运行时已静态捆绑),因此无需重新构建——只需获取嵌入模型和重排模型,这些模型不会自动下载。只需获取一次:

# Needs curl; ~2.1GB, or --quantized for ~0.6GB (slightly lower recall).
memkeeper pull-models

pull-models 会将模型写入 ~/.memkeeper/models/(可通过 MEMKEEPER_MODELS_DIR 或 --dir 覆盖)——这正是 memkeeper 默认查找模型的位置。因此,无需设置任何环境变量即可启用语义检索:随后运行 search 即可使用。

如果模型缺失,memkeeper 不会静默降级:它会记录模型缺失,并提示你运行 pull-models,将结果标记为语义检索不可用(例如 "semantic":{"attempted":false,"reason":"missing_embedding"}),并回退到词法检索(BM25/FTS),以确保搜索仍能正常工作。对于绝不能静默仅运行词法检索的部署,可设置 MEMKEEPER_REQUIRE_SEMANTIC=1 来严格失败——拒绝请求,而不是提供降级结果。

嵌入会在写入记忆时计算。在模型就绪前存储的记忆(例如上方“快速入门”中存储的记忆)在完成嵌入前只能进行词法检索。运行一次以下命令,为现有记忆补全嵌入:

memkeeper reindex --embed

模型就绪后写入的新记忆会自动进行嵌入。

仅词法检索

跳过 pull-models,发布版二进制文件便会运行确定性的、无模型的仅词法检索(BM25/FTS)——零网络、零模型。从源代码构建时使用 --no-default-features,会生成更精简的二进制文件,并完全省略 ONNX 运行时(参见从源代码构建)。

设备外语义检索(无需下载模型)

不想下载 ONNX 模型?可以改为将 memkeeper 指向兼容 OpenAI 的嵌入 API(OpenAI、OpenRouter 或任何兼容的代理)。此模式通过网络生成嵌入并进行重排,而不是加载本地模型,因此无需运行 pull-models:

# Embeddings (required for semantic): any OpenAI-compatible /embeddings endpoint.
export MEMKEEPER_EMBED_PROVIDER=openai     # "openai" = the OpenAI-compatible API dialect
export MEMKEEPER_EMBED_BASE_URL=https://api.openai.com/v1/embeddings   # or your provider, e.g. OpenRouter
export MEMKEEPER_EMBED_API_KEY=sk-...
export MEMKEEPER_EMBED_MODEL=text-embedding-3-small
export MEMKEEPER_EMBED_DIMS=1536

# Reranking (optional, recommended): Cohere /rerank dialect, which OpenRouter speaks.
export MEMKEEPER_RERANK_PROVIDER=openrouter
export MEMKEEPER_RERANK_API_KEY=sk-...
export MEMKEEPER_RERANK_MODEL=cohere/rerank-v3.5

预构建的发布版二进制文件支持全部三种模式(--features semantic,api):运行 pull-models,即可使用完全在设备上运行的本地语义检索(默认且推荐的模式);配置 API 密钥以使用设备外语义检索;或者不配置任何内容,让它们使用词法检索(BM25/FTS)。设置 MEMKEEPER_REQUIRE_SEMANTIC=1 后,它们会拒绝请求,而不是提供降级结果。

预构建的二进制文件适用于 macOS(Apple Silicon) 和 Linux x86_64。Windows 支持仍处于实验阶段——没有预构建的二进制文件,但可以从源代码构建并运行;参见 docs/windows.md。(其中,serve --socket 仅适用于 Unix;http 仪表板和 stdio 服务则支持跨平台运行。)

pack 如何结合语义检索和图检索

pack 使用一条检索路径。语义匹配和词法匹配提供记忆种子,精确实体和别名匹配提供图种子,而有界、基于证据的图遍历会通过规范记忆 ID 合并两组结果。随后,每个候选项都会进入同一个交叉编码器重排池参与竞争。图候选项没有预留名额,也不会自动降级;生产环境中不存在图检索开关模式。没有符合条件的图检索路径时,存储会原样返回语义和词法检索结果池。

切换嵌入模型

嵌入后端会按存储记录,memkeeper 不允许混用不同模型生成的向量(它们位于不同的向量空间)。要切换模型——在本地与设备外模型之间切换,或切换不同模型——请更改嵌入环境变量,然后在一个步骤中使用新模型重新嵌入每条记忆:

./target/release/memkeeper reindex --embed --store ~/.memkeeper/store.sqlite

此操作会清除旧向量、记录新的当前模型,并在一个事务中重新嵌入所有有效记忆。这是受支持的模型切换方式;不支持部分混用。

文档存储(RAG)

除了整理后的记忆之外,memkeeper 还可以保存单独一层已导入的文档块,用于检索增强场景。文档块存放在独立空间中(默认是 documents),与整理后的记忆层隔离,因此不会经过取代、去重、图处理或提升处理。

  • ingest — 将文档源保存为嵌入后的隔离文档块。再次导入相同的 source_path 时,会就地修复该文档块的来源信息;不同路径下的相同内容会作为独立文档块保留。
  • document-search — 对文档块进行混合搜索(BM25 + 向量),并提供指向 source_path 和文档块索引的引用。
  • document-get — 按路径获取文档的文档块,或按 ID 获取单个文档块。
  • document-duplicates — 将内容完全重复的文档块(不同来源下保存的相同内容)作为集合列出。stats 也会报告 document_duplicate_clusters 数量,让你了解是否存在值得审核的重复项。
  • document-prune — 删除你选定的特定文档块(支持 dry_run)。删除始终需要明确操作:审核重复项,决定保留哪些副本,然后清理其余副本。
  • promotion-candidates / mark-extracted — 对获得检索流量的文档块排序,并在文档块提升为记忆后将其标记为已提取。

运行 memkeeper schema <command> 可查看各命令接受的 JSON 字段。通过 serve --http 启动时,仪表板提供只读操作(搜索/获取/重复项)。写入操作(ingest、document-prune)默认禁用,除非设置写入令牌:在环境中使用 MEMKEEPER_HTTP_WRITE_TOKEN=<secret> 启动服务,然后在写入请求中通过 Authorization: Bearer <secret> 发送该令牌。不设置令牌时,HTTP 服务为只读。

仪表板

memkeeper serve --http 会启动一个只读本地仪表板(默认地址为 http://127.0.0.1:7777),用于浏览记忆和实体图。使用 --store <path>(或 MEMKEEPER_STORE)指定存储;否则使用默认存储。

新建的存储为空,这是预期行为。 两个视图的填充方式不同:

  • 记忆列表会随着你执行 remember 而逐渐填充。
  • 图用于可视化实体和关系,这是与原始记忆分开的独立层。原生 MCP remember 会在宿主 Agent 提供相关信息时,将有界实体、别名和类型化关系与确认后的记忆一同保存。原始 CLI 调用方可以传入相同的图结构,也可以使用 entity-upsert / relationship-upsert 对其进行整理。dream graph 任务可能会添加通用的 related_to 链接用于可视化,但这些链接不属于检索证据。没有图字段的普通记忆仍会填充列表,但不会增加图边。

基准测试

在 LoCoMo(10 段多轮对话、1,982 个带有证据的问题)上,memkeeper 默认语义检索的得分如下:

指标得分
recall@200.768
hit@200.880
MRR0.668

在预热的 serve 守护进程上进行提示词时搜索(ONNX 模型只加载一次),p50/p95 约为 25 ms,比每次查询都会重新加载模型的冷启动单次调用二进制文件快约 32 倍。

完整的方法说明、各配置的结果(包括晚期交互升级)以及复现脚本,见 docs/benchmarks.md。

从源代码构建

构建并非必需——快速入门中的二进制文件是独立的。从源代码构建,可跟踪最新的 main、生成更精简的纯词法二进制文件,或进行开发。

**先决条件:**需要 Rust 工具链(通过 rustup 安装稳定版;edition 2021,Rust 1.56+)以及用于原生依赖项的 C 工具链(内置 SQLite 和用于语义搜索的 ONNX 运行时)。macOS:Xcode 命令行工具(xcode-select --install);Debian/Ubuntu:build-essential。首次构建会从 crates.io 获取 crate;此后即可离线进行干净构建。

# Semantic build (default): local embeddings + cross-encoder rerank.
cargo build --release
# ...or lexical-only — omits the ONNX runtime and models entirely:
cargo build --release --no-default-features

# The binary lands at ./target/release/memkeeper (not on PATH). To install it:
cargo install --path crates/memkeeper-cli   # then a bare `memkeeper` works

然后运行 memkeeper pull-models 以启用语义搜索,步骤与快速入门完全相同。

工作区布局

Crate作用
memkeeper-core核心类型和检索策略
memkeeper-storeSQLite 存储、架构、索引、提升
memkeeper-embedONNX 嵌入 + 交叉编码器重排器
memkeeper-protocol线路协议(memkeeper.v0.1)
memkeeper-climemkeeper 二进制文件(CLI + 守护进程)

编辑器/Agent 集成位于 adapters/ 下(MCP 桥接和精简的扩展客户端)。

延伸阅读

memkeeper 博客中的设计说明和基准测试:

Memkeeper 系列

Warden 是一个配套的能力代理和执行关卡:它会根据明确声明且可审计的策略,判断 Agent 请求的操作(shell 命令、文件读写)是否获准,并记录每项决策。memkeeper 负责记忆;Warden 负责守护。

许可证

可自行选择采用 MIT 或 Apache-2.0 许可证进行双重授权。

参与贡献

请参阅 CONTRIBUTING.md。贡献者需要签署项目的贡献者许可协议——CLA 机器人会在你首次提交拉取请求时提示你。你仍保留自己贡献内容的版权。

评论

支持 Markdown

第一次接触 MCP?

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

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