摘要

上下文是 Agent 的有限资源:窗口容量有硬上限,且长上下文下信息召回精度会随长度衰减。业界常见做法里,截断不可逆,纯 Compaction(摘要压缩)有损,而每轮全量对话 RAG 对短会话开销偏大。本文给出一种可工程落地的混合策略:按 token 水位阈值 触发,将较旧对话的 原文 外置至可检索存储;窗口内仅保留 近期原文 + 结构化笔记;此后每轮经 query 改写 → 向量召回 → 重排序 → top-k 注入。细节以原文形式可逆保存,主线以笔记常驻,并附 评测协议 与 AI 可调用的 memory 工具接口。目标是:长对话不爆窗,且外置后信息是「暂时不在窗口」而非「永久丢失」。


1. 引言:为何在「更大窗口」之外仍要管上下文

Context engineering 已成为构建 Agent 的基础问题之一:优化的不是单句 prompt 措辞,而是 每次推理时,哪些 token 应当进入有限窗口。Anthropic 将其概括为在有限注意力预算下寻找 最小高信号 token 集;业界亦观察到 context rot——随窗口内 token 增加,从上下文中精确召回信息的能力下降。

因此,加大窗口只能推迟问题,不能取消问题。长对话 / 长任务仍需显式的上下文管理。

业界常见手段可放在同一谱系中比较:

手段主要作用细节保真主线连续可逆性
Truncation砍最老消息差差否
Compaction摘要压缩后重启窗口差(有损)中–好否
Structured note-taking窗口外持久笔记中好部分
Sub-agent 隔离细任务独立上下文中(视回传)好(主 Agent)视实现
全量对话 RAG每轮检索历史中中是

本文方案落在 note-taking 与 just-in-time retrieval 的交界,并增加两点约束:

  1. 不是每轮都全量向量化,而是 水位触发;
  2. 外置的是原文而非仅摘要,保证细节可逆。

与纯 Compaction 的本质差别:Compaction 是多对一 有损投影;本文对细节做 可逆搬迁,仅对主线做有损但受控的笔记压缩。


2. 问题形式化

设:

  • (C):模型上下文容量(token)
  • (u_t):第 (t) 轮入模前的已用 token 预估
  • (r):预留空间(输出上限 + 工具 schema 抖动 + 安全边界)
  • (\theta):触发水位(默认 0.8)
  • (B):每轮允许注入的历史增量预算(token)

触发条件(主):

[ u_t \ge \theta \cdot (C - r) ]

紧急档(兜底):

[ u_t \ge 0.95 \cdot (C - r) ]

触发后执行批量外置,直至 (u) 回落至安全区(例如 (0.6C \sim 0.7C)),并进入冷却期,避免逐轮挤牙膏式抖动。

目标:

  1. 持续对话中任务状态可延续;
  2. 外置前存在的事实细节在自然语言追问下可恢复;
  3. 单轮注入历史不超过 (B);
  4. 未触发阈值的短对话,路径与基线一致,不引入额外召回延迟。

反目标(明确禁止作为唯一策略):

  • 仅按「删除最老 N 轮」推进——信息不可逆丢失,违反「可恢复」目标。

3. 分层状态模型

采用与 working memory / episodic store 对齐的命名,避免自造黑话:

C0  System     系统提示、工具 schema、固定规则
C1  Working    最近窗口内的对话原文(始终保留,不外置)
C2  Scratchpad 结构化笔记:目标 / 已完成 / 未完成 / 关键约束 / 最近决策
C3  Episodic   外置对话原文块 + 元数据 + 向量索引

每轮注入集合:

[ \mathrm{Prompt}_t = C_0 \oplus C_1 \oplus C_2 \oplus \mathrm{TopK}_k \oplus x_t ]

其中 (\mathrm{TopK}_k) 为可选的历史召回片段;(x_t) 为当前用户输入(及必要的工具结果)。

不变式:

  1. (C_3) 保存 raw text;(C_2) 不得替代 (C_3) 作为细节唯一存储。
  2. (C_1) 存在轮数与 token 双下界(例如最近 12 轮 或 6k tokens,取更保守者)。
  3. 摘要只出现在 (C_2),用于任务主线,不承担细节检索职责。

4. 方法

4.1 触发与防抖

