关于 engram-server
Engram 是面向 AI Agent 的持久记忆服务,可从对话中提取事实,并以时序知识图谱存储,支持 SQLite 或 PostgreSQL。它以单一二进制文件运行,无需 Python 或额外基础设施,适合需要可自托管记忆层的开发者。
主要功能
- 01从对话中提取事实
- 02SQLite 或 PostgreSQL 存储
- 03向量与关键词混合检索
- 04时序知识图谱与作用域隔离
- 05多种 LLM 后端与 command 扩展
适用场景
- 01为本地 AI Agent 保存跨会话的用户偏好与事实
- 02在单个 SQLite 文件中搭建轻量记忆层
- 03为多用户或多租户应用按 org、user、session 隔离记忆
MCP 相关
该服务通过 stdio 提供 MCP 接口,暴露 memory_add、memory_recall、memory_search、memory_forget、messages_save 等七个记忆工具与四个消息存储工具,同时支持 REST 模式。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm ghcr.io/jamjet-labs/engram-server:0.5.0本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/jamjet-labs/engram-server:0.5.0stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
⚡ Engram
为 AI Agent 提供持久记忆——时序知识图谱、混合检索,支持 SQLite 或 PostgreSQL。
Engram 是一个为 AI Agent 提供的持久记忆层。它从对话中提取事实,将其存储在时序知识图谱中,并通过语义与关键词混合搜索进行检索——后端由单个 SQLite 文件或 PostgreSQL 数据库提供支持。
它提供两种形式:
jamjet-engram——可嵌入自有应用的 Rust 库。jamjet-engram-server(本 crate)——独立二进制程序,通过 stdio 提供 MCP,并通过 HTTP 提供 REST,因此 Claude Desktop、Cursor 和任何 HTTP 客户端都无需编写代码即可使用。
Engram 不绑定特定提供商。它开箱即用地接入了五种 LLM 后端,另外还有 command,可调用任意外部脚本,因此无需修改 Rust 代码,即可接入 Engram 未原生支持的提供商:
ENGRAM_LLM_PROVIDER= | 功能 |
|---|---|
ollama(默认) | 通过 /api/chat 使用本地 Ollama。免费、无需 API 密钥,可在笔记本电脑上运行。 |
openai-compatible | 任何支持 OpenAI 聊天补全协议的端点——参见下方的长列表。 |
anthropic | 通过 Messages API 使用 Anthropic Claude。 |
google | 通过 generateContent 和原生 JSON 模式使用 Google Gemini。 |
command | 调用用户提供的脚本。扩展能力无限,无需重新编译。 |
mock | 仅用于测试的确定性后端——返回空事实。 |
使用 ENGRAM_LLM_PROVIDER=… 选择一个——同一个二进制程序即可处理所有后端。
项目现状,2026 年 4 月。 Engram 刚刚推出——版本为 v0.3.2,社区规模较小,目前还没有公开的 LongMemEval / DMR 数据。下方的架构已可运行,测试也已通过,Docker 镜像能够正常运行。如果你现在需要生产规模的记忆能力,Mem0 Cloud 和 Zep Cloud 更成熟。如果你需要一个可试用、可自托管的单二进制记忆层,而且不依赖 Python、Postgres、Qdrant 或 Neo4j,那么 Engram 正是为你打造的。
为什么选择 Engram?
| 问题 | Engram 的解决方案 |
|---|---|
| 所有 Agent 记忆库都以 Python 为先 | Rust 核心,支持原生 Python、Java 和 MCP 客户端——无需旁路服务 |
| 仅仅为了试用就需要 Postgres + Qdrant + Neo4j | 单个 SQLite 文件(无需任何基础设施),或在需要时使用 Postgres |
| 对话历史不等于知识记忆 | 事实提取流水线——从消息中提取结构化事实 |
| 旧事实会逐渐偏移并相互矛盾 | 冲突检测 + 整合——衰减、提升、去重、总结、反思 |
| 记忆召回只能选择语义检索或关键词检索 | 混合检索——在一次查询中结合向量搜索和 SQLite FTS5 |
| Agent 在不同进程间会丢失记忆 | 默认持久化——使用 SQLite 或 Postgres,崩溃安全且可移植 |
| MCP 支持只是事后才添加的功能 | 原生支持 MCP——单个二进制文件即可提供 7 个工具 |
| 无法回溯 Agent 曾经知道的信息 | 时态知识图谱——每条事实都有作用域和时间戳 |
| 无法按用户或租户隔离记忆 | 一等作用域——组织 / 用户 / 会话内置于每次查询中 |
快速开始 — 30 秒
Engram 开箱即支持四种 LLM 提供商:Ollama(默认——免费、本地运行)、OpenAI、Anthropic Claude 和 Google Gemini。任选其一。
选项 A — Ollama(免费、本地运行、无需 API 密钥)
要求: Ollama,并已拉取 llama3.2 和 nomic-embed-text:
ollama pull llama3.2
ollama pull nomic-embed-text
Docker(最简单):
docker run --rm -i \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2
容器默认连接到 host.docker.internal:11434 上的 Ollama——在 Mac 和 Windows 的 Docker Desktop 上开箱即用。Linux 用户需要添加 --add-host=host.docker.internal:host-gateway。
选项 B — Anthropic Claude(托管服务,质量最高)
docker run --rm -i \
-e ENGRAM_LLM_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY=sk-ant-... \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2
默认使用 claude-haiku-4-5-20251001。可通过 -e ENGRAM_ANTHROPIC_MODEL=claude-sonnet-4-6 覆盖。
注意:Anthropic 没有原生 JSON 模式,因此 Engram 会从文本响应中解析 JSON。
llm_util::extract_json_payload辅助函数会去除 Claude 偶尔输出的 Markdown 代码围栏。
选项 C — Google Gemini
docker run --rm -i \
-e ENGRAM_LLM_PROVIDER=google \
-e GOOGLE_API_KEY=AIza... \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2
默认使用 gemini-flash-latest。可通过 -e ENGRAM_GOOGLE_MODEL=gemini-2.5-flash 覆盖。
选项 D — 任意兼容 OpenAI 的端点
docker run --rm -i \
-e ENGRAM_LLM_PROVIDER=openai-compatible \
-e OPENAI_API_KEY=sk-... \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2
默认使用 OpenAI 本身(https://api.openai.com/v1、gpt-4o-mini)。只需更改一个环境变量,即可指向以下任一提供商,无需重新编译:
| 提供商 | ENGRAM_OPENAI_BASE_URL= | 说明 |
|---|---|---|
| OpenAI | https://api.openai.com/v1 | 默认 |
| Azure OpenAI | https://<resource>.openai.azure.com/openai/deployments/<deployment> | |
| Groq | https://api.groq.com/openai/v1 | 推理速度非常快 |
| Together.ai | https://api.together.xyz/v1 | |
| Mistral | https://api.mistral.ai/v1 | |
| DeepSeek | https://api.deepseek.com/v1 | |
| Perplexity | https://api.perplexity.ai | |
| OpenRouter | https://openrouter.ai/api/v1 | 一把密钥,支持多种模型 |
| Fireworks | https://api.fireworks.ai/inference/v1 | |
| vLLM(可自托管) | http://your-host:8000/v1 | |
| LM Studio | http://localhost:1234/v1 | 本地桌面应用 |
| LocalAI | http://localhost:8080/v1 | 可自托管 |
Ollama /v1 兼容层 | http://localhost:11434/v1 | Ollama 的另一种接入方式 |
| 企业内部 LLM 网关 | 基础设施团队提供的任意 URL |
openai 可作为向后兼容的别名,代替 openai-compatible。
选项 E — command(调用任意命令)
对于 Engram 未原生支持的提供方——例如使用自定义 RPC 的内部模型、原始 SOAP 端点、本地推理二进制文件、基于 Python SDK 的快速封装,或未来新增的提供方——请使用 command 后端。Engram 会在每次提取调用时启动你的脚本,将 JSON 请求写入其标准输入,并从标准输出读取 JSON 响应。
**约定。**你的脚本从标准输入读取一个 JSON 对象:
{"system": "<extraction prompt>", "user": "<conversation text>", "structured": true}
然后向标准输出写入一个 JSON 值。可以是裸值:
{"facts": [{"text": "...", "entities": [...], "confidence": 0.95, "category": "..."}]}
也可以是封装对象(便于呈现错误):
{"content": {"facts": [...]}}
{"error": "rate limited, try again"}
成功时退出码为 0,失败时退出码为非零(并写入标准错误)。
Python 封装示例(约 15 行):
#!/usr/bin/env python3
# my-llm.py — wraps any Python SDK for Engram.
import json, sys
from my_llm_sdk import chat # your SDK
req = json.loads(sys.stdin.read())
resp = chat(
system=req["system"],
user=req["user"],
json_mode=req.get("structured", False),
)
sys.stdout.write(json.dumps(resp))
将 Engram 指向它:
docker run --rm -i \
-e ENGRAM_LLM_PROVIDER=command \
-e ENGRAM_LLM_COMMAND="python /scripts/my-llm.py" \
-v $(pwd)/scripts:/scripts \
-v engram-data:/data \
ghcr.io/jamjet-labs/engram-server:0.3.2
默认超时时间为 120 秒,可通过 ENGRAM_LLM_COMMAND_TIMEOUT=30 覆盖。
安全性:
command提供方会以 Engram 进程用户的身份运行任意命令。在不可信用户可以设置ENGRAM_LLM_COMMAND的多租户部署中,切勿使用它。这是仅供本地单租户使用的功能。
选项 F — cargo install(所有提供方使用同一个二进制文件)
cargo install jamjet-engram-server
engram serve # ollama (default)
ENGRAM_LLM_PROVIDER=anthropic ANTHROPIC_API_KEY=... engram serve
ENGRAM_LLM_PROVIDER=command ENGRAM_LLM_COMMAND="python /path/to/wrapper.py" engram serve
选项 G — 用于测试的 REST 模式
engram serve --mode rest --port 9090
curl -X POST http://localhost:9090/v1/memory \
-H 'content-type: application/json' \
-d '{
"user_id": "alice",
"messages": [
{"role": "user", "content": "I am allergic to peanuts and I love sourdough."}
]
}'
curl 'http://localhost:9090/v1/memory/recall?q=food%20allergies&user_id=alice'
无需服务端。无需配置。无需 Python 辅助进程。只需一个二进制文件。
MCP 客户端配置
Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json)
{
"mcpServers": {
"engram": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "engram-data:/data",
"ghcr.io/jamjet-labs/engram-server:0.3.2"
]
}
}
}
Cursor / 任意支持 MCP 的 IDE
将其指向同一条 docker run 命令,或本地安装的 engram serve 二进制文件。重启后,模型即可使用 11 个工具(7 个 memory_* + 4 个 messages_*)。
MCP 工具
记忆工具(7 个)
| 工具 | 功能 |
|---|---|
memory_add | 从对话消息中提取并存储事实(调用大模型进行提取) |
memory_recall | 对已存储的事实进行语义搜索,范围限定为 user_id / org_id |
memory_context | 为大模型提示词组装受令牌预算限制的上下文块,并按层级进行选择 |
memory_search | 对事实进行关键词搜索(SQLite FTS5 / Postgres 全文搜索) |
memory_forget | 按 ID 软删除一条事实,可选填写原因 |
memory_stats | 汇总计数:事实总数、有效事实、实体、关系 |
memory_consolidate | 执行整合周期——降低过时事实的权重、提升高价值事实,并去重近似重复项 |
所有工具均按 (org_id, user_id, session_id) 限定范围——组织的范围最粗,会话的范围最细。
消息存储工具(4 个)
| 工具 | 功能 |
|---|---|
messages_save | 保存对话的聊天消息(可选触发事实提取) |
messages_get | 按 ID 获取对话的所有消息 |
messages_list | 列出所有对话 ID |
messages_delete | 删除对话的所有消息 |
REST API
共 13 个端点,根路径为 /v1/memory。完整的 OpenAPI 风格接口:
| 方法 | 路径 | 处理程序 |
|---|---|---|
| GET | /health | 存活探针 |
| POST | /v1/memory | 添加消息(提取事实) |
| GET | /v1/memory/recall?q=…&user_id=… | 语义回忆 |
| POST | /v1/memory/context | 组装受令牌预算限制的上下文 |
| GET | /v1/memory/search?q=…&user_id=… | 关键词搜索 |
| GET | /v1/memory/stats | 汇总统计信息 |
| POST | /v1/memory/consolidate | 触发整合 |
| DELETE | /v1/memory/facts/:id | 忘记一条事实 |
| DELETE | /v1/memory/users/:id | 删除 GDPR 用户数据 |
| POST | /v1/memory/messages | 保存对话消息 |
| GET | /v1/memory/messages | 列出对话 ID |
| GET | /v1/memory/messages/:id | 获取对话消息 |
| DELETE | /v1/memory/messages/:id | 删除对话 |
配置
所有设置均通过 CLI 标志或环境变量传入。建议通过环境变量配置 Docker 镜像。
核心
| CLI 标志 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
--db | ENGRAM_DB_PATH | engram.db | SQLite 文件路径或 postgres://… 连接 URL |
--extract-on-save | ENGRAM_EXTRACT_ON_SAVE | true | 保存聊天消息时启用事实提取 |
--mode | ENGRAM_MODE | mcp | mcp(stdio)或 rest(HTTP) |
--port | ENGRAM_PORT | 9090 | REST 模式下的 HTTP 端口 |
--llm-provider | ENGRAM_LLM_PROVIDER | ollama | ollama、openai-compatible(别名 openai)、anthropic、google、command、mock |
--embedding-provider | ENGRAM_EMBEDDING_PROVIDER | ollama | ollama 或 mock(计划支持云端嵌入服务提供商) |
--embedding-model | ENGRAM_EMBEDDING_MODEL | nomic-embed-text | Ollama 嵌入模型 |
--embedding-dims | ENGRAM_EMBEDDING_DIMS | 768 | 必须与嵌入模型的输出维度一致 |
Ollama
| CLI 标志 | 环境变量 | 默认值 |
|---|---|---|
--ollama-url | ENGRAM_OLLAMA_URL | http://localhost:11434(Docker 镜像:http://host.docker.internal:11434) |
--ollama-llm-model | ENGRAM_OLLAMA_LLM_MODEL | llama3.2 |
OpenAI 兼容(OpenAI、Groq、Together、Mistral、DeepSeek、Azure、vLLM,……)
| CLI 标志 | 环境变量 | 默认值 |
|---|---|---|
--openai-api-key | OPENAI_API_KEY | (提供商为 openai-compatible 时必需) |
--openai-base-url | ENGRAM_OPENAI_BASE_URL | https://api.openai.com/v1 — 更改此项以切换提供商,请参见上方的大表格 |
--openai-model | ENGRAM_OPENAI_MODEL | gpt-4o-mini |
Anthropic
| CLI 标志 | 环境变量 | 默认值 |
|---|---|---|
--anthropic-api-key | ANTHROPIC_API_KEY | (提供商为 anthropic 时必需) |
--anthropic-base-url | ENGRAM_ANTHROPIC_BASE_URL | https://api.anthropic.com |
--anthropic-model | ENGRAM_ANTHROPIC_MODEL | claude-haiku-4-5-20251001 |
Google Gemini
| CLI 标志 | 环境变量 | 默认值 |
|---|---|---|
--google-api-key | GOOGLE_API_KEY | (提供商为 google 时必需) |
--google-base-url | ENGRAM_GOOGLE_BASE_URL | https://generativelanguage.googleapis.com/v1beta |
--google-model | ENGRAM_GOOGLE_MODEL | gemini-flash-latest |
命令(通过 Shell 执行)
| CLI 标志 | 环境变量 | 默认值 |
|---|---|---|
--llm-command | ENGRAM_LLM_COMMAND | (提供商为 command 时必需) — 通过 sh -c 运行 |
--llm-command-timeout | ENGRAM_LLM_COMMAND_TIMEOUT | 120 — 子进程被终止前的秒数 |
mock后端会返回空事实和确定性的字节循环向量。它用于测试和 CI。如果服务器检测到正在使用 mock 模式,启动时会打印清晰的警告。API 密钥和命令内容绝不会回显到 stdout 或日志中 — 服务器只会描述provider model at base_url或command \<first 60 chars>``。
数据库后端
Engram 支持 SQLite(默认)和 PostgreSQL 后端。后端由 --db URL 选择:
# SQLite (default)
engram serve --mode rest --db engram.db
# PostgreSQL
engram serve --mode rest --db postgres://user:pass@localhost:5432/engram
使用 PostgreSQL 时,首次启动会自动创建表。
聊天消息存储
Engram 可以在存储提取出的事实的同时存储原始聊天消息。这样即可集成 Spring AI ChatMemoryRepository。
REST 端点:
| 方法 | 端点 | 描述 |
|---|---|---|
| POST | /v1/memory/messages | 保存对话消息 |
| GET | /v1/memory/messages | 列出对话 ID |
| GET | /v1/memory/messages/{id} | 获取对话消息 |
| DELETE | /v1/memory/messages/{id} | 删除对话 |
MCP 工具: messages_save、messages_get、messages_list、messages_delete
保存消息时是否提取事实由 --extract-on-save 控制(默认值:true)。
嵌入此库
如果你不想运行独立进程,可以直接依赖 jamjet-engram:
[dependencies]
jamjet-engram = "0.3.2"
use engram::{Memory, OllamaEmbeddingProvider, OllamaLlmClient, Scope, ExtractionConfig, Message};
let embedding = Box::new(OllamaEmbeddingProvider::new());
let memory = Memory::open("sqlite:engram.db?mode=rwc", embedding).await?;
let scope = Scope::user("default", "alice");
let messages = vec![Message {
role: "user".into(),
content: "I am allergic to peanuts.".into(),
}];
let llm = Box::new(OllamaLlmClient::new());
let fact_ids = memory
.add_messages(&messages, scope.clone(), llm, ExtractionConfig::default())
.await?;
// Later, recall
let facts = memory.recall(&engram::memory::RecallQuery {
query: "food allergies".into(),
scope: Some(scope),
max_results: 5,
as_of: None,
min_score: None,
}).await?;
其他语言
Engram 是 JamJet 生态系统的一部分。这些客户端通过 REST 与 engram-server 通信:
| 语言 | 软件包 | 安装 |
|---|---|---|
| Python | jamjet(包含 EngramClient) | pip install jamjet |
| Java | dev.jamjet:jamjet-sdk(包含 EngramClient) | Maven Central |
| Spring Boot | dev.jamjet:engram-spring-boot-starter | Maven Central — 零配置 @Bean EngramMemory |
| Rust | jamjet-engram(直接嵌入) | cargo add jamjet-engram |
请参阅 java-ai-memory.dev,了解 Engram 与 LangChain4j ChatMemory、Spring AI ChatMemory、Koog、Embabel、Google ADK Memory Bank、Mem0 社区封装和 Zep 的比较,以及 Engram 适用的场景和替代方案更成熟的领域。
架构
┌──────────────────────────────────────────────────────────┐
│ Clients: Claude Desktop, Cursor, JamJet, │
│ Python SDK, Java SDK, Spring Boot, cURL │
├─────────────────┬────────────────────────────────────────┤
│ MCP (stdio) │ REST (HTTP + JSON) │
├─────────────────┴────────────────────────────────────────┤
│ engram-server │
│ (jamjet-engram-server) │
├──────────────────────────────────────────────────────────┤
│ engram (lib) │
│ Extraction pipeline │ Hybrid retrieval │ Scopes │
│ Conflict detection │ Consolidation │ Context │
├──────────────────────────────────────────────────────────┤
│ LlmClient trait │ EmbeddingProvider trait │
│ Ollama · Mock │ Ollama · Mock │
├──────────────────────────────────────────────────────────┤
│ Storage │
│ SQLite or PostgreSQL (facts, entities, FTS, vectors) │
└──────────────────────────────────────────────────────────┘
Engram 不是什么
- 不 只是 一个聊天历史存储。 Engram 现在包含消息存储(请参阅聊天消息存储),但它的主要价值在于其上层的事实提取和知识图谱层。如果你只需要保存对话的最近 N 条消息,使用框架内置的窗口可能更简单。
- 不是状态检查点工具。 如果你需要对 Agent 执行状态进行快照,以便恢复和重放,可以使用 LangGraph、Koog 持久化功能或 JamJet 自己的持久化运行时。它们可以与 Engram 搭配使用——它们解决的是不同的问题。
- 不是托管服务。 没有托管平台,除了作用域之外没有身份验证层,也不提供 SLA。进程管理器请自行准备。
- 尚未经过基准测试。 LongMemEval 和 DMR 的数据已列入路线图。在这些数据发布前,请对比较性说法保持应有的审慎。
路线图
| 状态 | 项目 |
|---|---|
| ✅ | 事实提取管道 + SQLite 存储 |
| ✅ | 混合检索(向量 + 带前缀匹配的 FTS5) |
| ✅ | 整合引擎(衰减、提升、去重、摘要、反思) |
| ✅ | MCP stdio 服务(7 个工具) |
| ✅ | REST API(9 个端点) |
| ✅ | 多提供商大模型后端:Ollama、兼容 OpenAI 的服务(OpenAI/Azure/Groq/Together/Mistral/vLLM/LM Studio/…)、Anthropic、Google、command shell 调用 |
| ✅ | Python、Java、Spring Boot 客户端 |
| ✅ | Docker 镜像、发布到 MCP Registry |
| ✅ | Postgres 后端(与 SQLite 并行) |
| ✅ | 聊天消息存储 + Spring AI ChatMemoryRepository 集成 |
| 📋 | LongMemEval + DMR 基准测试分数 |
| 📋 | Quarkus 扩展 |
| 📋 | 云端嵌入提供商(OpenAI text-embedding-3、Google text-embedding-004) |
许可证
Apache 2.0 — 请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。