每个 Coding Agent 都有一个致命问题
你让 Claude Code 或 Cursor 帮你修了一个 Bug,它修好了,你也保存了代码。关掉终端,第二天再打开,它完全不记得昨天修了什么、为什么这么改、哪几个文件被影响到了。
不是 Agent 笨,是它根本没有持久记忆。每次会话都是第一次见面。
现有的解决方案要么是 Claude Code 专用的 remember.md 文件(Agent 得自己写自己读,还经常忘),要么是 claude-mem 这种需要 ChromaDB + Node.js + Python + 额外进程的方案(装完发现比问题本身还复杂)。
Engram(读作 /ˈen.ɡræm/,神经科学里的"记忆痕迹")换了个思路:一个 Go 二进制,零依赖,SQLite + FTS5,20 个 MCP 工具,给你的任意 Coding Agent 装上跨会话记忆。
它到底是什么
Engram 不是一个 Coding Agent,它是一个记忆系统,通过 MCP 协议暴露给任何支持 MCP 的 Agent。
核心数据:
- 5,800 Star,MIT 协议,Go 语言,单二进制
- 零运行时依赖——不需要 Node.js、Python、Docker、ChromaDB,
go build一个二进制搞定 - 20 个 MCP 工具,覆盖保存、搜索、会话管理、冲突检测、知识图谱导出
- SQLite + FTS5——本地全文搜索,秒级响应,不需要外部向量数据库
- Agent 无关——Claude Code、Cursor、Windsurf、Codex、OpenCode、Gemini CLI、Kiro、Kilo Code、VS Code Copilot 全部支持
- 可选云同步——同一份记忆可以跨机器同步,还支持冲突检测
一句话总结:给你的 Coding Agent 一个跨会话的"大脑",它不再每次重启都失忆。
为什么比 claude-mem 更值得买关注
Engram 的 README 里专门有一页和 claude-mem 做对比。这两个项目解决的是同一个问题,但设计哲学完全不同:
| 维度 | Engram | claude-mem |
|---|---|---|
| 语言 | Go(单二进制,零依赖) | TypeScript + Python |
| Agent 支持 | 所有 MCP Agent(Claude Code、Cursor、Windsurf…) | Claude Code 专用(用插件钩子) |
| 搜索 | SQLite FTS5(内置,零配置) | ChromaDB 向量数据库(需额外进程) |
| 存储什么 | Agent 主动保存的结构化摘要 | 原始工具调用 + AI 压缩 |
| 压缩方式 | Agent 自己决定写什么,不需要额外 API | separate Claude API 调用压缩 |
| 进程 | 一个二进制(或没有——MCP stdio 就行) | worker 进程 + ChromaDB 两个服务 |
| 数据库 | 单个 ~/.engram/engram.db | SQLite + ChromaDB 两个存储 |
| Web UI | 终端 TUI(engram tui) | localhost:37777 网页 |
| License | MIT | AGPL-3.0 |
| 冲突检测 | 内置,支持 LLM 语义判冲突 | 无 |
| 云同步 | 内置,跨机器同步 + 冲突处理 | 无 |
核心区别在于一个哲学问题:记忆该由 Agent 决定,还是由系统自动捕获后压缩?
claude-mem 的做法是捕获所有工具调用,然后用 AI 压缩。好处是不用你操心,坏处是额外 API 调用、额外延迟、额外成本,而且原始调用会污染搜索结果直到被压缩。
Engram 的做法是信任 Agent——它已经完成了任务,已经理解了上下文,让它自己决定什么值得记住:mem_save("Fixed N+1 query in user list — added eager loading", type="bugfix")。简单、干净、零额外成本。
20 个 MCP 工具,分为 5 个能力域
Engram 通过 MCP 暴露了 20 个工具,不是堆数量,而是覆盖了记忆系统的完整生命周期:
保存与更新(4 个)
mem_save— 保存结构化观察(决策、bugfix、模式等),支持topic_key做 upsert,相同 topic 的后续保存会更新同一条记录而不是创建新的mem_update— 按 ID 更新已有记录mem_delete— 软删除(默认)或硬删除mem_suggest_topic_key— 在保存前让 Agent 生成一个稳定的 topic_key
搜索与检索(4 个)
mem_search— FTS5 全文搜索,支持match_mode: "any"放宽匹配mem_context— 获取最近会话的上下文摘要mem_timeline— 按时间线查看某条记忆的前后关联事件mem_get_observation— 获取单条记忆的完整内容
会话生命周期(3 个)
mem_session_start/mem_session_end— 标记会话起止mem_session_summary— 保存会话总结(Goal / Discoveries / Accomplished / Next Steps / Files)
冲突检测(2 个)
mem_judge— 对 FTS5 发现的冲突候选记录 LLM 裁决结果mem_compare— 持久化两条记忆之间的语义关系判定
这个能力是 Engram 独有的。当你保存"用 Postgres 做用户库"和"把用户库换成 MongoDB"两条记忆时,Engram 会用 FTS5 找到 lexically related 的候选,然后用你现有的 Agent 的 LLM 做语义判断——免费,因为你已经在用那个 LLM 了。
实用工具(7 个)
mem_stats— 记忆系统统计mem_current_project— 检测当前项目(避免多仓库环境下的歧义)mem_doctor— 运行诊断检查存储健康mem_review— 列出需要回顾的陈旧记忆mem_capture_passive— 从文本输出中提取学习点mem_save_prompt— 保存用户 prompt 供后续检索mem_merge_projects— 合并项目名变体
真正有意思的设计:3 层渐进式检索
Engram 的核心设计是渐进式披露(Progressive Disclosure)——不要一次把全部记忆塞给 Agent,而是让它自己决定挖多深:
第 1 层:mem_search "auth middleware"
→ 返回紧凑的结果摘要(约 100 tokens 每条)
第 2 层:mem_timeline observation_id=42
→ 查看那条记忆在什么会话背景下产生
第 3 层:mem_get_observation id=42
→ 获取完整内容(不截断)
这样 Agent 可以用最少的 token 先判断"这条记忆相不相关",再决定要不要深入。比直接把所有历史 dump 进上下文省得多。
Topic Key 设计:让 evolving 的决策不产生噪音
Engram 有个很聪明的设计叫 topic_key。默认情况下,每次 mem_save 创建一条新记录。但如果你传了 topic_key,相同 project + scope + topic_key 的保存会变成 upsert——更新现有记录,revision_count++,不会创建重复条目。
比如架构决策:topic_key: "architecture/auth-model",每次 Auth 方案调整都更新同一条记忆,保留完整演进历史。
而 bugfix 这种一次性事件就不需要 topic_key,每次保存就是独立记录。
topic_key 的格式约定是 family/specific-description,全部小写 kebab-case——这是为了让 SQLite FTS5 的分词器能正确 tokenize。
怎么接入
安装非常简单,一个二进制搞定:
# macOS / Linux
brew install gentleman-programming/tap/engram
# 或者从源码
git clone https://github.com/Gentleman-Programming/engram.git
cd engram && go build ./cmd/engram
然后给你的 Agent 装插件(以 Claude Code 为例):
claude plugin marketplace add Gentleman-Programming/engram
claude plugin install engram
支持的所有 Agent 一行搞定:
| Agent | 安装命令 |
|---|---|
| Claude Code | claude plugin marketplace add Gentleman-Programming/engram && claude plugin install engram |
| Cursor / Windsurf / VS Code | engram setup cursor / engram setup windsurf |
| OpenCode | engram setup opencode |
| Codex | engram setup codex |
| Gemini CLI | engram setup gemini-cli |
| Kiro / Kilo Code / Pi | engram setup kiro / engram setup kilocode / engram setup pi |
engram setup 会自动写 MCP 配置和 Memory Protocol 到你的 Agent 配置文件里,重启 Agent 即可。
对于不用插件的 Agent,也可以直接启动 MCP server:
# MCP stdio(大多数 Agent 都用这个)
engram mcp
# 或者 HTTP API(给 OpenCode 插件和 Pi 用)
engram serve # 默认监听 7437 端口
云端同步与冲突检测
Engram 支持可选的云同步(Engram Cloud),同一个项目可以在多台机器上共享记忆,跨机器同步时会检测冲突。
冲突检测有两个阶段:
- FTS5 阶段:基于关键词相似度找到候选冲突对(比如"用 Postgres"和"换成 MongoDB"都包含"user"和"database")
- LLM 语义阶段:用你现有的 Claude Code 或 OpenCode 的 LLM 来判断这两条记忆是否真的冲突(
--semantic模式,不额外花钱,因为你已经在付那个 Agent 的 API 了)
还有一个 engram tui 终端 UI,可以直接在终端里浏览、搜索、编辑记忆,不用开浏览器。
实际体验的几个坑
- MCP 传输只支持 stdio——没有 HTTP 或 TCP MCP 端点。如果你想在 Docker 容器里用,需要把二进制 mount 进去,目前还没有 bind-address 配置
- topic_key 格式有讲究——必须小写 kebab-case,不能用 camelCase 或空格,否则 FTS5 分词会出问题
- 多仓库环境需要指定项目——在包含多个 git 仓库的父目录下启动 MCP 时,会自动检测所有仓库,写入时需要
mem_current_project确认目标项目,否则返回ambiguous_project错误 - 云同步还在 Beta——冲突检测和跨机器同步功能在 beta 阶段,生产环境建议先用本地
- Memory Protocol 需要手动注入——部分 Agent(比如 Claude Code)需要在
CLAUDE.md里手动加一段 Memory Protocol snippet,才能让 Agent 在长会话/上下文压缩后还记得用 Engram。这不是必须的,但重度用户建议加
和 Context+ 有什么区别?
你可能已经注意到我们写过 Context+。这两个项目经常被人拿来比较,但它们解决的是不同的问题:
| 维度 | Engram | Context+ |
|---|---|---|
| 解决什么问题 | Agent 跨会话失忆 | Agent 看不懂大型代码库 |
| 核心能力 | 记忆保存与检索 | 代码语义图谱与搜索 |
| 技术栈 | SQLite + FTS5 | Tree-sitter AST + 向量嵌入 + 谱聚类 |
| 语言 | Go(单二进制) | TypeScript + WASM |
| 适用场景 | 任何 Coding Agent 工作流 | 大型多语言代码库 |
| 可以一起用吗 | 完全可以——Engram 管记忆,Context+ 管代码理解,两个 MCP server 同时挂给同一个 Agent | |
简单说:Engram 让你的 Agent 记住"昨天做了什么",Context+ 让你的 Agent 理解"代码结构是什么"。两个互补,不冲突。
适合谁用
- 用了 Claude Code / Cursor / Windsurf 但感觉 Agent"每次重启就忘"——装上 Engram,跨会话记忆立刻有了
- 在意部署复杂度——一个 Go 二进制,不需要 Docker、ChromaDB、Node.js 服务,比 claude-mem 简单一个量级
- 用多个 Agent——Engram 不绑定任何特定 Agent,Claude Code 和 Cursor 可以用同一份记忆
- 多机器工作——Engram Cloud 支持跨机器同步,换台电脑继续昨天的工作
- 想和 Context+ 搭配——一个管记忆,一个管代码理解,双重加持
总结
Engram 做的事情其实很简单:让 Coding Agent 在会话之间保留记忆。但它的实现方式比同类方案更优雅——一个 Go 二进制,SQLite FTS5 做搜索,零额外依赖,20 个精心设计的 MCP 工具,支持 10+ 个主流 Agent。
比起 claude-mem 的"全量捕获 + AI 压缩"方案,Engram 选择了"信任 Agent 自己决定什么值得记住"的路径。省掉了额外 API 调用,省掉了 ChromaDB 进程,代码也更简洁。
5,800 Star 不是天上掉下来的——它解决的是 Coding Agent 领域最普遍也最被忽视的问题:Agent 不应该失忆。