fix(consolidate): 按目标分组批量LLM决策,消除O(n²)调用风暴

原实现每对高相似记忆调一次LLM → limit=100产生4950对 → 223s+未完成
→ 每天processed=0(非namespace过滤bug)。改为: 外层目标i,内层收集
全部高相似候选,每目标一次LLM(UpdatePrompt原生支持多候选)。

验证: limit=20 → 4.3s返回 processed=1 updated=1; limit=100 2min(受
llama单slot排队限制)对每日低频可用。
This commit is contained in:
小唯 2026-09-06 00:32:27 +08:00
parent 0881b9c05f
commit 4c62074a61
1 changed files with 39 additions and 25 deletions

View File

@ -864,40 +864,54 @@ func NewServer() http.Handler {
ignored := 0
errors_ := 0
// 按目标分组整合:外层 i 为目标,内层收集所有高相似候选,
// 每个目标只调一次 LLMUpdatePrompt 原生支持多候选),避免 O(n²) LLM 调用风暴。
// 2026-09-06 fix(t_04 ④): 原实现每对相似记忆调一次 LLM → limit=100 产生 4950 对
// → 跑 223s+ 未完成 → 每天 processed=0不是 namespace 过滤 bug
for i := 0; i < len(mems); i++ {
// 收集所有与 mems[i] 高相似的候选j > i 且未处理)
var cands []distill.MemoryCandidate
for j := i + 1; j < len(mems); j++ {
if mems[j].Content == "" {
continue
}
sim := distill.TextSimilarity(mems[i].Content, mems[j].Content)
if sim < 0.5 {
continue
}
// 高相似 → LLM 决策(以 j 为目标i 为候选)
result, err := routes.DistillEngineRef.ConsolidateMemory(
distill.MemoryCandidate{ID: mems[j].ID, Content: mems[j].Content},
[]distill.MemoryCandidate{{ID: mems[i].ID, Content: mems[i].Content}},
)
if err != nil {
errors_++
continue
}
processed++
switch result.Action {
case "update":
if result.NewMemory != "" {
if err := ldb.UpdateMemoryContent(mems[j].ID, result.NewMemory, "consolidate"); err != nil {
log.Printf("[consolidate] update failed %s: %v", mems[j].ID, err)
} else {
updated++
}
}
case "delete":
if err := ldb.SoftDelete(mems[j].ID, "consolidate: conflict"); err != nil {
log.Printf("[consolidate] delete failed %s: %v", mems[j].ID, err)
cands = append(cands, distill.MemoryCandidate{ID: mems[j].ID, Content: mems[j].Content})
}
if len(cands) == 0 {
continue
}
// 一次 LLM 决策:目标 mems[i] + 全部高相似候选
result, err := routes.DistillEngineRef.ConsolidateMemory(
distill.MemoryCandidate{ID: mems[i].ID, Content: mems[i].Content},
cands,
)
if err != nil {
errors_++
continue
}
processed++
switch result.Action {
case "update":
if result.NewMemory != "" {
if err := ldb.UpdateMemoryContent(mems[i].ID, result.NewMemory, "consolidate"); err != nil {
log.Printf("[consolidate] update failed %s: %v", mems[i].ID, err)
} else {
deleted++
updated++
}
default:
ignored++
}
case "delete":
if err := ldb.SoftDelete(mems[i].ID, "consolidate: conflict"); err != nil {
log.Printf("[consolidate] delete failed %s: %v", mems[i].ID, err)
} else {
deleted++
}
default:
ignored++
}
}