Agent 的记忆、上下文与状态:不要混成一个概念

0阅读14分钟

为什么要区分三个概念

用过 ChatGPT、Claude 这类 AI 助手的人,可能都遇到过类似的情况:聊了很久之后,AI 开始「忘记」前面说过的内容;或者隔了几天再打开,它对你的偏好一无所知;又或者一个多步骤的任务中途断了,只能从头来过。

这些体验问题的根源,通常不在模型本身,而在于构建 Agent 系统时,把三个不同层次的信息混在了一起——上下文(Context)状态(State)记忆(Memory)

三者都和信息有关,但服务的是不同的问题。混在一起会导致信息过载、任务丢失、偏好污染。分清它们的边界,是构建可靠 Agent 的第一步。

三个类比

在正式定义之前,先用三个日常场景来建立直觉。

上下文 = 工作台

想象你有一张工作台,面积有限。你正在修一块手表,于是把螺丝刀、放大镜、零件图纸摆在台上。你不需要、也不应该把整个工具箱都搬上来——工具太多,反而找不到手边需要的那把螺丝刀。

上下文就是 Agent 每次「思考」时的工作台。它决定了这一次模型调用能看到什么信息。工作台上的东西越多,模型对每条信息的注意力就越分散。所以上下文需要精心挑选,而不是全部堆上去。

状态 = 书签

你在读一本 500 页的书,今天读到了第 187 页。你放了一枚书签,合上书去忙别的事。第二天回来,拿起书翻到书签的位置,接着读。

状态就是 Agent 的书签。它记录的是一个多步骤任务执行到了哪里、做了什么、下一步是什么。如果书签丢了,你只能从头翻起;如果任务没有结构化的状态记录,Agent 也只能从头开始。

记忆 = 笔记本

你认识一个朋友,知道他不爱吃香菜、喜欢跑步、住在浦东。这些信息不是某一次聊天教给你的,而是你们认识以来慢慢积累的。你把它记在脑子里(或者笔记本上),下次见面时自然会用上。

记忆就是 Agent 跨会话保留的知识。它来自多次交互的积累——用户偏好、事实、学到的技能。记忆需要整理、需要更新、也需要遗忘。你不会把每一次对话的每个字都记下来,而是提炼出有价值的信息。

三个类比对应三种不同的时间尺度:

概念类比时间跨度生命周期核心问题
上下文工作台单次调用调用结束即清空这次思考需要看到什么
状态书签单次任务任务结束可归档任务做到哪一步了
记忆笔记本跨会话长期保留,可管理跨会话需要记住什么

关键差异在于作用域失效条件:上下文在每次调用后失效,状态在任务完成后归档,记忆在用户删除前持续有效。

理论基础

这三个概念并不是凭空造出来的。学术界和工程界已经有了比较一致的认识。

认知科学的记忆分类

arXiv 上 2026 年 3 月的综述论文 Memory for Autonomous LLM Agents: Mechanisms, Evaluation, and Foreseeable Trends(arXiv:2603.07670)给出了一个被广泛引用的分类框架,和认知科学中的记忆分类对齐:

  • 工作记忆(Working Memory):对应上下文,是 Agent 此刻正在处理的信息。
  • 情景记忆(Episodic Memory):带时间戳的具体经历——某次对话、某次工具调用的结果。
  • 语义记忆(Semantic Memory):从多次经历中抽象出来的事实——用户的日期格式习惯、项目的技术栈约定。
  • 程序记忆(Procedural Memory):学到的可复用工作流——一种验证流程、一个调试步骤。

这篇论文同时指出一个关键结论:长上下文不等于记忆。即便上下文窗口已经扩展到 200k token 以上,长上下文模型在需要「选择性检索和主动管理」的任务上,仍然明显弱于专门设计的记忆系统。在被动回忆任务上接近满分的模型,到了需要主动使用记忆的任务上,准确率会跌到 40–60%。

换句话说,窗口再大,也不代表模型能「记住」所有东西。

注意力预算

Anthropic 在 2025 年 9 月发布的 Effective Context Engineering for AI Agents 中,把上下文窗口称为「注意力预算」(attention budget)。核心观点是:上下文是有限资源,塞进去的信息越多,模型对每条信息的注意力就越分散。他们把这种现象称为「上下文腐烂」(context rot),因为 token 之间的两两注意力关系是 O(n²) 级别。

