内容
# 英格拉姆
人工智能代理的长期记忆。简单、快速且与存储无关。
英格拉姆提供了一个基于向量的记忆系统,允许人工智能代理存储、检索、更新和删除具有语义搜索的记忆。它还包括两个自主认知引擎 — **反思** 和 **梦境** — 从原始记忆中合成高阶洞察。设计用于通过 [MCP](https://modelcontextprotocol.io/) (模型上下文协议)或 REST API 使用。
## 功能
- **4种记忆类型** — `identity`, `event`, `insight`, `directive` (+ 特定自由标签)
- **三组件评分** — 相关性 × 新鲜度 × 重要性,用于智能检索
- **MMR 重排序** — 平衡结果的相关性和多样性
- **自动去重** — 防止存储近似相同的记忆(可配置阈值)
- **记忆过期** — 可选的 `valid_until` 时间戳,用于自动清理时间有限的记忆
- **反思引擎** — 轻量级、频繁的综合(每天 1-3 次),从未反映的记忆中发现跨领域模式
- **梦境引擎** — 深度整合(每天 1 次),具有 4 相流水线:定向 → 收集 → 整合 → 修剪
- **与存储无关** — Qdrant 后端,具有其他存储的可插拔接口
- **与嵌入无关** — OpenAI (默认)或 Voyage AI,支持自定义嵌入
- **双重传输** — MCP (stdio) 和 HTTP REST API,具有 Bearer-token 认证
- **写透 + 环形缓冲区** — BoltDB 支持的提交日志,用于耐用性和崩溃恢复
- **热路径无LLM** — 存储和检索是纯向量操作。反思和梦境是可选的异步操作。
## 快速入门
### 选项 A:Docker Compose(推荐)
```bash
# 克隆仓库
git clone https://github.com/FBISiri/engram.git
cd engram
# 创建 .env 文件
cat > .env << EOF
ENGRAM_OPENAI_API_KEY=sk-...
EOF
# 启动 Qdrant + 构建英格拉姆镜像
docker-compose up -d qdrant
# 等待 Qdrant 健康检查完成,然后交互式运行英格拉姆(MCP stdio)
docker-compose run --rm engram serve
```
### 选项 B:二进制 + Docker Qdrant
```bash
# 1. 启动 Qdrant
docker run -d --name engram-qdrant \
--security-opt seccomp=unconfined \
-p 6333:6333 -p 6334:6334 \
-v engram_qdrant_data:/qdrant/storage \
qdrant/qdrant:v1.9.7
# 2. 构建英格拉姆
go build -o engram ./cmd/engram/
# 3. 配置
export ENGRAM_QDRANT_URL=localhost:6334
export ENGRAM_OPENAI_API_KEY=sk-...
# 4. 作为 MCP 服务器运行(stdio)
./engram serve
```
### 选项 C:Go 安装
```bash
# 先决条件:Qdrant 在 localhost:6334 上运行
go install github.com/FBISiri/engram/cmd/engram@latest
export ENGRAM_QDRANT_URL=localhost:6334
export ENGRAM_OPENAI_API_KEY=sk-...
engram serve
```
### 与 MCP 客户端一起使用
将英格拉姆添加到您的 MCP 客户端配置中(例如,Claude Desktop,Army of the Agent):
```json
{
"mcpServers": {
"engram": {
"command": "/path/to/engram",
"args": ["serve"],
"env": {
"ENGRAM_QDRANT_URL": "localhost:6334",
"ENGRAM_OPENAI_API_KEY": "sk-..."
}
}
}
}
```
或在 YAML 中(Army of the Agent):
```yaml
mcp_servers:
- name: "engram"
transport: stdio
command: /path/to/engram
args: ["serve"]
env:
ENGRAM_QDRANT_URL: "localhost:6334"
ENGRAM_OPENAI_API_KEY: "sk-..."
```
## 集成测试
在实时 Qdrant 实例上运行完整的端到端集成测试:
```bash
# 确保 Qdrant 在 localhost:6333/6334 上运行
ENGRAM_OPENAI_API_KEY=sk-... ./integration_test.sh
```
该测试涵盖所有 6 个 MCP 工具(搜索、添加、更新、删除、反射检查、反射运行),包括重复检测。
## 记忆类型
| 类型 | 描述 | 衰减 | 示例 |
| --- | --- | --- | --- |
| `identity` | 关于用户的稳定事实 | 永久 | 姓名、职业、偏好、关系 |
| `event` | 已经发生的事情 | 约 3 天半衰期 | 会话、观察、计划 |
| `insight` | 推断的模式 | 约 90 天半衰期 | 反思、行为倾向 |
| `directive` | 明确的用户指令 | 永久 | “始终用中文回应” |
使用 **标签** 进行进一步分类: `["relationship", "person:Alice"]`, `["study", "golang"]`, `["preference", "food"]`.
### 记忆过期
记忆可以具有可选的 `valid_until` 字段(Unix 时间戳)。后台 goroutine 每 10 分钟运行一次,以自动清理过期的记忆。设置为 `0` 或省略 `valid_until` 以使记忆永不过期。
### TTL 自动计算器
当 `valid_until` 在 `memory_add` / `memory_update` 中未显式设置时,英格拉姆从 **类型 × 重要性** 矩阵中推导出一个合理的 TTL(例如,低重要性 `event` 记忆在几天内过期,高重要性 `insight` 记忆在几个月内过期,`identity` / `directive` 类型默认永不过期)。显式 `valid_until` 值始终优先 — 自动计算器仅在调用者省略时填充。
## API
### MCP 工具
| 工具 | 描述 |
| --- | --- |
| `memory_search` | 具有类型/标签/时间过滤器的语义搜索 |
| `memory_add` | 存储记忆(自动去重) |
| `memory_update` | 查找旧记忆按含义 → 用新记忆替换 |
| `memory_delete` | 查找记忆按含义 → 删除 |
| `reflection_check` | 在运行前检查反射引擎触发条件 |
| `reflection_run` | 运行一个反射引擎周期(支持 `dry_run` 模式) |
### 传输模式:stdio vs HTTP
英格拉姆支持两种传输模式,可通过 `ENGRAM_TRANSPORT` 配置:
| 模式 | 值 | 用例 | 工作原理 |
| --- | --- | --- | --- |
| **MCP stdio** | `stdio` (默认) | MCP 客户端(Claude Desktop,Army of the Agent) | 从 stdin 读取 JSON-RPC,写入 stdout。MCP 客户端管理进程生命周期。 |
| **HTTP REST** | `http` | 直接 API 集成、仪表板、脚本 | 在 `ENGRAM_HTTP_PORT` 上启动 HTTP 服务器(默认为 8080)。具有 Bearer 认证的 RESTful JSON API。 |
| **两者** | `both` | 同时运行 MCP + REST | 在需要 MCP 进行代理和 REST 进行监控/管理的用例中很有用。 |
**何时使用 stdio**:您正在与兼容 MCP 的客户端集成。客户端将英格拉姆作为子进程启动,并通过 stdin/stdout 进行通信。无需网络配置。
**何时使用 HTTP**:您需要来自脚本、仪表板或非 MCP 客户端的编程访问权限。也需要用于容器编排器(Kubernetes、Docker 健康检查)使用的 `/health` 端点。
```bash
# stdio 模式(默认)— 用于 MCP 客户端
./engram serve
# HTTP 模式 — 用于 REST API 访问
ENGRAM_TRANSPORT=http ENGRAM_API_KEY=your-secret ./engram serve
# 两者 — MCP + REST 同时
ENGRAM_TRANSPORT=both ENGRAM_API_KEY=your-secret ./engram serve
```
### REST API(HTTP 传输)
启用 `ENGRAM_TRANSPORT=http` 或 `ENGRAM_TRANSPORT=both` (MCP + HTTP)。
认证:设置 `ENGRAM_API_KEY` 以要求所有 HTTP 请求的 `Authorization: Bearer <key>`。 `/health` 和 `/metrics` 端点绕过身份验证以进行监控。
**核心记忆操作**
| 方法 | 路径 | 描述 |
| --- | --- | --- |
| `POST` | `/memories` | 存储新记忆(自动去重) |
| `POST` | `/memories/search` | 语义搜索并过滤 |
| `GET` | `/memories/{id}` | 按 ID 获取特定记忆 |
| `PATCH` | `/memories/{id}` | 部分更新记忆 |
| `PUT` | `/memories/{id}` | 完全替换记忆 |
| `DELETE` | `/memories/{id}` | 删除记忆 |
| `POST` | `/memories/{id}/reset` | 重置记忆访问统计 |
| `POST` | `/memories/cross-search` | 跨多个集合搜索 |
**集合管理**
| 方法 | 路径 | 描述 |
| --- | --- | --- |
| `POST` | `/collections` | 创建新集合 |
| `GET` | `/collections` | 列出所有集合 |
| `POST` | `/collections/{name}/memories` | 将记忆添加到特定集合 |
| `POST` | `/collections/{name}/memories/search` | 在特定集合中搜索 |
**反射 & 维护**
| 方法 | 路径 | 描述 |
| --- | --- | --- |
| `POST` | `/reflect` | 运行一个反射引擎周期(可选:`{"dry_run": true}`) |
| `GET` | `/reflect/check` | 检查反射触发条件 |
| `GET` | `/memories/expiry-candidates` | 列出接近过期的记忆 |
| `DELETE` | `/memories/expired` | 清除过期记忆 |
**可观察性**
| 方法 | 路径 | 描述 |
| --- | --- | --- |
| `GET` | `/health` | 深度活跃度 — ping Qdrant(无需身份验证) |
| `GET` | `/metrics` | Prometheus 指标(无需身份验证) |
## 反射引擎
反射引擎定期从未反映的记忆中合成高-level 洞察,受 *Generative Agents* 论文启发。它比梦境引擎运行更轻量、更频繁。
**触发器**:未反映的记忆累计重要性 ≥ 阈值(默认:40)。最小间隔:2 小时。每天最多:3 次运行。
**输出**:`insight` 类型记忆,`source="system"`,标记反射源 ID。源记忆标记为 `reflected=true`.
通过环境变量配置:
| 变量 | 默认值 | 描述 |
| --- | --- | --- |
| `ENGRAM_REFLECTION_ENABLED` | `false` | 启用反射引擎 |
| `ENGRAM_REFLECTION_TRIGGER` | `count` | 触发模式:`count`, `cron`, `manual` |
| `ENGRAM_REFLECTION_COUNT` | `10` | 触发的最小未反映记忆数 |
| `ENGRAM_REFLECTION_MODEL` | `claude-sonnet-4-20250514` | 用于合成的 LLM 模型 |
## 梦境引擎
梦境引擎执行深度记忆整合 — 使用 4 相流水线进行自主洞察生成:
1. **定向** — 评估当前记忆格局,识别集群
2. **收集** — 收集相关记忆作为整合候选
3. **整合** — 合并冗余/相关记忆成高阶洞察
4. **修剪** — 删除过时的记忆以保持存储清洁
**门控条件**(必须全部通过):
- **门控 1(时间)**:≥ 20 小时自上次运行
- **门控 2(容量)**:≥ 20 个新记忆自上次运行
- **门控 3(PID)**:没有其他梦境进程当前运行(过时 PID 超时:2 小时)
状态保存在 `~/.siri/` (上次运行时间戳,PID 锁文件)。
## 评分
```
score = 1.0 × 相关性 + 0.5 × 新鲜度 + 0.3 × 重要性
```
- **相关性**:查询和记忆嵌入之间的余弦相似度
- **新鲜度**:基于记忆类型的指数衰减(可配置)
- **重要性**:用户分配的 1-10 评分,归一化
权重可通过 `ENGRAM_WEIGHT_RELEVANCE`, `ENGRAM_WEIGHT_RECENCY`, `ENGRAM_WEIGHT_IMPORTANCE` 配置。
## 配置
全部通过环境变量:
| 变量 | 默认值 | 描述 |
| --- | --- | --- |
| `ENGRAM_QDRANT_URL` | `localhost:6334` | Qdrant gRPC 地址 |
| `ENGRAM_QDRANT_API_KEY` | — | Qdrant API 密钥(如果安全) |
| `ENGRAM_EMBEDDER_PROVIDER` | `openai` | 嵌入提供者:`openai` 或 `voyage` |
| `ENGRAM_EMBEDDING_MODEL` | `text-embedding-3-small` | 嵌入模型名称 |
| `ENGRAM_EMBEDDING_DIMENSION` | `1536` | 嵌入向量大小 |
| `ENGRAM_OPENAI_API_KEY` | — | OpenAI API 密钥 |
| `ENGRAM_OPENAI_BASE_URL` | `https://api.openai.com/v1` | OpenAI API 基址 |
| `ENGRAM_VOYAGE_API_KEY` | — | Voyage AI API 密钥 |
| `ENGRAM_DEDUP_THRESHOLD` | `0.92` | 余弦相似度用于重复检测 |
| `ENGRAM_MMR_LAMBDA` | `0.5` | MMR 多样性因子(0=最大多样性,1=最大相关性) |
| `ENGRAM_WEIGHT_RELEVANCE` | `1.0` | 评分中相关性的权重 |
| `ENGRAM_WEIGHT_RECENCY` | `0.5` | 评分中新鲜度的权重 |
| `ENGRAM_WEIGHT_IMPORTANCE` | `0.3` | 评分中重要性的权重 |
| `ENGRAM_TRANSPORT` | `stdio` | 服务器传输:`stdio`, `http`, `both` |
| `ENGRAM_HTTP_PORT` | `8080` | REST API 端口 |
| `ENGRAM_API_KEY` | — | HTTP Bearer 认证的 API 密钥 |
| `ENGRAM_REFLECTION_ENABLED` | `false` | 启用反射引擎 |
| `ENGRAM_REFLECTION_TRIGGER` | `count` | 反射触发模式 |
| `ENGRAM_REFLECTION_COUNT` | `10` | 触发的最小未反映记忆数 |
| `ENGRAM_REFLECTION_MODEL` | `claude-sonnet-4-20250514` | 用于反射的 LLM 模型 |
查看 [完整配置参考](docs/configuration.md) 以获取所有选项。
## 架构
```
engram/
├── cmd/engram/ CLI 入口点
├── internal/
│ └── otel/ OpenTelemetry 跟踪(文件/stdout 导出器)
├── pkg/
│ ├── collection/ 多集合注册表(用户,agent_self,反射)
│ ├── config/ 环境变量配置
│ ├── dream/ 梦境引擎 — 4 相深度内存整合
│ ├── embedding/ 嵌入接口 + OpenAI + Voyage AI + LRU 缓存
│ ├── memory/ 核心类型,评分,重复检测,MMR,过期,TTL
│ ├── metrics/ Prometheus 指标
│ ├── qdrant/ Qdrant 存储 + 多存储实现
│ ├── reflection/ 反射引擎 — V1(扁平)+ V2(焦点)
│ ├── server/ MCP 服务器(stdio)+ HTTP 服务器(REST + CRUD)
│ └── sync/ 写透 + 环形缓冲区(BoltDB 提交日志)
├── docs/ API 参考 + 配置指南
├── Dockerfile 多阶段构建
├── docker-compose.yml 英格拉姆 + Qdrant
└── integration_test.sh 端到端 MCP 测试
```
## 可观察性
英拉姆使用 OpenTelemetry 进行分布式跟踪。默认情况下,跟踪导出到每日旋转的 JSONL 文件。
### 配置
| 环境变量 | 默认值 | 描述 |
| --- | --- | --- |
| `ENGRAM_OTEL_ENABLED` | `true` | 启用/禁用跟踪 |
| `ENGRAM_OTEL_EXPORTER` | `file` | 导出器:`file`, `stdout`, `none` |
| `ENGRAM_OTEL_FILE_DIR` | `/tmp/siri-state/engram-traces` | JSONL 跟踪文件目录 |
| `ENGRAM_OTEL_SAMPLE_RATIO` | `1.0` | 采样率(0-1) |
### §1 反射仪表盘(R-S3)
| Span 名称 | 入口点 | 属性 |
| --- | --- | --- |
| `engram.reflection.run` | `pkg/reflection/engine.go::Run` | `engram.memory.valid_until_set`(bool),`engram.memory.valid_until`(字符串,RFC 3339) |
### §2 反射 V2 仪表盘(R-S3)
与 `RunV2` 和 `RunSingleEvent` 发出的 `engram.reflection.run` 相同。
### §3 内存仪表盘(R-S5)
| Span 名称 | 入口点 | 属性 |
| --- | --- | --- |
| `engram.memory.search` | `pkg/server/server.go::handleSearch` | `query.length`, `tags.count`, `limit`, `result.count`, `latency_ms`, `embedder.provider` |
| `engram.memory.add` | `pkg/server/server.go::handleAdd` | `content.length`, `tags.count`, `type`, `importance`, `dedup.hit`(bool) |
| `engram.memory.dedup_check` | `pkg/server/server.go::checkDedup` | `query.length`, `threshold`, `top_score`, `decision`(添加/跳过),`latency_ms` |
错误路径设置 `span.RecordError(err)` + `span.SetStatus(codes.Error, ...)`.
`engram.memory.dedup_check` 是 `engram.memory.add` | `engram.memory.dedup_check` 是 `engram.memory.add` 的子 span。 |
## 背景
英格拉姆(名词):*神经组织中代表记忆的假设物理或生化变化。* 来自神经科学。
该项目源于在生产环境中运行 [chat2mem](https://github.com/FBISiri/chat2mem) (一个 Python MCP 内存服务器)数月。英格拉姆是在 Go 中从头开始重新设计,参考了 Graphiti, Hindsight, MemOS 和 Mem0 等系统的使用模式和研究成果。
## 许可
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器