fix(document memory): dedup graph sync, filter terminal output from archive, add min relevance threshold

This commit is contained in:
2026-07-19 14:21:04 +08:00
parent 617a6b0237
commit 908e4d6475
3 changed files with 27 additions and 7 deletions

View File

@ -1532,11 +1532,15 @@ func (a *Agent) executeDocTool(tc agentAPI.ToolCall) string {
parts = append(parts, " 标签: "+strings.Join(d.Tags, ", ")) parts = append(parts, " 标签: "+strings.Join(d.Tags, ", "))
} }
// 每个文档按原始时间写入 context 事件,确保时序正确 // 每个文档按原始时间写入 context 事件,确保时序正确
content := d.Content
if len(content) > 2000 {
content = content[:2000] + "..."
}
a.context.Append(ContextEvent{ a.context.Append(ContextEvent{
Timestamp: d.CreatedAt, Timestamp: d.CreatedAt,
Source: "cold_storage", Source: "cold_storage",
Input: fmt.Sprintf("加载文档记忆: %s", query), Input: fmt.Sprintf("加载文档记忆: %s", query),
Response: d.Content, Response: content,
}) })
refs = append(refs, fmt.Sprintf("#%d(%s)", i+1, d.Summary)) refs = append(refs, fmt.Sprintf("#%d(%s)", i+1, d.Summary))
} }
@ -2306,9 +2310,18 @@ func (a *Agent) syncGraphToDocs() {
} }
} }
summary := fmt.Sprintf("图记忆索引 (%d 实体, %d 关系)", len(result.Entities), len(result.Relations))
content := strings.Join(summaryParts, "\n")
// 去重:如果最近一篇 graph 文档内容相同,跳过
recent := a.docStore.RecentDocs(1)
if len(recent) > 0 && recent[0].Source == "graph" && recent[0].Content == content {
return
}
doc := &document.Doc{ doc := &document.Doc{
Summary: fmt.Sprintf("图记忆索引 (%d 实体, %d 关系)", len(result.Entities), len(result.Relations)), Summary: summary,
Content: strings.Join(summaryParts, "\n"), Content: content,
Tags: []string{"graph_memory", "auto_sync"}, Tags: []string{"graph_memory", "auto_sync"},
Entities: extractEntityNames(result.Entities), Entities: extractEntityNames(result.Entities),
Source: "graph", Source: "graph",

View File

@ -191,8 +191,15 @@ func (c *RelevanceContext) Prune(currentInput string, topK int, docStore *docume
archived := 0 archived := 0
if docStore != nil && len(archive) > 0 { if docStore != nil && len(archive) > 0 {
entries := make([]document.ContextEntry, len(archive)) var filtered []scored
for i, s := range archive { for _, s := range archive {
if s.event.Source == "agentcli" || s.event.Source == "terminal" {
continue
}
filtered = append(filtered, s)
}
entries := make([]document.ContextEntry, len(filtered))
for i, s := range filtered {
entries[i] = document.ContextEntry{ entries[i] = document.ContextEntry{
Timestamp: s.event.Timestamp, Timestamp: s.event.Timestamp,
Source: s.event.Source, Source: s.event.Source,
@ -202,7 +209,7 @@ func (c *RelevanceContext) Prune(currentInput string, topK int, docStore *docume
} }
doc, err := docStore.ContextToDoc("context_archived", entries, c.embedder) doc, err := docStore.ContextToDoc("context_archived", entries, c.embedder)
if err == nil && doc != nil { if err == nil && doc != nil {
archived = len(archive) archived = len(filtered)
} }
} }

View File

@ -84,7 +84,7 @@ func (s *Store) Search(query Vector, topK int) []DocVector {
for _, d := range s.docs { for _, d := range s.docs {
if d.ID == id { if d.ID == id {
score := CosineSimilarity(query, d.Vector) score := CosineSimilarity(query, d.Vector)
if score > 0 { if score > 0.05 {
results = append(results, scored{d, score}) results = append(results, scored{d, score})
} }
break break