水位行为
( < 0.70(C-r) )正常对话,不外置、不强制召回
( \ge 0.80(C-r) )执行外置(主阈值)
( \ge 0.95(C-r) )紧急外置 + 收紧 (k)
  • 批量:一次迁移到安全区,而不是每次只搬一轮。
  • 冷却:外置后 (N) 轮内或水位未重新越界前,不再连续触发。
  • 预留 (r):必须覆盖系统提示、工具定义与模型输出,否则「外置后立刻又满」。

4.2 切块与存储契约

外置单元(chunk)建议:

字段说明
chunk_id主键,供工具引用与删除
session_id / thread_id会话归属
turn_range起止轮次
roleuser / assistant / tool
timestamp时间
raw_text原文(召回时原样取回)
summary_hint可选短标签,仅辅助过滤展示

切块策略:

  • 主路径:按主题 / 连续相关轮次合并,避免一问一答过碎导致检索噪声。
  • 辅路径:超长单轮可再切,设 token 上下界。
  • 可选重叠:相邻块少量重叠,降低边界切断实体的概率。

写入动作与摘要更新解耦但同事务语义上成对完成:

  1. 块写入 (C_3) 并建索引;
  2. 从窗口移除对应旧轮原文;
  3. 生成或增量更新 (C_2);
  4. 记录触发与释放的 token 指标。

4.3 结构化笔记(C2)模板

固定结构,便于跨轮 diff 与评测:

[目标] 当前任务一句话
[已完成] 3–5 条
[未完成/待确认] 优先级排序
[关键约束] 数字、专名、用户偏好、硬性边界
[最近决策] 谁在何时决定了什么

容量目标:数百 token 量级。宁可短而准,不要流水账。

4.4 每轮召回链路

x_t
  → 改写 q'(补全指代 / 抽实体)
  → Embedding
  → 向量宽召回 top-R(R ≫ k,例如 20–50)
  → Rerank
  → 截断至 top-k(默认 3–8),并受预算 B 约束
  → 过滤与去重(session、chunk_id、时间序)
  → 拼入 Prompt

Query 改写(关键):
用户说「刚才那个方案呢?」时,直接嵌入该句召回差。改写可采用:最近 1–2 轮 + 当前句生成独立完整检索句,或规则抽取专名/数字;失败则降级为当前句原文。

何时跳过召回:

  • (C_3) 为空(从未触发);
  • 明确新开话题且无「之前 / 上次」类信号;
  • 可选:仅在出现回指词时强制召回,其余依赖自动轻量路径。

4.5 失败降级

故障行为
向量服务不可用仅 (C_0 \oplus C_1 \oplus C_2),记 fallback
召回为空同上;输出侧约束禁止编造旧细节
Rerank 失败退回向量分数 top-k
笔记生成失败保留上一版 (C_2),标记下轮重建

降级路径不得差于「硬截断」——这是最低线。

4.6 为何比纯 Compaction 更不易「丢信息」

将「丢失」定义为 永久不可恢复:

  • Compaction:压缩函数 (f: \mathrm{history} \to \mathrm{summary}) 多对一且无逆——细节永久丢失。
  • 本文:细节路径为 (\mathrm{history} \to C_3(\mathrm{raw}) \to \mathrm{retrieve}),在检索成功假设下可逆;有损仅发生在 (C_2) 主线摘要。

因此,在 原文入库成立 且 召回评测达标 的前提下,信息风险从「必然有损」变为「召回失败时的条件有损」。
这也意味着:没有召回评测,就不能声称「不易丢」(见 §6)。


5. 工具接口:AI 可调用的记忆能力

上下文管理不应全是框架黑盒。建议 自动保底 + 工具增强:

模式触发方职责
自动档水位阈值;可选每轮轻量 top-k防爆窗、保底可召回
工具档模型按需调用主动回忆、主动写入、查询状态

5.1 单工具 + 英文 type(能力面收敛)

与「一领域一工具、type 切换、help 必调」的工程约定一致,type 仅英文枚举:

memory {"type": "...", ...}
type作用典型参数默认权限
help用法与参数说明—开
recall按 query 检索历史query, top_k?开
remember写入一条长期要点text, tags?开(限长限频)
status水位与笔记摘要—开
offload手动触发外置until_tokens?默认关
forget删除 chunk / 范围chunk_id 等默认关 / HITL

调用示例(示意):

memory {"type":"help"}
memory {"type":"recall","query":"阈值触发与外置的结论","top_k":5}
memory {"type":"remember","text":"type 仅允许英文枚举","tags":["constraint"]}
memory {"type":"status"}

5.2 recall 返回契约

