Skip to main content

KeepM V3

KeepM Unicode wordmark

带准入控制、本地优先、无模型依赖的 AI 编码 Agent 长期记忆引擎。

Version Python MCP License

English · 简体中文

为什么需要 KeepM?

长对话会让重要事实淹没在上下文中间;如果任由 Agent 把自主推断直接写成长期记忆,一次误判又可能持续污染未来会话。

KeepM 在“推理”与“保留”之间建立明确的准入边界:

  • Markdown 是唯一真源。 记忆保留在本地,可迁移、可审查,也能用 Obsidian 或任意 Markdown 编辑器直接查看和修改。
  • SQLite 是可重建的机器索引。 名称、aliases、tags、description 和正文通过加权 FTS5 渐进检索,WikiLink 提供正向关系与反向链接。
  • 三层生命周期隔离污染。 已确认结论、Agent 推断候选和未完成任务状态走不同的准入路径。
  • 服务端不隐藏模型。 当前 Agent 负责语义提炼;KeepM 负责 Schema、去重、checksum、短时凭证、内容限制和安全状态流转。

核心原则:Markdown 是唯一真源,SQLite 是可删除、可完整重建的派生索引。

总体架构与数据流

┌──────────────────────────────────────────────────────────────┐
│ Agent 宿主:Codex / Claude Code / 其他 MCP 客户端            │
│ 语义提炼 · 准入分类 · 冲突处理                               │
└─────────────────────────────┬────────────────────────────────┘
                              │ MCP stdio
                              ▼
┌──────────────────────────────────────────────────────────────┐
│ KeepM MCP Server                                             │
│ 格式校验 · 槽位去重 · checksum · 冲突事务 · 生命周期 · 诊断  │
└──────────────────────┬──────────────────────┬────────────────┘
                       │ 权威写入             │ 派生路由
                       ▼                      ▼
┌──────────────────────────────┐  ┌────────────────────────────┐
│ 本地 Markdown                │  │ 本地 SQLite                │
│ 正式记忆 · Inbox · handoff   │  │ FTS5 · aliases · links     │
│ 唯一真源                     │  │ 可删除、可完整重建         │
└──────────────────────┬───────┘  └────────────────────────────┘
                       │
                       ▼
┌──────────────────────────────────────────────────────────────┐
│ Obsidian / 任意 Markdown 编辑器(可选的人类界面)            │
└──────────────────────────────────────────────────────────────┘

检索采用渐进式流程:memory_context 返回有长度边界的第一层上下文,memory_search 缩小候选范围,memory_read 只打开明确相关的权威笔记。Agent 无需全量扫描 Markdown 目录。

三层记忆生命周期

层级 存储内容 状态 是否进入普通检索
正式记忆 已确认的偏好、决策、约束、修复方法与可复用知识 activesupersededarchived active
Inbox Proposal Agent 推断但尚未确认的高价值候选结论 pendingpromotedrejected
Handoff 恢复未完成任务所需的临时状态 activecompleted

Handoff 存未完成的“事”,Inbox 存待确认的“候选结论”,正式记忆存已确认、可复用的“果”。

三层内容分别位于 <Markdown 根目录>/Memory/ 下的正式记忆目录、Inbox/.handoffs/;SQLite 索引与可选审计日志保存在用户数据目录,不会取代 Markdown 真源。

同一个 Markdown 根目录(或 Obsidian Vault)可以供多个已接入项目共用。Memory/global/ 保存跨项目适用的正式记忆,Memory/projects/<project-id>/ 保存项目专属记忆;这两个数据范围与 Agent 的安装范围无关。KeepM 只在明确选择的项目中注册 MCP、策略和 Hook,不提供用户级 Agent 接入。

快速开始

环境要求:Python 3.11+、uv 和一个本机可写的 Markdown 目录。

uvx keepm setup

