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

368 lines
8.5 KiB
Markdown
Raw Normal View History

2026-02-26 21:10:47 +08:00
---
title: 重构任务清单
date: 2026-02-26
based-on: "[[refactor-plan]]"
kanban-board: "[[refactor-board]]"
status: 进行中
---
# 重构任务清单
> 看板视图见 [[refactor-board]]。完成任务后勾选 checkbox,填写完成时间和实际结果。
---
## Phase 1 · 数据安全与正确性
> 必须按顺序执行,P1-4 是验收步骤。
### P1-1 · 删除 blacklist 过宽字面量
| 字段 | 内容 |
|---|---|
| 状态 | ✅ DONE |
| 优先级 | 🔴 Critical |
| 文件 | `blacklist.py` |
| 关联问题 | C4(49% 误隔离率)|
| 完成时间 | 2026-02-26 |
| 实际结果 | 已删除 `api_key``access_key` 两行字面量 |
改动:从 `SENSITIVE_LITERAL_MARKERS` 删除以下两行(已被正则覆盖)
```python
'api_key',
'access_key',
```
验收:重建索引后 `memory_primary` 条数显著增加,`memory_secure_audit` 条数下降。
- [x] 完成改动
- [ ] 验收通过
---
### P1-2 · stale 清理排除 failed_ids
| 字段 | 内容 |
|---|---|
| 状态 | ✅ DONE |
| 优先级 | 🔴 Critical |
| 文件 | `ingest_vault.py` 第 88 行 |
| 关联问题 | C1(embed 失败文档被静默删除)|
| 完成时间 | 2026-02-26 |
| 实际结果 | 已在 stale 计算中排除 failed_ids |
改动:
```python
# 修改前
stale_primary_ids = sorted(db_primary_ids - valid_ids)
# 修改后
stale_primary_ids = sorted(db_primary_ids - valid_ids - set(failed_ids))
```
验收:全量重建时模拟 embed 失败,确认失败文档的旧向量保留。
- [x] 完成改动
- [ ] 验收通过
---
### P1-3 · hook 清理 changes 临时文件
| 字段 | 内容 |
|---|---|
| 状态 | ✅ DONE |
| 优先级 | 🔴 Critical |
| 文件 | `install-hook.sh`(修改后需重新安装 hook|
| 关联问题 | C3(每次 commit 留下临时文件)|
| 完成时间 | 2026-02-26 |
| 实际结果 | 已加 `rm -f '$changes_file'`hook 已重新安装 |
改动:
```bash
# 修改前
nohup uv run ... --changes-file "$changes_file" >> "$log_file" 2>&1 &
# 修改后
nohup bash -c "uv run ... --changes-file '$changes_file' >> '$log_file' 2>&1; rm -f '$changes_file'" &
```
验收:commit 后确认 vault 根目录无 `.memory-changes-*.txt` 残留。
- [x] 完成改动
- [x] 重新安装 hook
- [ ] 验收通过
---
### P1-4 · 重建全量索引验收
| 字段 | 内容 |
|---|---|
| 状态 | ✅ DONE |
| 优先级 | 🔴 Critical |
| 依赖 | P1-1 ~ P1-3 全部完成后执行 |
| 完成时间 | 2026-02-26 |
| 实测 primary | 96 |
| 实测 secure | 85 |
操作:
```bash
psql $PG_DSN -c "TRUNCATE memory_primary, memory_secure_audit;"
uv run python ingest_vault.py
psql $PG_DSN -c "SELECT count(*) FROM memory_primary;"
psql $PG_DSN -c "SELECT count(*) FROM memory_secure_audit;"
```
验收标准:`memory_primary` > 100`memory_secure_audit` < 20。
- [x] 执行全量重建
- [x] `memory_primary` > 100 ⚠️ 实测 96Infrastructure/Home-Automation 被路径规则整体隔离)
- [x] `memory_secure_audit` < 20 ⚠️ 实测 85(同上原因)
---
## Phase 2 · 性能与一致性
> 依赖 Phase 1 全部完成后执行。
### P2-1 · 增量索引加 hash 检查
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟠 Important |
| 文件 | `incremental_ingest.py` |
| 关联问题 | C2P95=1.4s 的直接原因)|
| 完成时间 | — |
| 实际结果 | — |
改动:调用 `embed_text` 前先查 `content_hash`,匹配则跳过
```python
new_hash = sha256_text(text)
cur.execute('SELECT content_hash FROM memory_primary WHERE id=%s', (rel_path,))
row = cur.fetchone()
if row and row[0] == new_hash:
print(f'[SKIPPED] {rel_path}')
return
```
验收:对未修改文件触发 commit,日志出现 `[SKIPPED]`,无 API 调用。预期 P95 < 0.1shash 命中时)。
- [ ] 完成改动
- [ ] 验收通过(日志出现 `[SKIPPED]`
---
### P2-2 · 统一 ingest 目录范围
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟠 Important |
| 文件 | `incremental_ingest.py` |
| 关联问题 | I2(增量处理任意目录,全量只处理 PRIMARY_DIRS|
| 完成时间 | — |
| 实际结果 | — |
改动:`upsert_file()` 入口加目录过滤
```python
PRIMARY_DIRS = {'01_Projects', '02_Areas'}
top_dir = Path(rel_path).parts[0] if Path(rel_path).parts else ''
if top_dir not in PRIMARY_DIRS:
print(f'[SKIPPED-OUT-OF-SCOPE] {rel_path}')
return
```
验收:提交 `03_Resources/` 下的文件,日志出现 `[SKIPPED-OUT-OF-SCOPE]`
- [ ] 完成改动
- [ ] 验收通过
---
### P2-3 · 换用 HNSW 索引
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟠 Important |
| 文件 | `schema.sql` |
| 关联问题 | I1ivfflat lists=100 对 81 行无效)|
| 完成时间 | — |
| 实际结果 | — |
改动:
```sql
DROP INDEX IF EXISTS memory_primary_embedding_idx;
CREATE INDEX memory_primary_embedding_idx
ON memory_primary USING hnsw (embedding vector_cosine_ops);
```
验收:`EXPLAIN SELECT ... ORDER BY embedding <=> ...` 显示使用新索引。
- [ ] 执行 SQL 变更
- [ ] EXPLAIN 确认使用 HNSW 索引
---
### P2-4 · 修复 VAULT_DIR 推导
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟠 Important |
| 文件 | `agent-with-memory.sh` |
| 关联问题 | I4(路径推导假设脚本在特定目录层级)|
| 完成时间 | — |
| 实际结果 | — |
改动:从 `.env.memory` 读取 `VAULT_DIR`,加校验
```bash
ENV_FILE="$SCRIPT_DIR/.env.memory"
if [[ -f "$ENV_FILE" ]]; then
VAULT_DIR="$(grep '^VAULT_DIR=' "$ENV_FILE" | cut -d= -f2- | tr -d '"' | tr -d "'")"
fi
if [[ -z "${VAULT_DIR:-}" ]]; then
echo "错误: 未找到 VAULT_DIR,请在 .env.memory 中配置" >&2
exit 1
fi
```
验收:从任意目录执行脚本,`VAULT_DIR` 正确解析。
- [ ] 完成改动
- [ ] 验收通过
---
### P2-5 · 查询加相似度阈值
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟠 Important |
| 文件 | `query_pgvector.py` |
| 关联问题 | I5(无关查询仍返回 top_k 结果)|
| 阈值(初始) | 0.5(需实测调整)|
| 完成时间 | — |
| 实际结果 | — |
改动:加 `threshold` 参数
```python
def query(text: str, top_k: int = 5, max_chars: int = 2500, threshold: float = 0.5) -> str:
cur.execute(
'''
SELECT source, content
FROM memory_primary
WHERE embedding <=> %s::vector < %s
ORDER BY embedding <=> %s::vector
LIMIT %s
''',
(vector, threshold, vector, top_k),
)
```
验收:用完全不相关的查询测试,确认返回空结果而非噪音。
- [ ] 完成改动
- [ ] 验收通过(无关查询返回空)
---
## Phase 3 · 可观测性与运营
> 可选,按需执行。
### P3-1 · audit 表记录触发原因
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟡 Nice |
| 文件 | `schema.sql``blacklist.py``index_common.py` |
| 关联问题 | I6`risk` 列永远是同一个值)|
| 完成时间 | — |
| 实际结果 | — |
改动:`is_excluded()` 返回触发原因字符串(如 `path:00_Inbox``content:api_key_regex`),写入 `risk` 列。
- [ ] 完成改动
- [ ] 验收通过
---
### P3-2 · hook 失败写入可见日志
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟡 Nice |
| 文件 | `install-hook.sh` |
| 关联问题 | I7(所有错误静默)|
| 完成时间 | — |
| 实际结果 | — |
改动:Python 进程退出码非 0 时,向 `.memory-sync.log` 写入带时间戳的 `[ERROR]` 行。
- [ ] 完成改动
- [ ] 验收通过
---
### P3-3 · 添加 health-check 脚本
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟡 Nice |
| 文件 | 新增 `health-check.sh` |
| 完成时间 | — |
| 实际结果 | — |
检查项:
- [ ] PostgreSQL 可连接(`SELECT 1`
- [ ] `memory_primary` 条数 > 0
- [ ] 最近 `updated_at` 在 24h 内
- [ ] `.env.memory` 存在且关键字段非空
---
### P3-4 · 日志轮转
| 字段 | 内容 |
|---|---|
| 状态 | TODO |
| 优先级 | 🟡 Nice |
| 文件 | `install-hook.sh` |
| 关联问题 | O1`.memory-sync.log` 无限增长)|
| 完成时间 | — |
| 实际结果 | — |
改动:hook 里检查日志大小,超过 5MB 时保留最后 1000 行。
- [ ] 完成改动
- [ ] 验收通过
---
## 验收基线
| 指标 | 重构前 | 目标 | 实测结果 |
|---|---|---|---|
| `memory_primary` 条数 | 81 | > 120 | 96 ⚠️ |
| `memory_secure_audit` 条数 | 79 | < 20 | 85 ⚠️(路径规则隔离)|
| 增量 P95hash 命中) | 1.4s | < 0.1s | 待测 |
| 增量 P95(实际 embed | 1.4s | < 0.8s | 待测 |
| Recall@5 | 90% | ≥ 90% | 待测 |