Files
my-vault/01_Projects/AI-Development/Obsidian Agent/vault-memory/architecture.md
T

116 lines
4.4 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.
---
title: 架构设计
created: 2026-02-25
---
# 架构设计
## 设计目标
1. 不使用本地 embedding 模型(避免常驻 Ollama
2. 向量与元数据留在本地 PostgreSQL(数据可控)
3. 基于 Git 变更做增量 upsert/delete(避免全量重建)
4. 强一致:删除/重命名后不允许幽灵向量残留
5. 安全:敏感内容不入检索库,检索结果具备 Prompt 注入防护
## 双层记忆模型
```
┌─────────────────────────────────────────────┐
│ Claude Agent (agent-with-memory.sh) │
│ │
│ Layer B: MEMORY.md (偏好/事实/约束) │
│ Layer A: pgvector 语义检索结果 │
└─────────────────────────────────────────────┘
↑ ↑
Claude Code query_pgvector.py
MEMORY.md PostgreSQL + pgvector
incremental_ingest.py
git post-commit hook
Obsidian Vault (.md files)
```
### Layer A:文档语义记忆
- EmbeddingOpenRouter API`openai/text-embedding-3-small`dim=1536
- 存储:本地 PostgreSQL + pgvector 扩展
- 数据源:`01_Projects/``02_Areas/`
- 排除:`00_Inbox/``04_Archive/``Infrastructure/``Home-Automation/`
- 触发:git `post-commit` hook → 异步 `incremental_ingest.py`
### Layer B:事实与偏好记忆
- 来源:Claude Code `MEMORY.md`(查询时动态读取)
- 用途:用户偏好、约束、近期状态
## 组件职责
| 文件 | 职责 |
|---|---|
| `index_common.py` | 共享工具:环境加载、DB 连接、Embedding API、排除逻辑、跨平台锁 |
| `blacklist.py` | 排除规则:路径模式、文件名关键词、敏感内容特征 |
| `ingest_vault.py` | 全量重建索引,清理过期条目 |
| `incremental_ingest.py` | 解析 `git diff-tree` 输出,处理 A/M/D/R 事件 |
| `query_pgvector.py` | 余弦相似度检索,返回 `<retrieved_context>` 块 |
| `install-hook.sh` | 向 `.git/hooks/post-commit` 追加异步索引触发器 |
| `agent-with-memory.sh` | 合并 A+B 层上下文,启动带记忆的 claude 会话 |
| `schema.sql` | DB schema`memory_primary`(向量)、`memory_secure_audit`(隔离审计)|
## 数据库 Schema
```sql
-- 主检索表
memory_primary (
id TEXT PRIMARY KEY, -- vault 相对路径
source TEXT, -- 同 id,用于上下文注入显示
content TEXT, -- 完整 markdown 文本
content_hash TEXT, -- sha256,用于变更检测
embedding VECTOR(1536), -- ivfflat 余弦索引
updated_at TIMESTAMPTZ
)
-- 敏感文件审计表
memory_secure_audit (
id TEXT PRIMARY KEY,
source TEXT,
risk TEXT, -- 'excluded_or_sensitive'
updated_at TIMESTAMPTZ
)
```
索引:`ivfflat (embedding vector_cosine_ops) WITH (lists = 100)`
## 增量同步流程
```
git commit
└── post-commit hooknohup,不阻塞提交)
└── incremental_ingest.py --changes-file <tmp>
├── 解析 git diff-tree 输出(A/M/T/D/R
├── 获取 index_lock(跨平台文件锁)
└── 逐事件处理:
A/M/T → upsert_file()
D → DELETE from both tables
R → DELETE old, upsert_file(new)
```
## 安全策略
1. 路径精确匹配:按 `Path.parts` 做目录排除,非子串匹配
2. 单命中隔离:任一敏感特征命中即隔离到 `memory_secure_audit`
3. 强一致删除:D/R 事件先删旧 ID,再处理新路径
4. 单写者锁:跨平台文件锁串行化所有索引写操作
5. 只读上下文注入:检索结果包装为 `<retrieved_context>` 标签,明确标注为非指令
6. 长度截断:注入前全局 `max_chars=2500`
## 关键权衡
| 优点 | 代价 |
|---|---|
| 不跑本地模型,设备压力低 | Markdown 文本发送到 OpenRouter(非纯本地隐私)|
| 向量在本地 DB,数据控制力强 | 依赖网络与 API 可用性 |
| 与现有 Git 工作流兼容 | 需配置 API key 与限流/重试策略 |