uvx 会在隔离环境中运行 KeepM,无需永久安装。交互向导会完成最少且完整的接入:

  • 指定共用的 Markdown 存储根目录与默认记忆语言(zh / en);
  • 选择 Codex、Claude Code 或 pi;
  • 指定要接入的项目目录,默认使用当前工作目录;
  • 仅在该项目中注册 keepm stdio MCP Server、安装受管理的 Agent 记忆策略,并默认配置 SessionStart / Stop Hook。

三个宓主的接入位置:

宓主 MCP 注册 Agent 入口 生命周期 Hook
Codex .codex/config.toml AGENTS.md .codex/hooks.json
Claude Code .mcp.json CLAUDE.md .claude/settings.json
pi .mcp.json AGENTS.md 无宓主 Hook 文件,报 not-applicable

pi 与 Claude Code 共用同一份项目 .mcp.json,且两边都把 command 条目视为 stdio,因此一次注册对两个宓主同时生效,不会互相覆盖。写入采用 JSON 合并:其他 MCP Server 和未知顶层字段全部保留;文件格式非法、是符号链接或不是普通文件时直接报错,绝不整体重写。pi 没有 Claude 那种宓主 Hook 配置文件,setup 会在文本和 JSON 中把 lifecycle_hooks 明确报为 not-applicable,而不伪造成功;相同的会话与 checkpoint 指引由受管理的 AGENTS.md 策略承担。

自动化配置:

uvx keepm setup --yes --root /path/to/notes --agent codex --project-dir /path/to/project

--agent 可选 codexclaudepi

CI、安装脚本或 Agent 还可以请求机器可读的验收摘要:

uvx keepm setup --yes --format json --root /path/to/notes --agent codex --project-dir /path/to/project

文本和 JSON 输出都会分别汇总 Vault 可访问性、MCP 注册、受管理策略、Hook 与 Audit 配置。SQLite 健康和宿主 Elicitation 能力只有在首次 MCP 会话建立后才能验证,因此 setup 会明确标为 deferred,而不会伪造成功。

可选的运维参数包括 --deep-reconcile-seconds(默认 1800,0 禁用周期深扫)、--verification-review-days(默认 180)和 --sqlite-journal-mode wal|delete(默认 wal;网络文件系统可显式选择 delete,但这不会提供跨机器锁)。

重复执行 setup 是幂等的,只会更新目标项目中 KeepM 管理的配置块。~/.config/keepm/config.toml 只保存 KeepM 自身的本机 Vault 配置,不会在所有项目中全局启用 Agent。KeepM 不要求安装或运行 Obsidian;在 WSL 中直接使用 /mnt/c/... 形式的 Windows 挂载路径即可。

本地审核 UI

uvx keepm web                    # http://127.0.0.1:27182
uvx keepm web --port 39000       # 指定端口
uvx keepm web --host localhost   # 指定绑定地址
uvx keepm web --open             # 启动后打开浏览器

一个进程在同一个端口同时提供界面和 API,前端已打包进 wheel,无需任何构建步骤。运行时建立在 Starlette 与 uvicorn 上,二者随现有 FastMCP 依赖而来,因此普通 MCP 安装不会因为多了一个 UI 而变重。

默认端口 27182 在 32768+ 临时端口范围之外,系统不会把它分配给对外连接,也不是已注册服务端口。

界面提供总览、Inbox 审核、记忆浏览与编辑、关系图谱、任务交接、诊断和只读设置。浏览器审批与对话审批完全等价:两者都要求先完整读取,再以该次读取的 checksum 与一次性 token 提交,因此批准的永远是你看到的那一版。Agent 未启动时在界面批准也会直接写入 Markdown,MCP 客户端下次对账时自动看到。

安全边界:默认只绑 loopback,非法 Host 直接拒绝(同时阻止 DNS rebinding),所有写操作需要进程级 CSRF nonce 与同源 Origin。它没有鉴权,所以 --host 0.0.0.0 会明确告警:能访问该端口的人就能读写你的记忆。详见 web/README.md

极简维护命令

