跳转到内容

独立 Memory Agent 模式

独立 Memory Agent 模式

学习目标

本章聚焦 LibreChat 的 Memory Agent 实现。你将了解:

  • Memory Agent 与主对话 Agent 的完全解耦设计
  • set_memory / delete_memory 专用工具的 content_and_artifact 返回格式
  • Token 预算管理与双错误类型设计
  • 不同模型提供商的 Memory Agent 适配

前置知识

下文假设你已理解上述概念,直接聚焦 LibreChat 的具体实现。


项目实践

Memory Agent 与主 Agent 的解耦

LibreChat 的 Memory Agent 拥有完整的独立 Agent 栈:

createMemoryProcessor() → [memory, process(memory, messages)]
processMemory()
Run.create({
runId: messageId,
graphConfig: {
type: 'standard',
llmConfig: { provider: OpenAI, model: 'gpt-4.1-mini', streaming: false },
tools: [memoryTool, deleteMemoryTool],
instructions: memoryInstructions,
additional_instructions: memoryStatus,
toolEnd: true,
},
customHandlers: { TOOL_END: BasicToolEndHandler },
returnContent: true,
})

关键隔离点:

维度主 AgentMemory Agent
Run 实例主 Run独立 Run.create
模型用户选择固定 gpt-4.1-mini(可配置)
流式否(disableStreaming: true
温度用户配置固定 0.4
递归限制默认recursionLimit: 3

content_and_artifact 返回格式

Memory Agent 的工具使用 LangChain 的 content_and_artifact response format:

工具返回: [content: "Memory set for key 'name' (12 tokens)", artifact: {
memory: {
key: 'name',
value: '用户叫张三',
tokenCount: 12,
type: 'update',
}
}]

Artifact 的结构化设计支持三种类型:

type含义前端展示
update成功写入绿色确认卡片
delete成功删除灰色删除标记
error预算溢出红色警告卡片

Token 预算双错误类型

already_exceeded: 预算已完全耗尽,不再接受任何新记忆
would_exceed: 本次写入会导致超限,拒绝本次操作

双错误类型的设计让前端能够区分”完全不能再写”和”这次太大了”——前者需要用户清理记忆,后者可以尝试写更短的内容。

模型适配

Bedrock:Bedrock Converse API 要求对话以用户消息开始。Memory Agent 将系统提示和记忆状态合并到第一个 HumanMessage 中:

if isBedrock:
combinedInstructions = [instructions, memoryStatus].join('\n\n')
processedMessages[0] = new HumanMessage(combinedInstructions + '\n\n' + originalContent)
graphInstructions = undefined

GPT-5+:移除 temperature 参数,将 maxTokens 迁移到 modelKwargs

Anthropic Thinking:当启用 thinking 模式时删除 temperature

记忆 Artifacts 的流式通道适配

Memory Agent 可能在主回复已经开始流式输出后才完成:

if res.headersSent:
GenerationJobManager.emitChunk(streamId, { event: 'attachment', data: attachment })
else:
res.write(`event: attachment\ndata: ${JSON.stringify(attachment)}\n\n`)

这确保记忆操作结果能通过可恢复流式通道传递给前端,即使在 headersSent 之后。


问题与规避

问题 1:Memory Agent 失败阻塞主回复

规避processMemory 被 try-catch 包裹,失败仅记录日志,不影响主回复流。调用方(AgentClient)在发送主回复后异步触发 createMemoryProcessor 返回的处理函数。

问题 2:Token 计数与实际使用不一致

规避:统一使用 o200k_base tokenizer。Memory 写入时记录 tokenCount,后续预算检查基于累计值而非重新计算。

问题 3:Bedrock 系统提示格式导致 API 错误

规避:Bedrock 分支将系统提示合并到用户消息中,设置 graphInstructions = undefined


设计取舍

固定小模型 vs 复用主模型

Memory Agent 默认使用 gpt-4.1-mini(小型、低成本),而非复用用户选择的主模型。

方案优势代价
固定小模型成本低、延迟小、输出稳定需要额外配置管理
复用主模型配置简单成本可能很高(如用 Claude Opus 做记忆提取)

记忆提取是相对简单的 NLU 任务,不需要主模型的推理能力。小模型更经济。


参考来源