105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
// 织忆 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)
|
||
}
|