Files

8.5 KiB
Raw Permalink Blame History

title, date, based-on, kanban-board, status
title date based-on kanban-board status
重构任务清单 2026-02-26 refactor-plan refactor-board 进行中

重构任务清单

看板视图见 refactor-board。完成任务后勾选 checkbox,填写完成时间和实际结果。


Phase 1 · 数据安全与正确性

必须按顺序执行,P1-4 是验收步骤。

P1-1 · 删除 blacklist 过宽字面量

字段 内容
状态 DONE
优先级 🔴 Critical
文件 blacklist.py
关联问题 C449% 误隔离率)
完成时间 2026-02-26
实际结果 已删除 api_keyaccess_key 两行字面量

改动:从 SENSITIVE_LITERAL_MARKERS 删除以下两行(已被正则覆盖)

'api_key',
'access_key',

验收:重建索引后 memory_primary 条数显著增加,memory_secure_audit 条数下降。

  • 完成改动
  • 验收通过

P1-2 · stale 清理排除 failed_ids

字段 内容
状态 DONE
优先级 🔴 Critical
文件 ingest_vault.py 第 88 行
关联问题 C1embed 失败文档被静默删除)
完成时间 2026-02-26
实际结果 已在 stale 计算中排除 failed_ids

改动:

# 修改前
stale_primary_ids = sorted(db_primary_ids - valid_ids)

# 修改后
stale_primary_ids = sorted(db_primary_ids - valid_ids - set(failed_ids))

验收:全量重建时模拟 embed 失败,确认失败文档的旧向量保留。

  • 完成改动
  • 验收通过

P1-3 · hook 清理 changes 临时文件

字段 内容
状态 DONE
优先级 🔴 Critical
文件 install-hook.sh(修改后需重新安装 hook
关联问题 C3(每次 commit 留下临时文件)
完成时间 2026-02-26
实际结果 已加 rm -f '$changes_file'hook 已重新安装

改动:

# 修改前
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 残留。

  • 完成改动
  • 重新安装 hook
  • 验收通过

P1-4 · 重建全量索引验收

字段 内容
状态 DONE
优先级 🔴 Critical
依赖 P1-1 ~ P1-3 全部完成后执行
完成时间 2026-02-26
实测 primary 96
实测 secure 85

操作:

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 > 100memory_secure_audit < 20。

  • 执行全量重建
  • memory_primary > 100 ⚠️ 实测 96Infrastructure/Home-Automation 被路径规则整体隔离)
  • memory_secure_audit < 20 ⚠️ 实测 85(同上原因)

Phase 2 · 性能与一致性

依赖 Phase 1 全部完成后执行。

P2-1 · 增量索引加 hash 检查

字段 内容
状态 TODO
优先级 🟠 Important
文件 incremental_ingest.py
关联问题 C2P95=1.4s 的直接原因)
完成时间
实际结果

改动:调用 embed_text 前先查 content_hash,匹配则跳过

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() 入口加目录过滤

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 行无效)
完成时间
实际结果

改动:

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,加校验

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 参数

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.sqlblacklist.pyindex_common.py
关联问题 I6risk 列永远是同一个值)
完成时间
实际结果

改动:is_excluded() 返回触发原因字符串(如 path:00_Inboxcontent: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% 待测