Skip to content

About

Self-hosted agent memory system with MCP server, embedded web UI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

agent-memory

agent-memory 是一个自托管的记忆服务:AI agent 通过 MCP(HTTP)读写一处跨会话保留的长期记忆,人通过内置的 Web 界面查看、检索、整理和授权。

它记的是“这段时间在做什么”这类会过时、和具体项目或场景绑定的信息,由 agent 在日常工作中维护,而不是一份长期稳定的公共知识库。

主要特性

标签系统

标签是整个库共用的一套词汇表。project:nmmt 这样的键值对其实是一条从 project 指向 nmmt 的标签边:目标端是词条引用,同一个 nmmt 可以被多个源端指向,改名或补充描述会作用到所有出现的地方。

在标签之上,还可以用标签表达式精确圈定记忆范围,一层完整的布尔代数:

  • & 与、| 或、! 非、括号分组;
  • key=value 精确匹配一条边,数字按规范形式匹配(key=1.0 命中 key:1);
  • /regex/ 按正则匹配任一标签展示形式;
  • @name 引用命名谓词,把常用的标签组合固化成可复用的过滤器;
  • mutex(a, b, ...) 表示至多一个为真。

例如 project=nmmt & (rust | /^topic\./) & !archived。表达式不认识的标签名会直接报错并给出最接近的现有标签提示,过滤是硬性的:不满足表达式的记忆在任何搜索里都不会出现。

语义搜索

搜索不是简单的关键词匹配。服务端把多个检索通道各自独立排名,再用 Reciprocal Rank Fusion(RRF)融合成一份最终排序:

  • 内容关键词通道:空白分隔的词必须全部命中,引号内按短语精确匹配,摘要权重高于正文;
  • 标签通道:命中的标签按精确、子串等强度计分;
  • 语义向量通道(可选):接入 OpenAI 兼容的 embedding 服务后,换说法、跨语言的查询也能召回;每个候选可单独设置查询/文档指令前缀和余弦相似度下限,向量按模型缓存、多模型共存。

在融合结果之上还有两级可选增强:

  • 重排(reranker):配置 Cohere 风格的 /rerank 端点后,由交叉编码器对候选池重新打分,其排序再与融合排序加权合并;
  • 时效衰减与访问强化:两条独立、可关闭的信号,只调整相关结果的顺序,不扩大也不缩小召回范围。

embedding 与 reranker 都支持配置多个候选端点,按列表顺序故障切换,一个不可用自动切下一个。整个设计遵循“降级不失败”:语义服务不可用时搜索自动退回关键词并在响应里标明,写入从不因为向量缺失而阻塞,缺的向量随时可以补跑。

Rust 实现

单二进制、单文件 SQLite,依赖刻意极简,cargo install 即装即用;管理界面直接嵌在二进制里,不需要额外的部署。

管理界面

管理界面直接嵌在二进制里,浏览器打开服务地址即用;没有配置文件,所有设置存数据库、由界面维护。详见安装和构建。

核心原理

记忆模型

一条记忆由 id、摘要、可选正文、标签集合和时间组成。摘要是列表与搜索结果里看到的一行;正文是展开后才读的完整 Markdown。

读取采用渐进式披露:列表、搜索和资源目录只返回摘要与片段,只有按 id 读取单条才返回正文。这样 agent 可以先用少量上下文判断相关性,需要时再取全文。

id 形如 m3,但不稳定:删除或合并后失效,导出再导入会重新编号。因此正文里引用其他记忆时,用标签或关键词互链,不要写 id。写入时如果已有摘要相同或语义相近的记忆,响应会给出查重提示,可以直接合并。

记忆没有隐藏状态:没有置顶、归档或到期,删除是唯一的移除手段。

检索流程

一次搜索的完整路径:

  1. 用标签表达式做硬过滤,先于一切排序截断候选;
  2. 内容关键词、标签匹配、语义相似度三个通道分别排名,再用 RRF 融合成一份排序;
  3. 时效衰减与访问强化对融合结果做顺序微调;
  4. 配置了 reranker 时,对候选池再重排一次;
  5. 分页走短期搜索快照游标:翻页复用同一份快照,内容或设置的写入会使快照失效。

不同通道的量纲不同,服务端从不把它们直接加权比较,只融合排名。

时效与访问强化

时效衰减按有序的标签规则给不同记忆设置半衰期,默认不衰减;访问强化只统计成功的正文读取和显式的“使用”标记,列表、搜索曝光不算,同一身份短时间内的重复只算一次。两者都是独立的排序信号,可以分别关闭。

