memoryweave/IMPLEMENTATION-FIVE.md

18 KiB
Raw Blame History

织忆五步实施计划

创建时间2026-05-30 状态E1/E2/E3/E4 已完成E5 规划完成,准备实施 禁止:偷懒、随意更改变动设计语言


总览

阶段 内容 优先级 预计工期 状态
E1 图谱导航激活 🔴 1-2 天 完成
E2 多 agent 命名空间激活 🔴 1 天 完成
E3 增量 embedding 🟡 1 天 完成
E4 图谱推理 🟡 2-3 天 完成
E5 产品 UI 🔵 长期

E1图谱导航激活

目标

改造 /recall 链路,向量搜索后接图谱 BFS 扩展,让搜索结果融合结构化知识。

现状

  • 图谱数据1269 节点 / 31248 边(graph/stats 确认)
  • navigate.go BFS 导航代码已写好,但 /recall 没调用
  • /recall 当前纯语义搜索,不走图谱

实施步骤

E1.1 确认 navigate.go 接口

  • 找到 navigate.go 的函数签名和参数
  • 确认 BFS 扩展是 1 跳还是 2 跳
  • 确认输出格式(节点列表还是边列表)

E1.2 改造 recall 链路

修改 internal/api/routes/recall.go

语义搜索 → 向量 top-K →
图谱 BFS 扩展navigate 1跳邻居→
合并去重 → bge-reranker 重排 →
返回最终结果

E1.3 测试验证

# 验证图谱有数据
curl http://localhost:7821/api/v1/graph/stats

# 验证 recall 走图谱(找有图谱关联的记忆)
curl "http://localhost:7821/api/v1/recall?query=织忆图谱导航&top_k=5"

# 对比:图谱激活前 vs 激活后的召回结果差异
# 激活后应该出现更多 1 跳邻居相关结果

验收标准

  • graph/stats node_count > 1000已有确认不变
  • recall 结果中包含图谱扩展内容(通过日志或响应标记确认)
  • 延迟 < 500ms可接受范围

E2多 agent 命名空间激活

目标

Hermes 和 OpenClaw 使用独立 namespace数据物理隔离互不串味。

现状2026-05-31 验证)

  • Hermesagent_id="hermes-a06"namespace="hermes-main"Go deriveNamespace 自动推导)
  • OpenClawagent_id="openclaw"namespace="openclaw-main"zhiyi client 显式传递)
  • Rust sidecarsearch() / scan_all() 均有 only_if("namespace = '{}'", ns) namespace 过滤
  • 验证:同一 query 在 hermes-main 和 default-main 返回不同 ID 的记忆,隔离生效
  • 历史数据(agent_id=default)在 default-main,与 hermes-main/openclaw-main 物理隔离

实施步骤

E2.1 确认当前 namespace 配置(已验证)

  • Hermes 插件:agent_id="hermes-a06" 硬编码于 ZhiYiClient.commit/recall~/.hermes/plugins/zhiyi/__init__.py
  • OpenClaw 插件:agent_id="openclaw", namespace="openclaw-main" 硬编码于 ZhiYiClient/persistent/.../memory-zhiyi/src/client.ts

E2.2 验收2026-05-31 通过)

# Hermes recall → hermes-main
curl -X POST http://localhost:7821/api/v1/recall \
  -H "X-API-Key: zhiyi-dev-key-2026" \
  -d '{"query":"牧尘 小唯","top_k":3,"namespace":"hermes-main"}'
# → 返回 hermes-main 专属记忆

# OpenClaw recall → openclaw-main
curl -X POST http://localhost:7821/api/v1/recall \
  -H "X-API-Key: zhiyi-dev-key-2026" \
  -d '{"query":"牧尘 小唯","top_k":3,"namespace":"openclaw-main"}'
# → 返回 openclaw-main 专属记忆

验收标准

  • namespace=hermes-main 查询不到 namespace=openclaw-main 的记忆
  • namespace=openclaw-main 查询不到 namespace=hermes-main 的记忆
  • Rust sidecar 在 commit/recall 时正确使用 namespace 过滤

