本文是对 AI Agent 上下文管理相关知识的学习整理,涵盖 Context 抽象、窗口编排、摘要压缩、细节召回、用户画像、长任务处理等核心主题。
一、核心概念:Context 与 Context Window
1.1 Context:Agent 的全部信息空间
Context 指 Agent 当前可获得的全部信息空间,不等于已经塞进 Prompt 的内容。
数据来源分为四块:
| 来源 | 说明 | 示例 |
|---|---|---|
| 用户输入数据 | 用户直接提供的各种数据 | Excel、PDF、文本输入 |
| Agent 自身产生 | 提示词、大模型输入输出、中间结果 | 对话历史、Plan 状态 |
| 内部数据 | 来自业务系统的数据 | 通过接口或直接访问 MySQL/ES |
| 外部数据 | 与外部系统交互获得的数据 | 外部 API、MCP 工具调用 |
从存储角度:同一份数据可能在内存、缓存、数据库中各存一份。比如用户画像,MySQL 中一份,Redis 中缓存一份。
从时效角度:有只作用于当前轮对话的 Context,也有作用于整个多轮对话的 Context,还有像缓存一样有效期不同的 Context。
核心观点:万物皆 Context。Memory 只是部分 Context 的别名,是一种拟人化描述,针对大模型没有状态这个问题。不要过度神化 Memory 概念。
1.2 Context Window:当前调用的工作集
Context Window 是从全部 Context 中经过筛选、压缩、排序后得到的模型可见内容。
类比:Context 是仓库,Context Window 是当前工作台。
核心公式:
1 | Context Window = f(Context) |
最复杂的 f 描述:
1 | Window = Inject(Order(Compress(Select(Retrieve(Context))))) |
- Retrieve:找出可能相关的 Context
- Select:选择当前真正需要的内容
- Compress:压缩到合适的粒度
- Order:决定内容的排列顺序
- Inject:以合适的结构注入大模型
1.3 Context 分类(面试参考)
| 分类 | 说明 |
|---|---|
| Instruction Context | 指令上下文,System Prompt、业务 Spec、行业标准 |
| Goal Context | 目标上下文,用户最终目标、当前子目标 |
| User Context | 用户上下文,用户画像、历史决策 |
| Task Context | 任务上下文,当前任务、执行步骤 |
| Tool Context | 工具上下文,工具输入、输出 |
| Constraint Context | 约束上下文,硬约束、软约束 |
1.4 Context Item 统一抽象
每个 Context Item 可以用以下结构描述:
1 | { |
关键字段说明:
- source:信息从哪里来(用户、系统、工具、模型推测)
- scope:有效范围(当前步骤、当前任务、当前会话、全局等)
- authority:权威程度,用于冲突仲裁。参考:系统规则 > 用户明确输入 > 工具事实 > 已确认摘要 > 模型推测
- confidence:可信度,小型 Agent 中可与 authority 合并使用
- expires_at:过期时间。用户偏好有效期长,天气信息有效期短
- token_cost:注入成本,用于评估窗口占用
关于 authority 的补充:要区分观点和事实。用户描述的观点要尊重并给予重要权重,无须分辨对错;用户描述的事实可以在 Replan 阶段尝试验证。
1.5 每个 Context Item 要考虑的问题
- 怎么获得:用户画像怎么获得?硬约束怎么获得?
- 怎么存储:要不要持久化?要不要缓存到 Redis?
- 怎么查询:怎么从存储的地方检索出来?(与”获得”做区分)
二、滑动窗口算法
2.1 基础滑动窗口
窗口只保留最近一段上下文,旧的上下文随着对话推进逐渐被挤出去。
优点:
- 实现简单
- 性能稳定
- 不需要复杂检索
- 近期上下文通常最相关
- 容易控制 Token 成本
两种计量方式:
- 按轮次:窗口放 N 轮对话
- 按 Token:如 64K 窗口
注意事项:
- 每轮要限制用户最大输入 X 和模型最大输出 Y,N 轮就是 N × (X+Y)
- 窗口不要占满整个窗口,要给其他内容留出空间(如 128K 总窗口,滑动窗口限制在 32K)
- 窗口内不一定要放纯对话,关键点、中间产物也可以放进去
- 致命问题:最近的上下文不一定是最重要的,也不一定是最相关的
2.2 变种滑动窗口
窗口内放两大块:
- 近 N 轮对话:直接放原文
- 近 [N+1, N+M] 轮对话:用户输入放原文,模型输出放摘要
核心洞察:用户输入通常很短,模型输出一般很长。
需要考虑的边界情况:
- 用户输入很长(如粘贴堆栈)→ 也需要摘要
- 模型输出很短 → 可以直接放原文
进阶:N 和 M 可以动态调整——剩余窗口大则大,剩余窗口小则小。
2.3 摘要生成时机
不在窗口内的对话内容靠摘要和细节召回处理。
摘要生成时机:
- 即时生成:第 K×N 轮结束时立刻生成
- 延迟生成:等到第 K×N+1 轮开始时再回过头来生成
摘要如何生成:调用大模型,提供摘要规则(什么保留、什么不保留)。
三、分层上下文
3.1 统一抽象
分层的核心思想是分而治之。不同层次之间通过映射函数 f1、f2 连接:按照一定规则从下一层挑选出上一层的内容。
3.2 按生命周期分层
| 层级 | 主要内容 | 生命周期 |
|---|---|---|
| 工作上下文 | 当前输入、当前步骤、工具结果 | 一次或几次模型调用 |
| 会话上下文 | 当前对话目标、最近历史 | 当前会话 |
| 长期上下文 | 用户画像、长期偏好 | 跨会话 |
| 归档上下文 | 完整历史、原始记录 | 长期保存,按需召回 |
3.3 按作用范围分层
| 层级 | 主要内容 | 作用范围 |
|---|---|---|
| 步骤级 | 当前工具调用参数、搜索 Query | 只对当前步骤有效 |
| 阶段级 | 信息收集阶段收集到的内容 | 一组相关步骤内有效 |
| 任务级 | 任务目标、成功标准、任务约束 | 整个任务执行期间有效 |
| 会话级 | 最近讨论的话题、语言风格 | 当前对话中有效 |
| 用户级 | 用户长期画像、稳定偏好 | 跨多个任务、多个会话复用 |
| 系统级 | 业务规范、全局工具说明、权限策略 | 对所有用户、所有任务有效 |
3.4 按信息形态分层
| 层级 | 主要内容 | 信息形态 |
|---|---|---|
| 原始层 | 完整用户输入、完整对话消息 | 保存完整原始内容 |
| 结构化事实层 | 稳定事实 | 从原始内容中抽取 |
| 摘要层 | 摘要 | 保留整体语义和过程 |
| 索引层 | 索引(如哈希结构) | 不保存具体内容,只保存”去哪里找” |
3.5 按权威性分层
| 层级 | 主要内容 | 使用策略 |
|---|---|---|
| 强规则层 | 系统规则、安全规则、权限限制 | 不允许被低层覆盖 |
| 已确认事实层 | 用户确认、权威系统查询结果 | 可作为决策依据 |
| 有证据推断层 | 基于多个证据推导的结论 | 可使用,但需保留证据 |
| 待确认假设层 | 模型推测、临时假设 | 不得当成事实 |
| 已否定层 | 用户否认、验证失败的信息 | 禁止继续使用 |
3.6 按冷热程度分层
| 层级 | 主要内容 | 描述 |
|---|---|---|
| 热 Context | 当前任务状态、当前 Goal | 频繁使用,放内存/Redis |
| 温 Context | 当前会话早期内容 | 偶尔使用,需要检索 |
| 冷 Context | 完整历史消息、过期工具结果 | 低频使用,主要用于归档 |
实践建议:可以混用多种分层方式。比如先按冷热分,在热 Context 里面再按权威性分。结合业务特点找有特色的分层方式。
四、上下文窗口动态编排
4.1 Prompt Prefix Cache
如果 Prompt 的前缀部分相同,可以利用之前推理的缓存快速推理。类比 SQL 的前缀索引。
在设计上下文顺序时要考虑缓存友好性。
4.2 Context Compiler
整体抽象:
1 | Window_t = Inject(Order(Compress(Select(AllContext_t, TaskState_t), TokenBudget_t))) |
- AllContext_t:系统里所有可用的 Context
- TaskState_t:当前任务状态
- TokenBudget_t:当前可用的 Token 预算
4.3 筛选(Select)
核心思路:每个阶段、每个步骤需要的内容不同,”弱水三千,只取一瓢”。
三种筛选机制:
| 机制 | 说明 | 适用场景 |
|---|---|---|
| 强规则筛选 | Prompt 模板/代码层面直接决定 | 确定性高的场景 |
| 检索召回 | 向量数据库/ES 查找相关内容 | 参考 RAG 机制 |
| 模型筛选 | 先调用轻量模型判断需要什么 | 成本较高,不太常用 |
Prompt 模板示例(Go 模板语法):
1 | {{ .UserProfile }} |
代码直接写死的做法(对 LLMAction 二次封装,内部决定从 Context 获取哪些字段)在实践中很好用。
4.4 压缩(Compress)
压缩取决于:
- Context 内容的重要性
- 剩余窗口大小
- 当前任务目标
核心原则:越重要的内容越不能压缩;剩余窗口越大越不需要压缩。
多版本预压缩策略:
| 层级 | 内容 | 说明 |
|---|---|---|
| L0 | 一句话摘要 | 窗口几乎放满 |
| L1 | 关键结论摘要 | 窗口比较满 |
| L2 | 结构化事实 | 窗口放了一些内容 |
| L3 | 详细摘要 | 窗口还挺大 |
| L4 | 完整原文 | 窗口非常充足 |
好处:提前压缩好,运行时无额外开销。
级联考虑:
- 两个强相关的 Context Item → 保持同一压缩级别
- 两个有信息重合的 Item → 一个极度压缩,另一个尽量原文
兜底机制:在 Prompt 中增加兜底条款——如果发现某个内容压缩程度太高,可以召回更详细的内容。
4.5 排序(Order)
大模型对内容顺序敏感,同样的内容排序不同输出也不同。
参考排序:
- System / Spec
- 当前 Goal
- 硬约束
- 当前任务状态 / Plan 节点
- 已确认关键事实
- 当前步骤需要的 Evidence
- 工具 Observation
- 候选 Action / Tool
- 动态 few-shot
- 历史摘要
- 补充背景
排序要考虑两个因素:
- 重要性:越重要越靠前
- 缓存友好性:不常变动的内容可以往后放以命中 Prefix Cache
4.6 基于剩余窗口大小的动态策略
把窗口看成预算池。核心问题:哪些原样放、哪些压缩、哪些只放索引、哪些不放?
必须原样放的内容:
- 最新用户输入
- 硬约束
- 已确定关键事实
- Plan 和执行状态
动态压缩的档位设计:
| 档位 | 剩余窗口 | 策略 |
|---|---|---|
| Full Mode | 80%-100% | 基本不压缩 |
| Balanced Mode | 20%-80% | 部分压缩,Agent 应主要在此阶段运行 |
| Compact Mode | 5%-20% | 大部分压缩 |
| Minimal Mode | 0%-5% | 极度紧张,应尽快解决窗口问题 |
更多动态因素:
- 当前步骤:不同步骤需要的 Context Item 不同
- 任务风险等级:高风险任务应尽量用大窗口模型
- 信息可恢复性:可恢复的先不放,不可恢复的优先放
- 信息可信度:优先保留高可信信息
- 信息新鲜度:新旧冲突时新信息通常更重要(但用户画像等老信息可能是例外)
- 工具调用需求:需要选工具就放工具描述
- few-shot 动态策略:窗口充足放 3-5 个,紧张就不放
4.7 动态编排决策表(参考)
| Context 类型 | 窗口充足 | 窗口中等 | 窗口紧张 | 极度紧张 |
|---|---|---|---|---|
| 当前用户输入 | 原文 | 原文 | 原文 | 原文 |
| Goal | 完整结构化 | 完整结构化 | 简化结构化 | 一句话 |
| 硬约束 | 完整原样 | 完整原样 | 完整原样 | 完整原样 |
| 当前 Plan | 完整 Plan | 当前节点+依赖 | 当前节点 | 当前节点一句话 |
| 关键事实 | 完整 | 完整 | Top-K | Top-3 |
| 历史对话 | 详细摘要 | 结构化摘要 | 一句话+索引 | 只放索引 |
| 用户画像 | 相关画像完整 | 任务相关画像 | 关键画像 | 默认不放 |
| 工具结果 | 结构化+原文片段 | 核心字段 | 必要字段 | 最小字段 |
| 检索结果 | Top-K 片段 | Top-3 | Top-1 | 只放证据索引 |
| few-shot | 3-5 个 | 1-2 个 | 默认不放 | 不放 |
| 工具描述 | 完整描述 | 核心描述 | 名称+边界 | 名称+一句话 |
五、摘要与细节召回
5.1 摘要类型
对话整体摘要
总结整个多轮对话的内容。应总结的内容:
- 大模型和用户已达成一致的内容
- 讨论进度、里程碑
- 用户相关信息(用户画像的一部分)
注意:摘要不是一段话,实践中的摘要会有很多字段。
如果对话中用户切换过多个不相关意图,应在摘要里分意图存储。
建议长期保存,不要归档。
对话章节摘要
在长对话中引入章节概念,每 N 轮一个章节,每个章节独立生成摘要。
两种用法:
- 整体摘要 + 最近 N 个章节摘要(N=2,3)
- 完全抛弃整体摘要,放入全部章节摘要(细节丰富但占窗口多)
大模型输出摘要
大模型面向用户输出的内容充满了对模型来说”无意义”的内容(铺垫、转场、情绪表达)。后续在窗口内携带时,传入摘要而非原文,可大幅节省 Token。
关键事实
定义:会影响后续决策、工具调用、上下文组织、最终输出、约束校验的信息。
关键事实的分类:
- 目标类事实:用户在多轮对话期间修改自己的意图
- 硬约束:一旦丢失,Agent 容易输出让用户情绪爆炸的内容
- 软偏好:不是必须满足,但会影响用户体验,不能长期多次违反
- 用户确认过的事实:正面肯定和反面否定都要保存
- 决策类事实:做了什么决策以及为什么
- 实体信息:项目、商品、方案、人、公司等,建议组织成实体表
中间结果保存
部分工具输出结果在后续步骤中会反复用到,要考虑准备摘要和细节召回。注意时效性,大部分实时查询结果只能用于当轮对话。
5.2 什么细节值得召回?
判定标准:细节是否会影响当前决策。
具体类型:
- 影响目标的细节
- 影响约束的细节
- 影响路径选择的细节(如方案 A 已失败)
- 影响工具调用的细节(如某工具之前调用失败)
- 影响最终表达的细节(如用户说”简单点”)
猜想:在关键事实提取做得好的情况下,大部分时候不需要召回细节。
5.3 摘要生成方案
时机:
- 同步:使用前生成,如滑动窗口算法中 N%10=0 时生成
- 异步:对话结束时、下一轮开始时、定时扫描触发
异步的注意事项:可能在需要摘要时还没生成,需要等待机制(轮询或并发控制如 WaitGroup/Semaphore)。
建议:面试中推荐使用异步生成策略。
5.4 细节召回方案
基础架构:数据同步 + 数据检索,建议做成独立服务/模块/子 Agent。
数据延迟解决方案:当轮对话的细节不走召回,当轮对话之前数据已完成同步。可扩展到”当前 K 轮对话的细节不走召回,直接原文传递”。
5.5 细节冲突裁决
- last win:最新的为主
- 权威优先:优先级更高的为准
- 区分”冲突”还是”强化”:大部分大模型难以处理,需要在 Prompt 中给出规则
5.6 模型可读摘要
核心思想:压缩后的内容不是给人看的,而是给模型看的。去掉低信息密度的表达,只保留目标、实体、事实、约束、决策和状态。
示例:
- 原文:”这是一个很好的问题。你其实已经意识到了上下文压缩里面最关键的一点……”
- 压缩后:”上下文压缩目标:降 token + 保留关键事实;必须保留:目标/约束/用户确认事实/中间产物”
原理:大模型具备很强的语义补全能力,只要保留关键实体和关系,它就能继续推理。
注意:不是简单删除停用词。”不能”、”必须”、”不超过”、”大概”、”可能”这些词承载约束或不确定性,不能随便删。
Prompt 参考要求:
- 删除礼貌表达、转场句、口语填充词、重复解释、情绪价值表达
- 保留目标、实体、关键事实、硬约束、软偏好、用户确认、用户否认、数字、时间、决策、理由、风险、缺失信息、证据来源
- 可以使用短句、列表、键值对,不要求自然语言流畅
- 不得改变原意
- 不得把不确定信息改成确定事实
- 不得把建议改成已执行决策
- 不得把 Assistant 推测改成用户确认事实
- 硬约束和用户否认内容必须显式保留
5.7 迭代式细节召回
基础思路:先传递内容的索引给大模型,大模型判断需要哪些细节,通过 Action 召回。召回后再次调用大模型,判断是否需要更多细节。循环直到满足或达到最大迭代次数。
窗口放不下的处理:
- 执行压缩,或要求大模型告诉你可以忽略什么细节
- 报错
实践慎用,面试大胆用。
5.8 核心结论
只要上下文窗口有限,细节就不可能 100% 不丢。成熟的 Agent 不是幻想记住一切,而是通过关键事实提取、细节召回、冲突裁决、模型可读摘要等机制,保证真正影响决策的细节尽量不丢。
六、用户画像
6.1 为什么用户画像重要
模型能力大家都能调用,拉不开差距。用户画像才是私有资产,是 Agent 胜出的杀手锏。
用户对 Agent 的期望是”像真人”,传统标签式画像(男/28岁/一线城市)远远不够。
6.2 反面案例
- 永远在重复询问用户已经说过的事情
- 明知道用户不喜欢,还是反复推荐
- 看起来回答正确,实际上牛头不对马嘴
- 输出风格和用户完全不匹配
- 错误画像瞎指导(偶然行为被当成稳定偏好)
6.3 用户画像维度
| 维度 | 说明 | 影响 |
|---|---|---|
| 目标画像 | 用户想达成什么 | 指导内容生成方向 |
| 能力画像 | 用户理解能力如何 | 决定输出深度和语言 |
| 偏好画像 | 喜欢什么、不喜欢什么 | 不喜欢什么比喜欢什么更重要 |
| 决策画像 | 用户怎么做选择 | 指定候选方案排序和解释方式 |
| 关系画像 | 用户讨论的人之间什么关系 | 影响语气、权限、信息透露 |
6.4 用户画像的影响范围
几乎可以影响 Agent 的任何环节:
- 用户输入理解(如”性价比”对不同用户含义不同)
- 意图识别和 Slot Filling
- 上下文选择(不同步骤需要不同画像)
- Plan 和路径选择
- 最终输出(如写作风格)
6.5 用户画像来源
| 来源 | 说明 | 注意事项 |
|---|---|---|
| 用户明确表达 | 置信度最高 | 区分长期偏好和当前状态 |
| 行为推断 | 从用户行为中推断 | 做了 ≠ 喜欢(买低价可能是买给父母) |
| 多轮对话提取 | 分析对话过程 | 重点看”为什么”而不只是”做了什么” |
| 外部业务系统 | 接入已有画像 | 可能需要中间转换 |
核心:所有画像都只是一定程度上可信,并非完全可信。
6.6 提取时机
| 时机 | 说明 | 适用场景 |
|---|---|---|
| 实时提取 | 每轮对话结束后立即判断 | 生成当前画像,不适合修改长期画像 |
| 对话结束后提取 | 一次对话/任务结束后统一提取 | 可以看到完整对话过程 |
| 离线提取 | 定期分析近期行为和对话 | 发现趋势、合并重复、判断稳定性 |
最佳实践:实时 + 离线的混合方式。实时保证及时性,离线保证准确性。
6.7 层级用户画像
三层设计:
- 当前画像:本次对话中的即时偏好
- 候选画像(中期/不稳定/待确定):有待验证的新信号
- 长期画像:沉淀的稳定用户特征
覆盖关系:后者可以覆盖前者。长期偏好一般是候选画像慢慢升级上来的。
6.8 生命周期控制
| 状态 | 说明 |
|---|---|
| 激活 | 活跃状态,经过多次验证 |
| 弱化 | 长期无新证据或出现相反行为 |
| 过期 | 超过有效期,默认不再使用 |
每三个月没有新证据则降级可信度。
6.9 画像冲突裁决原则
- 当前明确表达优先于历史推断
- 用户明确表达优先于行为推断
- 用户纠正优先
- 领域画像优先于全局画像
6.10 4C 稳定性评分模型
用于判断用户偏好是否为一时兴起。
1 | stability_score = w0 × Count + w1 × Continuity + w2 × Cross-context + w3 × Confirmation |
Count(出现次数):跨独立对话的反复验证。公式:count_score = 25 × (1 - e^(-n/3)),效果递减。
Continuity(持续时间):区分一时兴起和稳定偏好的关键。公式:continuity_score = 25 × min(1, ln(1+d)/ln(1+H)),H 取 180 天(心理学理论:激情保持约 90 天)。
Cross-context(跨场景一致性):不同场景下是否表现一致。公式:cross_score = 25 × min(1, max(0, s-1)/4),s 为独立会话数。
Confirmation(用户确认):最可靠的方式。评分参考:
| 确认方式 | 得分 |
|---|---|
| 没有确认 | 0 |
| 没有反对也没有承认 | 0-5 |
| “对,差不多”(有所怀疑) | 10 |
| 明确确认某一场景下成立 | 20 |
| 明确确认长期成立 | 25 |
使用标准:
| 分数 | 状态 | 使用方式 |
|---|---|---|
| 0-29 | candidate | 仅保留,不影响结果 |
| 30-49 | weak/short-term | 只能用于排序参考 |
| 50-69 | active | 可影响推荐,不能作为硬过滤 |
| 70-84 | stable | 可作为默认偏好 |
| 85-100 | confirmed stable | 稳定使用,但仍服从用户当前输入 |
6.11 电商用户画像设计
建议分成三层:
- 全局画像:跨品类的用户特征
- 品类画像:最重要,用户在不同品类下偏好可能完全不同
- 当前购物画像:当前任务的即时偏好
价格偏好高级设计:
- 建立品类级别的价格偏好(用户在不同品类价格偏好不同)
- 通过离线计算:遍历订单,计算购买时价格的百分位数
- 叠加相似类目价格参考(没买过裤子,参考上衣的价格偏好)
注意事项:
- 购买者和使用者可能不是同一个人
- 浏览记录和购物车不等于满意(要分析为什么不满意)
- 广告商品可以轻微违反用户需求说明,但不能太过
七、长任务处理
7.1 长任务的核心难点
不是步骤多、工具调用多,而是不断产生新信息,且信息之间的依赖关系复杂。
信息多且依赖复杂是长任务出错的关键原因。大模型自身能力不足也会影响,但这不是开发者能直接改变的。
核心结论:长任务问题,本质上就是上下文管理问题。
7.2 长任务中的漂移
| 漂移类型 | 原因 | 示例 |
|---|---|---|
| 目标漂移 | Goal Context 管理不善 | 让修空指针,结果重构了几十个文件 |
| 约束漂移 | Constraint Context 管理不善 | 说不能虚构,结果擅自补上”千万级用户” |
| 状态漂移 | Task State Context 管理不善 | 工具返回失败,Agent 标记为成功 |
| 证据漂移 | Evidence Context 管理不善 | 根据两年前文档得出”不支持” |
| 细节丢失 | 上下文压缩不当 | “预算 5000”摘要后变成”预算有限” |
| 错误累积 | Observation Context 管理不善 | “累计用户数”看成”日活用户数”,后续全错 |
7.3 基础解决方案
核心思路:不要让 Agent 一口气跑到最后,在执行过程中不断停下来检查。
Plan 模式:Checkpoint
在关键节点完成后暂停执行并检查:
- 原始目标有没有发生漂移
- 用户硬约束有没有被违反
- 当前任务状态是否准确
- 中间结果和证据是否可信
- 原计划是否仍然适用
- 是否需要 Retry、Rollback 或 Replan
设置位置:业务阶段结束、关键中间产物生成、高风险工具调用后、被大量后续步骤依赖的节点后。
ReAct 模式:每轮检查
每一轮循环开始或结束时检查:
- 目标判断:当前要逼近的最终目标是什么?
- 状态判断:哪些已完成,哪些未完成?
- 约束判断:当前 Action 是否违反硬约束?
- 差距判断:距离目标还缺少什么?(最重要)
- 证据判断:上一轮 Observation 能否支持当前结论?
关键点:不只是总结”我得到了什么”,更要判断”还缺什么”。
7.4 高级解决方案
上下文健康检查与漂移检测
引入独立的 Context Verifier,定期检查上下文是否漂移。可以理解为 Checkpoint 的异步化。
检查内容:Goal 是否偏离、硬约束是否丢失、Task State 是否一致、关键结论是否有 Evidence 支持等。
检测到问题后:输出漂移类型、影响范围和修复建议,交给大模型决定修复方式。
触发时机:阶段结束、上下文占用达到阈值、Replan 前后、出现异常信号。
事件溯源与可信快照
不只维护一份不断被覆盖的当前状态,而是记录关键事件(用户新增约束、Agent 完成步骤、工具返回结果等)。
关键节点生成可信快照。当前状态可通过”最近一次快照 + 后续事件”重新构建。
最大价值:可追溯。发现跑偏时可以定位是哪一次状态更新引入了错误。
恢复方式:回到最近一个可信快照,丢弃后续被污染的状态,重新执行受影响的步骤。
分阶段执行与上下文交接
将长任务拆成多个阶段,每个阶段只使用与自己相关的局部上下文。
阶段结束后生成结构化的上下文交接信息:
- 当前总目标
- 已完成的工作
- 已确认的事实
- 仍然有效的硬约束
- 关键证据及其索引
- 未解决的问题
- 下一阶段需要的输入
大量临时 Observation、失败尝试和局部推理过程留在原阶段,需要时再检索召回。
难点:交接粒度——太少会丢失关键太多又退化成全量传递。
三个方案可以组合使用:分阶段控制上下文规模 + 事件溯源保存完整执行历史 + Context Verifier 定期检查漂移。
八、面试策略
8.1 基础面试策略
围绕五个问题展开:
- 有什么上下文:结合业务挑出核心几类(不只是聊天记录)
- 怎么存:根据结构和生命周期,使用不同存储方式
- 怎么找:根据不同内容使用不同查询方式
- 太长了怎么办:区分普通上下文和关键上下文,不能一刀切
- 压缩后怎么找回细节:保留原始数据和索引,摘要不足时可重新召回
8.2 高级面试策略
不要只谈长期记忆、短期记忆、滑动窗口——这些已没有竞争力。
找一个具体的业务难题,围绕它把 2-3 个机制组合起来。
推荐问题:在有限上下文窗口中,如何既保留稳定的用户偏好,又适应用户临时变化,同时避免压缩后丢失关键细节?
这个问题可以自然串联:用户画像(个性化信息)→ 分层上下文(组织信息)→ 动态编排(本轮放什么)→ 差异化压缩(解决窗口不足)→ 细节召回(找回丢失内容)。
8.3 话术参考
我们不会简单地把所有历史对话都放进 Prompt,而是先将上下文拆成用户信息、目标和约束、任务状态、历史对话、知识内容以及工具结果等几类。根据数据结构和生命周期,分别存放在运行时状态、Redis、MySQL、ES、向量数据库和对象存储中。
每次调用大模型之前,根据当前意图和执行步骤,通过结构化查询、关键词检索和向量检索找出候选上下文,只选择当前任务真正需要的内容进入窗口。
窗口不足时,普通历史对话会摘要,工具结果会抽取关键字段,但目标、硬约束和关键任务状态会独立保留。
摘要和压缩不会删除原始数据。当当前摘要不足以完成指代消解、事实判断或错误定位时,会重新召回原始对话、工具结果和中间产物。
总结
上下文管理的核心就是:Context Window = f(Context)。
Memory 是 Context 的子集,不要过度神化。分层是分而治之思想的体现。摘要和细节召回是双生子。用户画像才是 Agent 的杀手锏。长任务问题本质上是上下文管理问题。
真正的区别不是”上下文存在哪里”,而是”什么内容,应该在什么时间,以什么形式、什么粒度和什么顺序,进入当前的大模型窗口”。