内容
# 记忆系统
适用于大型语言模型应用的持久记忆层。存储、检索并注入过去对话的相关上下文,使您的AI助手记住您是谁以及您关心什么。
暴露一个 [模型上下文协议(MCP)](https://modelcontextprotocol.io) 服务器,任何兼容MCP的客户端(Claude Desktop、Cursor等)都可以连接到它。
## 工作原理
```bash
用户消息
│
▼
┌─────────────────────────────────────────────────────┐
│ 会话图 │
│ 加载工作内存(Redis) │
│ → 检索情景记忆(pgvector) │
│ → 检索长期事实(pgvector) │
│ → 将记忆块注入系统提示 │
│ → 使用记忆上下文生成LLM响应 │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ 消化图 │
│ LLM从对话中提取关键事实 │
│ → 自动选择分块策略 │
│ → 嵌入分块(OpenAI text-embedding-3) │
│ → 存储在pgvector + 提取的事实作为 │
│ 长期记忆 │
└─────────────────────────────────────────────────────┘
```
### 记忆层级
| 层级 | 存储 | TTL | 目的 |
|---|---|---|---|
| `working` | Redis | 4小时 | 会话内上下文(当前对话) |
| `episodic` | Postgres | 随时间衰减 | 具体事件和交互 |
| `long_term` | Postgres | 持久 | 稳定事实、偏好、习惯 |
| `semantic` | Postgres | 持久 | 跨剧集提取的一般知识 |
### 检索流程
每个查询都通过 **混合搜索** (密集向量 + BM25关键词)、**互惠排名融合** 、可选的 **Cohere重排序** 和 **token-budget修剪** ,然后再返回记忆。
## 先决条件
- Docker和Docker Compose
- Python 3.11+
- `pip` 或 `uv`
## 安装
### 1. 克隆并进入目录
```bash
git clone <repo-url>
cd mnemosyne
```
### 2. 配置环境
```bash
cp .env.example .env
```
打开 `.env` 并填写所需的值:
```env
# 必需:用于嵌入的OpenAI密钥(始终需要)
OPENAI_API_KEY=sk-...
# 必需:为生成选择一个LLM提供商
LLM_PROVIDER=gemini # anthropic | openai | gemini | local
GEMINI_API_KEY=your-key # 或 ANTHROPIC_API_KEY / OPENAI_API_KEY
# 可选但推荐:用于重排序的Cohere
COHERE_API_KEY=
# 可选:用于可观察性的Langfuse(在cloud.langfuse.com获取密钥)
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
# 可选:存储记忆的静态加密
ENCRYPT_KEY=
```
**LLM提供商选项:**
| `LLM_PROVIDER` | 默认模型 | 免费层 |
|---|---|---|
| `gemini` | `gemini-1.5-pro` | 是 — 设置 `LLM_MODEL=gemini-2.0-flash` 以获得最佳免费限制 |
| `anthropic` | `claude-opus-4-8` | 否 |
| `openai` | `gpt-4o` | 否 |
| `local` | `llama3` 通过Ollama | 是 — 需要在本地运行Ollama |
要覆盖模型,请设置 `LLM_MODEL=gemini-2.0-flash` (或任何模型ID)。
### 3. 启动基础设施
```bash
make up
```
通过Docker启动Postgres(带有pgvector)和Redis,分别在端口 `5432` 和 `6379` 上。
### 4. 安装Python依赖项
```bash
pip install -e ".[dev]"
# 或使用uv:
uv pip install -e ".[dev]"
```
### 5. 运行数据库迁移
```bash
make migrate
```
### 6. 启动MCP服务器
```bash
python mcp/server.py
```
## 与Claude Desktop一起使用
将Mnemosyne添加为MCP服务器,以便Claude Desktop自动获得持久记忆。
打开 `~/Library/Application Support/Claude/claude_desktop_config.json` 并添加:
```json
{
"mcpServers": {
"mnemosyne": {
"command": "python",
"args": ["/absolute/path/to/mnemosyne/mcp/server.py"],
"env": {
"PYTHONPATH": "/absolute/path/to/mnemosyne"
}
}
}
}
```
重启Claude Desktop。输入栏中会出现一个锤子图标,包含4个可用的记忆工具。
### Claude现在可以做的事
Claude将自动调用记忆工具。您也可以直接提示它:
```
"记住我更喜欢所有项目中的深色模式。"
"你知道我的编程偏好是什么吗?"
"忘记我旧工作的所有信息。"
"我们上周关于身份验证系统讨论了什么?"
```
### 可用的MCP工具
| 工具 | 功能 |
|---|---|
| `ingest_memory_tool` | 保存当前对话中的信息 |
| `retrieve_memory_tool` | 按主题或查询搜索过去的记忆 |
| `session_init_tool` | 在对话开始时加载所有相关记忆 |
| `forget_memory_tool` | 按ID删除特定记忆 |
## 与Cursor一起使用
添加到 `~/.cursor/mcp.json` (全局)或 `.cursor/mcp.json` (按项目):
```json
{
"mcpServers": {
"mnemosyne": {
"command": "python",
"args": ["/absolute/path/to/mnemosyne/mcp/server.py"]
}
}
}
```
## 直接使用Python API
```python
import asyncio
from mnemosyne.agents.router import Intent, route
async def main():
# 存储记忆
await route(
Intent.INGEST,
user_id="user-123",
content="用户更喜欢Python而不是JavaScript,并使用VS Code。",
conversation_id="conv-abc",
tier="long_term",
)
# 提问 — 记忆被检索并自动注入
result = await route(
Intent.CHAT,
user_id="user-123",
conversation_id="conv-abc",
user_message="我应该为这个项目设置哪个编辑器?",
)
print(result.response)
# → "根据您对VS Code的偏好,这里是设置方法..."
# 在不生成响应的情况下检索原始记忆
result = await route(
Intent.RETRIEVE,
user_id="user-123",
query="编程语言偏好",
)
for memory in result.final_memories:
print(f"[{memory.tier.value}] {memory.content} (分数:{memory.score:.3f})")
asyncio.run(main())
```
## 本地LLM与Ollama(无API密钥)
完全离线运行:
```bash
# 从 https://ollama.com 安装Ollama,然后拉取模型
ollama pull llama3
```
在 `.env` 中设置:
```env
LLM_PROVIDER=local
LOCAL_LLM_BASE_URL=http://localhost:11434
LOCAL_LLM_MODEL=llama3
```
> 注意:您仍然需要 `OPENAI_API_KEY` 进行嵌入。要删除此依赖项,请在 [`embedding/tiered.py`](embedding/tiered.py) 中使用 `LocalEmbedder` 类将嵌入提供程序切换到本地模型。
## 背景作业
定期运行这些作业(cron或类似)以保持记忆健康:
```bash
# 衰减旧记忆 — 减少陈旧情景/长期记忆的分数
# 推荐:每天运行
python jobs/decay_sweep.py
# 重建BM25关键词搜索索引
# 推荐:批量摄入后运行
python jobs/index_rebuild.py
```
## 开发
```bash
make test # 运行测试套件
make lint # ruff + mypy
make down # 停止Docker服务
```
### 项目结构
```
mnemosyne/
├── agents/ # LangGraph管道(摄入、检索、会话)
├── chunking/ # 自动选择文本分块策略
├── config/ # 设置(pydantic-settings)和结构化日志记录
├── embedding/ # OpenAI和本地嵌入提供程序,分层路由
├── evals/ # 评估框架和黄金标准集
├── infra/ # Dockerfile
├── jobs/ # 衰减扫描和索引重建的cron作业
├── llm/ # LLM提供程序:Anthropic、OpenAI、Gemini、Local(Ollama)
├── mcp/ # MCP服务器和工具定义
├── memory/ # 记忆类型、衰减和访问跟踪
├── observability/ # Langfuse跟踪、指标、健康检查
├── prompts/ # YAML提示模板
├── retrieval/ # 混合搜索、BM25、重排序器、RRF、装配器
└── storage/ # Postgres(pgvector)、Redis、S3、加密、RLS
```
## 架构说明
- **不需要LLM即可运行** — 如果未设置 `LLM_PROVIDER` 或缺少API密钥,摄入仍然存储原始分块,并且 `session_init` 仍然返回记忆块。您可以将记忆块传递给自己的LLM。
- **多用户** — 每个调用都使用 `user_id` 。通过Postgres行级安全隔离用户记忆。
- **可插拔的重排序** — Cohere重排序是可选的。如果没有 `COHERE_API_KEY` ,系统将回落到RRF排序。
- **分块是自动的** — 摄入管道检查内容并选择最佳策略:固定、递归、基于句子或结构化(适用于Markdown/代码)。