💾 记忆与上下文窗口管理¶
模型"看完就忘",上下文窗口有限且按 token 计费。记忆与上下文管理决定了成本、效果、是否越权。本页讲清短期/长期记忆、上下文裁剪策略、窗口优化、隔离安全。以官方实践为准。
📌 适用版本 / 更新日期:概念与范式稳定;最后更新 2026-08。
1. 两类记忆¶
| 类型 | 是什么 | 实现 |
|---|---|---|
| 短期记忆 | 本轮对话历史 | messages 数组传入模型 |
| 长期记忆 | 跨会话记住的用户/业务信息 | 向量库 / 数据库,检索后拼入 |
最大误解
"模型记得之前聊过"是错觉——每次调用都是独立的,所谓记忆是你把历史重新拼进 prompt。忘记拼 = 模型失忆。
2. 上下文窗口:有限且贵¶
- 窗口 = 单次能看到的最大 token。超出被截断(末尾或中间丢失)。
- 输入 + 输出都计费。每轮重发全历史 → 成本随轮数线性增长。
Lost in the middle
长上下文里,放开头和结尾的信息模型最关注,中间易忽略。关键信息别塞一大段中间。
3. 上下文裁剪策略(成本与效果平衡)¶
| 策略 | 做法 | 取舍 |
|---|---|---|
| 滑动窗口 | 只留最近 N 轮 | 简单,但忘早期约定 |
| 摘要压缩 | 旧对话交给模型总结成一段 | 省 token,摘要可能丢细节 |
| 检索式记忆 | 长期记忆存向量库,按需召回相关片段 | 精准,需 RAG 基建 |
| 关键事实抽取 | 把"用户偏好/约定"抽成结构化存库 | 稳定,需抽取逻辑 |
function buildContext(history: Msg[], max = 20) {
if (history.length <= max) return history
const old = history.slice(0, -max)
const recent = history.slice(-max)
const summary = await summarize(old) // 调模型总结
return [{ role: 'system', content: `早期摘要: ${summary}` }, ...recent]
}
务实组合
短期用滑动窗口保新鲜,长期用向量检索保准确,关键约定用结构化抽取保稳定。三者结合最稳。
4. 长期记忆与越权¶
flowchart LR
U[用户问题] --> R[向量检索长期记忆]
R -->|按 userId 过滤| M[(记忆库)]
M --> C[拼入 prompt]
记忆越权坑(严重)
长期记忆检索必须按 userId 隔离 + 权限校验,否则 A 用户的历史被 B 用户检索到 = 数据泄露。工具执行时也要再校验"只能读自己的数据"(见安全)。
5. 成本联动¶
6. 踩坑汇总¶
记忆/上下文高频坑
- 历史无限堆积 → 超窗口 + 成本爆炸。
- 关键信息塞上下文中间被遗忘。
- 长期记忆不按用户隔离 → 越权。
- 摘要过度压缩丢关键约束。
- 把密钥/PII 存进记忆库 → 二次泄露。
衔接:RAG · 向量数据库 · Vercel AI SDK