记忆

Memory Provenance

记忆溯源系统 - 追踪每条记忆的来源、置信度和演变历史

Memory Provenance(记忆溯源)

概述

Memory Provenance 是 aster 的核心功能,用于追踪每条记忆的来源、置信度和演变历史。这对于构建可信赖的 AI 系统至关重要,使得系统能够:

  • 追踪记忆的数据来源
  • 评估记忆的可信度
  • 管理记忆的生命周期(包括遗忘)
  • 处理多源数据的冲突

核心组件

1. MemoryProvenance(记忆溯源信息)

每条记忆都包含完整的溯源信息:

type MemoryProvenance struct {
    SourceType         SourceType  // 数据来源类型
    Confidence         float64     // 置信度(0.0-1.0)
    Sources            []string    // 来源标识列表
    CreatedAt          time.Time   // 创建时间
    UpdatedAt          time.Time   // 最后更新时间
    Version            int         // 版本号
    IsExplicit         bool        // 是否为显式记忆
    CorroborationCount int         // 验证次数
    LastAccessedAt     *time.Time  // 最后访问时间
    Tags               []string    // 标签
}

2. 数据来源类型(SourceType)

const (
    SourceBootstrapped  // 系统预加载(如 CRM),最高信任度
    SourceUserInput     // 用户输入(显式/隐式)
    SourceAgent         // 其他代理的输出
    SourceToolOutput    // 工具执行结果,最不稳定
)

3. 置信度计算器(ConfidenceCalculator)

自动计算和更新记忆的置信度,综合考虑:

  • 时间衰减:使用指数衰减模型(半衰期默认 30 天)
  • 多源验证:每次验证提升 5% 置信度(最多 20%)
  • 访问记录:最近访问的记忆获得额外权重
  • 来源类型:不同来源有不同的基础置信度
cfg := DefaultConfidenceConfig()
// DecayHalfLife: 30天
// MinConfidence: 0.20(低于此值将被剪枝)
// CorroborationBoost: 每次验证 +5%
// MaxCorroborationBoost: 最多 +20%

calc := NewConfidenceCalculator(cfg)
confidence := calc.Calculate(provenance)

4. 谱系管理器(LineageManager)

追踪记忆之间的派生关系,支持:

  • 级联删除(删除记忆时同时删除其派生记忆)
  • 数据源撤销(撤销特定数据源的所有记忆)
  • 谱系分析(计算记忆深度和统计信息)
lm := NewLineageManager()

// 追踪记忆创建
lm.TrackMemoryCreation("mem-1", provenance, nil)

// 追踪派生关系
lm.TrackMemoryCreation("mem-2", provenance, []string{"mem-1"})

// 级联删除
deletedIDs, _ := lm.DeleteMemoryWithLineage(ctx, "mem-1", true)

// 撤销数据源
deletedIDs, _ := lm.RevokeDataSource(ctx, "session-123")

使用示例

基础用法

// 1. 创建 Semantic Memory 并启用 Provenance
sm := memory.NewSemanticMemory(memory.SemanticMemoryConfig{
    Store:               vectorStore,
    Embedder:            embedder,
    EnableProvenance:    true,  // 启用溯源
    DefaultSourceType:   memory.SourceUserInput,
})

// 2. 索引记忆(自动创建 Provenance)
err := sm.Index(ctx, "doc-1", "用户喜欢窗口座位", map[string]interface{}{
    "user_id":     "user-123",
    "source_id":   "session-456",
    "is_explicit": true,  // 显式记忆
})

// 3. 检索记忆(自动按置信度过滤和排序)
hits, err := sm.SearchWithConfidenceFilter(ctx, "座位偏好", map[string]interface{}{
    "user_id": "user-123",
}, 5, 0.5)  // 最低置信度 0.5

// 4. 按来源类型检索
hits, err := sm.SearchBySourceType(ctx, "用户偏好", meta, 5, []memory.SourceType{
    memory.SourceBootstrapped,
    memory.SourceUserInput,
})

高级用法:手动管理 Provenance

// 1. 创建显式 Provenance
provenance := memory.NewExplicitProvenance(
    memory.SourceUserInput,
    "session-789",
)

// 2. 添加标签
provenance.Tags = []string{"preferences", "important"}

// 3. 索引时指定 Provenance 和派生关系
err := sm.IndexWithProvenance(ctx, "doc-2", "综合偏好:窗口+靠前",
    map[string]interface{}{"user_id": "user-123"},
    provenance,
    []string{"doc-1"},  // 派生自 doc-1
)

// 4. 验证记忆(多源确认)
provenance.Corroborate("session-790")
sm.IndexWithProvenance(ctx, "doc-1", text, meta, provenance, nil)

