133 lines
4.2 KiB
Markdown
133 lines
4.2 KiB
Markdown
# 织忆 consolidate 修复工作记录
|
||
> 日期:2026-05-31
|
||
> 目标:修复 consolidate cronjob 监控发现的问题
|
||
|
||
---
|
||
|
||
## 问题清单(来自 cronjob 报告)
|
||
|
||
| 项目 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| prune "no such column" 错误 | ✅ 已修复 | 日志中无 prune 报错 |
|
||
| DBSCAN 聚类数量 | ❌ 仍是 1 | `1 clusters + 0 noise from 1477 items` |
|
||
| quality 分数 | ❌ 仍是 0.000 | 但 `task=full` 时 Step 4 有执行 |
|
||
| decay 校准 | ✅ 正常 | 12 个类别 decay_rates 有值 |
|
||
|
||
---
|
||
|
||
## 根因分析
|
||
|
||
### 1. DBSCAN 始终 1 cluster
|
||
**根因:所有 1477 条向量全为零向量(norm=0.000)**
|
||
|
||
Python migration 时用 JSON 数组写入 LanceDB FixedSizeList 列,但 Arrow 读取返回 null,全部 fallback 到 `vec![0.0; 1024]`。零向量之间 L2 距离恒为 0,任何 eps 值都无法产生多 cluster。
|
||
|
||
**证据(sidecar 日志):**
|
||
```
|
||
[consolidate] vector norms: min=-0.0000 max=0.0000 avg=0.0000
|
||
[consolidate] sample distances (20 vecs, 190 pairs): p5=-0.000 p50=-0.000 p95=-0.000
|
||
```
|
||
|
||
### 2. quality=0.000
|
||
**不是 bug**:Go API 返回的 `quality_score` 字段来自 `ConsolidationReport` 结构体,而 Rust 的质量分存在 `QualityBacktracer` 返回值中,需要从 `report_json` 字段解析。当前 Step 4 有执行(见 sidecar 日志),但 API 响应字段名不匹配。
|
||
|
||
---
|
||
|
||
## 已修复的问题
|
||
|
||
### ✅ Go → Rust mode 传递(1fa8349)
|
||
- `consolidation_pipe.go`:`RunWithMode(mode)` 正确传递 task 给 IPC
|
||
- Rust sidecar:收到的 `task="full"` 日志已确认
|
||
|
||
### ✅ BGE HTTP 连通性检查(1fa8349)
|
||
- Step 4 前用 `TcpStream::connect_timeout(2s)` 检测 port 8000
|
||
- 不通时跳过质量回溯,不挂起
|
||
|
||
### ✅ embed.rs 请求超时(1fa8349)
|
||
- `.timeout(Duration::from_secs(10))` 防止无限等待
|
||
|
||
### ✅ WriteTimeout 60s(1fa8349)
|
||
- Go server.go:`WriteTimeout` 从 10s → 60s(之前 exit 52 根因)
|
||
|
||
### ✅ LanceDB FixedSizeList 存储格式(1fa8349)
|
||
- `insert_batch` 改用 `Float32Array::from_iter_values` + `try_new`
|
||
- 仅影响新写入,历史向量仍需重新编码
|
||
|
||
### ✅ DBSCAN eps 调整(1fa8349)
|
||
- eps 从 1.5 → 0.1(cosine threshold 0.995)
|
||
- 等向量修复后需要重新调 eps
|
||
|
||
### ✅ nil guards(1fa8349)
|
||
- `consolidation_pipe.go`:防止 report 为 nil 时 panic
|
||
|
||
---
|
||
|
||
## 当前状态(2026-05-31)
|
||
|
||
```
|
||
cluster_only: ✅ 正常(7-8s 完成)
|
||
full mode: ✅ Step 1-5 全部执行(decay 正常,quality 有执行但 API 字段不匹配)
|
||
task=full ✅ mode 正确传到 Rust
|
||
```
|
||
|
||
---
|
||
|
||
## 待解决问题
|
||
|
||
### 🔴 P0: 1477 条向量重新编码
|
||
LanceDB 中 1477 条历史向量全为零,修复后:
|
||
1. BGE HTTP 服务(embed-server.py port 8000)需恢复正常
|
||
2. 批量读取 1477 条记忆内容
|
||
3. 用 BGE 编码得到 1024-dim 向量
|
||
4. 写回 LanceDB
|
||
|
||
### 🟡 P1: DBSCAN eps 重新调参
|
||
向量修复后,基于真实距离分布重新找合适 eps 值(当前 eps=0.1 可能过于严格)。
|
||
|
||
### 🟡 P2: embed-server.py 启动问题
|
||
当前 `embed-server.py`(pid=917)在 port 8000 但 `/v1/embeddings` 请求超时(curl exit 28)。进程 5.4GB RAM 表明模型可能已加载但 encode 调用挂起。需要修复或替换为 Rust ONNX 实现。
|
||
|
||
---
|
||
|
||
## 技术细节
|
||
|
||
### IPC 协议
|
||
```json
|
||
{"type":"consolidate","consolidate":{
|
||
"task":"full",
|
||
"lancedb_path":"/var/lib/memoryweave",
|
||
"sqlite_path":"/var/lib/memoryweave/graph.db",
|
||
"llm_endpoint":"...",
|
||
"llm_model":"...",
|
||
"llm_api_key":"...",
|
||
"llm_budget":20,
|
||
"epsilon":0.1,
|
||
"min_points":3,
|
||
"model_dir":"/home/muc/models/bge-m3/onnx"
|
||
}}
|
||
```
|
||
|
||
### DBSCAN eps 数学
|
||
对于 1024-dim BGE-M3 单位向量:
|
||
- euclidean² = 2(1-cosine)
|
||
- cosine = 1 - euclidean²/2
|
||
- eps=0.1 → cosine > 0.995(很严格,几乎相同才聚一起)
|
||
- eps=0.5 → cosine > 0.875
|
||
- eps=1.0 → cosine > 0.5
|
||
- eps=1.5 → cosine > 0(几乎全聚一起)
|
||
|
||
### Git Commit
|
||
```
|
||
1fa8349 fix: mode propagation, eps=0.1, BGE connectivity check, vector storage, WriteTimeout 60s
|
||
```
|
||
|
||
---
|
||
|
||
## 定时器配置
|
||
|
||
- `zhiyi-consolidate.timer`:每周日 03:00 执行 `zhiyi-consolidate.service --mode full`
|
||
- 90s cluster_only 定时器:已不存在(之前某个阶段的遗留设计)
|
||
|
||
---
|
||
|
||
*最后更新:2026-05-31 15:50* |