这两个视角合在一起,可以给三个概念下一个工程化的定义:

概念回答的问题时间跨度存储位置
上下文这次模型调用需要看到什么单次调用上下文窗口(prompt)
状态任务执行到哪一步、做了什么、下一步是什么单次任务结构化存储(数据库 / 文件)
记忆跨会话保留的用户偏好、事实或可复用经验跨会话外部记忆系统(向量库 / KV / 图)

三者关系:信息如何流动

三层信息在每次 Agent 调用时发生一次「组装 → 执行 → 沉淀」的循环。下图展示了这个循环的完整流程:

流程图画布 · 115%
Mermaid 流程图加载中...

每次调用时,系统从外部存储中取出相关记忆和当前状态,和系统指令、工具定义一起组装成完整的 prompt 发给模型。模型输出动作后,系统更新任务状态、提炼新记忆、追加对话历史。

这个循环中有三个容易出错的环节:

  1. 记忆检索过宽:把不相关的记忆塞进上下文,模型被干扰。
  2. 状态未持久化:任务中断后无法恢复,只能从头开始。
  3. 上下文被当成记忆:把对话历史直接存入长期记忆,导致错误结论被固化。

接下来分别展开三层的原理。

上下文:注意力预算的管理

上下文是三层中生命周期最短的一层,也是对模型行为影响最直接的一层。它的核心挑战是:工作台空间有限,如何挑选放上去的东西

组装优先级

上下文按优先级分配有限的 token 预算。一个工程上可行的优先级顺序是:

  1. 系统指令与工具定义:固定前缀,每次调用都一样,可以被缓存。
  2. 当前任务状态:本次任务的进度、已执行动作、待处理项。
  3. 检索到的相关记忆:经过相关性过滤的记忆片段,而非全部历史。
  4. 最近几轮对话:压缩后的摘要,而非原始文本。
  5. 按需注入的工具结果和环境信息:只在需要时加入。

这个顺序的核心思路是:稳定的、高优先级的信息放在前面,按需的、低优先级的信息放在后面。

Manus 在 2025 年 7 月的工程博客中提出了一个实用原则:保持 prompt 前缀稳定,让上下文尽量 append-only(只追加不修改),在需要时显式标记缓存断点。这样既能利用模型的 KV cache 减少重复计算,也能让上下文内容可追溯。

压缩策略

当对话接近上下文窗口上限时,必须有压缩机制。Anthropic 总结了三种主要策略:

策略做法适用场景风险
压缩(Compaction)对历史对话生成摘要,用摘要替代原始文本长对话、多轮迭代低频细节在反复压缩中被悄悄丢弃
工具结果清理深层历史中的工具返回结果只保留结论,丢弃原始输出频繁调用工具的 Agent后续如果需要重新检查原始数据,无法回溯
子 Agent 卸载把子任务交给独立 Agent 处理,只把浓缩结果返回主 Agent复杂研究、并行探索子 Agent 的上下文对主 Agent 不可见,调试困难

Claude Code 的 compaction 机制是一个典型的实现:当对话接近上下文上限时,系统会生成一份摘要,保留架构决策、未解决的 bug 和关键约束,丢弃冗余的工具输出和重复讨论。然后用这份摘要作为新的起点继续工作。

代码片段:预算式上下文构建

下面是一段简化后的代码,展示「按优先级分配预算」的思路:

def build_context(user_id: str, query: str, task: Task | None):
    budget = ContextBudget(total_tokens=120_000)
 
    # 1. 固定前缀(系统指令 + 工具定义),可缓存
    prefix = build_stable_prefix(system_prompt, relevant_tools(query))
    budget.consume(prefix)
 
    # 2. 任务状态(如果有进行中的任务)
    if task:
        budget.consume(render_task_state(task))
 
    # 3. 检索相关记忆(带相关性过滤,有 token 上限)
    memories = memory_store.retrieve(
        query=query, user_id=user_id,
        top_k=5, max_tokens=2000, min_relevance=0.7,
    )
    budget.consume(render_memories(memories))
 
    # 4. 最近对话的压缩摘要
    recent = conversation_store.get_recent_summary(
        user_id=user_id, max_turns=5, max_tokens=3000,
    )
    budget.consume(recent)
 
    # 5. 当前查询
    budget.consume(f"User: {query}")
 
    return budget.render()

