feat(memory): P1 长期记忆升级 —— 异步攒批 Consolidate + 软删 + importance/last_seen #1

Merged
Blizzard merged 181 commits from feat/wails3 into main 2026-07-17 01:12:32 +00:00
Showing only changes of commit 835a6d7432 - Show all commits
+16 -2
View File
@@ -134,7 +134,7 @@ func normJudge(v float64) float64 {
func (e *Evaluator) llmJudge(ctx context.Context, input, output string) (float64, string, bool) { func (e *Evaluator) llmJudge(ctx context.Context, input, output string) (float64, string, bool) {
user := fmt.Sprintf("【用户输入】%s\n\n【模型输出】%s\n\n%s\n\n"+ user := fmt.Sprintf("【用户输入】%s\n\n【模型输出】%s\n\n%s\n\n"+
"只输出 JSON{\"score\":1到5整数,\"reason\":\"先点最主要的缺陷(没有就说无明显缺陷)再给结论,一句话\"},不要多余文字。", "只输出 JSON{\"score\":1到5整数,\"reason\":\"先点最主要的缺陷(没有就说无明显缺陷)再给结论,一句话\"},不要多余文字。",
evalTruncate(input, 500), evalTruncate(output, 1500), evalQualityRubric) evalTruncate(input, 500), evalReviewOutput(output), evalQualityRubric)
txt, err := e.chat(ctx, evalQualitySys, user) txt, err := e.chat(ctx, evalQualitySys, user)
if err != nil { if err != nil {
return 0, "", false return 0, "", false
@@ -161,7 +161,7 @@ func (e *Evaluator) llmJudgeGrounded(ctx context.Context, input, output string,
"faithfulness(忠实度):5=每个关键说法都有资料依据;分数随无依据/编造的说法增多而降;只要有一处明显编造,faithfulness 不得高于 2。\n"+ "faithfulness(忠实度):5=每个关键说法都有资料依据;分数随无依据/编造的说法增多而降;只要有一处明显编造,faithfulness 不得高于 2。\n"+
"unsupported:列出回答中未被检索资料支持的具体说法(无则空数组)。\n"+ "unsupported:列出回答中未被检索资料支持的具体说法(无则空数组)。\n"+
"只输出 JSON{\"quality\":1到5整数,\"faithfulness\":1到5整数,\"unsupported\":[\"...\"],\"reason\":\"一句话\"},不要多余文字。", "只输出 JSON{\"quality\":1到5整数,\"faithfulness\":1到5整数,\"unsupported\":[\"...\"],\"reason\":\"一句话\"},不要多余文字。",
evalTruncate(input, 400), src, evalTruncate(output, 1500)) evalTruncate(input, 400), src, evalReviewOutput(output))
txt, err := e.chat(ctx, sys, user) txt, err := e.chat(ctx, sys, user)
if err != nil { if err != nil {
return 0, 0, nil, "", false return 0, 0, nil, "", false
@@ -186,6 +186,20 @@ func evalTruncate(s string, n int) string {
return string(r[:n]) + "…" return string(r[:n]) + "…"
} }
// evalReviewLimit 是喂给 judge 的「模型回答」最长字数。不能太短:报告/多智能体综合等长答案
// 普遍 2000+ 字,截太短会让 judge 误判「回答不完整/截断」(而那是评审自己截的)。
const evalReviewLimit = 6000
// evalReviewOutput 把待评审的模型回答按 evalReviewLimit 截断;若确被截断,明确标注是评审所为,
// 让 judge 不要因结尾不完整而扣分(杜绝长答案被误判 warn/poor 的假阴性)。
func evalReviewOutput(s string) string {
r := []rune(s)
if len(r) <= evalReviewLimit {
return s
}
return string(r[:evalReviewLimit]) + "\n…(注:回答过长,已被评审系统截断,请勿因结尾不完整而扣分)"
}
// evalStripFence 去掉模型可能包裹的 ```json … ``` 围栏。 // evalStripFence 去掉模型可能包裹的 ```json … ``` 围栏。
func evalStripFence(s string) string { func evalStripFence(s string) string {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)