mcpField
C
cogvault

cogvault

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

关于 cogvault

cogvault 是面向 Agent 的本地记忆服务,可为普通 Markdown 文件建立索引,无需 LLM。它结合语义与关键词搜索,并支持隔离的租户目录;Markdown 始终是可编辑的事实来源。

主要功能

  1. 01基于 Markdown 的记忆
  2. 02向量与 BM25 混合搜索
  3. 03隔离的租户目录
  4. 04增量索引
  5. 05可选时间衰减与 MMR

适用场景

  1. 01跨 Agent 会话查找决策
  2. 02搜索现有 Markdown 笔记库
  3. 03为多个 Agent 分隔记忆
  4. 04根据标注查询评估召回效果

MCP 相关

MCP 服务提供 cogvault_recall,用于混合搜索记忆;并提供 cogvault_record,将事实保存为已索引的 Markdown 卡片。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"nbibikov-cogvault": {
"command": "uvx",
"args": [
"cogvault"
],
"env": {
"COGVAULT_MODEL": "<COGVAULT_MODEL>",
"COGVAULT_LOG": "<COGVAULT_LOG>"
}
}
}
}
启动命令uvx cogvault
需要配置的环境变量
COGVAULT_MODELEmbedding model override; otherwise .cogvault.toml in the tenant, then the multilingual default
COGVAULT_LOGRecall log: 'off' to disable, or a path to relocate the JSONL log

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

安装包
pypicogvault0.12.2

工具

还没有获取到工具列表

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

详细介绍

30 秒快速上手

Claude Code 插件 — MCP 服务加上一项技能,用于告诉 Agent 何时回忆以及 何时记录:

/plugin install cogvault --marketplace NBibikov/cogvault

Claude Code 低于 2.1.275 的版本:先运行 /plugin marketplace add NBibikov/cogvault,再运行 /plugin install cogvault@cogvault。

记忆存储在 ~/.cogvault/memory 中(设置 COGVAULT_TENANT 可更改路径)。该插件 还会添加 /cogvault:remember。

任意 MCP 客户端,一行命令(需要 uv):

claude mcp add cogvault -- uvx cogvault mcp --tenant ~/agent/memory
Claude Desktop、Cursor、Windsurf、Cline — JSON 配置

将以下内容添加到 claude_desktop_config.json、~/.cursor/mcp.json 或客户端的 MCP 配置中:

{
  "mcpServers": {
    "cogvault": {
      "command": "uvx",
      "args": ["cogvault", "mcp", "--tenant", "~/agent/memory"]
    }
  }
}

已有 Markdown 记忆? 将租户指向它即可,无需导入。Claude Code 的自动记忆可以直接使用(包括 frontmatter type、[[links]] 等):

M=~/.claude/projects/<project>/memory
uvx cogvault index  --tenant $M --ignore MEMORY.md   # first pass embeds, later passes are incremental
uvx cogvault search --tenant $M "how do we deploy"

MCP 服务会在启动时自动建立索引;CLI 的 search 会读取现有索引。 --ignore MEMORY.md 可避免索引文件与其指向的卡片争抢检索结果。

使用 cogvault 插件的真实 Claude Code 会话:询问 worker 为何不断重启后,Agent 回忆起一张记忆卡片并给出修复方法;收到记住某事的指示后,又保存了一张新卡片

来自真实会话的未经编辑的回答(Sonnet,已安装插件,包含六张卡片的演示记忆);仅删去了等待时间。


为什么

大多数“AI Agent 记忆”工具都想成为自主运行的 LLM 守护进程,将你的工作总结到不透明的数据库或无法读取的图谱中。对于只需要可靠地回忆决策、缺陷修复或基础设施细节的编码 Agent 集群来说,这并不是合适的取舍。

cogvault 选择了相反的方向:

  • 你的 Markdown 文件是事实来源。 可以打开、编辑,也可以用 git diff 查看。SQLite 索引只是派生缓存——删掉后会从文件重新构建。
  • 一个库,多个租户。 每个 Agent 都通过自己的目录获得隔离的记忆命名空间。一个进程只加载一次各嵌入模型,并在其接触的所有租户之间共享;使用 stdio MCP 服务时,这意味着每个 Agent 会话只需一个小型进程,而非中央守护进程。
  • LLM 不参与其中。 写入和检索都是确定性的。你的 Agent 就是 LLM——记忆不需要第二个 LLM。
  • 本地、私密、离线。 FastEmbed 在设备上运行。任何内容都不会离开你的机器。