资源

除工具外,记忆库还以 MCP 资源的形式暴露:

  • memory://tags/{tag}:一个标签的目录,含标签元数据与最近更新的 100 条记忆摘要,不含正文;
  • memory://memories/{id}:单条记忆的完整 Markdown 正文。

带保留标签 convention 的记忆会作为常驻约定出现在资源目录里,agent 可以先读约定再开始工作。这个标签不能被改名或删除,挂载和摘取需要管理员。

安装和构建

需要 Rust 1.85 或更新版本;构建完整管理界面还需要 Node.js 与 pnpm。

git clone https://github.com/Leawind/agent-memory.git
cd agent-memory
pnpm install && pnpm build   # 构建管理界面,产物会嵌入二进制
cargo install --path .
agent-memory serve

如果只用 MCP、不需要管理界面,可以跳过 pnpm 两步;此时服务嵌入的是占位页。

默认监听 127.0.0.1:8899,数据写入当前目录的 memory.db(首次启动自动建库):

客户端配置示例(本地开放模式可以去掉 headers):

{
  "mcpServers": {
    "agent-memory": {
      "type": "http",
      "url": "http://127.0.0.1:8899/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}

数据库路径和服务地址都走命令行参数:

agent-memory --db /srv/agent-memory/memory.db serve --host 0.0.0.0 --port 9000

语义模型配置示例

在“管理 → 搜索模型”里添加 OpenAI 兼容的 /embeddings 候选;列表顺序就是故障切换顺序:

部署 base_url model API Key
SiliconFlow(国内直连) https://api.siliconflow.cn/v1 BAAI/bge-m3 必填
本地 Ollama(数据不出机) http://127.0.0.1:11434/v1 bge-m3 留空
其他 OpenAI 兼容服务 各家端点 对应 embedding 模型 按需

身份与权限

没有账号体系,token 就是身份;服务端只存哈希,明文只在创建或重置时显示一次。能力分为:读取、新建记忆、修改记忆、删除记忆、管理标签、管理谓词、管理员。

默认是开放模式,服务也只监听本机:任何能连上本机的程序都能读写。对局域网或公网开放前,先开启鉴权,并在前面放一层 HTTPS 反向代理(服务本身只提供 HTTP):

  1. 先在管理面板创建一个带“管理员”能力的身份,保存好它的 token;
  2. 再打开 Token 鉴权开关;
  3. 之后按需为每个使用者创建身份,逐项勾选能力。

鉴权开启后,/mcp 和 /api 都必须携带 Authorization: Bearer <token>。可以为无 token 的请求单独配置一组匿名能力(例如只读);没有配置时无 token 一律 401。丢失唯一的管理员 token 时,可以用 agent-memory token reset 重置最早创建的管理员身份。

备份与体检

全部数据在一个 SQLite 文件里。停止服务后复制这个文件,就能把整个库搬到另一台机器;运行中的 WAL 文件不要单独拷。

也可以导出为 JSON 备份,再导入空库恢复。JSON 备份只包含记忆、标签、谓词、时效策略和访问统计;身份、鉴权开关与模型配置不在里面,需要在新机器上重新配置。向量是派生数据,同样不在备份里,恢复后跑一次 embed-backfill 补齐。doctor 检查数据库完整性、引用一致性、标签大小写冲突、空摘要、重复记忆和向量覆盖等问题,发现问题时退出码为 1。

命令行

所有子命令共用全局参数 --db <PATH>:

命令 作用
serve 启动 HTTP 服务(默认子命令)
stats 打印记忆数、标签数、文件大小与向量覆盖
doctor 数据体检,发现问题时退出码为 1
export <FILE> 导出 JSON 备份,拒绝覆盖已有文件
import <FILE> 从备份恢复到空数据库
embed-backfill 为缺失向量的记忆补跑 embedding
token reset [NAME] 重置身份 token;省略名字时重置最早创建的管理员

agent-memory --help 与各子命令的 --help 是参数的最终说明。

从源码开发

pnpm install && pnpm build   # 改了 ui/ 时需要,产物嵌入二进制
cargo install --path .       # 安装到 ~/.cargo/bin
cargo test                   # 单元 + 端到端测试
cargo clippy --all-targets   # 提交前应零告警

更多见 AGENTS.md(架构不变量)和 ui/README.md(组件库集成指南)。

About

Self-hosted agent memory system with MCP server, embedded web UI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages