feat(memory): P1 长期记忆升级 —— 异步攒批 Consolidate + 软删 + importance/last_seen #1
@@ -48,9 +48,18 @@ func buildMessages(ctx context.Context, rc *RunCtx) ([]*schema.Message, error) {
|
||||
sys.WriteString("\n\n以下是前序协作 agent 的产出,请在此基础上继续完成你的部分(不要重头再来):\n")
|
||||
sys.WriteString(strings.Join(rc.Upstream, "\n---\n"))
|
||||
}
|
||||
// 防御:剔除空 content 的历史消息。OpenAI 兼容 API 拒绝「content 与 tool_calls 都为空」的
|
||||
// assistant 消息(400 Invalid assistant message),一条脏历史会毒化整段会话的后续请求。
|
||||
history := make([]*schema.Message, 0, len(rc.History))
|
||||
for _, m := range rc.History {
|
||||
if m == nil || (strings.TrimSpace(m.Content) == "" && len(m.ToolCalls) == 0) {
|
||||
continue
|
||||
}
|
||||
history = append(history, m)
|
||||
}
|
||||
return chatTemplate.Format(ctx, map[string]any{
|
||||
"system": sys.String(),
|
||||
"history": rc.History,
|
||||
"history": history,
|
||||
"query": rc.Query,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -270,6 +271,11 @@ const consolidateEveryTurns = 3
|
||||
|
||||
// memorize 写回阶段(异步、离热路径):落短期历史;每 N 轮做一次记忆对账(consolidate)。
|
||||
func (o *Orchestrator) memorize(t *contract.Task, answer string) {
|
||||
// 空答复(LLM 失败/降级/拒绝)不落历史:空 assistant 消息会被 LLM API 拒绝(400),
|
||||
// 一旦写入会毒化该会话后续所有请求。失败的一轮干脆不留痕。
|
||||
if strings.TrimSpace(answer) == "" {
|
||||
return
|
||||
}
|
||||
uid, _ := t.Meta[contract.MetaUserID].(string)
|
||||
sid, _ := t.Meta[contract.MetaSessionID].(string)
|
||||
if sid != "" && o.tools != nil {
|
||||
|
||||
Reference in New Issue
Block a user