对比

于 2026-10-05 对照各项目的 README 和文档核查。

cogvaultbasic-memorymem0GraphitiLetta Code
唯一事实来源Markdown 文件Markdown 文件向量数据库(Qdrant / pgvector)图数据库(Neo4j、FalkorDB、……)每个 Agent 在各自 git 仓库中的 Markdown
存储或回忆是否需要大模型否否(可选重排器)默认需要(add() 会提取事实)摄取时需要需要——由 Agent 编辑自己的记忆
检索向量 + BM25、RRF、衰减、MMR全文 + 向量,可选重排语义 + BM25 + 实体语义 + BM25 + 图文件搜索;可选混合检索
基础设施单进程、SQLite 文件单进程、SQLite(可选 Postgres)库,或 Docker + Postgres 服务图数据库Letta 后端

在以下情况下选择其他方案: 你希望由大模型为你提炼并合并事实(mem0);实体间的关系是重点(Graphiti);你希望 Agent 管理自己的记忆(Letta);或者你想要一款基于相同 Markdown 理念、功能更丰富的笔记应用,支持 Obsidian 同步和托管选项(basic-memory——与 cogvault 最接近)。

在以下情况下选择 cogvault: 你运行多个 Agent,并希望每个 Agent 的记忆都隔离在各自的目录中,由一个进程统一管理;你希望回忆过程可确定且离线;并且你希望对它进行度量——cogvault eval 会根据 Agent 的真实查询为回忆效果评分,cogvault analyze 会列出它们尝试回忆但未能找回的内容。

工作原理

Markdown 文件会被索引到派生的 SQLite 数据库(向量 + FTS5)中,并通过 MCP、CLI 或 Python 进行回忆
回忆机制剖析
查询会经过语义和关键词排序器,通过 RRF 融合,然后依次进行时间衰减、MMR 和每张卡片仅命中一次

混合检索通过倒数排名融合融合语义(向量)和关键词(BM25/FTS5)排序,然后可选应用时间衰减(近期记忆优先于陈旧记忆)和 MMR(让靠前的结果更多样,而不是出现 5 个近乎重复的结果)。每张卡片只贡献其最佳文本块,因此单个长文件不会占满整个结果列表。

基准测试

柱状图,65 个真实 Agent 查询:带摘要分块的 e5-small,hit@1 为 0.57,hit@5 为 0.91,MRR 为 0.70;MiniLM 默认 hit@5 为 0.80;bge-small-en hit@5 为 0.77

使用真实召回流量进行测量,而非合成问题:从 6 个在线 Agent 租户的查询日志中抽取 66 个查询(58% 为乌克兰语,其余为英语),并根据实际卡片逐条判断——包括没有任何配置返回答案的查询。其中一个查询在记忆中没有答案,计为一个缺口,因此评分查询共 65 个。每种配置都在相同租户的副本上使用 cogvault 0.11.0 从头重新建立索引。

配置hit@1hit@5MRR@10
multilingual-e5-small,chunk_chars = 700,摘要分块0.570.910.70
multilingual-e5-small,chunk_chars = 700,无摘要分块0.550.860.69
paraphrase-multilingual-MiniLM-L12-v2(内置默认配置)0.540.800.66
bge-small-en-v1.5(仅英语)0.570.770.65

这些数字能说明什么,不能说明什么:

  • hit@1 不相上下。 四种配置的结果都在 0.54–0.57 之间,95% bootstrap 区间几乎完全重叠。真实 Agent 查询读起来像卡片标题,因此通常仅凭卡片名称就能选中正确卡片。
  • 差距体现在前 5 个结果中。 在这种混合语言的记忆中,带摘要分块的 e5-small 能让 91% 的查询在前 5 个结果中找到答案,而默认 MiniLM 为 80%,仅支持英语的 bge 为 77%。这正是 Agent 实际读取 5 个结果时能感受到的差异。
  • 65 个查询仍然只是小样本。 对小于约 0.1 的差异,应视为噪声。汇总数据见 assets/benchmark.json;查询内容为私有数据,并保留在各自租户中。
