Agent记忆系统三层架构深度测评:短期、长期、压缩优劣对比

2026-06-16阅读 0热度 0
其他

记忆系统不只是"存聊天记录"

把对话历史一股脑儿塞进prompt——这其实是最粗糙、最原始的记忆方式。现实中,Agent对记忆的需求远比你想象的要复杂:

Agent 系列(15):Agent 记忆系统进阶——短期、长期、压缩,三层记忆架构

  • 用户在第3轮提到了自己的城市,第10轮问天气时Agent应该知道去哪儿查数据。
  • 用户上周告诉过系统他们用的是哪个产品套餐,本次新会话不应该再问一遍。
  • 对话进行了20轮,context window快撑不住了,怎么压缩又不丢失关键信息?

这三个场景,对应三种完全不同的记忆机制。下面展开聊。


三层记忆架构

短期记忆   会话内        MemorySa ver checkpointer    多轮问答
长期记忆   跨会话        持久化 KV 存储 / 向量库      个性化
历史压缩   会话内保护     摘要替换                    长对话 token 守卫

Demo 1:短期记忆——MemorySa ver

LangGraph 的 MemorySa ver 是最轻量的短期记忆实现:把对话历史绑定到一个 thread_id,下次调用时自动注入,省得你手动拼历史。

from langgraph.checkpoint.memory import MemorySa ver
from langchain_core.runnables import RunnableConfigcheckpointer = MemorySa ver()
stateful_agent = create_react_agent(
    model=llm,
    tools=[get_weather, calculator, get_product_info],
    checkpointer=checkpointer,
)THREAD_A: RunnableConfig = {"configurable": {"thread_id": "thread-alice"}}# Turn 1: 告知名字和城市
r1 = stateful_agent.invoke(
    {"messages": [HumanMessage("Hi, I'm Alice. I live in Beijing.")]},
    config=THREAD_A,
)# Turn 2: 用同一个 thread_id,历史自动附带
r2 = stateful_agent.invoke(
    {"messages": [HumanMessage("What's the weather like where I live today?")]},
    config=THREAD_A,
)

来看看实际跑出来的效果:

Thread A Turn 1: Hello Alice! How can I assist you today?Thread A Turn 2: Sure, I can help you with that. I will need to know the 
                 city you are in. Could you please provide me with the 
                 name of your city?
                 Tools used: []Thread B (no context): I can help with that. Could you please provide 
                       your city name?
                       Tools used: []

Thread A 和 Thread B 给出了同样的回答。

这个结果很有意思:MemorySa ver 的基础设施是正常的——Thread A 的第二次调用实际上带着完整的历史(两条消息),而 Thread B 只有一条。但 GLM-4-Flash 没有把"I live in Beijing"(第一轮)和"where I live"(第二轮)连起来。这其实是模型能力的问题,而不是 MemorySa ver 的问题。

同样的 prompt,如果换成 GPT-4 或 Claude,它们会直接去查北京天气;能力弱的模型可能需要更明确的表述(比如直接问"What's the weather in Beijing?")才能触发工具调用。

短期记忆有两层含义,必须分开看:

  1. 基础设施层:MemorySa ver 确保历史消息被传递——这件事它干得漂亮。
  2. 模型层:LLM 能否从历史中提取并使用上下文——这取决于模型自身的推理能力。

Demo 2:长期记忆——跨会话事实存储

跨会话记忆的核心思路很直接:用 LLM 从对话中提取关键事实,存入持久化存储,下次会话时注入系统提示词。这样模型就不用从历史中猜了,直接告诉你答案。

Session 1 — 提取并存储:

# 模拟持久化存储(生产环境替换为数据库或向量库)
LONG_TERM_STORE: dict[str, dict[str, str]] = {}def extract_facts(conversation: str) -> dict[str, str]:
    resp = llm.invoke([
        SystemMessage(
            "Extract key facts about the user. "
            'Return ONLY JSON: {"city": "...", "plan": "..."}'
        ),
        HumanMessage(f"Conversation:n{conversation}"),
    ])
    # 解析 JSON 响应
    ...

Session 1 对话内容:

User: I'm Alice. I'm based in Shanghai and my team uses WonderBot Pro.
User: We mainly use the API for data processing — about 50,000 calls a month.

提取结果并存入:

{'name': 'alice', 'city': 'shanghai', 'team': 'wonderbot pro', 'api_calls': '50000'}

Session 2 — 注入并使用:

stored = load_user_facts("user-alice")
facts_text = "; ".join(f"{k}={v}" for k, v in stored.items())personalized_prompt = (
    "You are a helpful assistant. "
    f"Known facts about this user: {facts_text}. "
    "Use these facts to personalize your responses without asking the user to repeat themselves."
)personalized_agent = create_react_agent(model=llm, tools=TOOLS, prompt=personalized_prompt)

Session 2 运行结果:

User: What's the weather like in my city today?
Agent: The current weather in Shanghai is 22 degrees Celsius with cloudy conditions.
Tools used: ['get_weather']

