memoryweave/go/internal/selfoptimize/quality_monitor.go

105 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 织忆 MemoryWeave — 质量下降自动动作
// quality_score < 0.3 → 自动降权 → 7天未改善 → deprecated → tombstones
package selfoptimize
import (
"sync"
"time"
)
// QualityDropMonitor 质量下降监控器
type QualityDropMonitor struct {
mu sync.Mutex
// memoryID → 质量下降记录
dropped map[string]*DropRecord
// 阈值
lowThreshold float64 // < 0.3 → 触发
minFeedbacks int // ≥ 2 次反馈 → 有效(降低阈值从 5→2
deprecationDays int // 7 天未改善 → deprecated
}
type DropRecord struct {
MemoryID string `json:"memory_id"`
Score float64 `json:"score"`
NotifiedAt time.Time `json:"notified_at"`
DaysSinceDrop int `json:"days_since_drop"`
Status string `json:"status"` // notified / deprecating / deprecated
}
var QualityMonitor = &QualityDropMonitor{
dropped: make(map[string]*DropRecord),
lowThreshold: 0.3,
minFeedbacks: 2,
deprecationDays: 7,
}
// Check 检查质量分数
// 返回: 是否需要通知
func (qm *QualityDropMonitor) Check(memoryID string, score float64, feedbackCount int) *DropRecord {
qm.mu.Lock()
defer qm.mu.Unlock()
// 不满足阈值 → 清除记录
if score >= qm.lowThreshold || feedbackCount < qm.minFeedbacks {
delete(qm.dropped, memoryID)
return nil
}
record, exists := qm.dropped[memoryID]
if !exists {
record = &DropRecord{
MemoryID: memoryID,
Score: score,
NotifiedAt: time.Now(),
Status: "notified",
}
qm.dropped[memoryID] = record
return record
}
// 更新分数
record.Score = score
record.DaysSinceDrop = int(time.Since(record.NotifiedAt).Hours() / 24)
// 7 天未改善 → 标记 deprecated
if record.DaysSinceDrop >= qm.deprecationDays {
record.Status = "deprecating"
}
return record
}
// MarkDeprecated 标记为已淘汰
func (qm *QualityDropMonitor) MarkDeprecated(memoryID string) {
qm.mu.Lock()
defer qm.mu.Unlock()
if record, ok := qm.dropped[memoryID]; ok {
record.Status = "deprecated"
}
}
// GetDeprecating 获取待淘汰列表(用于批量淘汰)
func (qm *QualityDropMonitor) GetDeprecating() []*DropRecord {
qm.mu.Lock()
defer qm.mu.Unlock()
var list []*DropRecord
for id, record := range qm.dropped {
if record.Status == "deprecating" {
list = append(list, record)
_ = id
}
}
return list
}
// ActiveAlerts 活跃告警数
func (qm *QualityDropMonitor) ActiveAlerts() int {
qm.mu.Lock()
defer qm.mu.Unlock()
return len(qm.dropped)
}