重排序

交叉编码器会同时读取查询和每张候选卡片,因此它可以判断哪张卡片能回答问题,而不仅仅是判断哪张卡片与问题主题相同。设置 rerank = "BAAI/bge-reranker-v2-m3-int8" 后,cogvault 会根据每个卡片文件的前 800 个字符,为混合检索的前 10 个结果评分并重新排序。在同一组 65 个查询上(cogvault 0.12.0,e5-small + 摘要分块):

hit@1hit@5MRR@10
仅混合检索0.600.880.70
混合检索 + 重排序器0.800.910.85

重排序器改善了 17 个查询,使 3 个查询变差。hit@1 提升幅度的 95% bootstrap 区间为 +0.09 至 +0.34。代价是约 2 GB RAM,以及在 Apple M 系列 CPU 上每次召回耗时 1–2 秒,因此它仅在共享守护进程和 cogvault eval 中运行(--no-rerank 会在不使用重排序器的情况下评分)。

在你自己的记忆上运行相同的检查:将经过判断的查询放入 <tenant>/.cogvault-golden.jsonl({"query": "...", "relevant": ["file.md"]},relevant 为空表示已知缺口),然后运行 cogvault eval --tenant DIR。

选择嵌入模型

Agent 的记忆通常不只包含英文。默认使用多语言模型,确保开箱即用——但请根据你的设备群的语言组合选择合适的模型(设置 COGVAULT_MODEL,或使用 Config(model=...))。切换模型时会自动重建索引。

模型(COGVAULT_MODEL)维度大小真实查询 hit@5*西里尔字母 / 多语言适用场景
paraphrase-multilingual-MiniLM-L12-v2 (默认)3840.22 GB0.80✅ 可用多语言设备群;安全的默认选项
BAAI/bge-small-en-v1.53840.13 GB0.77❌ 西里尔字母向量会出错仅含英文的记忆
intfloat/multilingual-e5-small3840.47 GB0.91✅ 每 GB 表现最佳(512-token 窗口)多语言设备群;使用 chunk_chars = 700
intfloat/multilingual-e5-large10242.24 GB未测量✅ 最佳追求最高质量,且内存充足

*数据来自上方的基准测试:针对混合英语和乌克兰语记忆进行的 65 次真实查询,cogvault 0.11.0。对于仅含英文的记忆,bge-small-en 是不错的选择;但对于乌克兰语内容,它会返回负相关性边际(干扰项的排名高于答案),因此不适合非英文记忆。请在自己的知识库上运行 cogvault eval 来做决定。

COGVAULT_MODEL=BAAI/bge-small-en-v1.5 cogvault index --tenant ~/agent/memory

按租户固定模型,让模型随数据一起使用,而不是依赖每条命令都导出 COGVAULT_MODEL(一旦忘记,模型不匹配就会悄悄重新嵌入整个索引)。在租户根目录下放置 .cogvault.toml:

# ~/agent/memory/.cogvault.toml
model = "BAAI/bge-small-en-v1.5"
# optional: recursive = true, strip_frontmatter = true, ignore_globs = ["Templates/*"]

现在,cogvault search --tenant ~/agent/memory "…" 无需环境变量即可使用正确的模型。优先级:显式指定的 --model / $COGVAULT_MODEL > .cogvault.toml > 内置默认值。

安装

uv tool install cogvault        # CLI on PATH
# or
pip install cogvault

也可以跳过安装,按需使用 uvx cogvault … 运行。首次运行时会下载嵌入模型(约 0.2–0.5 GB,每台机器只需下载一次)。

一行命令即可将其作为 MCP 服务添加到 Claude Code:

claude mcp add cogvault -- uvx cogvault mcp --tenant ~/agent/memory

它也已列入官方 MCP Registry,名称为 io.github.NBibikov/cogvault。每个 GitHub 发行版都附带 Wheels。

快速入门

# index a tenant's markdown memory
cogvault index --tenant ~/agent/memory

# search (hybrid semantic + keyword)
cogvault search --tenant ~/agent/memory "how do I restart the worker service"

# enable temporal decay (recent wins) and tune diversity
cogvault search --tenant ~/agent/memory "deployment steps" --half-life 30 --mmr 0.5