E3增量 embedding

目标

commit 时同步调用 vLLM embedding不等 Rust sidecar batch延迟从分钟级降到毫秒级。

现状2026-05-31 验证)

  • 已实现Go core.go:79Commit() 中调用 a.Embedder.EncodeSingle(req.Content)
  • BGE HTTP:连接 localhost:8000/v1/embeddings17ms/条L2 归一化
  • IPC 传输Go 将 vector + 文本一起发往 Rust lancedb_insertRust 直接存储(不重编码)
  • 验证commit 后立即 recall 测试记忆排第一score=0.843),无需等待 batch
  • embedder.go 有 MOLIFANG_API_KEY fallback当前未启用环境无此 key

实施步骤

E3.1 确认当前 embedding 流程(已验证)

  • Go core.go:79a.Embedder.EncodeSingle(req.Content) → BGE HTTP 8000 → 1024-dim vector
  • Go core.go:123Vector: vector 写入 models.MemoryRecord
  • Go core.go:129a.LanceDB.InsertMemory(mem) → IPC lancedb_insert 发送到 Rust
  • Rust lancedb_ops.rs:160-163 → 从 JSON 读取 vector直接写入 LanceDB FixedSizeListArray

E3.2 验证结果2026-05-31

# commit 后立即 recall
curl -X POST http://localhost:7821/api/v1/commit \
  -H "X-API-Key: zhiyi-dev-key-2026" \
  -d '{"content":"E3增量embedding测试验证commit时同步生成vector","namespace":"default-main"}'
# → memory_id: mem_1780211630617301197

curl -X POST http://localhost:7821/api/v1/recall \
  -H "X-API-Key: zhiyi-dev-key-2026" \
  -d '{"query":"E3增量embedding测试","top_k":3,"namespace":"default-main"}'
# → mem_1780211630617301197 排第一score=0.843 ✅

