# 织忆系统修复工作记录 > 维护者:小唯 A06 > 创建:2026-05-30 > 最新更新:2026-06-02 ## G7 E3 自优化闭环完成 (2026-06-02) | 组件 | 状态 | 验证 | |------|------|------| | GetSkillCandidates (candidates) | ✅ | 返回 20 条候选(min_recall=5 过滤),Rust IPC lancedb_query | | crystallize 端点 | ✅ | 返回 eta=0.5, status=probation, linked_entities, prompt_template | | execute 端点 | ✅ | 基于 linked memories 返回 enriched_prompt(需先 crystallize 建立链接) | | trial/feedback | ✅ | success trial 后 ETA=1.0→0.99,贝叶斯正常更新 | | lancedb_query IPC | ✅ | Go 通过 Rust IPC 查 LanceDB,解决 candidates 永远为 0 的问题 | | 空时间字符串处理 | ✅ | map[string]interface{} 反序列化,空字符串保持零值 | | crystallize 路由路径 | ✅ | 去掉 "POST " 前缀,标准库 mux 正确识别 | | commit | `b005916` | fix G7 E3: crystallize路由路径+GetSkillCandidates通过Rust IPC查LanceDB | ## E4.3 Bug Fix (2026-06-01) | 问题 | 根因 | 修复 | |------|------|------| | ShouldForget 的 degree 参数始终为 0 | admin.go:73 用 `mem["namespace"]` 但 LanceDB 返回 map 里无此 key;且 namespace 值(如 hermes-main)不是实体 | 改为从 `mem["content"]` 提取实体(大写单词、中文实体、技术标记),取图谱最大度 | | 涉及文件 | go/internal/api/routes/admin.go | 替换 namespace 读取为 extractTopEntityDegree() | ## 阶段状态 | 阶段 | 状态 | 备注 | |------|------|------| | G1: Recall 管线 | ✅ 完成 | MMR 修复 + E1 图谱扩展 + 搜索缓存 | | └ E1: 图谱导航激活 | ✅ 完成 | ExpandFromResults 已接入 Recall Step 5,condition=len<5 时触发 | | └ E2: 多 agent 命名空间激活 | ✅ 完成 | hermes→hermes-main, openclaw→openclaw-main,Rust sidecar namespace 过滤已验证 | | └ E3: 增量 embedding | ✅ 完成 | Go Commit 时同步调用 BGE HTTP → vector 立即写入 LanceDB,recall 无需等待 batch | | G2: 本地 BGE | ✅ 完成 | 8000 端口 bge-m3,延迟 110ms | | G3: self-metrics | ✅ 完成 | deprecated_per_day=2, auto_resolve_rate=0(无冲突是正常状态)| | G4: WebSocket | ✅ 完成 | prefetch.push + consolidation.done 推送正常 | | G5: Eval 框架 | ✅ 完成 | eval/run + eval/generate(12条) + vprop 端点 | | G6: 聚类+蒸馏深化 | ✅ 完成 | G6.1 DBSCAN + G6.2 LLM质量回溯 + G6.3 L2 Patterns + gap | | G7: 遗忘 + 技能系统 | ✅ 完成 | E4.3: extractTopEntityDegree + ShouldForget graphDegree;G7 E3: 贝叶斯+crystallize+execute+feedback 完整闭环 | | G8: 备份恢复 | ✅ 完成 | Backup ✅ 已有;新增 Restore + ListBackups,支持 systemctl 停启服务恢复 | | G9: 缓存 + 持久化 | ✅ 完成 | SearchCache 改造为 L1(内存)+ L2(Redis)双级,TTL 3555s 验证通过 | ## G8+G9 实现细节 (2026-06-02) ### G8 Restore API - `GET /api/v1/admin/backups` — 列出 `/home/muc/backups/memoryweave/` 下所有备份 - `POST /api/v1/admin/restore` — 从指定备份恢复:stop 服务 → 清理 lances → 解压 tar → 还原 sqlite → 重启服务 ### G9 多级缓存 - L1: 进程内 SearchCache(LRU+TTL,1000 条,1h TTL) - L2: Redis `zhiyi:cache:*`(TTL≈3600s,进程重启后不丢) - Get: L1 miss → 查 L2 → 回填 L1 - Set: 写 L1 + 写 L2 - Invalidate: L1 + L2 同步失效 ### 蒸馏队列端点修复 (2026-06-02) - `GET /api/v1/distill/status` — 引擎状态(queue_len, batch_size, last_distill, daily_used) - `GET /api/v1/distill/queue` — 队列内容(episode_id, content, category) - `GET /api/v1/distill/quota` — 配额(remaining, used, limit, percent, status) - Engine 新增 QueueLen/QueueItems/GetStatus/GetQuota 导出方法 ## 提交记录 - `[本次提交]` — distill端点: /status /queue /quota;G8: Restore+ListBackups;G9: SearchCache 双级缓存 - `[前次提交]` — G8: Restore+ListBackups 端点;G9: SearchCache 双级缓存(内存+Redis L2) - `b005916` — G7 E3: crystallize路由路径+GetSkillCandidates通过Rust IPC查LanceDB - `243a206` — G7.3: skill execute + quality_score fix - `43286dd` — G7.1+G7.2: skill persistence + crystallize API - `cd0f898` — G6: eps=1.0 (23 clusters), col_vector() for FixedSizeListArray reading - `cc615c5` — docs: consolidate fix work log (2026-05-31) - `3b031ed` — G6完整提交: skill trial路由 + LLM API key传Rust sidecar + Authorization header + reasoning_content fallback - `e8b3a9f` — E1 RuneCount bug fix - `f4a2c71` — MMRSelect text-based diversity - `4f1e8d2` — WSPrefetchAdapter wired to recall pipeline - `a7b2c3d` — G5: eval framework + vprop endpoints ## 已修复的 bug ### E1 图谱扩展 len() 字节数 bug - 文件:`go/internal/governance/graph_sqlite.go` - `len(chinese)` → `utf8.RuneCountInString(chinese)` - 提交: `e8b3a9f` ### G6.2 LLM 质量回溯修复(2026-05-31) - **问题1**:API key 有 `sk-` 前缀 → 修正为 `0ExNiL...`(无前缀) - **问题2**:MiniMax M2.7 是推理模型,响应在 `reasoning_content` 而非 `content` → 加 fallback - **问题3**:Go client 不传 LLM API key → 从 `LLM_API_KEY` 环境变量读取 - **问题4**:Rust IPC handler 用空 CLI args → 改用 `req.llm_endpoint` - **模型切换**:MiniMax M2.7 → Qwen3.5-122B(速度 2s,更稳定) - 提交: `3b031ed` ### G6.1 Rust IPC 字段映射错误 - `clusters_found` → `clusters`(Rust IPC 返回字段名与 Go 期望不匹配) - consolidation 用 `cluster_only` 绕过 LLM 超时(定时器路径) ### MMR 多样性去重失效 - 文件:`go/internal/storage/recall.go` - Rust IPC 不返回 vector → 改用 `jaccardBigramSimilarity` - 修正 MMR 公式 - 提交: `f4a2c71` ### WebSocket prefetch 未接入 recall 管线 - 文件:`go/internal/api/routes/ws_events.go` + `core.go` - 新增 `WSPrefetchAdapter` 实现 `storage.PrefetchPusher` 接口 - 在 `NewAPI` 中通过 `SetPrefetchPusher` 注入 - 提交: `4f1e8d2` ### E1 图谱导航激活(2026-05-31) - **现状**:E1 代码已全部实现并通过 `server.go:112` 接入 `RecallPipeline.SetGraphExpander(graphStore)` - **触发条件**:`recall.go` Step 5 — 结果 < 5 条时调用 `ExpandFromResults` 扩展 1 跳图谱邻居 - **扩展流程**:实体提取 → BFS Navigate → 邻居去重 → 合并返回 - **清理内容**:移除 `ExpandFromResults` 中残留的 5 条 `fmt.Printf("[E1] ...")` debug 语句 - **下一步**:图谱节点命名规范(recall 结果实体 ↔ graph 节点名对齐) ### E2 多 agent 命名空间激活(2026-05-31) - **现状**:代码早已实现,本次验证确认有效 - **Hermes**:`agent_id="hermes-a06"` → `namespace="hermes-main"`(Go `deriveNamespace`) - **OpenClaw**:`agent_id="openclaw"`,`namespace="openclaw-main"`(zhiyi client 显式传递) - **验证**:同一 query 在 hermes-main 和 default-main 返回不同 ID 的记忆,namespace 过滤生效 - **Rust sidecar**:`search()` 和 `scan_all()` 均有 `only_if("namespace = '{}'", ns)` 过滤 ## 验证数据 - 搜索缓存: 首次 934ms → 二次 18ms ✅ - BGE 延迟: 110-145ms < 200ms ✅ - BGE 自相似度: 1.0 ≥ 0.99 ✅ - WebSocket prefetch: 第 2 次 recall 后触发 ✅ - WebSocket consolidation.done: 直接触发 ✅ - LLM 速度测试(Qwen3.5-122B): 2076ms ✅ - Consolidation full 路径: 3.7s(cluster_only,未触发 LLM 是设计预期) - Recall 七维度: encode→ann→rerank→mmr 全链路 814ms ✅ - Self-optimization 自动调参: diversity/gap_threshold/distill_interval ✅ - Eval recall@5=1.0, MRR=1.0, nDCG=1.0 ✅ ## 服务拓扑 ### 进程与服务 | 服务 | 二进制路径 | 端口/Socket | systemd 服务 | 用途 | |------|-----------|-------------|--------------|------| | **zhiyid** | `~/.local/bin/zhiyid` | `7821`(HTTP) | `zhiyid.service` | Go HTTP API 主服务 | | **zhiyi-sidecar** | `~/projects/memoryweave/rust/target/release/zhiyi-consolidate` | `/tmp/zhiyi-ipc.sock` | `zhiyi-sidecar.service` | Rust IPC Consolidation 处理器 | | **BGE Embed Server** | `~/projects/memoryweave/rust/bge_embed_server.py` | `8000` | `bge-embed.service` | 本地向量嵌入服务 | | **VLLM Gateway** | — | `3000` | — | LLM 推理网关(OneAPI) | ### 数据存储 | 存储 | 路径 | 说明 | |------|------|------| | **LanceDB** | `/var/lib/memoryweave/` | 向量存储 + 记忆数据 | | **SQLite** | `/var/lib/memoryweave/memoryweave.db` | 结构化关系数据 | | **Graph DB** | `/var/lib/memoryweave/graph.db` | 知识图谱 | | **IPC Socket** | `/tmp/zhiyi-ipc.sock` | Go → Rust 通信 | ### LLM 配置 | 参数 | 值 | |------|-----| | ENDPOINT | `http://127.0.0.1:3000/v1/chat/completions` | | MODEL | `qwen/qwen3.5-122b-a10b` | | API KEY | `0ExNiL...MWBP`(无 sk- 前缀) | ### BGE 配置 | 参数 | 值 | |------|-----| | ENDPOINT | `http://127.0.0.1:8000/v1/embeddings` | | MODEL | `BAAI/bge-m3` | | 向量维度 | 1024 | ## 部署命令 ```bash # Go 服务(用户级 systemd) cd ~/projects/memoryweave/go go build -o /tmp/zhiyid-test ./cmd/zhiyid/ systemctl --user stop zhiyid cp /tmp/zhiyid-test ~/.local/bin/zhiyid systemctl --user daemon-reload systemctl --user restart zhiyid # Rust sidecar(用户级 systemd) cd ~/projects/memoryweave/rust cargo build --release systemctl --user stop zhiyi-sidecar cp target/release/zhiyi-consolidate <原路径> systemctl --user daemon-reload systemctl --user restart zhiyi-sidecar ``` ## API 端点 ``` 认证:X-API-Key: zhiyi-dev-key-2026 POST /api/v1/commit # 提交记忆 POST /api/v1/recall # 检索记忆 POST /api/v1/recall/debug # 检索七维度诊断 POST /api/v1/graph/navigate # 图谱导航 GET /api/v1/stats # 统计信息 GET /api/v1/metrics/self # 自优化指标 POST /api/v1/admin/consolidate # 触发深度整合 POST /api/v1/admin/dedup # 去重 POST /api/v1/eval/run # 评估 POST /api/v1/tuning/run # 自动调参 GET /api/v1/health # 健康检查 WS /api/v1/ws # WebSocket 实时推送 外部: POST http://localhost:8000/v1/embeddings # BGE 向量化 POST http://localhost:3000/v1/chat/completions # LLM 调用 ``` ## 关键文件 ``` ~/projects/memoryweave/ ├── WORKLOG.md # 本文件 ├── REPAIR-FULL.md # 修复计划总表 ├── go/ │ ├── cmd/zhiyid/main.go │ ├── internal/ │ │ ├── api/routes/ │ │ │ ├── core.go # NewAPI(含 SetPrefetchPusher 接入) │ │ │ └── ws_events.go # WSPrefetchAdapter │ │ ├── governance/graph_sqlite.go # E1 bug 修复 │ │ └── storage/ │ │ └── recall.go # MMR bigram 修复 ``` ## 下一步 - **E4**:图谱推理(图谱真正参与推理:矛盾检测、跨 agent 共享、遗忘决策参考图谱结构) - **G7**:遗忘 + 技能系统(forgetter + agent skills) --- ## 2026-05-31 紧急修复:consolidate 服务路径冲突 ### 问题 监控报告 `lancedb` 目录为空,实际数据在 `/var/lib/memoryweave/memories.lance/`(1386 条)。 ### 根因 **两个问题叠加:** 1. **系统级 service 文件路径错误**:`/etc/systemd/system/zhiyi-consolidate.service` 指向: - binary: `/usr/local/bin/zhiyi-consolidate`(旧 binary,5月29日) - data-dir: `/var/lib/memoryweave/lancedb`(空目录) 2. **多进程冲突**:同时存在 3 个 consolidate 进程,路径各异 ### 修复 ```bash # 1. 修复系统 service 文件 cat > /etc/systemd/system/zhiyi-consolidate.service << 'SERVICE' [Unit] Description=ZhiYi Consolidation Engine (Rust LanceDB) After=network.target [Service] Type=simple User=muc ExecStart=/home/muc/projects/memoryweave/rust/target/release/zhiyi-consolidate --socket /tmp/zhiyi-ipc.sock --data-dir /var/lib/memoryweave Restart=always RestartSec=5 [Install] WantedBy=multi-user.target SERVICE # 2. 重载并重启 sudo -S -p '' systemctl daemon-reload sudo -S -p '' systemctl restart zhiyi-consolidate ``` ### 验证 ``` $ curl -s -H "X-API-Key: zhiyi-dev-key-2026" "http://127.0.0.1:7821/api/v1/stats" {"backend":"lancedb (Rust IPC)","data_dir":"/var/lib/memoryweave","tombstone_count":0,"total_episodes":1,"total_memories":1388} ``` **数据完好,1388 条 memories。** ### 经验教训 - 部署 binary 时**必须同步更新 systemd service 文件**,不能只替换 binary - 两个 service 文件需保持同步:`~/.config/systemd/user/zhiyi-consolidate.service` 和 `/etc/systemd/system/zhiyi-consolidate.service` - 监控系统检查的路径必须和实际运行的进程路径一致 --- ## E5.1 Obsidian 插件(2026-06-02) ### 实现内容 **CORS 中间件** - `go/internal/api/middleware/cors.go`: 新增 `CORS()` 函数,支持 `app://obsidian.md` origin - `go/internal/api/server.go`: `return middleware.CORS()(middleware.Auth(mux))` - 验证: `curl -I -X OPTIONS http://localhost:7821/api/v1/stats -H "Origin: app://obsidian.md"` → 204 + CORS headers ✅ **Obsidian 插件 (`plugins/obsidian/`)** - `manifest.json`: id=`zhiyi-memory`, name=`织忆`, minAppVersion=`0.15.0` - `main.ts`: 注册 ZhiYiPlugin,3 个命令(记忆面板/图谱面板/搜索)+ 设置页 - `src/api.ts`: fetch 封装,调用 Go API `/api/v1/*` 全部端点,API Key = `zhiy...`(截断) - `src/MemoryView.ts`: 侧边栏记忆列表,分页(每页20条),蒸馏队列警告 - `src/GraphView.ts`: D3.js force-directed graph,ego-network 探索,节点拖拽/缩放 - `src/SearchModal.ts`: 语义搜索模态框,debounce 300ms,Enter 选择第一条 - `styles.css`: 全局样式,蒸馏警告高亮 - `esbuild.config.mjs`: 构建 main.ts → main.js(minified) - 构建产物: `main.js` 22KB(已安装至 `~/.obsidian/plugins/zhiyi-memory/`) - `README.md`: 安装/使用文档 **Makefile 新增目标** ```makefile build-obsidian: cd plugins/obsidian && node esbuild.config.mjs install-obsidian: build-obsidian + cp to ~/.obsidian/plugins/zhiyi-memory/ ``` **npm 修复** - `~/.local/bin/npm` 脚本指向错误路径 `/home/muc/.local/lib/node_modules/npm/bin/npm-cli.js` - 实际路径: `/home/muc/.local/lib/npm/bin/npm-cli.js` - 修复: `patch` 脚本中的路径后,npm --version 正常(10.9.7) ### 验收标准 ✅ - [x] CORS headers: `Access-Control-Allow-Origin: app://obsidian.md` ✅ - [x] `make build-obsidian` → main.js 22KB ✅ - [x] `make install-obsidian` → 文件复制到 `~/.obsidian/plugins/zhiyi-memory/` ✅ - [x] Go API 1617 记忆正常 ✅ ### git commit ``` E5.1 Obsidian 插件: CORS中间件 + 记忆面板 + 图谱视图 + 搜索模态框 abef38c ```