核心思路是:先分配固定部分(系统指令),再按优先级依次分配(任务状态 → 相关记忆 → 对话摘要 → 当前查询),每一层都有 token 上限,超出预算就截断或压缩。

与之对应的常见错误做法是:把所有历史对话、所有记忆、所有工具结果全部拼接在一起,不做任何过滤和压缩。这种做法在初期能跑通,但随着对话变长,token 消耗会线性甚至超线性增长,模型也会被无关信息干扰。

状态:任务进度的结构化保存

状态是三层中最容易被忽视的一层。很多 Agent 系统把任务进度「隐含」在对话历史里——系统靠回顾对话来推断任务执行到了哪一步。一旦对话被压缩或丢失,进度也就丢了。

MindStudio 在 2026 年 4 月的文章中把 Agent 的状态分为两类:

  • 工作流状态(Workflow State):与具体会话无关,描述任务本身的进度。任何 Agent 实例都应该能读取这个状态并继续工作,不需要重建对话历史。
  • 会话状态(Session State):与一次会话绑定,描述这次交互的临时上下文。会话结束即可丢弃。

区分这两种状态很重要。工作流状态是「这本书读到第几页」,会话状态是「这次阅读时桌上的笔记和便签」。前者需要持久化,后者可以随会话消亡。

状态机思路

arXiv 上 2024 年的论文 Enhancing LLM Task-Solving through State-Driven Workflows(StateFlow)提出了一个思路:把复杂任务建模为状态机。每个节点是一个明确的执行阶段,边是状态转移条件,由 LLM 在每一步决定下一步走哪条边。

这种做法的好处是:任务进度可以被检查、可以被恢复、可以被回放。坏处是:需要预先定义状态空间,对于高度开放的任务不够灵活。

一个折中的方案是「结构化状态 + 自由文本注释」。核心字段(当前步骤、已完成动作、待执行动作、阻塞项、已生成产物)用结构化数据记录,保证可以程序化地读取和恢复;同时保留一个自由文本字段,让模型可以记录一些不方便结构化的观察。

class TaskState:
    task_id: str
    status: 'planned' | 'in_progress' | 'blocked' | 'completed' | 'failed'
    current_step: int
    total_steps: int
    completed_actions: list[Action]     # 已执行的动作列表
    pending_actions: list[Action]       # 待执行的动作列表
    blockers: list[Blocker]             # 阻塞项
    artifacts: list[Artifact]           # 已生成的产物
    last_checkpoint: datetime           # 上次检查点时间
    notes: str                          # 自由文本注释

这个数据结构独立于对话历史存在。即使进程崩溃、会话断开,只要状态存储还在,任务就可以从最后一个检查点恢复。

持久化模式选择

任务状态需要存到哪里?这取决于任务的持续时间和失败代价:

模式持久化方式可靠性复杂度适用场景
内存状态进程内存低(重启即丢失)原型、短任务
文件状态JSON / SQLite 文件单用户、本地 Agent
数据库状态PostgreSQL / Redis多用户、多实例
Workflow 引擎Temporal / Durable Functions高(event sourcing)长时间运行、关键业务
混合模式热状态在 Redis,冷状态归档到对象存储大规模、需要回放

一个几分钟的对话任务用文件状态就够;一个可能运行几天、涉及外部系统写入的任务,需要 Workflow 引擎或等价机制。Temporal 在 2025 年 10 月的工程博客中分享了用 Workflow 引擎实现 Agent 状态持久化的方案:每次状态变更都被记录为 event,进程崩溃后可以从最后一个 event 恢复,不需要把整个对话历史保留在内存中。

记忆:跨会话的长期资产

记忆是三层中生命周期最长、也最需要谨慎处理的一层。arXiv 2603.07670 论文指出一个被广泛忽视的问题:

记忆值得获得与 LLM 本身同等的工程投入。模型选型通常会花几个月仔细评测;记忆架构往往只得到一个下午。

记忆的类型与作用域

