update memory gateway

This commit is contained in:
2026-04-30 16:09:28 +08:00
parent e6b1520bce
commit ba84b1ddb3
98 changed files with 1341 additions and 6783 deletions

475
README.md
View File

@ -1,166 +1,99 @@
# SOC Memory POC
# Memory Gateway
面向 SOC case 研判辅助场景的记忆系统 POC。这个项目不是泛化记忆平台而是验证 AI agent 在处理钓鱼邮件、O365 异常登录等告警时,能否稳定获得更好的历史 case、KB / Playbook、Obsidian 研判笔记和可沉淀结论
Memory Gateway 是一个通用记忆网关,用于给 AI agent / harness 提供统一的记忆检索、文档上传、LLM 总结和知识沉淀能力
当前项目阶段:**最小可运行 POC / Hermes 集成验证阶段**
它的定位不是某个单一业务场景的垂直应用,而是一个可复用的本地 memory/context gateway上层 agent 通过 REST、MCP 或 Hermes skill 调用它,底层由 OpenViking 承载 memory/resource由 Obsidian 承载人工可维护的 Markdown 知识
## 当前已经完成什么
## 当前能力
### 1. 总体设计与文档
- 搜索 OpenViking memory / resource。
- 写入普通 memory。
- 写入结构化 resource。
- 对任意文本调用 LLM 总结,并按需沉淀到 OpenViking。
- 上传文档,使用 MarkItDown 转 Markdown。
- 将上传文档保存到 Obsidian vault。
- 将文档摘要和结构化 artifact 写入 OpenViking knowledge。
- 给 Hermes 提供通用 `memory-gateway` skill。
已完成 SOC 记忆系统的核心设计文档:
- [docs/architecture.md](/home/tom/soc_memory_poc/docs/architecture.md):整体架构、模块边界、数据流
- [docs/poc-scope.md](/home/tom/soc_memory_poc/docs/poc-scope.md):第一阶段 POC 范围
- [docs/data-model.md](/home/tom/soc_memory_poc/docs/data-model.md)SOC memory 数据模型
- [docs/namespaces.md](/home/tom/soc_memory_poc/docs/namespaces.md)OpenViking namespace / URI 设计
- [docs/sample-data-spec.md](/home/tom/soc_memory_poc/docs/sample-data-spec.md)mock case / KB 样本规范
- [docs/hermes-demo-prompts.md](/home/tom/soc_memory_poc/docs/hermes-demo-prompts.md)Hermes demo 输入样例
### 2. Mock 数据集
当前没有真实 SOC 数据,所以项目先构造了两类典型场景的数据:
- 钓鱼邮件4 个历史 case
- O365 异常登录5 个历史 case
- KB / Playbook7 个条目
- normalized case9 个
- normalized KB / Playbook7 个
数据目录:
## 架构
```text
evaluation/datasets/
├── mock_cases/
├── mock_kb/
├── normalized_cases/
└── normalized_kb/
Agent / Harness / CLI
-> Memory Gateway REST / MCP
-> OpenViking memory / resource
-> Obsidian markdown vault
-> OpenAI-compatible LLM summary
```
这些数据用于验证检索、研判、Obsidian note 生成和 Hermes skill 的完整链路。
### 3. Normalize Pipeline
已完成基础数据标准化脚本:
- [pipeline/transforms/normalize_case.py](/home/tom/soc_memory_poc/pipeline/transforms/normalize_case.py):把 mock / 原始 case 转成统一 case memory 格式
- [pipeline/transforms/normalize_kb.py](/home/tom/soc_memory_poc/pipeline/transforms/normalize_kb.py):把 KB / Playbook 转成统一 knowledge memory 格式
- [pipeline/jobs/ingest_case.py](/home/tom/soc_memory_poc/pipeline/jobs/ingest_case.py):批量生成 normalized case
- [pipeline/jobs/ingest_kb.py](/home/tom/soc_memory_poc/pipeline/jobs/ingest_kb.py):批量生成 normalized KB / Playbook
### 4. Memory Gateway + OpenViking 接入
[Memory Gateway](/home/tom/soc_memory_poc/memory_gateway/server.py) 已经可以作为统一入口访问 OpenViking
- REST `/health`
- REST `/api/search`
- REST `/api/memories`
- REST `/api/resources`
- MCP `tools/list`
- MCP `search`
- MCP `add_memory`
- MCP `add_resource`
- API Key 校验已生效
- FastAPI lifespan 已挂载,启动时会检查 OpenViking 健康状态
OpenViking resource URI 当前采用:
## 目录结构
```text
viking://resources/soc-memory-poc/case/<scenario>/<case_id>.json
viking://resources/soc-memory-poc/knowledge/<doc_type>/<doc_id>.json
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
```
### 5. Skills
## 环境
当前已实现 3 个项目内 skill
- [retrieve_context_skill](/home/tom/soc_memory_poc/skills/retrieve_context_skill/retrieve_context.py):支持本地 normalized 数据检索和 OpenViking 检索
- [commit_memory_skill](/home/tom/soc_memory_poc/skills/commit_memory_skill/commit_to_openviking.py):把 normalized case / KB 写入 OpenViking resource
- [summarize_case_skill](/home/tom/soc_memory_poc/skills/summarize_case_skill/generate_case_note.py):从 normalized case 生成 Obsidian case note并可用 OpenViking 检索结果增强关联内容
### 6. Obsidian Vault
已创建 Obsidian vault 骨架和模板:
```text
obsidian-vault/
├── 02_Cases/
│ ├── phishing/
│ └── o365_suspicious_login/
└── 05_Templates/
```
当前已生成 9 篇 case note覆盖钓鱼邮件和 O365 异常登录两类场景。
模板包括:
- [case-note-template.md](/home/tom/soc_memory_poc/obsidian-vault/05_Templates/case-note-template.md)
- [playbook-template.md](/home/tom/soc_memory_poc/obsidian-vault/05_Templates/playbook-template.md)
- [report-summary-template.md](/home/tom/soc_memory_poc/obsidian-vault/05_Templates/report-summary-template.md)
### 7. Hermes Agent 集成
已在本机 Hermes skill 目录创建 `soc-memory-poc` skill并在仓库中保留了一份可版本化副本
- 本机 Hermes 实际加载路径:`/home/tom/.hermes/skills/soc-memory-poc/`
- 仓库副本路径:`integrations/hermes/soc-memory-poc/`
本机 Hermes skill 文件结构:
```text
/home/tom/.hermes/skills/soc-memory-poc/
├── SKILL.md
└── scripts/
├── search_context.py
├── search_obsidian_docs.py
├── triage_alert.py
├── triage_email.py
├── triage_from_text.py
├── generate_case_note.py
└── commit_case_memory.py
```
当前 Hermes 可通过该 skill 完成:
- 输入结构化告警或原始邮件文本
- 自动抽取 sender、subject、attachment、URL、IP、host、user 等关键信息
- 查询 OpenViking 中相似历史 case
- 查询 OpenViking 中相关 KB / Playbook
- 查询 Obsidian 中相关 case note
- 输出包含 `研判结果``关键证据``关联 Memory Retrieval``关联 Obsidian 文档``建议动作` 的研判报告
- 从 normalized case 生成 Obsidian case note
## 当前还没有完成什么
当前项目还不能算生产可用,主要缺口如下:
- 还没有接入真实 SOC 数据源,例如 SIEM、EDR、邮件网关、ticket system、情报平台、月报、PO、历史报告。
- 还没有自动 Obsidian sync。现在 Obsidian 新增或修改 md 不会自动总结并写入 OpenViking。
- 还没有实现 EverMemOS worker。长期记忆抽取、合并、衰减、演化目前仍停留在设计和目录占位。
- 检索排序仍是 POC 级别。当前可用,但还没有基于真实 SOC 数据做 rerank、误报模式识别、字段权重优化。
- 评估闭环还不完整。已有 mock 数据,但还缺少批量 evaluation scripts、命中率统计、人工满意度记录和对比实验。
- 安全治理还未生产化。缺少真实环境需要的权限隔离、审计日志、敏感字段脱敏、租户隔离、数据保留策略。
- Agent 写回策略还比较保守。当前支持提交 normalized artifact但还没有完善的“高价值记忆判定 -> 审核 -> 写回 -> 去重”工作流。
## 如何启动
使用已有环境:
使用当前虚拟环境
```bash
cd /home/tom/soc_memory_poc
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
```
`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
```
启动 Memory Gateway
```bash
python -m memory_gateway.server --config /home/tom/soc_memory_poc/config.yaml
```
默认监听:
```text
http://127.0.0.1:1934
cd /home/tom/memory-gateway
source /home/tom/OpenViking/.venv/bin/activate
python -m memory_gateway.server --config /home/tom/memory-gateway/config.yaml
```
健康检查:
@ -169,173 +102,181 @@ http://127.0.0.1:1934
curl http://127.0.0.1:1934/health
```
如果 `1934` 端口被占用,先检查已有进程,不要重复启动:
## REST 接口
### `GET /health`
检查 Gateway 和 OpenViking 状态。
### `POST /api/search`
搜索 OpenViking memory / resource。
```bash
ss -ltnp | grep 1934
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
cd /home/tom/soc_memory_poc
source /home/tom/OpenViking/.venv/bin/activate
PYTHONPATH=/home/tom/soc_memory_poc python pipeline/jobs/ingest_case.py \
--input-dir evaluation/datasets/mock_cases \
--output-dir evaluation/datasets/normalized_cases
PYTHONPATH=/home/tom/soc_memory_poc python pipeline/jobs/ingest_kb.py \
--input-dir evaluation/datasets/mock_kb \
--output-dir evaluation/datasets/normalized_kb
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."
}'
```
## 如何写入 OpenViking
### `POST /api/resource`
写入 case
写入结构化 resource。
```bash
cd /home/tom/soc_memory_poc
source /home/tom/OpenViking/.venv/bin/activate
PYTHONPATH=/home/tom/soc_memory_poc python skills/commit_memory_skill/commit_to_openviking.py \
--directory evaluation/datasets/normalized_cases
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\"}"
}'
```
写入 KB / Playbook
### `POST /api/summary`
调用 LLM 总结任意文本,并按需沉淀到 OpenViking。
```bash
PYTHONPATH=/home/tom/soc_memory_poc python skills/commit_memory_skill/commit_to_openviking.py \
--directory evaluation/datasets/normalized_kb
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
cd /home/tom/soc_memory_poc
source /home/tom/OpenViking/.venv/bin/activate
PYTHONPATH=/home/tom/soc_memory_poc pytest -q
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"
```
运行 Python 编译检查
```bash
python -m compileall -q memory_gateway pipeline skills tests
python -m py_compile /home/tom/.hermes/skills/soc-memory-poc/scripts/*.py
```
运行一次核心 triage smoke test
```bash
python /home/tom/.hermes/skills/soc-memory-poc/scripts/triage_email.py --text "From: billing@vendor-payments.com
To: alice@corp.example
Subject: Invoice overdue notice
Attachment: invoice_review.html
User clicked the link after opening the HTML attachment. DMARC failed. Review at https://vendor-payments-login.com/review from IP 198.51.100.20 on host FIN-LAPTOP-12."
```
预期输出应包含:
- `研判结果`
- `关键证据`
- `关联 Memory Retrieval`
- `关联 Obsidian 文档`
- `建议动作`
## 如何用 Hermes 演示
确保 Memory Gateway 已启动,然后执行:
```bash
/home/tom/.local/bin/hermes chat --quiet --skills soc-memory-poc -q "Use the soc-memory-poc skill. Triage this email alert and include Memory Retrieval and Obsidian references.
From: billing@vendor-payments.com
To: alice@corp.example
Subject: Invoice overdue notice
Attachment: invoice_review.html
User clicked the link after opening the HTML attachment. DMARC failed. Review at https://vendor-payments-login.com/review from IP 198.51.100.20 on host FIN-LAPTOP-12."
```
演示重点不是让 Hermes 凭空研判,而是展示它会先调用 SOC Memory POC skill检索历史 case、KB / Playbook 和 Obsidian note再把这些证据带入最终研判。
## 如何生成 Obsidian Case Note
```bash
cd /home/tom/soc_memory_poc
source /home/tom/OpenViking/.venv/bin/activate
PYTHONPATH=/home/tom/soc_memory_poc python skills/summarize_case_skill/generate_case_note.py \
--input evaluation/datasets/normalized_cases/CASE-2026-0001.json \
--enrich-from-openviking \
--top-k 3
```
输出文件位于:
默认保存到
```text
obsidian-vault/02_Cases/<scenario>/
obsidian-vault/01_Knowledge/Uploaded/
```
## 当前效果
## MCP Tools
当前 POC 已经可以完成一条基础 SOC 研判辅助链路
`POST /mcp/rpc` 支持
1. analyst 或 Hermes 输入告警 / 邮件内容。
2. Hermes skill 抽取关键字段并判断场景。
3. 通过 Memory Gateway 查询 OpenViking 中的相似历史 case。
4. 通过 Memory Gateway 查询相关 KB / Playbook。
5. 本地检索 Obsidian case note。
6. 输出带证据来源的研判报告。
7. 对成熟 case可生成 Obsidian case note并可将 normalized artifact 写回 OpenViking。
- `search`
- `add_memory`
- `add_resource`
- `commit_summary`
- `get_status`
- `list_memories`
- `list_resources`
在真实 SOC 场景中,当前版本适合做 demo、POC 验证和离线评估;不建议直接作为生产系统接入真实告警闭环。
## Hermes Skill
## 下一阶段开发计划
通用 Hermes skill
### P0补齐真实输入与评估闭环
```text
/home/tom/.hermes/skills/memory-gateway/
```
- 设计真实 ticket / alert 的最小字段映射,不先接全量日志。
- 增加 `evaluation/scripts/`,批量跑 mock case统计 case 命中率、KB 命中率、输出完整率。
- 为 phishing / O365 两类场景定义人工标注答案,用于评估检索质量。
仓库副本:
### P1增强 Obsidian 与 OpenViking 的同步
```text
integrations/hermes/memory-gateway/
```
- 新增 Obsidian md 扫描脚本,读取新增 / 修改 note。
- 从 Obsidian note 中抽取 title、tags、scenario、case_id、summary、IOC、verdict。
- 生成 normalized knowledge / case artifact。
- 经过去重和质量阈值后写入 OpenViking。
主要脚本:
### P1完善 Hermes 研判工作流
```text
scripts/retrieve_memory.py
scripts/commit_summary.py
scripts/upload_knowledge.py
scripts/search_obsidian.py
```
- 让 Hermes 输出更稳定地引用具体 `case_id``doc_id`、Obsidian 相对路径。
- 增加 O365 异常登录专用 triage prompt 和 demo。
- 增加 case 结束后的“是否沉淀为记忆”判断模板。
检索记忆:
### P2实现 EverMemOS 长期记忆整理层
```bash
python /home/tom/.hermes/skills/memory-gateway/scripts/retrieve_memory.py \
--query "document upload summary memory gateway" \
--uri viking://resources \
--limit 5
```
- 从 case note、process summary、agent final report 中抽取长期可复用记忆。
- 对重复 case pattern 做合并。
- 对低价值、过时、误导性记忆做衰减或清理。
- 将高价值 pattern 回灌到 OpenViking必要时生成 Obsidian 摘要 note。
总结沉淀:
### P2生产化安全与治理
```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 "最终结论或可复用知识..."
```
- 增加 API Key / token 的部署规范。
- 增加数据脱敏策略。
- 增加写入审计日志。
- 增加 namespace / workspace / agent 级别隔离。
上传知识:
## 推荐落地顺序
```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
```
1. 固定 phishing 和 O365 两类场景的 normalized schema。
2. 建立 20 到 50 条脱敏样本,先覆盖真实高频告警。
3. 完成批量 evaluation明确检索命中率和输出质量基线。
4. 接入 Obsidian -> OpenViking 的半自动同步。
5. 接入一个真实 agent 工作流,例如 Hermes triage。
6. 再实现 EverMemOS 长期记忆整理,不要过早做复杂长期记忆平台。
## 测试
## License
```bash
cd /home/tom/memory-gateway
source /home/tom/OpenViking/.venv/bin/activate
PYTHONPATH=/home/tom/memory-gateway pytest -q
```
MIT
当前测试覆盖:
- 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”输出约束。
- 增加更多文档解析格式和异常处理测试。