# only cards of one frontmatter type (user / feedback / project / reference / …)
cogvault search --tenant ~/agent/memory "hard rules for deploys" --type feedback
记忆卡片

cogvault 支持两种轻量级 Markdown 约定(均为可选——普通文件也可以正常建立索引):

  • Frontmatter type——支持扁平格式(type: reference)或嵌套格式(metadata: → type: reference)。在建立索引时解析,并可在搜索时筛选(--type、MCP type 参数、search(card_type=...))。每条搜索结果都包含 type 字段;没有 frontmatter 的卡片会将该字段设为 null。
  • [[wiki-links]]——链接目标会被编入索引,排名最高的搜索结果会包含一个 related 列表,其中列出索引中存在的关联卡片(不存在的链接会被忽略;按精确的文件名主干匹配)。
作为 MCP 服务使用(Claude Code、Cursor 及任何 MCP 客户端)
claude mcp add cogvault -- uvx cogvault mcp --tenant ~/agent/memory

提供两个工具:

  • cogvault_recall——以自然语言对该 Agent 的记忆进行混合搜索。可选的 type 参数可按一种 frontmatter 卡片类型筛选;排名最高的结果会包含根据其 [[wiki-links]] 生成的 Related: 行。
  • cogvault_record——保存事实;内容会写入 Markdown 卡片并编入索引
为文件夹树编制索引(Obsidian 库、知识库)

默认情况下,一个租户是由 .md 文件组成的扁平目录。对于嵌套库 (例如 Obsidian,其中包含 01-Projects/…、frontmatter 和要跳过的文件夹),可选择启用:

cogvault index --tenant ~/vault \
  --recursive \
  --strip-frontmatter \
  --ignore ".obsidian/*" --ignore ".trash/*" --ignore "Templates/*"
  • --recursive 会遍历子目录;文件保留相对于租户的路径,因此不同文件夹中同名的 Tasks.md 永远不会冲突。
  • --strip-frontmatter 会移除开头的 YAML --- … --- 块,以免其中的键污染嵌入内容。
  • --ignore GLOB(可重复使用)会跳过相对于租户根目录的路径。

search 和 mcp 也支持相同的标志,库则可使用 Config(recursive=True, strip_frontmatter=True, ignore_globs=(...))。索引采用增量方式:首次处理时会嵌入所有内容,之后只会重新嵌入有更改的文件。(参考数据:约 3,500 条笔记的库 → 约 9,500 个文本块,首次索引约需 3–4 分钟,之后热缓存召回耗时为个位数毫秒。)

作为库使用
from cogvault import Vault, Config

vault = Vault("~/agent/memory", Config(half_life_days=30))
vault.reindex()
for hit in vault.search("where are credentials stored"):
    print(hit["score"], hit["file"], hit["snippet"])

保持租户健康

cogvault doctor --tenant DIR 会报告会悄然降低召回效果的问题:缺少 frontmatter 或类型的卡片、旧式时间戳文件名、嵌套的 frontmatter、重复的 name: slug,以及无法解析到任何内容的 [[links]]。链接会根据 frontmatter 中的 name:、文件名主体、任一分隔符样式,以及是否包含卡片类型前缀进行解析;代码中的链接和指向租户外文件的路径不计入。

cogvault repair --tenant DIR 会修复可机械处理的问题(默认进行试运行,使用 --apply 写入更改):展开嵌套的 frontmatter、推断缺失的类型,将 card-<timestamp>-….md 重命名为 <type>_<slug>.md 并重写所有指向它的引用(包括 MEMORY.md),并为缺少 frontmatter 的 <type>_*.md 卡片添加最精简的 frontmatter。健康的卡片不会被改动,修复后的卡片会保留其 mtime,因此不会重置时间衰减。

效果日志

每次召回都会记录一行 JSONL,以便衡量记忆是否确实发挥了作用。cogvault analyze 会将日志整理成报告:

cogvault analyze            # recalls, latency, per-tenant hit distance, weakest hits, card writes
cogvault analyze --json     # machine-readable
cogvault analyze --since 7  # only the last 7 days (or --since 2026-10-05)

