Files
memory-gateway/README.md
2026-05-05 16:18:31 +08:00

470 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Memory Gateway
Memory Gateway 是一个通用记忆网关,用于给 AI agent / harness 提供统一的记忆检索、文档上传、LLM 总结和知识沉淀能力。
它的定位不是某个单一业务场景的垂直应用,而是一个可复用的本地 memory/context gateway上层 agent 通过 REST、MCP 或 Hermes skill 调用它,底层由 OpenViking 承载 memory/resource由 Obsidian 承载人工可维护的 Markdown 知识。
## 当前能力
- 搜索 OpenViking memory / resource。
- 写入普通 memory。
- 写入结构化 resource。
- 对任意文本调用 LLM 总结,并按需沉淀到 OpenViking。
- 上传文档,使用 MarkItDown 转 Markdown。
- 将上传文档保存到 Obsidian vault。
- 将文档摘要和结构化 artifact 写入 OpenViking knowledge。
- 给 Hermes 提供通用 `memory-gateway` skill。
- 新增通用 Memory Gateway v1 方案与 POC 骨架多用户、namespace、visibility/ACL、episode、session commit、audit、skills 分层。
- v1 metadata 默认持久化到 SQLite覆盖 users、memories、episodes、profiles、audit。
- `/v1/memory/search` 先做本地 ACL 过滤,再按可见 namespace 查询 OpenViking。
- v1 MCP tools 已接入现有 `/mcp/rpc`
- `/v1/sessions/{session_id}/commit` 优先调用独立 EverMemOS HTTP 服务;服务不可用且允许 fallback 时,才使用 Gateway 进程内 POC worker。
完整方案见:
```text
docs/generic-memory-gateway-design.md
```
## 架构
```text
Agent / Harness / CLI
-> Memory Gateway REST / MCP
-> OpenViking memory / resource
-> Obsidian markdown vault
-> OpenAI-compatible LLM summary
```
## 目录结构
```text
memory-gateway/
├── memory_gateway/ # Gateway 服务代码
│ ├── server.py # REST / MCP 接口
│ ├── openviking_client.py # OpenViking client
│ ├── llm.py # OpenAI-compatible LLM summary
│ ├── document_ingest.py # MarkItDown + Obsidian write helpers
│ ├── config.py
│ └── types.py
├── integrations/hermes/
│ └── memory-gateway/ # 通用 Hermes skill
├── obsidian-vault/
│ ├── 01_Knowledge/Uploaded/ # 上传文档转成的 Markdown
│ └── 05_Templates/ # 通用知识模板
├── tests/
├── config.example.yaml
└── pyproject.toml
```
## 环境
使用当前虚拟环境:
```bash
cd /home/tom/memory-gateway
source /home/tom/OpenViking/.venv/bin/activate
```
本地配置文件:
```text
/home/tom/memory-gateway/config.yaml
```
关键配置:
```yaml
memory:
default_namespace: memory-gateway
llm:
base_url: https://oai.bwgdi.com/v1
api_key: <local secret, git ignored>
model: MiniMaxAI
obsidian:
vault_path: /home/tom/memory-gateway/obsidian-vault
knowledge_dir: 01_Knowledge/Uploaded
review_dir: Reviews/Queue
storage:
backend: sqlite
sqlite_path: /home/tom/memory-gateway/memory_gateway.sqlite3
```
`config.yaml` 已被 `.gitignore` 忽略,不会提交密钥。
## 启动
OpenViking 需要先运行在 `127.0.0.1:1933`
```bash
source /home/tom/OpenViking/.venv/bin/activate
openviking-server --host 127.0.0.1 --port 1933
```
启动本机 EverMemOS 服务:
```bash
cd /home/tom/memory-gateway
source /home/tom/OpenViking/.venv/bin/activate
python -m memory_gateway.evermemos_service \
--config /home/tom/memory-gateway/config.yaml \
--host 127.0.0.1 \
--port 1995
```
启动 Memory Gateway
```bash
cd /home/tom/memory-gateway
source /home/tom/OpenViking/.venv/bin/activate
python -m memory_gateway.server --config /home/tom/memory-gateway/config.yaml
```
健康检查:
```bash
curl http://127.0.0.1:1934/health
curl http://127.0.0.1:1995/health
curl http://127.0.0.1:1934/v1/evermemos/health
```
## REST 接口
### `GET /health`
检查 Gateway 和 OpenViking 状态。
### `POST /api/search`
搜索 OpenViking memory / resource。
```bash
curl -X POST http://127.0.0.1:1934/api/search \
-H "Content-Type: application/json" \
-d '{
"query": "memory gateway document upload summary",
"uri": "viking://resources",
"limit": 5
}'
```
### `POST /api/memory`
写入普通 memory。
```bash
curl -X POST http://127.0.0.1:1934/api/memory \
-H "Content-Type: application/json" \
-d '{
"namespace": "memory-gateway",
"memory_type": "preference",
"content": "The user prefers concise technical summaries."
}'
```
### `POST /api/resource`
写入结构化 resource。
```bash
curl -X POST http://127.0.0.1:1934/api/resource \
-H "Content-Type: application/json" \
-d '{
"uri": "viking://resources/memory-gateway/knowledge/example.json",
"resource_type": "json",
"content": "{\"title\":\"example\"}"
}'
```
### `POST /api/summary`
调用 LLM 总结任意文本,并按需沉淀到 OpenViking。
```bash
curl -X POST http://127.0.0.1:1934/api/summary \
-H "Content-Type: application/json" \
-d '{
"title": "Project decision summary",
"content": "需要总结和沉淀的内容...",
"namespace": "memory-gateway",
"memory_type": "decision",
"tags": ["project", "decision"],
"persist_as": "resource"
}'
```
`persist_as` 支持:`none``memory``resource``both`
### `POST /api/knowledge/upload`
上传文档MarkItDown 转 Markdown保存到 ObsidianLLM 总结后写入 OpenViking knowledge。
```bash
curl -X POST http://127.0.0.1:1934/api/knowledge/upload \
-F "file=@/path/to/document.pdf" \
-F "title=Design Notes" \
-F "namespace=memory-gateway" \
-F "knowledge_type=design_doc" \
-F "tags=project,design,reference" \
-F "persist_as=resource"
```
默认保存到:
```text
obsidian-vault/01_Knowledge/Uploaded/
```
## v1 通用 Memory API
v1 API 面向多 agent 框架,带 user / agent / workspace / session 上下文和基础 ACL。
### 创建用户
```bash
curl -X POST http://127.0.0.1:1934/v1/users \
-H "Content-Type: application/json" \
-d '{"user_id":"user_tom","display_name":"Tom","preferences":{"language":"zh-CN"}}'
```
### 写入记忆
```bash
curl -X POST http://127.0.0.1:1934/v1/memory \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_tom",
"agent_id": "agent_hermes",
"workspace_id": "ws_memory_gateway",
"memory_type": "preference",
"content": "用户偏好中文输出,结构化但不要过度工程化。",
"summary": "中文、结构化、轻量 POC 优先。",
"tags": ["preference", "style"],
"importance": 0.8,
"confidence": 0.9,
"visibility": "private",
"source": "manual"
}'
```
### 检索记忆
```bash
curl -X POST http://127.0.0.1:1934/v1/memory/search \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_tom",
"agent_id": "agent_hermes",
"workspace_id": "ws_memory_gateway",
"query": "中文输出",
"limit": 5
}'
```
返回会包含:
- `local_total`SQLite metadata 命中的记忆数量。
- `openviking_total`:按可见 namespace 查询 OpenViking 的命中数量。
- `searched_namespaces`Gateway 展开并允许查询的 namespace。
### 修改记忆
```bash
curl -X PATCH "http://127.0.0.1:1934/v1/memory/MEMORY_ID?user_id=user_tom&agent_id=agent_hermes&workspace_id=ws_memory_gateway" \
-H "Content-Type: application/json" \
-d '{"summary":"用户偏好中文、结构化、少废话。","importance":0.9}'
```
### 写入 episode 并 commit session
```bash
curl -X POST http://127.0.0.1:1934/v1/episodes \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_tom",
"agent_id": "agent_hermes",
"workspace_id": "ws_memory_gateway",
"session_id": "sess_demo",
"content": "结论:这个项目必须保留用户隔离和 namespace ACL。",
"tags": ["decision"]
}'
curl -X POST http://127.0.0.1:1934/v1/sessions/sess_demo/commit \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_tom",
"agent_id": "agent_hermes",
"workspace_id": "ws_memory_gateway",
"session_id": "sess_demo",
"promote": true,
"min_importance": 0.6
}'
```
流程说明:
- 短期记忆先写入 SQLite 的 `episodes`namespace 通常是 `session/{session_id}/episodic`
- commit session 时Gateway 把当前 session episodes、可见长期记忆和访问上下文发给 `http://127.0.0.1:1995/v1/sessions/consolidate`
- EverMemOS 返回候选记忆、可直接提升的长期记忆、重复/冲突信息和 review draft 路径。
- Gateway 只把正常稳定候选写入长期 memory高价值或冲突候选不会直接进入长期记忆会写入
```text
obsidian-vault/Reviews/Queue/
```
## MCP Tools
`POST /mcp/rpc` 支持:
- `search`
- `add_memory`
- `add_resource`
- `commit_summary`
- `get_status`
- `list_memories`
- `list_resources`
- `memory_search`
- `memory_upsert`
- `memory_append_episode`
- `memory_commit_session`
- `memory_get_profile`
- `memory_list_namespaces`
- `memory_delete`
- `memory_feedback`
## Hermes Skill
通用 Hermes skill
```text
/home/tom/.hermes/skills/memory-gateway/
```
仓库副本:
```text
integrations/hermes/memory-gateway/
```
主要脚本:
```text
scripts/evermemos_health.py
scripts/memory_create_user.py
scripts/memory_append_episode.py
scripts/memory_commit_session.py
scripts/memory_search.py
scripts/memory_upsert.py
scripts/retrieve_memory.py
scripts/commit_summary.py
scripts/upload_knowledge.py
scripts/search_obsidian.py
```
检查 EverMemOS
```bash
python /home/tom/.hermes/skills/memory-gateway/scripts/evermemos_health.py
```
检索记忆:
```bash
python /home/tom/.hermes/skills/memory-gateway/scripts/retrieve_memory.py \
--query "document upload summary memory gateway" \
--uri viking://resources \
--limit 5
```
总结沉淀:
```bash
python /home/tom/.hermes/skills/memory-gateway/scripts/commit_summary.py \
--title "Reusable conclusion" \
--namespace memory-gateway \
--memory-type decision \
--tag project \
--persist-as resource \
--text "最终结论或可复用知识..."
```
上传知识:
```bash
python /home/tom/.hermes/skills/memory-gateway/scripts/upload_knowledge.py \
--file /path/to/document.md \
--title "Knowledge note" \
--namespace memory-gateway \
--knowledge-type reference \
--tags project,reference \
--persist-as resource
```
完整长短期记忆测试:
```bash
python /home/tom/.hermes/skills/memory-gateway/scripts/memory_create_user.py \
--user-id user_tom \
--display-name "Tom" \
--preference language=zh-CN
python /home/tom/.hermes/skills/memory-gateway/scripts/memory_append_episode.py \
--user-id user_tom \
--agent-id agent_hermes \
--workspace-id ws_memory_gateway \
--session-id sess_demo \
--tag decision \
--text "结论:本机 EverMemOS 服务负责从 session episode 中整理稳定长期记忆。"
python /home/tom/.hermes/skills/memory-gateway/scripts/memory_append_episode.py \
--user-id user_tom \
--agent-id agent_hermes \
--workspace-id ws_memory_gateway \
--session-id sess_demo \
--tag review \
--tag high-value \
--text "重要:高价值记忆应该进入 Obsidian review queue避免错误记忆污染长期系统。"
python /home/tom/.hermes/skills/memory-gateway/scripts/memory_commit_session.py \
--user-id user_tom \
--agent-id agent_hermes \
--workspace-id ws_memory_gateway \
--session-id sess_demo \
--min-importance 0.6
python /home/tom/.hermes/skills/memory-gateway/scripts/memory_search.py \
--user-id user_tom \
--agent-id agent_hermes \
--workspace-id ws_memory_gateway \
--session-id sess_demo \
--query "EverMemOS 服务负责" \
--limit 5
```
## 测试
```bash
cd /home/tom/memory-gateway
source /home/tom/OpenViking/.venv/bin/activate
PYTHONPATH=/home/tom/memory-gateway pytest -q
```
当前测试覆盖:
- API key 校验。
- MCP tools/list。
- OpenViking search 透传。
- LLM summary artifact 构建。
- document upload -> markdown -> Obsidian -> OpenViking resource。
## 下一步
- 在 Gateway 层加强 `/api/search` 的 URI prefix 过滤和去重。
-`/api/knowledge/upload` 增加文件大小限制、类型白名单和 dry-run。
- 增加 Obsidian -> OpenViking 增量同步脚本。
- 给 Memory Gateway skill 增加更稳定的“回答时引用 memory/resource/Obsidian note”输出约束。
- 增加更多文档解析格式和异常处理测试。