每条结果必须 可直接进上下文且限长,并携带溯源:

[ts | turn a-b | chunk_id]
(raw 片段,截断至单条上限)
  • 无结果:显式 no match,禁止模型编造;
  • 单条与总条数同时限幅,受 (B) 约束;
  • 返回 chunk_id,便于后续引用或受控 forget。

5.3 与自动路径的关系

  • 自动轻量召回可保持开启,避免模型「忘记调工具」时完全失忆;
  • 定向、高成本、高精度召回可主要走 memory.recall;
  • remember 与自动切块 去重:同一 chunk_id / 近重复文本不双写;
  • remember 适合偏好与硬约束,不适合整段闲聊灌库。

5.4 工具描述要点(ACI)

  • 声明 type 英文枚举;不确定先 help;
  • 写清 Use / Do not use;
  • 说明返回格式与 no match 语义;
  • 高危 type 默认关闭,符合最小权限。

6. 评测协议

没有评测,不能声称外置后「信息没丢」。建议最小协议如下。

6.1 任务集

  1. Needle 回填(细节可恢复)
    外置前埋入 N 条事实(数字、专名、约束);触发外置后,用自然语言(含指代)提问,测是否命中。

  2. 任务连续性(主线)
    多步待办对话;中途强制触发外置;检查后续是否仍按 (C_2) 推进目标与未完成项。

  3. 窗口压力
    合成长度至 2× / 3× 原生窗口;比较完成率、中途失败类型、编造率。

  4. 基线对比
    同一任务集上比较:

    • Truncation
    • Compaction-only
    • 每轮全量对话 RAG
    • 本方法

6.2 指标

指标含义
Recall@k(事实级)外置后细节可找回比例
Task completion Δ相对未外置基线的任务成功率差
Injected tokens / turn注入体积
Latency p50/p95embed / recall / rerank 分解
Fallback rate降级频率
Hallucination-on-miss召回为空时是否编造旧细节

6.3 建议合格线(可按产品调整)

  • Recall@5 达到预设阈值(例如实验集 ≥ 0.85,以你的数据为准);
  • 外置前后 Task completion 下降不超过 (\varepsilon);
  • 未触发路径与截断/全量基线在行为与延迟上无显著回归;
  • Fallback 时输出不劣于 truncation。

6.4 必埋日志

trigger_ratio, tokens_freed, chunks_offloaded
query_raw, query_rewritten
recall_ids, rerank_scores, final_k
latency_embed / recall / rerank
fallback_flag

用于区分:「没存进去」「没搜到」「搜到了没排进 top-k」「进窗口了模型仍答错」——四类失败责任完全不同。


7. 失败模式与局限

失败模式影响缓解
改写失败召回错/空规则兜底 + 回指词强制召回
块边界切断实体关键事实检不到主题切块 + 重叠 + 实体检查
Embedding / rerank 漂移排序不稳定期离线评测集回归
笔记过度膨胀吃掉窗口(C_2) 硬上限与结构模板
原文入库隐私合规风险加密、保留策略、分租户
双路径重复注入冗余与成本chunk_id 去重

适用边界:

  • 适合:单线程长对话、长任务 Agent、个人知识型会话。
  • 不适合:短会话(无触发收益)、强实时超低延迟且不愿付 rerank 成本的路径(可只用自动截断或更轻策略)。

第一版明确不做: 跨租户知识融合、以删除向量库代替审计日志、多路图检索融合。


8. 结论

长对话的上下文管理,不必在「全量保留」与「有损摘要」之间二选一。本文策略可概括为三句话:

  1. 主线用笔记(C2)常驻,保证任务不漂;
  2. 细节用原文外置(C3)保存,保证可逆;
  3. 按水位触发搬迁,按改写召回 + 重排序按需注入,保证窗口体积可控。

再加一层 memory 工具面(help / recall / remember / status),让模型在自动保底之外能主动读写记忆,且高危操作默认关闭。

工程上是否合格,不取决于架构图是否好看,而取决于 §6 的 Recall@k、任务完成率与降级行为是否达标。先定义丢失,再定义不丢;先写评测,再谈不易丢失。


参考

  1. Anthropic. Effective context engineering for AI agents.
  2. Anthropic. Building effective agents.
  3. Guo et al. Empowering Working Memory for Large Language Model Agents. arXiv:2312.17259.
  4. 业界 RAG 与重排序(rerank)通用实践;具体实现栈可按项目替换(向量库 / rerank 模型)。