内容
# ctrl-memory
**轻量级、本地优先的MCP内存服务器,用于LLM代理。**
存储、搜索和检索代理记忆,零外部依赖。将其插入Hermes、Claude Code、Cursor或任何与MCP兼容的客户端。
```bash
pip install ctrl-memory
ctrl-memory-mcp
```
---
## ✨ 功能
- **零依赖核心** — 纯Python,无数据库,无外部服务
- **两个后端** — JSON文件(MVP,零依赖)或SQLite(生产环境,WAL模式)
- **语义搜索** — 可选`sentence-transformers`用于余弦相似度排名
- **混合检索** — 关键词召回 + 向量重排序以获得最佳精度/召回率
- **模糊匹配** — 内置Damerau-Levenshtein拼写容错
- **范围过滤** — 基于标签的领域隔离
- **超会话感知** — 自动过滤过时/过期的事实
- **Hermes插件** — 自动预取上下文,自动捕获对话回合
- **MCP标准输入/输出服务器** — 连接到任何与MCP兼容的客户端
- **用户隔离** — 每个用户的内存完全隔离
- **跨会话持久性** — 记忆在对话之间持续存在
---
## 🚀 快速开始
### 一行安装(推荐)
```bash
curl -fsSL https://raw.githubusercontent.com/ctrlProgrammer/ctrl-memory-system/main/install.sh | bash
```
这会在`~/.local/share/ctrl-memory/`中创建一个隔离的虚拟环境,安装带有语义搜索的ctrl-memory,并使`ctrl-memory-mcp`命令在全局范围内可用。不需要`pip install --user`或`sudo`。
安装后,打开一个新的终端(或`exec $SHELL`)并运行:
```bash
ctrl-memory-mcp
```
### 使用pip手动安装
```bash
# 核心(零依赖)
pip install ctrl-memory
# 带有语义搜索
pip install "ctrl-memory[embeddings]"
```
> ⚠️ 如果您的系统限制全局pip安装(PEP 668),请使用上述一行安装程序或在虚拟环境中安装:
> ```bash
> python3 -m venv .venv
> source .venv/bin/activate
> pip install "ctrl-memory[embeddings]"
> ```
### pipx(替代方案)
```bash
pipx install "ctrl-memory[embeddings]"
```
### 运行MCP服务器
```bash
ctrl-memory-mcp
```
服务器监听**标准输入/标准输出**(MCP标准输入/输出传输)。它在客户端连接时启动,在客户端断开连接时退出 — 无后台守护进程。
### 检查是否正常工作
在一个终端中启动服务器:
```bash
ctrl-memory-mcp
```
在另一个终端中运行:
```bash
# 1. 初始化会话
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}' | ctrl-memory-mcp
# 2. 添加事实
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"add_memory","arguments":{"user_id":"alice","content":"Alice prefers Fastify over Express"}}}' | ctrl-memory-mcp
# 3. 搜索
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_memory","arguments":{"user_id":"alice","query":"web framework"}}}' | ctrl-memory-mcp
```
> 💡 对于Hermes用户:插件在启动新对话时**自动激活**。无需单独运行`ctrl-memory-mcp`。内存按用户存储在会话之间。
---
## 🔄 更新
```bash
# 如果您使用了安装脚本 — 只需重新运行它(原地升级):
curl -fsSL https://raw.githubusercontent.com/ctrlProgrammer/ctrl-memory-system/main/install.sh | bash
# 如果您使用了pip:
pip install --upgrade "ctrl-memory[embeddings]"
# 如果您使用了pipx:
pipx upgrade ctrl-memory
```
---
## 📦 后端
### JSON后端(默认)
- 零依赖
- 一个用户一个文件:`~/.ctrl-memory/<user_id>.json`
- 自动递增ID,仅追加写入
- 最适合:MVP,个人使用,<1000个事实
### SQLite后端
- 单个`.db`文件,WAL模式
- 索引查询,ACID事务
- 语义搜索的嵌入存储
- 最适合:生产环境,多用户,>1000个事实
```bash
ctrl-memory-mcp --backend sqlite
```
---
## 🧠 语义搜索
当安装了`sentence-transformers`时,ctrl-memory会自动启用:
- **自动嵌入** — 事实在写入时被向量化(384维all-MiniLM-L6-v2)
- **混合搜索** — 关键词候选 → 余弦相似度重排序 → 按相关性排序
- **分数过滤** — 可配置的`min_score`阈值来过滤弱匹配
```bash
pip install "ctrl-memory[embeddings]"
```
不需要标志 — 自动检测。
---
## 🔌 Hermes代理插件
ctrl-memory附带一个本地Hermes代理提供程序。
### 安装
```bash
# 复制插件
cp -r hermes_provider ~/.hermes/hermes-agent/plugins/memory/ctrl-memory/
```
### 配置
添加到`~/.hermes/config.yaml`:
```yaml
memory:
provider: ctrl-memory
config:
backend: sqlite # 或 json(默认)
db_path: ~/.hermes/memory.db
```
插件提供:
- **自动预取** — 在每个LLM回合之前注入相关上下文
- **回合捕获** — 从对话中提取事实并存储
- **4种工具** — `add_memory`,`search_memory`,`delete_memory`,`memory_status`
---
## 🔧 MCP工具
| 工具 | 描述 |
|---|---|
| `add_memory` | 存储带有可选元数据标签的新事实 |
| `search_memory` | 混合关键词 + 语义搜索 |
| `get_fact` | 通过ID检索特定事实 |
| `list_facts` | 列出用户的所有事实,分页 |
| `update_fact` | 编辑现有事实(如果启用语义,则重新嵌入) |
| `delete_fact` | 删除事实(清理嵌入) |
| `count_facts` | 获取用户的总事实数 |
| `search_memory_semantic` | 纯余弦相似度搜索(使用嵌入) |
---
## 🏗️ 架构
```
┌─────────────────────────────────────┐
│ MCP客户端 │
│ (Hermes, Claude Code, Cursor...) │
└──────────────┬──────────────────────┘
│ 标准输入/输出JSON-RPC
┌──────────────▼──────────────────────┐
│ mcp_server.py │
│ MCP标准输入/输出传输层 │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ memory_backend.py │
│ ┌─────────┐ ┌──────────┐ │
│ │ JSON │ │ SQLite │ │
│ │ 存储 │ │ 存储 │ │
│ └─────────┘ └────┬─────┘ │
│ │ │
│ ┌─────────────────▼──────────┐ │
│ │ EmbeddingEngine │ │
│ │ (可选,自动检测) │ │
│ └────────────────────────────┘ │
└─────────────────────────────────────┘
```
### 搜索流程
```
查询
│
▼
1. 关键词搜索(token-OR,停用词过滤)
│
├── 无结果? → 模糊fallback(Damerau-Levenshtein)
│
▼
2. 余弦相似度重排序(如果有嵌入)
│
▼
3. 范围过滤(如果标签匹配)
│
▼
4. 超会话过滤(删除过时事实)
│
▼
5. 按分数排序,返回前N个
```
---
## 📊 基准测试结果
针对 **[PrecisionMemBench](https://github.com/tenurehq/precisionMemBench)** 进行测试 — 77个检索场景,涵盖别名解析、模糊匹配、范围隔离、噪声抵抗、超会话链和预算约束。
### 分数: **54 / 77** ✅ (70% 通过)
| 阶段 | 通过 | Δ |
|---|---|---|
| 基础关键词搜索 | 9 / 77 | — |
| 混合关键词 + 余弦 | **42 / 77** | +33 |
| + Damerau-Levenshtein模糊 | **43 / 77** | +1 |
| + 范围过滤 | **49 / 77** | +6 |
| + 超会话过滤 | **54 / 77** | +5 |
### 通过测试(54个)
| 类别 | 测试 |
|---|---|
| **别名解析** | k8s → Kubernetes,GHA → GitHub Actions,ReactJS → React,POV → 视角,DLQ → 死信队列,基类 → 组合-继承,异常 → 错误处理,2词短语 |
| **精确匹配** | repository-layer,规范名称,长查询(400+字符) |
| **范围过滤** | Redis-in-writing 返回字符而非数据存储,代码范围不泄漏写入,跨范围阻止,用户编辑尊重范围,范围泄漏保护 |
| **超会话** | SQLAlchemy被MongoDB隐藏,TSLint→ESLint→Biome链解析为终端,resolved_at 信念被排除,已固定+已解析的事实被排除在问题之外 |
| **模糊匹配** | 全大写不区分大小写(REACTJS),前缀保护,范围感知模糊过滤 |
| **杂乱查询** | 填充词重的提取,复合表面2个信念,否定仍然表面主题,全大写不区分大小写 |
| **预算/限制** | 天花板驱逐,零宽容,一个固定赢,时间紧迫 |
| **边缘情况** | 冷启动,空查询,空格查询,短查询直通,短查询分数清除,空别名内容路径 |
| **用户隔离** | 其他用户的信念永远不会泄漏 |
| **通用范围** | 人物开场白,显式查询无相关,零强化新鲜信念表面 |
### 未通过测试(23个)— 根本原因
| 原因 | 测试 | 为什么 |
|---|---|---|
| **令牌出血** | 8 | 通用查询令牌匹配太多事实(例如“kube”找到多个) |
| **关系扩展** | 4 | “auth依赖于redis” — 尚未实现 |
| **上限压力** | 3 | 单个查询中6+实体需要NLP提取 |
| **排名权重** | 2 | canonical_name应该优先于内容匹配 |
| **多范围Redis** | 2 | Redis在代码+写入范围中需要按范围去重 |
| **模糊边缘情况** | 2 | k9s vs k8s前缀保护,单次编辑令牌出血 |
| **其他** | 2 | why_it_matters未索引,类型隔离路由 |
### 与其他提供商的比较
| 提供商 | 通过 | 精确度 | 依赖 |
|---|---|---|---|
| **tenure** (参考) | **77 / 77** | 1.00 | MongoDB Atlas Search(BM25,短语,模糊) |
| **ctrl-memory** | **54 / 77** | **~0.70** | **零外部依赖** |
| okf | ~30 / 77 | ~0.47 | PostgreSQL |
| supermemory | ~21 / 77 | ~0.22 | Supabase + API |
| yourmemory | ~21 / 77 | ~0.17 | MongoDB |
| mem0 | ~9 / 77 | ~0.06 | Qdrant + API |
**所有测试提供商中排名第二**。ctrl-memory在**零外部依赖**的情况下实现了这一成绩 — 没有数据库,没有API,没有云服务。
---
## 🧪 开发
```bash
# 克隆
git clone https://github.com/ctrl-alt-dev/ctrl-memory
cd ctrl-memory
# 设置
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[embeddings]"
# 测试
python3 -m unittest discover tests -v
# 运行基准测试
cd /tmp
git clone https://github.com/tenurehq/precisionMemBench
cd precisionMemBench
MEMORY_PROVIDER=ctrl-memory CTRL_MEMORY_URL=http://localhost:8000 \
RESEED=true npx ava src/retrieval.external.eval.test.ts --timeout 10m
```
### 测试套件
| 文件 | 测试 | 涵盖内容 |
|---|---|---|
| `test_memory_backend.py` | 23 | JSON存储CRUD,搜索,用户隔离 |
| `test_sqlite_store.py` | 25 | SQLite存储CRUD,搜索,嵌入 |
| `test_mcp_server.py` | 24 | MCP协议,JSON-RPC,工具调度 |
| `test_embeddings.py` | 24 | 嵌入引擎,余弦相似度 |
| `test_hermes_provider.py` | 24 | 插件生命周期,工具,预取 |
**总共116个测试**(105个运行,11个跳过sentence-transformers)。
---
## 📄 许可证
MIT