Memory Quality Metrics 提供多维度的记忆质量评估系统,帮助识别和改进低质量记忆,确保 Agent 的记忆系统可靠性。
package main
import (
"context"
"github.com/astercloud/aster/pkg/memory"
)
func main() {
// 创建质量评估系统
config := memory.DefaultQualityMetricsConfig()
qm := memory.NewQualityMetrics(config)
// 评估记忆质量
memoryWithScore := &memory.MemoryWithScore{
DocID: "mem-123",
Text: "User prefers dark mode interface",
Provenance: memory.NewProvenance(memory.SourceUserInput, "user-1"),
Score: 0.85,
}
quality, err := qm.Evaluate(context.Background(), "mem-123", memoryWithScore)
if err != nil {
panic(err)
}
// 查看质量分数
fmt.Printf("准确性: %.2f\n", quality.Score.Accuracy)
fmt.Printf("完整性: %.2f\n", quality.Score.Completeness)
fmt.Printf("一致性: %.2f\n", quality.Score.Consistency)
fmt.Printf("时效性: %.2f\n", quality.Score.Timeliness)
fmt.Printf("相关性: %.2f\n", quality.Score.Relevance)
fmt.Printf("综合得分: %.2f\n", quality.Score.Overall)
}
// 创建分析器
qa := memory.NewQualityAnalyzer(qm, semanticMemory)
// 检测不一致性
inconsistencies, _ := qa.DetectInconsistencies(ctx, memories)
for _, inc := range inconsistencies {
fmt.Printf("[%s] %s (严重程度: %.2f)\n",
inc.Type, inc.Description, inc.Severity)
}
// 生成质量报告
report, _ := qa.GenerateReport(ctx, memories)
fmt.Printf("平均质量: %.2f\n", report.Stats.AverageQuality)
fmt.Printf("低质量记忆数: %d\n", report.Stats.LowQualityCount)
// 获取改进建议
improvements, _ := qa.SuggestImprovements(ctx)
for _, imp := range improvements {
fmt.Printf("记忆 %s 需要改进:\n", imp.MemoryID)
for _, suggestion := range imp.Suggestions {
fmt.Printf(" - %s\n", suggestion)
}
}
基于 Memory Provenance 的置信度评分:
基于内容长度和元数据完整度:
基于佐证数量和内部一致性:
基于记忆年龄的时间衰减:
MaxAge: 最大有效期(默认 90 天)TimelinessDecay: 每天衰减率(默认 1%)score = exp(-decay * days)直接使用检索时的相似度分数 (0.0-1.0)
Overall = Accuracy * 0.3 +
Completeness * 0.2 +
Consistency * 0.2 +
Timeliness * 0.15 +
Relevance * 0.15
可通过配置调整各维度权重。
// 1. 矛盾 (Contradiction)
memories := []memory.MemoryWithScore{
{Text: "User is online"},
{Text: "User is not online"}, // 矛盾!
}
// 2. 重复 (Duplicate)
memories := []memory.MemoryWithScore{
{Text: "User logged in successfully"},
{Text: "User logged in successfully"}, // 重复!
}
// 3. 过时 (Outdated)
// 超过 180 天自动检测
// 4. 低置信度 (Low Confidence)
// 置信度 < 0.4 自动检测
inconsistencies, _ := qa.DetectInconsistencies(ctx, memories)
for _, inc := range inconsistencies {
switch inc.Type {
case memory.InconsistencyContradiction:
// 处理矛盾
case memory.InconsistencyDuplicate:
// 处理重复
case memory.InconsistencyOutdated:
// 处理过时
case memory.InconsistencyLowConfidence:
// 处理低置信度
}
}
// 获取所有质量信息
qualities := make(map[string]*memory.MemoryQuality)
for _, q := range qm.GetAll() {
qualities[q.MemoryID] = q
}
// 按质量重新排序检索结果
ranked := memory.RankByQuality(memories, qualities)
// 综合得分 = 质量分数 * 0.7 + 检索分数 * 0.3
// 只保留高质量记忆(>= 0.7)
highQuality := memory.FilterByQuality(memories, qualities, 0.7)
report, _ := qa.GenerateReport(ctx, memories)
// 统计信息
fmt.Printf("总记忆数: %d\n", report.Stats.TotalMemories)
fmt.Printf("平均质量: %.2f\n", report.Stats.AverageQuality)
fmt.Printf("高质量: %d, 中等: %d, 低质量: %d\n",
report.Stats.HighQualityCount,
report.Stats.MediumQualityCount,
report.Stats.LowQualityCount)
// 维度分布
for dim, score := range report.DimensionScores {
fmt.Printf("%s: %.2f\n", dim, score)
}
// TOP 问题
for _, issue := range report.TopIssues {
fmt.Println(issue)
}
// 改进建议
for _, rec := range report.Recommendations {
fmt.Println(rec)
}
config := memory.QualityMetricsConfig{
// 维度权重(总和应为 1.0)
AccuracyWeight: 0.3,
CompletenessWeight: 0.2,
ConsistencyWeight: 0.2,
TimelinessWeight: 0.15,
RelevanceWeight: 0.15,
// 时效性配置
MaxAge: 90 * 24 * time.Hour, // 90 天
TimelinessDecay: 0.01, // 1% 每天
// 质量阈值
MinQualityThreshold: 0.3, // 低于此值为低质量
WarningThreshold: 0.5, // 低于此值发出警告
// 自动清理
EnableAutoCleanup: true,
AutoCleanupInterval: 24 * time.Hour,
}
// 手动创建质量分数
quality := &memory.MemoryQuality{
MemoryID: "custom-123",
Score: memory.QualityScore{
Accuracy: 0.9,
Completeness: 0.8,
Consistency: 0.7,
Timeliness: 1.0,
Relevance: 0.85,
Overall: 0.85,
},
UpdatedAt: time.Now(),
}
// 获取统计信息随时间变化
stats1 := qm.GetStats()
// ... 一段时间后 ...
stats2 := qm.GetStats()
qualityChange := stats2.AverageQuality - stats1.AverageQuality
fmt.Printf("质量变化: %+.2f\n", qualityChange)
for _, mem := range memories {
_, _ = qm.Evaluate(ctx, mem.DocID, &mem)
}
// 获取低质量记忆
lowQuality := qm.GetLowQuality()
fmt.Printf("发现 %d 个低质量记忆\n", len(lowQuality))
// 后台定期评估新记忆
ticker := time.NewTicker(1 * time.Hour)
go func() {
for range ticker.C {
// 获取最近添加的记忆
recent := semanticMemory.RetrieveRecent(ctx, 100)
// 评估质量
for _, mem := range recent {
_, _ = qm.Evaluate(ctx, mem.DocID, &mem)
}
}
}()
// 只存储高质量记忆
quality, _ := qm.Evaluate(ctx, memID, memory)
if quality.Score.Overall >= 0.7 {
semanticMemory.Store(ctx, memory)
} else {
log.Printf("拒绝低质量记忆: %.2f", quality.Score.Overall)
}
inconsistencies, _ := qa.DetectInconsistencies(ctx, memories)
for _, inc := range inconsistencies {
if inc.Type == memory.InconsistencyContradiction && inc.Severity > 0.8 {
// 严重矛盾,发送警报
alertSystem.Send("检测到严重矛盾", inc.Description)
}
if inc.Type == memory.InconsistencyDuplicate {
// 自动删除重复记忆
semanticMemory.Delete(ctx, inc.MemoryID2)
}
}
improvements, _ := qa.SuggestImprovements(ctx)
for _, imp := range improvements {
// 获取原始记忆
mem, _ := semanticMemory.Retrieve(ctx, imp.MemoryID)
// 根据建议改进
for _, suggestion := range imp.Suggestions {
if strings.Contains(suggestion, "佐证") {
// 寻找支持性证据
corroboration := findCorroboration(mem)
mem.Provenance.AddCorroboration(corroboration)
}
}
// 重新评估
qm.Evaluate(ctx, imp.MemoryID, mem)
}
运行质量评估测试:
go test ./pkg/memory/... -run Quality -v