健康报告复用 memory_doctor 的确定性诊断结果,只导出状态和 finding 元数据,不包含记忆正文、Proposal 内容或任何 repair/update token:

uvx keepm doctor --format json
uvx keepm doctor --format markdown --output keepm-health.md

Safe GC 只处理 Memory/.trash/ 中具有可信软删除时间、且超过指定期限的普通文件。默认命令只生成预览和短时一次性计划;repair 备份、符号链接、无可信删除时间的文件以及正常的 active/archived/superseded 记忆均不会被删除:

# 仅预览,不删除
uvx keepm gc --older-than-days 30

# 使用预览返回的 token 执行完全相同且未变化的计划
uvx keepm gc --confirm --token <gc-token>

确认后的 GC 是不可恢复删除;trash 内容、checksum、候选集合或 token 时效发生变化时会拒绝执行并要求重新预览。

JIT 两阶段读取与可复现卡片契约

上下文压缩丢细节的真正原因往往不是“没存”,而是“存得太粗”与“召回靠语义联想”。KeepM 把两个问题分开解决。

写入侧:确定性契约。 decisionconstraintfix 必须包含固定英文段落 ## Decision and constraints## Reproducible parameters(无论正文是中文还是英文),fix 还必须在 frontmatter 携带至少一个仓库相对 sources 指针:

sources:
  - deploy/docker-compose.yml#service:db
  - src/config/database.py#symbol:get_engine

指针路径是机器真源,# 后的锚点只是给人看的提示,KeepM 绝不做 AST 解析,避免重构造成误报。契约只在写入时生效(create / propose / inbox_update / promote,以及改变正文或 kind 的 update);契约之前保存的卡片仍然可解析、可检索,只刷新 verified_attags 也不会被拦。写入层另外会拦住带密码的连接串与显式密码赋值,但会放行 ***${PGPASSWORD}<password> 这类脉敏写法。

读取侧:两阶段 JIT。

阶段 1:骶架探测
  memory_context(query)          ─► 相关记忆、handoff、Inbox 计数
  memory_catalog()               ─► 有界槽位句柄(name / kind / scope / 30 字用途 / is_stale)

阶段 2:目标点读
  memory_catalog(source_path="deploy/docker-compose.yml")
                                 ─► 路径反查到 postgres-wsl2-io-config
  memory_read(identifier="postgres-wsl2-io-config")
                                 ─► 完整参数、真源指针、版本凭证

目录只返回句柄,不返回事实:排序固定为 pinned → kind 优先级 → verified_at → name_key,默认 limit=20、用途行截断到 30 字符,并带 notice 明确禁止从槽位名推测参数。同名的 global 槽位被 project 槽位遮蔽后不会重复出现,is_stale 直接复用 doctor 的验证判据(只对 active 的 constraint / fix / workflow 生效)。

路径反查把“该读哪张卡”从语义联想变成确定性路由:准备修改 deploy/docker-compose.yml 时,相关 fix 卡片会直接被命中,而不依赖 Agent 猜到名字。目录支持文件与目录前缀,并对 ./、反斜杠和大小写做可移植归一化。

Agent 工作流与低噪对话式审核

任务开始
  └─ memory_context(query)
       ├─ 上下文充足 ─────────────────► 继续主任务
       └─ 上下文不足
            └─ memory_search ─► 只 memory_read 相关记忆

产生值得保留的信息
  ├─ 用户明确要求或已确认 ─────────────► memory_create / memory_update
  ├─ Agent 推断且有长期价值 ──────────► memory_propose ─► Inbox 待审核
  └─ 尚未完成的任务状态 ──────────────► memory_handoff_create / update

写操作会立即刷新对应索引,不需要在任务开始或结束时常规调用 memory_sync。Hook 只负责提醒当前 Agent 做有边界的恢复或检查点整理;KeepM 不读取原始对话,也不会调用模型。

