memoryweave/WORKLOG.md

339 lines
14 KiB
Markdown
Raw Permalink 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.

# 织忆系统修复工作记录
> 维护者:小唯 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 5condition=len<5 时触发 |
| E2: agent 命名空间激活 | 完成 | hermeshermes-main, openclawopenclaw-mainRust sidecar namespace 过滤已验证 |
| E3: 增量 embedding | 完成 | Go Commit 时同步调用 BGE HTTP vector 立即写入 LanceDBrecall 无需等待 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 graphDegreeG7 E3: 贝叶斯+crystallize+execute+feedback 完整闭环 |
| G8: 备份恢复 | 完成 | Backup 已有新增 Restore + ListBackups支持 systemctl 停启服务恢复 |
| G9: 缓存 + 持久化 | 完成 | SearchCache 改造为 L1内存+ L2Redis双级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: 进程内 SearchCacheLRU+TTL1000 1h TTL
- L2: Redis `zhiyi:cache:*`TTL3600s进程重启后不丢
- 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 /quotaG8: Restore+ListBackupsG9: 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.7scluster_only未触发 LLM 是设计预期
- Recall 七维度: encodeannrerankmmr 全链路 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` binary5月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`: 注册 ZhiYiPlugin3 个命令记忆面板/图谱面板/搜索+ 设置页
- `src/api.ts`: fetch 封装调用 Go API `/api/v1/*` 全部端点API Key = `zhiy...`(截断)
- `src/MemoryView.ts`: 侧边栏记忆列表分页每页20条蒸馏队列警告
- `src/GraphView.ts`: D3.js force-directed graphego-network 探索节点拖拽/缩放
- `src/SearchModal.ts`: 语义搜索模态框debounce 300msEnter 选择第一条
- `styles.css`: 全局样式蒸馏警告高亮
- `esbuild.config.mjs`: 构建 main.ts main.jsminified
- 构建产物: `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
```