跳到主要内容

个性化上下文工程:如何为 AI 智能体构建长期记忆

· 阅读需 8 分钟
Tian Pan
Software Engineer

大多数智能体演示都是无状态的。用户提问,智能体回答,会话结束——下一次对话从头开始。这对于计算器来说没问题。但对于一个应该了解你的助手来说,这就不行了。

有用的智能体和令人沮丧的智能体之间的差距,往往归结为一点:系统是否记住了重要信息。本文将详细阐述如何在生产级 AI 智能体中构建持久化、个性化的记忆——涵盖其四阶段生命周期、分层优先级规则以及如果你跳过工程设计将遇到的具体故障模式。

为什么“只用更大的上下文窗口”会失败

当团队首次尝试添加记忆时,他们会想到显而易见的解决方案:记录所有内容并将历史记录塞入提示中。一个 128K-token 的窗口似乎有足够的空间。

但事实并非如此——至少不是你所期望的那样。

问题不在于存储,而在于信噪比。随着会话历史的增长,模型不会优雅地退化——它们会分心。生产经验持续表明,加载包含 50 轮聊天历史的模型,通常会产生比简洁的 3 段式个人资料更差的个性化响应。模型默认会匹配最新的 token 模式,而不是根据真正重要的事实进行推理。

有四种需要注意的独特故障模式:

  • 上下文污染:第三轮中出现的错误假设会在后续每一轮中重复出现,并悄无声息地加剧。
  • 上下文干扰:过多的历史信息导致模型鹦鹉学舌般地重复旧行为,而不是回应当前问题。
  • 上下文混淆:模型检索到不相关的记忆块,并根据错误的事实进行推理。
  • 上下文陈旧:六个月前捕获的偏好覆盖了用户今天刚刚说的话。

解决方案不是更大的窗口或更智能的检索系统,而是一种具有明确生命周期阶段的精心设计的记忆架构。

四阶段记忆生命周期

有效的智能体记忆遵循一个一致的模式:注入 → 提炼 → 修剪 → 整合。每个阶段都有特定的任务,跳过其中任何一个都会在下游产生复合问题。

阶段 1:注入

会话开始时,智能体将一个结构化的状态对象加载到系统提示中。这不是原始数据库转储——它是智能体完成工作所需信息的渲染表示。

一个简洁的模式是将 YAML frontmatter 用于结构化事实,并将 Markdown 列表用于自由形式的笔记:

---
user_profile:
name: Alex
role: Engineering Manager
timezone: US/Pacific
preferred_summary_format: bullet_points
---

## Long-Term Preferences
- Prefers concise status updates, not narrative prose
- Dislikes being asked follow-up clarifying questions mid-task
- Always wants to see cost estimates before tool calls that incur charges

## Recent Context
- Last session focused on Q4 hiring plan
- Mentioned burnout concerns in the team

YAML 部分为模型提供了可可靠引用的结构化事实。Markdown 部分为它提供了难以编码为键值对的叙述性上下文。这种混合方法在模型理解方面优于纯 JSON(死板)和纯散文(嘈杂)。

阶段 2:提炼

在会话期间,智能体应主动通过工具调用发出候选记忆,而不是被动地积累所有内容。

一个 save_memory_note(note: str, scope: "session" | "global") 工具让智能体决定什么值得保留。工具模式应明确约束:捕获高价值、可重用的信息;拒绝推测、PII(个人身份信息)和系统级指令。

这是一个被低估的见解:记忆质量是在写入时确定的,而不是读取时。让模型在有护栏的情况下决定保存什么,会产生比任何事后过滤系统都更清晰的记忆。

阶段 3:修剪

长对话最终会超出上下文窗口。当需要修剪时,你必须做到精准:保留最后 N 轮用户对话以保持即时对话连贯性,但不要丢失智能体一直在积累的会话笔记。

模式是使用一个标志,在修剪发生后的下一轮触发自动记忆重新注入。如果没有这个,智能体会悄无声息地丢失其会话上下文——这种故障模式几乎不可能从外部检测到,因为模型会继续生成看似合理的响应,只是缺少它所需的上下文。

阶段 4:整合

