docs: add implementation plans for P0/P1/P2 features
This commit is contained in:
parent
5e24646600
commit
f4313a40ef
|
|
@ -0,0 +1,61 @@
|
|||
# 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)`:
|
||||
|
||||
```go
|
||||
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` 字段:
|
||||
|
||||
```go
|
||||
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-293)中,当 `a.Pipeline.Recall()` 返回 err 时(行 240),不直接 500,而是调用 graph store 的 fallback 搜索:
|
||||
|
||||
```go
|
||||
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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 验证方法
|
||||
```bash
|
||||
# 正常状态能搜到
|
||||
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 关键词搜索)
|
||||
```
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# P1: 自动注入钩子 — 织忆 Hermes 插件
|
||||
|
||||
## 目标
|
||||
增强 Hermes 织忆插件的 prefetch/queue_prefetch,实现:
|
||||
1. queue_prefetch 缓存下一轮记忆(异步预取)
|
||||
2. 社交关闭检测(skip trivial messages)
|
||||
3. 新增 [织忆] 标记注入格式,与 hermes 原生记忆区分
|
||||
4. 更好的话题重叠检测(避免同一轮注入重复上下文)
|
||||
|
||||
## 修改文件
|
||||
|
||||
### `~/.hermes/hermes-agent/plugins/memory/zhiyi/__init__.py`
|
||||
|
||||
#### 1. 新增社交关闭检测(参考 Memory-OS hooks.py:251-268)
|
||||
```python
|
||||
_SOCIAL_CLOSERS = frozenset({
|
||||
"ok", "好的", "👍", "👌", "✅", "谢谢", "感谢", "知道了",
|
||||
"明白", "嗯", "好", "行", "yes", "yep", "thanks", "thx",
|
||||
"no", "不用", "没事", "可以", "done", "完成",
|
||||
})
|
||||
|
||||
def _is_social_close(text: str) -> bool:
|
||||
text = text.strip().lower()
|
||||
if text in _SOCIAL_CLOSERS:
|
||||
return True
|
||||
if len(text) < 6 and not any(c in text for c in "://.@#$_?"):
|
||||
return True
|
||||
return False
|
||||
```
|
||||
|
||||
#### 2. 实现 queue_prefetch(原为 pass)
|
||||
```python
|
||||
def queue_prefetch(self, query: str, *, session_id: str = "") -> None:
|
||||
"""异步预取:本轮对话结束后立即查询织忆,下一轮 prefetch 直接返回缓存。"""
|
||||
if not self._client or not query or len(query.strip()) < 2:
|
||||
return
|
||||
if _is_social_close(query):
|
||||
return
|
||||
# 后台线程查询并缓存
|
||||
def _async_prefetch():
|
||||
results = self._client.recall(query.strip(), top_k=3)
|
||||
notes = self._client.search_notes(query.strip(), max_hops=2, max_notes=3)
|
||||
with self._prefetch_lock:
|
||||
self._prefetch_cache["queue"] = {
|
||||
"results": results,
|
||||
"notes": notes,
|
||||
"timestamp": time.time()
|
||||
}
|
||||
threading.Thread(target=_async_prefetch, daemon=True).start()
|
||||
```
|
||||
|
||||
#### 3. 增强 prefetch 方法
|
||||
```python
|
||||
# 在 prefetch 入口处:
|
||||
if _is_social_close(query):
|
||||
return "" # 关闭消息不触发预取
|
||||
|
||||
# 优先从 queue_prefetch 缓存取
|
||||
with self._prefetch_lock:
|
||||
queued = self._prefetch_cache.pop("queue", None)
|
||||
if queued and (time.time() - queued["timestamp"]) < 30:
|
||||
# 用缓存结果
|
||||
pass
|
||||
|
||||
# 输出格式改成带 [织忆] 标记
|
||||
blocks = ["[织忆 Memory — relevant past context]"]
|
||||
for r in results:
|
||||
blocks.append(f" [{score:.2f}][{cat}] {content[:500]}")
|
||||
```
|
||||
|
||||
## 验证方法
|
||||
```bash
|
||||
cd ~/.hermes/hermes-agent && python3 -c "
|
||||
from plugins.memory.zhiyi import HermesZhiYiMemoryProvider
|
||||
p = HermesZhiYiMemoryProvider()
|
||||
# 测试 prefetch
|
||||
result = p.prefetch('织忆记忆系统架构', session_id='test')
|
||||
print('prefetch result:', result[:200] if result else 'empty')
|
||||
# 测试 social closer
|
||||
result2 = p.prefetch('好的', session_id='test')
|
||||
print('social closer prefetch:', repr(result2))
|
||||
"
|
||||
```
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# P2: 信任评分 — 织忆 Go daemon
|
||||
|
||||
## 目标
|
||||
给 graph.db 的 edges 表加信任评分字段,新增反馈 API 端点。
|
||||
|
||||
## 修改文件
|
||||
|
||||
### 1. `/tmp/memoryweave/go/internal/governance/graph_sqlite.go`
|
||||
|
||||
#### a) Upgrade SQL 迁移(在 migrate() 中追加)
|
||||
```sql
|
||||
ALTER TABLE graph_edges ADD COLUMN trust_score REAL DEFAULT 0.5;
|
||||
ALTER TABLE graph_edges ADD COLUMN retrieval_count INTEGER DEFAULT 0;
|
||||
ALTER TABLE graph_edges ADD COLUMN helpful_count INTEGER DEFAULT 0;
|
||||
```
|
||||
注意:ALTER TABLE ADD COLUMN 要先检查列是否存在,用 sqlite3 的 `PRAGMA table_info(graph_edges)` 检查。
|
||||
|
||||
#### b) 新增方法
|
||||
```go
|
||||
// AddEdgeFeedback 记录边反馈
|
||||
func (gs *SQLiteGraphStore) AddEdgeFeedback(edgeID string, helpful bool) error
|
||||
// 实现:UPDATE graph_edges SET helpful_count = helpful_count + 1 WHERE id = ?
|
||||
// 如果不是 helpful: UPDATE graph_edges SET retrieval_count = retrieval_count + 1 WHERE id = ?
|
||||
|
||||
// UpdateEdgeTrustScores 批量更新信任评分(定时或触发)
|
||||
func (gs *SQLiteGraphStore) UpdateEdgeTrustScores() error
|
||||
// 实现:UPDATE graph_edges SET trust_score =
|
||||
// CASE
|
||||
// WHEN retrieval_count > 0 THEN CAST(helpful_count AS REAL) / retrieval_count
|
||||
// ELSE 0.5
|
||||
// END
|
||||
|
||||
// IncrementEdgeRetrieval 递增边的检索计数(在 ExpandFromResults 里调用)
|
||||
func (gs *SQLiteGraphStore) IncrementEdgeRetrieval(edgeID string) error
|
||||
```
|
||||
|
||||
#### c) 在 ExpandFromResults(行 679-733)中,每条被检索的边调用 IncrementEdgeRetrieval
|
||||
|
||||
### 2. `/tmp/memoryweave/go/internal/api/routes/core.go`
|
||||
新增端点:
|
||||
|
||||
```go
|
||||
// POST /api/v1/graph/edge/feedback
|
||||
func (a *API) EdgeFeedback(w http.ResponseWriter, r *http.Request) {
|
||||
// body: { edge_id: string, helpful: bool }
|
||||
// 调用 a.GraphStore.AddEdgeFeedback(edgeID, helpful)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. `/tmp/memoryweave/go/internal/api/server.go`
|
||||
注册新路由:
|
||||
```go
|
||||
mux.HandleFunc("/api/v1/graph/edge/feedback", api.EdgeFeedback)
|
||||
```
|
||||
|
||||
### 4. `/tmp/memoryweave/go/internal/api/routes/core.go`
|
||||
在 Recall handler 中,当结果返回时(行 292),遍历每条结果的 edge ID,递增 retrieval_count。
|
||||
|
||||
## 验证方法
|
||||
```bash
|
||||
# 提交反馈
|
||||
curl -s -X POST -H "X-API-Key: zhiyi-dev-key-2026" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"edge_id":"e_xxx","helpful":true}' \
|
||||
http://localhost:7821/api/v1/graph/edge/feedback
|
||||
|
||||
# 验证 trust_score 更新
|
||||
sqlite3 /var/lib/memoryweave/graph.db "SELECT id, trust_score, retrieval_count, helpful_count FROM graph_edges LIMIT 5"
|
||||
```
|
||||
Loading…
Reference in New Issue