Agent 直接查询了 Shanghai,没有问"你住哪"。原因很简单:city=shanghai 已经在系统提示词里了——模型不需要从对话历史中推断,而是直接读取了显式提供的事实。

这也是为什么长期记忆比短期记忆更可靠:事实以明确的 KV 格式注入,不依赖模型从历史中做推理。换句话说,你把答案直接喂到模型嘴边,它不用自己去翻聊天记录。


Demo 3:历史压缩

对话越长,token 消耗和响应延迟就线性增长。压缩策略很直接:设置一个 token 阈值,超过之后就用摘要替换掉历史消息。

COMPRESSION_THRESHOLD = 250   # tokensdef summarize_messages(messages: list) -> str:
    history_text = "n".join(
        f"{'User' if isinstance(m, HumanMessage) else 'Agent'}: {str(m.content)[:150]}"
        for m in messages
        if isinstance(m, (HumanMessage, AIMessage)) and not getattr(m, "tool_calls", None)
    )
    resp = llm.invoke([
        SystemMessage(
            "Summarize this conversation in 2-3 sentences. "
            "Preserve all key facts: names, cities, numbers, product names."
        ),
        HumanMessage(f"Conversation:n{history_text}"),
    ])
    return str(resp.content)# 在每轮对话后检查 token 数
if total_tokens > COMPRESSION_THRESHOLD:
    summary = summarize_messages(messages)
    messages = [SystemMessage(f"Conversation summary so far: {summary}")]

Demo 3 的真实结果:5 轮对话(Bob 在深圳,评估 WonderBot Pro,8 位开发者,年费 299*12=3588),总 token 保持在 198,未超过 250 阈值,因此压缩未触发。

最终验证:

User: Quickly summarize: who am I, what city, and what's the annual API cost?
Agent: You are Bob, from Shenzhen, and the annual API cost for WonderBot Pro 
       for 8 developers is $3,588.

10 条消息历史完整保留,Agent 记住了所有关键事实。压缩机制本质上是安全阀,不是每轮对话都要触发——当对话足够短时,原始历史比摘要更精确。阈值建议设置在 4k token 左右,因为超过这个值模型推理效率会明显下降。


三种模式的实测对比

模式Demo 1 结果Demo 2 结果关键差异
短期记忆MemorySa ver 存储正常,但 GLM-4-Flash 未能利用隐含上下文依赖模型推断能力
长期记忆直接调 get_weather(Shanghai),零追问显式 KV 注入,不依赖推断
压缩安全阀机制,按需触发

核心结论:

  • 需要可靠的跨轮上下文 → 用长期记忆的显式注入,而不是只依赖 MemorySa ver。
  • MemorySa ver 的价值在于会话隔离(不同 thread_id 互不影响)和自动历史传递,它不是用来解决"模型能否推断隐含信息"这个问题的。
  • 压缩是生产环境的必备组件,但阈值不要设得太低(太低会丢失细节,得不偿失)。

设计 Checklist

短期记忆(MemorySa ver)

  • 每个用户/会话分配独立 thread_id
  • thread_id 用用户 ID 而不是随机数,确保同一用户的多轮对话连续
  • 不要依赖 MemorySa ver 解决"模型无法推断隐含信息"的问题
  • 生产环境用持久化 checkpointer(SqliteSa verPostgresSa ver),而不是 MemorySa ver

长期记忆

  • 用 LLM 提取事实,不要手写规则解析
  • 事实以 KV 格式注入系统提示词,明确优于隐含
  • 设置更新策略:事实过时时覆盖,不要无限追加
  • 生产环境:数据库存结构化事实,向量库存语义记忆

历史压缩

  • 阈值建议:2000-4000 token(过低会频繁压缩,损失精度)
  • 摘要 prompt 要求"保留具体数字和名称",否则 LLM 会过度抽象
  • 压缩后验证:在摘要里确认关键事实仍然存在
  • 不要在工具调用中间触发压缩(会破坏上下文)

总结

五个核心结论,值得反复琢磨:

  1. MemorySa ver 是基础设施,不是银弹:它确保历史被传递,但模型能否利用隐含上下文取决于模型本身。
  2. 显式注入比隐含推断更可靠:把 city=shanghai 写进系统提示词,比期望模型从 10 条消息里推断要稳定得多。
  3. 三层记忆要组合使用:短期(会话隔离)+ 长期(跨会话个性化)+ 压缩(token 守卫),缺一不可。
  4. 事实提取是长期记忆的关键步骤:LLM 提取 + JSON 解析,把非结构化对话转成结构化事实,这一步做不好后续全白搭。
  5. 压缩是安全阀,不是每轮都跑:对话短时原始历史更精确,超阈值才压缩,别提前触发。

参考资料

  • LangGraph Persistence 文档
  • LangGraph MemorySa ver
  • 本系列完整 Demo 代码:agent-14-memory
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策