memoryweave/docs/p0-fallback-plan.md

2.2 KiB
Raw Permalink Blame History

P0: Recall 降级策略 — 织忆 Go daemon

目标

当 bge-embed (8000) 或 Rust IPC sidecar 不可用时recall 自动降级到 graph.db 关键词搜索,不返回 500 错误。

修改文件

1. /tmp/memoryweave/go/internal/governance/graph_sqlite.go

新增方法 FallbackTextSearch(query, namespace, limit)

func (gs *SQLiteGraphStore) FallbackTextSearch(query, namespace string, limit int) []map[string]interface{} {
    // 1. 从 edge properties 中搜索 content 字段JSON 内 text 字段)
    // 2. LIKE '%query%' 模糊匹配 nodes 的 name
    // 3. 按 pagerank DESC 排序
    // 4. LIMIT limit
}

sqlite-go 通过 CGo 操作,参考已有 queryRows 函数(行 1037。 类似 SearchNodes行 865的模式但搜索 edges 的 properties 字段。

2. /tmp/memoryweave/go/internal/storage/recall.go

RecallPipeline 结构体新增 GraphStore 字段:

type GraphExpander interface {
    // ... existing methods
}

不用改 interface。在 Recall 方法末尾(当前行 149 return nil 之前),如果 candidates 为空且 lanceDB 搜索失败,尝试从 GraphStore 的 FallbackTextSearch 获取结果。

3. /tmp/memoryweave/go/internal/api/routes/core.go

Recall handler行 209-293a.Pipeline.Recall() 返回 err 时(行 240不直接 500而是调用 graph store 的 fallback 搜索:

if err != nil {
    // Fallback: graph.db keyword search
    fallbackResults := a.GraphStore.FallbackTextSearch(req.Query, req.Namespace, req.Limit)
    if len(fallbackResults) > 0 {
        // Convert fallback results to RecallResult format
        results = convertFallbackResults(fallbackResults)
        // return with 200 + warning header
    } else {
        respondError(w, 500, "recall failed: "+err.Error())
        return
    }
}

验证方法

# 正常状态能搜到
curl -s -X POST -H "X-API-Key: zhiyi-dev-key-2026" \
  -d '{"query":"小唯","top_k":3}' \
  http://localhost:7821/api/v1/recall | python -c "import json,sys;d=json.load(sys.stdin);print(f'count: {d.get(\"count\",0)}')"

# 模拟 bge-embed 挂了
# curl 应该仍返回结果(从 graph.db 关键词搜索)