我给 12 家 AI 编码 agent 造了个本地记忆库:会话自动捕获 + MCP「连接即续接」(开源)

0 阅读4分钟

起因:会话历史是一堆"数据孤岛"

我同时用三四个 AI 编码 agent(Codex 跑长任务、ZCode 日常干活、Claude Code / Hermes 换着用),它们各有一套会话存储,而且藏得越来越深、格式各不相同:

Agent会话数据位置(2026-10 时点)格式
Codex CLI~/.codex/sessions/**/rollout-*.jsonlJSONL 树(含分支)
ZCode~/.zcode/cli/db/db.sqliteSQLite 三表(2026-10 起开源)
OpenCode~/.local/share/opencode/opencode.dbSQLite(2.x 换了新 schema)
Claude Code(CLI)~/.claude/projects/**JSONL
Claude 桌面版元数据 + ~/.claude/history.jsonl对话正文不落盘,只有元数据
Hermes(桌面)自带 state.db + memories/*.mdSQLite
Qwen Code~/.qwen/**/chats/*.jsonlJSONL 树,GenAI 线格式
Kimi CLI~/.kimi/sessions/**/context.jsonlkosong 消息行,无逐条时间戳
CodeBuddy Code~/.codebuddy/projects/**/*.jsonl与 Claude Code 同构
WorkBuddy~/.workbuddy/projects/**/*.jsonl + workbuddy.dbJSONL + SQLite 元数据
Qoder CLI~/.qoder / ~/.qoder-cn 双根Claude 兼容 JSONL

(还有两家桌面端没法直接抓:Trae CN 本地库 SQLCipher 加密、通义灵码纯云端——这类走内置的「导入对话」,粘贴聊天记录文本或选导出文件,启发式还原入库。)

这些孤岛带来两个问题:换 agent 要重新铺垫全部背景;想搜一条历史会话无从下手。

我做了什么

MemorySQL——本地优先的 Electron 应用,三件事:

1. 捕获层:一家一个适配器,统一走 capture-factory

12 家 agent 各一个捕获插件,共用同一套工厂:文件发现 → 解析 → 消息归一化(统一为 user/assistant/tool 三角色 + 工具名)→ 入库。chokidar 监听增量,原始文件只读不改;.env/credentials* 一律跳过。SQLite 权威存储的(ZCode/OpenCode)直接读库;Claude 桌面版那种"没有正文只有元数据"的,三源合并去重。

image.png

image.png 2. 存储层:SQLite 双索引

better-sqlite3 单文件库,业务表全部带 updated_at / device_id / deleted(tombstone,为增量同步预留)。检索两条腿:

  • FTS5 trigram:中文友好,不需要分词器
  • sqlite-vec + 本地 ONNX embedding(bge-small-zh):语义召回,全程离线;memory_search 里字面未命中的概念性查询用「·语义」标注补足

3. MCP 层:7 个工具,本机 http://127.0.0.1:8642/mcp

核心是 memory_get_context:一次调用返回画像 + 长期记忆(可按 agent 过滤)+ 项目状态 + 最近会话(带 id)+ 上一棒交接摘要(内联最近会话 tail)。新会话一句「续接 <项目名>」就恢复全部上下文。

image.png

其余:memory_get_project_brief(交接简报)、memory_list_sessions / memory_get_session(回读)、memory_search(双路检索)、memory_write(写记忆,agent 归因 + 去重)、memory_log_progress(收工汇报 → 候选记忆,人工确认才转正)。

几个值得聊的工程决策

  • 本地明文,出口脱敏:入库不脱敏(界面/MCP 全量可见),但任何导出/分享路径强制过 privacy-export 模块——信任模型是"本机是你的地盘,出口才是边界"。代价也说清楚:本地 SQLite 是明文,且 MCP 端点只绑 127.0.0.1、无鉴权,完整披露在仓库 PRIVACY.md。
  • LLM 是可选项:会话摘要/冲突检测用 LLM,但没有 LLM 自动降级回规则提炼,零配置可跑;语义检索是本地模型,不依赖任何云端 embedding。
  • 一切皆插件:捕获、检索、脱敏、开机自启,全是插件,和外部插件走同一套加载协议(manifest.json + main.js 单文件 CommonJS,ctx 提供 db/ipc/mcp/watcher/events 能力,单插件异常被宿主隔离)。
  • 敢做减法:上周(v0.6.0)把「笔记」和「知识图谱」两个功能整个砍了——长期自用后判断实用性不高,连带移除 CodeMirror 与 cytoscape,renderer 产物 2.79 MB → 0.68 MB(-75.7%)。旧数据一概不删。做加法容易,砍功能才是对自己诚实。
  • 上游会改格式,得有人看着:12 家 agent 没有一家公开承诺会话格式稳定,所以做了契约台账 + 每日黑盒探针(四态判定:匹配/漂移/源不存在/检查器故障),上游一改存储布局就能发现,而不是等用户报"会话不显示了"。
  • 内存治理踩过的坑:语义索引全量重算改水位增量、ONNX InferenceSession 空闲 15 分钟释放、大会话 tail 分页——桌面常驻应用,内存就是产品体验的一部分。

使用

winget install Logic647.MemorySQL   # 审核中
# 或 scoop / Releases 下安装包(Windows 105MB / macOS arm64 / Linux AppImage·deb·tar.gz)

装完它就在托盘常驻(MCP 保持在线),设置 → 连接 Agent 向导一键写入各家 agent 的 MCP 配置(写入前自动备份原配置)。macOS 包未签名,首次启动右键「打开」确认一次即可。

GitHub(MIT):github.com/Logic647/Me…

欢迎来 issue 区提需求:想接哪家 agent、想要什么 MCP 工具。
觉得好用的话可以点点Star