验收标准

  • commit 响应包含 memory_id写入成功
  • commit 后立即 recall 能搜到(无需等待 Rust sidecar batch
  • recall 得分 > 0.8(证明向量有效,非零向量)

E4图谱推理

目标

图谱真正参与推理:矛盾检测、跨 agent 共享、遗忘决策参考图谱结构。

现状

  • 图谱存了 1269 节点/31248 边只搜不用2026-05-31 修复了 fmt.Printf debug
  • E4.1: Commit 路径已接入 ConflictDetector检测率依赖 dedup 搜索覆盖
  • E4.2: Recall 结果 < 3 时自动补充 shared namespace
  • E4.3: Forgetter.ShouldForget 支持 graphDegree 可变参数

实施步骤

E4.1 矛盾检测( 已实现2026-05-31

实现位置

  • governance/governance.go: IsContradiction() + DetectContradiction() 方法(导出供 routes 包调用)
  • routes/core.go:API: 添加 ConflictDetector 字段,构造函数签名更新
  • server.go: ConflictDetector 提到 NewAPI 之前创建(避免作用域错误)

Commit 流程

Commit() → dedup 搜索 top-5 相似记忆
  → 3a: exact match → merge
  → 3b: near-dup (cos ≥ 0.98) → merge
  → 3c: 对其余相似记忆运行 DetectContradiction()
      → 有矛盾 → {"status":"ok","conflicts":["矛盾内容"]}

限制:依赖 dedup 搜索结果的覆盖率。语义相反的陈述在向量空间中未必是 top-5 最近邻。2026-05-31 修复了 IsContradiction 中文感知问题(原用 strings.Fields 对中文无效,改用 unicode.Han 字符级切分 + containsNegCN 否定词检测)。

E4.2 跨 agent 知识共享( 已实现2026-05-31

实现位置routes/core.go:Recall()pipeline.Recall() 结果 < 3 时,补充 shared namespace 搜索

流程

Pipeline.Recall(query, ns, limit) → len < 3 && ns != "shared"
  → EncodeSingle(query) → LanceDB.Search("memories", vec, 5, "shared")
  → 去重已出现在 own ns 的记忆 → 追加到 resultsScore 降权 0.5

E4.3 遗忘决策参考图谱( 已实现2026-05-31

实现位置governance/governance.go:ShouldForget()

逻辑(向后兼容,不传 graphDegree 则行为不变):

// 节点度 > 5 时,每超 1 度 + 0.03 保留分
if len(graphDegree) > 0 && graphDegree[0] > 5 {
    score += float64(graphDegree[0]-5) * 0.03
}

调用方待接入routes/admin.go:71server.go:904 — 需要在遗忘循环中查 GraphStore.GetEntityDegree() 注入 graphDegree 参数。

验收标准

  • E4.1: Commit 响应包含 conflicts 字段(如有矛盾)— 逻辑已接入
  • E4.2: Recall < 3 结果时自动补充 shared — 已实现
  • E4.3: ShouldForget 签名支持 graphDegree — 已实现,调用方待接

E5产品 UI

规划版本v1.0 | 2026-06-02 目标给织忆构建三层可视化入口Obsidian 插件 / 增强 CLI / Web UI覆盖日常快速查询和图谱深度探索两种场景。


E5.1Obsidian 插件(优先级最高)

为什么先做 Obsidian

  • 牧尘的笔记和记忆本来就在 Obsidian 里,界面切换成本最低
  • 插件形式天然接入 vault 工作流,不需要另外打开窗口
  • 图谱可以直接嵌入笔记界面,实体关系和笔记内容联动

目标功能

  • E5.1.1 插件骨架:manifest.json + main.ts + styles.cssObsidian 加载并注册 ZhiYiPlugin
  • E5.1.2 记忆侧边栏面板:展示最近记忆列表,支持按 namespace 过滤,支持分页
  • E5.1.3 实体图谱视图:基于 D3.js force-directed graph/api/v1/graph/entity/{entity}/neighbors 获取数据,节点颜色区分 categoryhover 显示关系标签
  • E5.1.4 记忆搜索模态框:输入查询词调用 /api/v1/search/recall,显示 top-20 结果,点击跳转到记忆详情
  • E5.1.5 实体详情视图:选中图谱节点后,从 /api/v1/memories/by-entity/{entity} 获取关联记忆列表
  • E5.1.6 蒸馏状态面板:展示 /api/v1/distill/status/api/v1/distill/quota,队列为非空时高亮提醒

技术方案

  • 开发目录:~/projects/memoryweave/plugins/obsidian/
  • 插件通过 fetch() 调用 Go API端口 7821Go 服务需添加 CORS 头(Access-Control-Allow-Origin: app://obsidian.md
  • 图谱渲染D3.js v7 从 CDN 加载(https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js),不用本地打包
  • 构建esbuild 打包 main.tsmain.jsnpx esbuild main.ts --bundle --outfile=main.js
  • Obsidian 开启「第三方插件」后,插件文件夹挂载到 ~/.obsidian/plugins/zhiyi-memory/

CORS 适配Go 服务改动)

// api/middleware/cors.go — 新增
func CORS() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Header("Access-Control-Allow-Origin", "app://obsidian.md")
        c.Header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        c.Header("Access-Control-Allow-Headers", "X-API-Key, Content-Type")
        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }
        c.Next()
    }
}
// server.go — 注册 middleware
server.Use(apiMiddleware.CORS())

文件结构

plugins/obsidian/
├── manifest.json          # Obsidian 插件清单
├── styles.css             # 插件样式
├── main.ts                # 插件入口,注册侧栏、图谱视图、搜索模态框
├── src/
│   ├── api.ts             # 调用 Go APIfetch 封装baseURL = http://localhost:7821
│   ├── MemoryView.ts       # 记忆侧边栏面板
│   ├── GraphView.ts       # D3 图谱渲染
│   └── SearchModal.ts     # 搜索弹窗
├── esbuild.config.mjs     # 构建配置
└── README.md

验收标准

  • Obsidian 加载插件后,左侧出现「织忆」侧边栏
  • 侧边栏显示最近 20 条记忆namespace=default点击展开内容
  • 图谱视图能渲染至少 3 层邻居节点,节点可拖拽
  • 搜索模态框输入关键词返回结果(<500ms
  • 蒸馏队列非空时侧边栏顶部出现红色提示

E5.2:增强 CLI第二优先级

目标功能

  • E5.2.1 zhiyi tree 命令:树形展示 namespace 下记忆结构,按 category 分组,每条记忆显示前 60 字符摘要
  • E5.2.2 zhiyi graph 命令ASCII art 渲染 ego-network 图谱(中心节点 + 一跳邻居 + 关系标签)
  • E5.2.3 zhiyi recall <query> 命令:语义搜索,返回 top-10 结果,显示 relevance score 和摘要
  • E5.2.4 zhiyi stats 命令显示记忆总数、namespace 分布、今日新增、蒸馏队列状态
  • E5.2.5 zhiyi entity <name> 命令:查询实体详情(出现次数、关联实体列表、记忆片段)

技术方案

  • CLI 命令入口:~/projects/memoryweave/go/cmd/zhiyi-cli/
  • 使用 cobra 或原生 flag 解析子命令
  • 图谱 ASCII 渲染:用 Unicode box-drawing 字符(┌─┬┐│├┼┤└┴┘),中心节点用 ,邻居用
  • 调用现有 Go API 端点,不直接操作存储

文件结构

go/cmd/zhiyi-cli/
├── main.go
├── cmd/
│   ├── root.go
│   ├── tree.go
│   ├── graph.go
│   ├── recall.go
│   ├── stats.go
│   └── entity.go
└── output/
    ├── ascii_graph.go     # ASCII 图谱渲染
    └── formatter.go       # 格式化输出

验收标准

  • zhiyi tree 输出格式正确(树形、分组、摘要)
  • zhiyi graph <entity> 渲染 ASCII 图谱,实体数 ≥ 5 时换行正确
  • zhiyi recall 输出 relevance score 排序正确
  • zhiyi stats 显示记忆数、namespace 分布、蒸馏配额used/limit

E5.3Web UI第三优先级

目标功能

  • E5.3.1 React 项目骨架Vite + React + TypeScript路由 /memories /graph /search /distill
  • E5.3.2 记忆列表页:分页表格(每页 20 条id / content_preview / category / created_at / namespace支持点击展开完整内容
  • E5.3.3 图谱探索页:全屏 D3.js force-directed graph支持缩放/拖拽/筛选category / namespace点击节点弹出详情 drawer
  • E5.3.4 语义搜索页:输入框 + 实时结果debounce 300ms显示 relevance 和摘要,高亮匹配片段
  • E5.3.5 蒸馏监控页:进度条显示 daily used / limit队列列表episode_id / category / content_preview
  • E5.3.6 响应式布局,支持 1280px+ 宽屏

技术方案

  • 项目目录:~/projects/memoryweave/web-ui/
  • 技术栈Vite + React 18 + TypeScript + TailwindCSS + D3.js v7
  • API 层Axios 调用 Go API响应式状态用 React Query 管理缓存
  • 图谱:与 E5.1 共用 /api/v1/graph/navigate 和邻居接口,数据结构一致
  • 部署Go 服务新增静态文件中间件(/static/*web-ui/dist/make build-web 构建后自动同步

文件结构

web-ui/
├── index.html
├── package.json
├── vite.config.ts
├── tailwind.config.js
├── src/
│   ├── main.tsx
│   ├── App.tsx
│   ├── api/
│   │   └── zhiyi.ts         # API 客户端封装
│   ├── pages/
│   │   ├── MemoriesPage.tsx
│   │   ├── GraphPage.tsx
│   │   ├── SearchPage.tsx
│   │   └── DistillPage.tsx
│   └── components/
│       ├── GraphCanvas.tsx   # D3 图谱组件
│       ├── MemoryTable.tsx
│       └── DistillStatus.tsx
└── dist/                     # 构建输出,由 Go 静态中间件托管

Go 服务静态文件中间件

// api/middleware/static.go — 新增
func StaticFile(root string) gin.HandlerFunc {
    fs := http.FileServer(http.Dir(root))
    return func(c *gin.Context) {
        if _, err := os.Stat(filepath.Join(root, c.Request.URL.Path)); err == nil {
            fs.ServeHTTP(c.Writer, c.Request)
            c.Abort()
        } else {
            c.Next()
        }
    }
}
// server.go — 注册
if opt.Mode == "dev" {
    server.Use(apiMiddleware.StaticFile("../web-ui/dist"))
}

验收标准

  • Web UI 能加载并显示记忆列表(分页正常)
  • 图谱页渲染实体节点 ≥ 10 个,缩放拖拽流畅
  • 搜索页输入关键词后 1 秒内显示结果,高亮匹配文字
  • 蒸馏监控页显示正确的 used/limit 进度条
  • 各页面在 1920×1080 和 1366×768 下布局正常

E5 总体依赖关系

E5.1 (Obsidian 插件)
  └── Go API 需添加 CORS 中间件
  └── 构建系统需新增 esbuild 步骤

E5.2 (增强 CLI)
  └── 复用 E5.1 的 CORS 无关紧要
  └── 直接调用 Go API无需其他依赖

E5.3 (Web UI)
  └── 复用 E5.1 的 CORS 中间件
  └── Go 服务新增静态文件中间件
  └── 需要独立的 Vite 构建流程

实施顺序

第一波E5.1 Obsidian 插件)

  1. 添加 Go CORS 中间件,构建部署
  2. 创建 plugins/obsidian/ 目录结构
  3. 实现 ZhiYiPlugin 骨架,注册侧边栏
  4. 实现 MemoryView记忆列表
  5. 实现 GraphViewD3 图谱)
  6. 实现 SearchModal搜索
  7. 本地测试Obsidian 加载插件,验证全部功能
  8. 提交WORKLOG 同步

第二波E5.2 增强 CLI

  1. 创建 go/cmd/zhiyi-cli/ 项目结构
  2. 实现 tree / graph / recall / stats / entity 命令
  3. 本地测试所有子命令
  4. 提交WORKLOG 同步

第三波E5.3 Web UI

  1. 初始化 Vite + React + TypeScript 项目
  2. 实现 MemoriesPage
  3. 实现 GraphPage基于 E5.1 相同的 D3 数据源)
  4. 实现 SearchPage
  5. 实现 DistillPage
  6. Go 服务添加静态文件中间件
  7. make build-web 集成到 Makefile
  8. 完整测试,提交

附录外部调研GitHub 开源参考)

方向 参考项目 关键技术
Obsidian 插件 obsidianmd/obsidian-sample-plugin manifest.json, Plugin class, CustomView
图谱可视化 react-force-graph (底层 D3) force-directed layout, zoom/pan
Web UI 图谱 vis-network / react-vis alternative to raw D3
CLI 图谱 dogmapMastodon ASCII 工具) box-drawing 字符布局


阶段推进规则

  1. 必须按顺序完成E1 → E2 → E3 → E4 → E5
  2. 每个阶段必须测试验证后才能进入下一阶段
  3. 禁止跳过测试验证步骤
  4. 禁止偷懒:实施步骤必须逐条执行
  5. 禁止随意更改变动设计语言:阶段目标和验收标准锁定
  6. 如有阻塞,记录到 BLOCKED 章节,继续下一个阶段

BLOCKED阻塞记录

时间 阶段 阻塞原因 尝试方案
- - 无阻塞 -

进度追踪

阶段 开始时间 完成时间 状态
E1 图谱导航激活 2026-05-30 2026-05-30
E2 多 agent 命名空间 2026-05-30 2026-05-30
E3 增量 embedding 2026-05-30 2026-05-30
E4 图谱推理 2026-05-31 2026-05-31 E4.1/E4.2/E4.3 已实现E4.3 调用方已接入extractTopEntityDegree
E5 产品 UI 2026-06-02 - 🔨

最后更新2026-06-02E5 规划完成)