KeepM 使用受控对话完成 Inbox 审核,不强制依赖 GUI 或 Obsidian 插件。Agent 只有在用户主动要求、当前对话刚产生新 Proposal,或 Inbox 出现过期/数量阈值信号时,才会在主任务回答末尾提醒;每次最多呈报 3 条。宿主支持 MCP Elicitation 时,实际提升前还会显示一次与 Proposal checksum 和目标方案绑定的原生最终确认。

Agent 对话式审核示例

顺便提醒:检测到 2 条待审核候选记忆:

  • Proposal P1[项目偏好] 优先使用 pnpm 而非 npm(建议:批准
  • Proposal P2[架构决策] 放弃 Redis,改用 SQLite(建议:批准

可以回复“批准 Proposal P1、拒绝 Proposal P2”或“稍后”。

主任务永远优先,Proposal 使用独立于 Step 1 等主任务步骤的编号。“行”“好的”“按你说的办”“按建议处理”等泛化赞同只授权主任务,绝不授权 Inbox 变更;多条候选时用户必须明确引用 Proposal P1 等标签。只有最近明确呈报了一条 Proposal 时,“批准记忆提案”才可授权该唯一候选。用户回复“稍后”或忽略提醒后,本次会话不再重复打扰;沉默不会批准、拒绝、修改或删除任何内容。

正式记忆使用“槽位命名”:project-package-manager 表示稳定主题,pnpm 只是该槽位当前的结论。memory_context / memory_search 在发现 active 名称、别名硬碰撞或同 kind 主题重叠时会返回有界的 conflict_hints;Agent 必须完整读取相关候选并核对项目真源,不能只信第一条。

确认冲突并得到用户明确授权后,Agent 先预览 memory_resolve_conflict(dry_run=true),再用绑定同一方案的短时 token 执行。supersede 保留历史关系,archive 归档失去独立价值的节点,delete 只把错误节点移入可恢复回收站。KeepM 会同时校验两份 checksum/token、拒绝 supersedes 环,并通过可恢复的文件事务日志与单次 SQLite 事务保证崩溃一致;若进程在多文件替换中断,下次启动会继续提交或安全回滚。

MCP 工具一览

分组 工具 用途
上下文 memory_statusmemory_context 运行状态、有长度边界的任务上下文和仅计数的 Inbox 信号
检索 memory_catalogmemory_searchmemory_readmemory_links 有界槽位目录与文件路径反查、active 记忆加权检索、权威读取、WikiLink 与反向链接
正式记忆 memory_creatememory_updatememory_deletememory_resolve_conflict 创建已确认记忆;保护更新、删除及两条 active 记忆的预览式冲突解决
Inbox memory_proposememory_inbox_listmemory_inbox_readmemory_inbox_updatememory_inbox_promotememory_inbox_rejectmemory_inbox_prune 隔离、查看、修正、批准、拒绝、合并或安全清理候选
Handoff memory_handoff_creatememory_handoff_readmemory_handoff_updatememory_handoff_complete 保存、恢复、更新和归档未完成任务状态
运维 memory_doctormemory_repairmemory_sync 诊断损坏、预览授权的确定性修复、对账或重建索引

修改或删除已有对象前必须完整读取当前内容,并提供一次性版本凭证;如果 Markdown 在读写之间发生变化,KeepM 会拒绝过期操作,不会盲目覆盖。

对账、文件系统与长期健康

  • 分层对账: 高频快速路径使用 mtime_ns + size;服务启动、默认每 30 分钟一次的周期深扫,以及 memory_doctor 都会重新计算内容 SHA-256。memory_status 返回 last_checksum_scandeep_scan_due
  • 落盘边界: 单文件写入会先 fsync 临时文件,os.replace 后再 fsync 父目录;Markdown 仍是唯一真源,Doctor 只报告损坏,不猜测性重写。
  • 单活 Writer: 一个 Vault 同一时间只能由一台机器写入。memory_status 会尽力识别 NFS/SMB 等网络文件系统并给出提示;SQLite journal mode 可显式配置为 waldelete,但两者都不能替代跨主机协调。
  • 核验提示: memory_doctor 只对 active 的 constraintfixworkflow 给出 verification_missing / verification_overdue info;decisionpreference 默认免检,系统绝不因此自动归档或改写记忆。
  • 指针校验: 只有本机配置记录了 [projects.<id>].root,且该目录仍然解析回相同 project id 时,doctor 才会检查 sources 指针是否存在;否则返回 source_pointer_check_skipped。缺失只会产生 info 级 source_pointer_missing,绝不把报告标为 failed——因为同一个 Vault 会被多台机器共用。项目根目录只保存在本机 ~/.config/keepm/config.toml,绝不写入 Vault。
  • 结构化报告: memory_doctor(report_format=json|markdown)keepm doctor 复用同一份无正文健康报告;CLI 可安全写入本地 JSON/Markdown,不引入 HTML 渲染。
  • Host 确认适配: memory_status.host_confirmation 根据 MCP 客户端能力报告 elicitationproposal-protocol。不支持 Elicitation 时沿用已经明确完成的 Proposal P1/P2 授权;宿主声明支持后,只有原生确认明确接受才会继续,拒绝、取消或调用错误都会保持 Proposal pending,不写入正式记忆。
  • 无正文审计溯源: Proposal 提升审计记录来源 Proposal、MCP 客户端、来源引用、目标记忆、KeepM 策略版本与确认模式,但不会记录 Proposal 正文、描述或 Prompt。

设计哲学与非目标

  • 本地优先且透明: 不依赖云服务、HTTP 守护进程或私有存储格式。
  • 先准入,后保留: 用户确认的知识才能成为正式记忆;Agent 推断在批准前只能留在 Inbox。
  • 确定性安全护栏: 正文限长、高置信度秘密检测、Unicode 槽位去重、单文件原子写入、可恢复冲突事务、checksum、短时凭证、关系环检测、软删除和 doctor 授权修复。
  • 人类可编辑真源: 手工修改的 Markdown 会增量对账;无效文件会被诊断和隔离,不会被猜测性改写。
  • 不内置 LLM、Embedding 或向量数据库: 语义提炼由当前 Agent 完成,KeepM 只执行确定性规则。
  • 不使用伪置信度、静默衰减或自动提升: 用明确生命周期状态和 verified_at 管理记忆,审核阈值绝不构成写入授权。
  • 不强制 Obsidian 插件或审核 UI: 受控 Agent 对话是通用审核入口;支持 MCP Elicitation 的宿主可额外提供原生最终确认。
  • 不归档原始对话: 临时进度进入有边界的 handoff,长期记忆只保留提炼后的可复用结论。

License

MIT

Release files for keepm 3.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for keepm 3.6.0
File Size Uploaded
keepm-3.6.0.tar.gz 369.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for keepm 3.6.0
File Interpreter ABI Platform
keepm-3.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 677.6 kB

Release files / keepm-3.6.0.tar.gz

Download URL keepm-3.6.0.tar.gz
Size 369.6 kB
Tags Source
SHA-256 checksum
How to use checksums
5b87063fca5bc99b2fadae3872fbe5ecea48b6e9b48891f2bfe9b5afd767cb2a
BLAKE2b-256 checksum
How to use checksums
174e723e50989c4ec5a022d0797e10b65b0318021bd9ca73cffd78993bf59211
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / keepm-3.6.0-py3-none-any.whl

Download URL keepm-3.6.0-py3-none-any.whl
Size 308.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a6851cd7018b3c0ebd0abae3c962adb2c013de41d5970051dd8afce46c05216
BLAKE2b-256 checksum
How to use checksums
060c0893c4835821108d6ef4d63f870f0a9a41a154325ac0fc5f70de20e2a239
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

3.6.0 This release

2 release files

3.5.1

2 release files

3.5.0

2 release files

3.4.0

2 release files

3.2.0

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.1

2 release files

3.0.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page