内容
# 永忆
[](https://github.com/Evermemoai/evermemo/actions/workflows/ci.yml)
[](https://github.com/Evermemoai/evermemo/releases)
[](https://pkg.go.dev/github.com/Evermemoai/evermemo)
[](https://goreportcard.com/report/github.com/Evermemoai/evermemo)
[](LICENSE)
**适用于人类和AI代理的微型通用记忆引擎。**
一个小型Go二进制文件。无需外部服务。它可以用作CLI、HTTP API和MCP服务器,因此任何东西都可以记住事情:您的终端、脚本、Claude Code、Cursor或其他任何代理。以中心模式运行,一个组织中的所有代理共享相同的可信知识。
```
┌──────────────┐ ┌─────────────┐ ┌──────────────────┐
│ 您(CLI) │ │ 任何应用程序 │ │ AI代理(MCP) │
│ 永忆添加 │ │ HTTP API │ │ Claude,Cursor │
└──────┬───────┘ └──────┬──────┘ └────────┬─────────┘
└──────────────────┼──────────────────┘
┌───────▼──────┐
│ 永忆 │ 单个二进制文件
│ SQLite+FTS5 │ BM25 + 语义搜索
└──────────────┘
```
## 安装
**预编译二进制文件** (macOS,Linux,Windows,amd64/arm64):从 [Releases](https://github.com/Evermemoai/evermemo/releases) 中获取。
**Go:**
```sh
go install github.com/Evermemoai/evermemo@latest
```
**Docker:**
```sh
docker run -v evermemo-data:/data -p 7777:7777 ghcr.io/evermemoai/evermemo:latest
```
**从源代码:**
```sh
git clone https://github.com/Evermemoai/evermemo.git && cd evermemo
go build -o evermemo .
```
有关生产中心,请参阅 [deploy/](deploy/) 中的systemd和Docker Compose示例,以及 [SECURITY.md](SECURITY.md) 中的强化检查清单。
## CLI
```sh
evermemo add "用户更喜欢深色模式和标签而不是空格" --tags prefs,ui
echo "部署在UTC 6点运行" | evermemo add --tags ops --ttl 7d # 7天后过期
evermemo search "部署时间"
evermemo list
evermemo get mem_a1b2c3d4e5f60718
evermemo update mem_a1b2c3d4e5f60718 "部署在UTC 7点运行"
evermemo delete mem_a1b2c3d4e5f60718
evermemo export > memories.jsonl # 备份/迁移
evermemo import < memories.jsonl
```
## 交互式UI
运行 `evermemo` 时不带参数(或 `evermemo ui`)以获取类似Claude Code的终端UI:
输入任何内容以记住它,使用 `/search`、`/list`、`/get`、`/delete`、`/ns` 管理记忆,使用 `/help` 获取所有信息,使用 `/exit` 离开。
## HTTP API
```sh
evermemo serve --addr :7777
```
| 方法 | 路径 | 描述 |
| ------ | -------------------- | ------------------------------------ |
| GET | `/health` | 健康检查 + 记忆数量 |
| POST | `/v1/memories` | 创建: `{content, tags?, namespace?, metadata?, ttl?}` |
| GET | `/v1/memories?q=...` | 搜索(混合排名);省略 `q` 以列出 |
| GET | `/v1/memories/{id}` | 获取一个 |
| PUT | `/v1/memories/{id}` | 更新: `{content?, tags?}` |
| DELETE | `/v1/memories/{id}` | 删除 |
| POST | `/mcp` | 通过HTTP的MCP(JSON-RPC),无需本地二进制文件 |
```sh
curl -X POST localhost:7777/v1/memories \
-d '{"content":"发票应在30天内支付","tags":["billing"]}'
curl "localhost:7777/v1/memories?q=invoice+due"
```
设置 `EVERMEMO_API_KEY=secret` 以要求所有 `/v1` 路由上的 `Authorization: Bearer secret`。
## MCP(Claude Code,Cursor,任何代理)
evermemo 通过stdio使用模型上下文协议,暴露八种工具:
`add_memory`、`update_memory`、`search_memory`、`list_memories`、`get_memory`、
`link_memory`、`verify_memory`、`delete_memory`。
**Claude Code:**
```sh
claude mcp add evermemo -- /path/to/evermemo mcp
```
**Cursor / 通用MCP配置:**
```json
{
"mcpServers": {
"evermemo": {
"command": "/path/to/evermemo",
"args": ["mcp"]
}
}
}
```
现在您的代理跨会话记住事情。
## 所有代理的共享内存(中心模式)
运行一个evermemo作为组织的记忆中心,并将所有代理指向它。
所有代理共享、搜索和建立在相同的知识基础上,每个记忆都记录了哪个代理写入了它。
```sh
# 在中心机器上:每个代理身份一个密钥
EVERMEMO_AGENT_KEYS='claude:key1,cursor:key2' evermemo serve --addr :7777
# 在每个代理的机器上:MCP代理到中心而不是本地文件
evermemo mcp --remote https://memory.internal:7777 --key key1 --agent claude
```
任何一个代理存储的内容都可以立即被其他所有代理搜索,具有 provenance(`"agent": "claude"`)的每个记忆。
未知密钥的请求被拒绝。 `EVERMEMO_REMOTE`、`EVERMEMO_API_KEY` 和 `EVERMEMO_AGENT` 环境变量作为标志默认值。
设置 `EVERMEMO_RATE=120` 以限制每个调用者每分钟120个请求。
代理也可以通过HTTP直接与中心进行MCP通信(`POST /mcp`)。
## 语义搜索(可选)
默认情况下,搜索是SQLite FTS5和BM25排名:快速、离线、无依赖。
将evermemo指向嵌入式提供程序,搜索变为混合(BM25加余弦相似度,与互惠排名融合),因此“我们何时部署”会找到“发布计划是星期四”。
```sh
# Ollama(本地,免费)
export EVERMEMO_EMBED_URL=http://localhost:11434
export EVERMEMO_EMBED_MODEL=nomic-embed-text # 默认
# ... 或任何OpenAI兼容的API
export EVERMEMO_EMBED_URL=https://api.openai.com
export EVERMEMO_EMBED_API_KEY=sk-...
```
记忆在写入时嵌入;如果提供程序关闭,搜索静默地恢复为仅限关键词。
有关完整的、一步一步的 **完全离线设置与Ollama** (语义搜索、合并和自动回忆代理 - 所有本地,无云),请参阅 [docs/ollama.md](docs/ollama.md)。
## 可信知识:出处、置信度、图、ACL
每个记忆都记录了谁编写了它。在此基础上:
- **验证**:代理确认或驳斥彼此的记忆(`verify_memory` 工具,`POST /v1/memories/{id}/verify`)。
投票改变置信度(初始值为0.6;+0.10每次确认,-0.15每次驳斥)。
- **记忆图**:使用 `supersedes`、`relates_to` 或 `derived_from`(`link_memory` 工具,`evermemo link <from> <rel> <to>`)
来追踪知识如何演变。链接在 `GET /v1/memories/{id}` 时返回。
- **命名空间ACL**:限制哪些代理可以读取或写入哪些命名空间:
```sh
EVERMEMO_ACL='finbot:finance:rw,hrbot:hr:rw,hrbot:finance:r,auditor:*:r' \
EVERMEMO_AGENT_KEYS='finbot:key1,hrbot:key2,auditor:key3' \
evermemo serve
```
在REST API和 `/mcp` 传输上强制执行。如果未设置ACL,则访问权限为开放。
## 生产中心:TLS,密钥轮换,备份
```sh
# HTTPS(或在Caddy/nginx中终止TLS)
evermemo serve --cert cert.pem --key key.pem
# 热加载密钥文件:添加/轮换/吊销代理密钥,无需重启
cat > keys.txt <<EOF
# agent:key,一行一个
claude:key1
cursor:key2
EOF
evermemo serve --keys-file keys.txt # 自动应用编辑
# 一致的在线快照(安全且正在运行;使用SQLite VACUUM INTO)
evermemo backup /backups/evermemo-$(date +%F).db
```
注意:承载密钥在纯HTTP上明文传输。始终在中心可达 localhost 以外的情况下使用TLS(内置或反向代理)。
## 记忆合并(LLM驱动的卫生)
随着时间的推移,记忆会积累重复和矛盾。 将evermemo指向聊天LLM,让它清理:
```sh
export EVERMEMO_LLM_URL=http://localhost:11434 # Ollama;或任何OpenAI兼容的API
evermemo consolidate --ns default --dry-run # 查看计划
evermemo consolidate --ns default # 应用它
```
LLM合并重复项,解决矛盾(最新赢得)并存档过时的记忆。
没有任何内容被删除:源被存档(隐藏在搜索中,保留审计)并链接到它们的替换项,带有 `derived_from`/`supersedes`。
## 自动回忆代理(无需工具的记忆)
将evermemo放在您的应用程序和LLM API之间,并自动将相关记忆注入每个聊天请求中。
无需 `search_memory` 调用:
```sh
evermemo proxy --target https://api.openai.com --addr :8788
# 然后将您的SDK指向 http://localhost:8788 而不是 api.openai.com
```
适用于OpenAI风格(`/v1/chat/completions`)和Anthropic风格(`/v1/messages`)的API,通过SSE流式传输响应,并将所有其他路由保持不变。
使用 `--remote https://your-hub:7777` 从共享中心回忆。
## 配置
| 环境变量 | 默认 | 描述 |
| ------------------ | ------------------------ | -------------------------------- |
| `EVERMEMO_DB` | `~/.evermemo/evermemo.db` | 数据库文件路径 |
| `EVERMEMO_API_KEY` | *(unset)* | 如果设置,HTTP API需要Bearer认证 |
| `EVERMEMO_AGENT_KEYS` | *(unset)* | 每个代理的密钥:`alice:key1,bob:key2` |
| `EVERMEMO_RATE` | *(unset)* | 每个调用者每分钟的最大请求数(0/未设置 = 关闭) |
| `EVERMEMO_REMOTE` | *(unset)* | `mcp`模式下的中心枢纽URL |
| `EVERMEMO_AGENT` | *(unset)* | 记录为出处代理名称 |
| `EVERMEMO_EMBED_URL` | *(unset)* | 嵌入式提供程序URL(启用语义搜索) |
| `EVERMEMO_EMBED_MODEL` | 提供程序默认值 | 嵌入式模型名称 |
| `EVERMEMO_EMBED_API_KEY` | *(unset)* | OpenAI兼容提供程序的密钥 |
| `EVERMEMO_EMBED_PROVIDER` | `ollama` | `ollama` 或 `openai` |
| `EVERMEMO_LLM_URL` | *(unset)* | 用于 `consolidate` 的聊天LLM |
| `EVERMEMO_LLM_MODEL` | 提供程序默认值 | 聊天模型名称 |
| `EVERMEMO_LLM_API_KEY` | *(unset)* | OpenAI兼容聊天提供程序的密钥 |
| `EVERMEMO_ACL` | *(unset)* | 命名空间ACL:`agent:ns:perm`(r/rw,`*`通配符) |
| `EVERMEMO_TLS_CERT` / `EVERMEMO_TLS_KEY` | *(unset)* | `serve`的TLS证书/密钥文件 |
| `EVERMEMO_KEYS_FILE` | *(unset)* | 热加载代理密钥文件 |
每个命令还接受 `--db` 以指向特定数据库,以及 `--ns`/`namespace` 以按项目、用户或代理分区记忆。
## 为什么
- **小**: 一个二进制文件,一个SQLite文件,零依赖项即可运行。
- **通用**: 人类CLI,任何语言的HTTP,任何代理的MCP。
- **快速**: SQLite FTS5和BM25排名;百万行毫秒级搜索。
- **您自己的**: 本地优先,无云,无遥测。 `scp` 文件备份。
## 路线图
- [x] 通过可选的嵌入式提供程序进行语义(向量)搜索
- [x] 记忆过期/ TTL
- [x] 导入/导出(JSONL)
- [x] 流式HTTP MCP传输
- [ ] Web仪表板(浏览,搜索,审计,图表)
- [ ] Webhooks / 更改订阅(反应式记忆)
- [ ] 具有中心同步的本地优先副本
## 贡献
欢迎贡献,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
发现安全问题?请遵循 [SECURITY.md](SECURITY.md)。
## 许可证
[MIT](LICENSE)