Mem0 在 2026 年 4 月的报告中提出了一个四维作用域模型,按 user_idagent_idsession_idorg_id 四个维度组织记忆。对应到前面的认知科学分类:

记忆类型作用域内容示例写入时机检索方式
用户语义记忆user_id用户偏好、个人信息、长期习惯从对话中提炼按用户 + 查询语义检索
Agent 能力记忆agent_idAgent 学到的技能、有效的工具组合任务完成后提炼按任务描述检索
会话情景记忆session_id本次对话的关键决策、中间结论对话过程中实时写入按会话 ID 直接读取
组织知识记忆org_id团队约定、项目规范、领域知识人工维护或从文档导入全局检索 + 权限过滤

用户语义记忆是「这个用户喜欢用 Markdown 格式」「这个用户在上海」;Agent 能力记忆是「上次用这种工具组合解决了类似问题」;会话情景记忆是「这次对话中用户确认了方案 A」;组织知识记忆是「公司的 API 规范」「项目的部署流程」。

四种记忆的写入方式、检索方式和生命周期都不同。把它们放在同一个存储里、用同一种方式处理,会导致检索混乱和权限问题。

记忆写入的五个阶段

记忆写入是最容易出错的环节。论文指出,写入路径至少需要五个阶段:

  1. 提取:从对话中识别值得长期保留的信息。闲聊、确认、重复信息不值得写入。
  2. 过滤:给候选记忆打分,低信号内容不写入。
  3. 去重:与已有记忆比较,避免重复存储。如果新信息与旧信息冲突,更新旧信息而非新增。
  4. 打分:根据置信度、重要性等维度给记忆排优先级。
  5. 标注元数据:记录记忆的类型、来源、创建时间等元数据,方便后续检索和管理。

任何一个阶段缺失,都会导致记忆质量下降。最常见的错误是把模型输出直接存入记忆——对话中的每句话都被存下来,没有过滤、没有去重、没有元数据。这样做的结果是记忆库快速膨胀,检索精度持续下降。

async def on_message(user_id: str, message: str, response: str):
    # 1. 让模型判断本次对话是否有值得长期保留的信息
    extraction = await llm.call(
        prompt=MEMORY_EXTRACTION_PROMPT,
        context={"user_message": message, "agent_response": response},
    )
 
    for candidate in extraction.memories:
        # 2. 过滤:低信号内容不写入
        if candidate.signal_score < 0.6:
            continue
 
        # 3. 去重:与已有记忆比较
        existing = await memory_store.find_similar(
            user_id=user_id,
            content=candidate.content,
            threshold=0.85,
        )
        if existing:
            # 有冲突,保留新版本
            await memory_store.update(existing.id, content=candidate.content)
        else:
            # 4-5. 打分并带完整元数据写入
            await memory_store.save(
                user_id=user_id,
                content=candidate.content,
                memory_type=candidate.type,
                confidence=candidate.confidence,
                tags=candidate.tags,
            )

记忆检索:多信号融合

Mem0 的实践表明,单纯的向量相似度检索在记忆系统中不够用。高相似度不等于高相关性——一条语义上相似但已经过时的记忆,检索出来反而会误导模型。

更稳健的做法是多信号检索,把多个维度的分数融合为一个最终排序:

  1. 语义相似度:用向量数据库做 embedding 检索,找到语义上最接近的记忆。
  2. 关键词匹配:用传统关键词索引,捕捉向量检索可能遗漏的精确匹配。
  3. 实体匹配:提取查询中的实体(人名、项目名、日期等),找到涉及相同实体的记忆。
  4. 时效性加权:新记忆的权重更高,旧记忆逐渐衰减。
  5. 重排:用 cross-encoder 对 top 结果做精排,然后控制在 token 预算内。

这种多信号融合的方式,比单纯依赖向量相似度更能捕捉「当前真正需要」的记忆。

遗忘机制

一个值得警惕的发现是:「没有人能很好地评测遗忘」。但在长期运行的系统中,无法丢弃过时信息会逐渐毒化检索精度。