最重要的部分是效果最弱的命中:每个租户中按向量距离排序最差的十分位——这些查询中召回确实返回了某些内容(混合搜索几乎总会如此),但很可能没有返回答案。这份列表展示了你的 Agent 尝试召回却未能找到的内容,也就是有待填补的记忆空白。设置 COGVAULT_LOG=off 可禁用日志,或设置 COGVAULT_LOG=/path.jsonl 更改日志位置。

多租户集群

一个进程可连接多个租户——每个目录都是一个隔离的命名空间,测试套件已验证此行为(test_multi_tenant_isolation)。除非将 Agent B 指向 Agent A 的目录,否则 Agent B 永远无法召回 Agent A 的记忆。

四个 Agent 各自指向自己的记忆目录并使用自己的索引;租户之间相互隔离 ### 共享守护进程

每个 MCP 客户端都会启动自己的 cogvault mcp。没有守护进程时,这些进程中的每一个都会加载嵌入模型(约 1 GB),而且都无法负担重排器的开销。cogvault daemon 会为所有租户各加载一次模型,并通过 Unix 套接字提供服务(~/.cache/cogvault/daemon.sock,模式为 600)。cogvault mcp 和 cogvault search 会自动发现它并转发请求;此时 MCP 进程的内存占用会保持在约 40 MB。守护进程停止时,它们会像以前一样在进程内搜索,但不使用重排器,并在查询日志中记录一条 daemon-fallback 事件。

cogvault daemon            # run in the foreground
cogvault daemon --status   # ping it: version, loaded models, tenants served

模型在 10 分钟内没有搜索或重新索引操作后会被守护进程卸载,并在下一次召回时重新加载(该次调用额外耗时约 1.5 秒)。设置 --idle-unload SECONDS 或 $COGVAULT_IDLE_UNLOAD(设为 0 可保持模型加载状态)。使用 e5-small 和重排器测得:加载时约 1.8 GB,卸载后约 0.4 GB。ONNX Runtime 使用 4 个线程($COGVAULT_THREADS,0 = 使用所有核心),且不使用 CPU 内存 Arena,因此完整重新索引的峰值内存约为 1 GB,而不会在此后继续占用数 GB 内存。在守护进程停止时启动的垫片最多等待 60 秒;若守护进程仍未启动,它便会自行加载模型,并在守护进程恢复响应后立即卸载自行加载的模型。

重排器有独立的线程数设置($COGVAULT_RERANK_THREADS,默认值 = Apple 芯片上的性能核心数,否则为 4)。它只在召回时运行,也是召回延迟的主要来源:在 10 个 P 核上,召回 p50 耗时从 2.3 秒(4 个线程)降至 1.65 秒;使用 onnxruntime 1.31 后降至 1.05 秒(该版本还将 4 线程召回耗时降至 1.5 秒)。

在 macOS 上,可通过 launchd 运行它,并设置 RunAtLoad 和 KeepAlive(程序参数为 cogvault daemon)。升级 cogvault 后,请重启守护进程: launchctl kickstart -k gui/$(id -u)/<label>。

设计说明

决策原因
Markdown = 事实来源人类可读,可用 git 进行版本管理,可编辑,永远不会被锁在数据库中
SQLite + sqlite-vec + FTS5无需基础设施的混合搜索;一个可移植的 .db 文件;可重建
FastEmbed(默认使用多语言 MiniLM,384 维)进程内 ONNX,无需服务端、无需 API 密钥,约 220 MB
内容哈希缓存重新索引时仅为已更改的块生成嵌入
RRF + 衰减 + MMR无需图数据库即可兼顾准确性、时效性和多样性
单进程,多租户面向服务集群的基础设施,而非单用户桌面附属程序
WAL + 增量重新索引一个进程写入时,多个 Agent 可并发读取;仅为已更改的文件重新生成嵌入
可选的共享守护进程服务集群中的每个模型只加载一份;守护进程停止时,客户端会退回到进程内运行

路线图

  • 导入器(从其他存储迁移现有记忆)
  • 可插拔的嵌入器(Ollama、兼容 OpenAI 的端点)
  • 每张卡片的 valid_until 时效性
  • 可选的 FastMCP 传输方式

许可证

MIT — 你的记忆、你的文件、你的基础设施。永久如此。

图示由 assets/make_graphics.py 手工生成 SVG;运行 python assets/make_graphics.py --png 可重新生成。

评论

支持 Markdown

第一次接触 MCP?

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

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