// 5. 获取记忆的溯源信息
memProv, err := sm.GetMemoryProvenance(ctx, "座位偏好", meta)
fmt.Printf("置信度: %.2f, 来源数: %d\n",
    memProv.Confidence,
    len(memProv.Sources))

置信度管理

calc := memory.NewConfidenceCalculator(memory.ConfidenceConfig{
    DecayHalfLife:          30 * 24 * time.Hour,
    MinConfidence:          0.20,
    CorroborationBoost:     0.05,
    MaxCorroborationBoost:  0.20,
    RecencyWeight:          0.3,
})

// 更新置信度
calc.UpdateConfidence(provenance)

// 判断是否应该剪枝
if calc.ShouldPrune(provenance) {
    sm.DeleteMemoryWithLineage(ctx, "doc-1", false)
}

// 获取置信度分级
tier := memory.GetConfidenceTier(provenance.Confidence)
// TierVeryHigh (>0.9)
// TierHigh (0.7-0.9)
// TierMedium (0.5-0.7)
// TierLow (0.3-0.5)
// TierVeryLow (<0.3)

谱系管理

lm := memory.NewLineageManager()

// 追踪记忆创建和派生关系
lm.TrackMemoryCreation("summary-1", provenance, []string{"conv-1", "conv-2"})

// 获取派生记忆(递归)
derivedIDs := lm.graph.GetDerivedMemories("conv-1")

// 获取父记忆(递归)
parentIDs := lm.graph.GetParentMemories("summary-1")

// 获取特定数据源的所有记忆
memIDs := lm.graph.GetMemoriesBySource("session-123")

// 撤销数据源(级联删除)
deletedIDs, _ := lm.RevokeDataSource(ctx, "session-123")

// 获取谱系统计
stats := lm.GetLineageStats()
fmt.Printf("总记忆数: %d, 根记忆: %d, 最大深度: %d\n",
    stats.TotalMemories,
    stats.RootMemories,
    stats.MaxDepth)

最佳实践

1. 选择合适的数据来源类型

  • SourceBootstrapped: 用于从可信系统(如 CRM)预加载的数据
  • SourceUserInput: 用于用户输入,区分显式(is_explicit: true)和隐式
  • SourceAgent: 用于代理生成的推断
  • SourceToolOutput: 用于工具执行结果,建议短期缓存而非长期记忆

2. 配置置信度衰减策略

// 针对不同应用场景调整配置
cfg := memory.ConfidenceConfig{
    DecayHalfLife: 60 * 24 * time.Hour,  // 长期记忆:60天半衰期
    MinConfidence: 0.30,                  // 提高剪枝阈值
}

3. 定期清理低置信度记忆

// 在后台任务中定期执行
func pruneOldMemories(sm *memory.SemanticMemory) {
    // TODO: 需要扩展 VectorStore 接口支持列举所有文档
    // deletedIDs, _ := sm.PruneMemories(ctx, namespace)
}

4. 追踪关键记忆的谱系

// 对于重要的合并记忆,明确追踪其来源
provenance := memory.NewProvenance(memory.SourceAgent, "consolidator-v1")
provenance.Tags = []string{"consolidated", "user-preferences"}

sm.IndexWithProvenance(ctx, "user-profile", profileText, meta,
    provenance,
    sourceMemberIDs)  // 明确标记派生自哪些记忆

与 Google 白皮书的对齐

本实现完全对齐 Google "Context Engineering: Sessions, Memory" 白皮书的要求:

白皮书要求aster 实现状态
Memory Provenance✅ MemoryProvenance 结构完整
Source Type Tracking✅ 4种来源类型完整
Confidence Scoring✅ ConfidenceCalculator完整
Time Decay✅ 指数衰减模型完整
Corroboration✅ Corroborate() 方法完整
Lineage Tracking✅ LineageManager完整
Cascade Deletion✅ DeleteMemoryWithLineage()完整
Data Source Revocation✅ RevokeDataSource()完整

测试

运行完整的测试套件:

go test ./pkg/memory/... -v

测试覆盖:

  • ✅ Provenance 创建和元数据转换
  • ✅ 置信度计算和时间衰减
  • ✅ 多源验证和置信度提升
  • ✅ 谱系追踪和级联删除
  • ✅ 数据源撤销
  • ✅ 记忆剪枝逻辑

参考资料

  • Google "Context Engineering: Sessions, Memory" 白皮书
  • pkg/memory/provenance.go - 核心数据结构
  • pkg/memory/confidence.go - 置信度计算
  • pkg/memory/lineage.go - 谱系管理
  • pkg/memory/semantic.go - Semantic Memory 集成