遗忘不能只是硬性的时间过期。一个用户三年前说的偏好可能今天仍然有效,一个月前说的偏好可能已经改变。一个实用的遗忘策略需要结合四种机制:

  • 显式过期:用户主动删除、或设定了过期时间的记忆。
  • 矛盾检测:当新记忆与旧记忆冲突时,标记旧记忆为 superseded(已被取代),而非直接删除,保留溯源能力。
  • 重要性衰减:被频繁检索和引用的记忆保持活跃,长期未被引用的记忆逐渐降低优先级。
  • 定期整合:周期性地把多条相关记忆合并为一条更抽象的总结,减少碎片。

遗忘不是丢失信息,而是让过时的信息不再影响当前决策。这是记忆系统最难做好的部分,也是区分「能用」和「好用」的关键。

设计原则

综合上面的讨论,可以提炼出六条设计原则:

原则含义违反时的症状
上下文有预算每次调用前主动分配 token,而非被动堆积响应变慢、token 成本失控、模型被无关信息干扰
状态独立于对话任务进度是结构化数据,不依赖对话历史推断进程重启后任务丢失、压缩对话后进度模糊
记忆需要提炼长期记忆是从对话中提取的,不是对话本身的复制记忆库膨胀、过时信息污染决策
记忆可以遗忘有过期、去重、合并和删除机制检索精度随时间下降、旧偏好覆盖新偏好
三层可追溯每次调用的上下文组装过程可记录、可回放出了问题无法定位是记忆错误、状态错误还是上下文错误
用户可管理记忆用户能查看、修改、删除自己的长期记忆隐私风险、用户信任丧失

前三条解决「能不能跑」的问题,后三条解决「能不能长期跑」的问题。

检查清单

上下文

  • 每次调用前有明确的 token 预算分配,而非把可用信息全部塞入。
  • 系统提示和工具定义作为稳定前缀,支持 KV cache 复用。
  • 记忆检索有相关性过滤和 token 上限,不是全量注入。
  • 对话历史在超过阈值后会被压缩,压缩时保留关键决策和未解决问题。

状态

  • 任务进度是结构化数据(状态机或 checkpoint),不依赖对话历史推断。
  • 任务中断后可以从最后一个检查点恢复,不需要从头开始。
  • 状态存储与对话存储分离,可以独立备份和恢复。

记忆

  • 长期记忆是从对话中提炼的,不是对话文本的直接复制。
  • 记忆写入前有过滤、去重和元数据标注。
  • 记忆检索使用多信号融合,而非单纯向量相似度。
  • 有过期、去重、合并和删除机制,避免过时信息污染决策。
  • 用户可以查看、修改和删除自己的长期记忆。

可观测性

  • 每次调用的上下文组装过程可记录、可回放。
  • 记忆的每次读、写、更新、删除都有审计日志。
  • 出了问题时能定位是记忆错误、状态错误还是上下文组装错误。

参考资料

  1. arXiv:2603.07670. Memory for Autonomous LLM Agents: Mechanisms, Evaluation, and Foreseeable Trends. 2026. 关于 LLM Agent 记忆机制的系统综述,提出了工作记忆 / 情景记忆 / 语义记忆 / 程序记忆的分类框架。

  2. Anthropic Engineering. Effective Context Engineering for AI Agents. 2025. 提出「注意力预算」和「上下文腐烂」概念,介绍了 compaction、note-taking 和子 Agent 卸载三种上下文管理策略。

  3. Mem0. State of AI Agent Memory 2026: Benchmarks, Architectures and Production Patterns. 2026. 介绍了四作用域记忆模型和多信号检索架构。

  4. Manus Engineering Blog. Context Engineering for AI Agents: Lessons from Building Manus. 2025. 提出 prompt 前缀稳定、上下文 append-only、显式标记缓存断点三个工程原则。

  5. arXiv:2403.11322. Enhancing LLM Task-Solving through State-Driven Workflows (StateFlow). 2024. 把复杂 LLM 任务建模为状态机的学术工作。

  6. Temporal Blog. Building a Persistent Conversational AI Chatbot with Temporal Workflows. 2025. 介绍如何用 Workflow 引擎实现 Agent 状态的 event sourcing 和崩溃恢复。

  7. MindStudio. What Is Workflow State vs Session State in AI Agents? 2026. 区分工作流状态和会话状态。

评论 0

0 / 1000