会话结束时,运行第二次 LLM 调用,将会话笔记合并到全局记忆中。基于规则的去重很快就会失效——在三次会话中用不同措辞表达的相同偏好,在字符串比较时将无法匹配。

一个模型调用,比如“这是当前的全局笔记和今天的会话笔记——生成一个去重、整合的版本,并按新近度解决冲突”,可以可靠地工作。整合提示的关键约束:

  • 当两条笔记冲突时,优先选择具体性而非普遍性。
  • 剥离短暂的会话细节(例如,“用户今天很匆忙”)。
  • 将新近度作为矛盾偏好的决胜标准。

异步运行此操作——没有理由让用户在会话结束时等待记忆整合。

优先级规则:什么覆盖什么

分层记忆系统需要明确的优先级规则,否则你会遇到奇怪的边缘情况,即陈旧的全局记忆会覆盖用户刚刚告诉代理的内容。

层级结构应为:

  1. 当前对话中最新的用户指令 — 总是优先
  2. 会话范围的记录 — 覆盖本次对话的全局默认设置
  3. 全局长期记忆 — 代理回退的基础

在你的系统提示中明确记录这个层级结构。例如:“如果用户给出的指令与存储的偏好相矛盾,请遵循当前指令并相应更新会话记录。” 如果没有这一点,代理将会犹豫不决——试图同时遵守存储的偏好和新指令——从而产生不连贯的响应。

记忆应该捕获什么,不应该捕获什么

记忆系统设计中最大的陷阱是将其视为日志问题。记忆不是日志。它是代理在多个会话中良好执行其工作所需的工作模型。

一个有用的框架是:在与客户通话之前,一个熟练的人类专业人士会在工作记忆中保留什么? 不是每次先前会议的逐字记录——而是一个提炼过的偏好、约束、活跃上下文以及任何不便再次询问的信息的概要。

长期记忆的良好候选者:

  • 沟通偏好(格式、长度、详细程度)
  • 领域上下文(团队结构、项目名称、约束)
  • 重复模式(“总是在批准前要求成本”)
  • 需要谨慎处理的敏感话题

不佳候选者:

  • 会话特有的情感上下文(“今天看起来很紧张”)
  • 推测性推断(“可能基于 Y 偏好 X”)
  • 任何个人身份信息 (PII) 或认证凭据
  • 属于代理设置而非用户记忆的系统配置

保持记忆精简使检索更清晰、整合成本更低、注入的配置文件更小——这直接有益于响应质量。

生产环境中需要预期的故障模式

除了上述四种上下文故障模式之外,生产记忆系统中还会可靠地出现一些操作问题:

无声的记忆陈旧。 一年前捕获的偏好会覆盖用户在当前会话中说的话——但模型没有标记冲突。为长期记录添加明确的陈旧时间戳,并在整合期间发现冲突,而不是默默地丢弃它们。

冲突指令下的记忆漂移。 如果用户在多个会话中给出相互矛盾的偏好,幼稚的整合将选择最新版本或表达最详细的版本。明确跟踪并呈现冲突,而不是默默地解决它们。

新用户的冷启动。 没有记忆历史的代理需要合理的默认设置。不要让新用户体验一个空的系统提示——使用适合角色的默认设置进行引导,并让提炼阶段在第一个会话中覆盖它们。

基于检索的记忆并不能解决难题。 用于记忆检索的向量搜索感觉很优雅,但引入了语义脆弱性。当当前查询是关于“报告格式”时,用户对“项目符号”的偏好并不能可靠地检索。对于高风险偏好,具有确定性注入的结构化状态更为可靠,即使它会消耗更多的 token。

总结

记忆是代理个性化真正发生的地方——也是大多数生产代理悄然崩溃的地方。这里的模式并非理论:注入结构化状态、通过工具提炼、使用再注入保护修剪、用模型整合并强制执行明确的优先级规则。

工程投入会以复利的方式获得回报:一个能展现记忆的代理会建立信任,而信任直接转化为采用。感到被理解的用户会更多地使用系统,产生更多信号,并创建更好的记忆——这使得代理在下一次会话中更有用。

没有深思熟虑的记忆架构,这种飞轮就不会启动。无状态代理不仅让人感觉不人性化——它们对于任何跨越一次对话的任务来说都是功能失调的。

Let's stay in touch and Follow me for more thoughts and updates