收藏!9种大模型上下文记忆方案,帮你省token又不丢信息(小白程序员必备)
大模型无状态特性导致对话记忆需拼接历史,但会引发token消耗和注意力稀释问题。本文介绍全量记忆、滑动窗口、摘要压缩、向量记忆(RAG)、分层混合记忆、状态变量提取、工具/函数调用等8种方案,从简单到复杂、从廉价到智能,助你按需选择。其中向量检索(RAG)是工业界主流,分层混合记忆兼顾短时连贯与长时检索,状态变量提取适用于高度结构化任务。建议根据项目需求选择合适方案,平衡token节省与信息保留能力。
一、为什么记忆必然消耗token?
很多小伙伴可能觉得,大模型就像一个人,你说过的话它应该天然记得住。
错!
大模型本质上是一个无状态的函数。
每次调用都是独立的,它没有任何“记忆细胞”。
为了让AI记住之前聊过什么,唯一的办法就是:把历史对话拼接到下一次请求里。
这就是所谓的“上下文注入”。

看到没?
第N次请求携带的历史,是前N-1轮的总和。
token消耗随着对话轮数线性增长——更准确地说,是O(n)级别的增长。
但事情没这么简单。
Transformer模型的核心是自注意力机制,它的计算复杂度是**O(n²)**。
也就是说,输入长度翻一倍,计算量翻四倍。
更可怕的是,当输入过长时,模型会患上“中间迷失症”——位于长文本中间的信息被严重忽略。
所以,我们的真实困境是:
保留全部历史 → token爆炸 + 注意力稀释 → 又贵又笨
丢弃历史 → 信息丢失 → AI变“金鱼脑”
有没有一条中间道路?
有。
下面我会介绍8种方案,从简单到复杂,从廉价到智能,你可以根据自己的场景按需选择。
二、方案一:全量记忆
简单粗暴,但不推荐。
这是最直觉的实现:把所有对话都存下来,每次请求全部带上。
public class FullMemorySession {
// 使用LinkedList存储全部对话轮次
private List<Message> fullHistory = new ArrayList<>();
public void addTurn(String userMsg, String assistantMsg) {
fullHistory.add(new Message("user", userMsg));
fullHistory.add(new Message("assistant", assistantMsg));
}
public String buildContext() {
StringBuilder sb = new StringBuilder();
for (Message msg : fullHistory) {
sb.append(msg.getRole()).append(": ").append(msg.getContent()).append("\n");
}
return sb.toString();
}
// 消息实体
staticclass Message {
String role;
String content;
// 构造器、getter省略
}
}
代码解析:逻辑非常直接——fullHistory列表保存所有消息,buildContext()把它们全部拼接成字符串。没有任何优化。
优点:
- 信息零损失,完美保留每句话
- 实现极简单,5分钟写完
缺点:
- token消耗随轮数线性增长,100轮可能几万token
- 达到模型上下文上限后(比如8K/128K),旧消息会被截断
- 响应时间越来越慢,账单越来越高
适用场景:只适合Demo演示、调试测试,或者保证对话不超过10轮的极短场景。
生产环境慎用。
三、方案二:滑动窗口
省token,但记性差。
滑动窗口只保留最近N轮对话,超出窗口的直接丢弃。
public class SlidingWindowMemory {
privatefinalint windowSize; // 窗口大小,比如5轮
privatefinal Queue<Message> window; // 用队列自动淘汰旧数据
public SlidingWindowMemory(int windowSize) {
this.windowSize = windowSize;
this.window = new ArrayDeque<>();
}
public void addTurn(String userMsg, String assistantMsg) {
// 加入新消息
window.offer(new Message("user", userMsg));
window.offer(new Message("assistant", assistantMsg));
// 如果超过窗口大小(注意:一轮=2条消息),就移除头部
while (window.size() > windowSize * 2) {
window.poll();
}
}
public String buildContext() {
return window.stream()
.map(m -> m.getRole() + ": " + m.getContent())
.collect(Collectors.joining("\n"));
}
}
代码解析:ArrayDeque作为队列,offer()在尾部添加,当大小超出windowSize * 2(因为一轮包含用户和助手两条消息)时,poll()移除最旧的。
这样窗口始终保持固定大小。
优点:
- token消耗严格可控,不会无限增长
- 实现简单,性能高
- 响应速度快
缺点:
- 早期信息永久丢失。用户第一句说“我是VIP会员”,第20轮问“我的会员权益”,AI已经忘了
- 无法处理需要长期记忆的任务
适用场景:客服快速问答、闲聊机器人、临时对话——那些不需要记住早期信息的场景。
四、方案三:摘要压缩
让AI自己总结记忆。
这个方案的想法很巧妙:不保留原始对话,而是定期让大模型把旧对话“压缩”成一段摘要,只保留关键信息。
public class SummaryMemory {
private String summary = ""; // 历史摘要
private List<Message> recentMessages = new ArrayList<>(); // 未压缩的新消息
privatefinalint compressThreshold; // 触发压缩的token阈值
privatefinal LLMClient llm; // 大模型客户端
public SummaryMemory(LLMClient llm, int compressThreshold) {
this.llm = llm;
this.compressThreshold = compressThreshold;
}
public void addTurn(String userMsg, String assistantMsg) {
recentMessages.add(new Message("user", userMsg));
recentMessages.add(new Message("assistant", assistantMsg));
// 估算当前token数,超过阈值则触发压缩
if (estimateTokenCount() > compressThreshold) {
compress();
}
}
private void compress() {
// 构建待压缩的内容:旧摘要 + 新消息
String toCompress = summary + "\n" + formatMessages(recentMessages);
String prompt = """
请将以下对话历史压缩成一段简洁的摘要,保留:
1. 用户的关键信息(姓名、偏好、身份、已做出的决定)
2. 重要的任务状态和上下文
3. 任何后续对话可能需要的事实
原始对话:
%s
摘要:
""".formatted(toCompress);
// 调用大模型生成摘要
String newSummary = llm.chat(prompt);
this.summary = newSummary;
// 压缩后清空近期消息,但可以保留最后一轮作为锚点(防止断层)
this.recentMessages.clear();
}
public String buildContext() {
// 上下文 = 摘要 + 最近未压缩的消息
if (summary.isEmpty()) {
return formatMessages(recentMessages);
}
return"【历史摘要】\n" + summary + "\n\n【最近对话】\n" + formatMessages(recentMessages);
}
private int estimateTokenCount() {
// 简单估算:中文1字≈2token,英文1词≈1.3token,这里粗略用字符数/2
int totalChars = summary.length() + formatMessages(recentMessages).length();
return totalChars / 2;
}
private String formatMessages(List<Message> msgs) {
return msgs.stream()
.map(m -> m.getRole() + ": " + m.getContent())
.collect(Collectors.joining("\n"));
}
}
代码详解:
summary字段存储压缩后的历史摘要,初始为空。recentMessages存储尚未被压缩的新消息。- 每次添加消息后,估算总token数(摘要+新消息),如果超过阈值,调用
compress()。 - 压缩时,将旧摘要和新消息一起发给大模型,让它生成一个新的、更精炼的摘要。
- 压缩完成后清空
recentMessages,但也可以选择保留最后1-2轮,防止摘要丢失近期细节。 buildContext()返回摘要+最近消息的拼接,作为下次请求的上下文。
优点:
- 压缩比极高:100轮对话可能压缩成200字摘要,token节省90%以上
- 关键信息被提炼出来,比滑动窗口聪明得多
- 成本可控,摘要生成的调用次数不多(每隔N轮一次)
缺点:
- 摘要可能失真:模型可能漏掉重要细节或产生幻觉
- 每次压缩需要额外调用LLM,增加几十毫秒延迟
- 摘要的“信息密度”随着压缩次数增加而下降(反复压缩会丢失细节)
适用场景:长周期对话(几十到几百轮),对信息完整性要求不是100%严谨的场景,比如教育辅导、角色扮演。
五、方案四:向量记忆(RAG)
检索相关而不是保留全部。
这是目前工业界最主流的方案。
思路是:不保存全部历史,而是把历史消息向量化后存入数据库,每次只检索最相关的几条历史。
public class VectorMemory {
privatefinal EmbeddingClient embeddingClient; // 向量化模型,如OpenAI embedding
privatefinal VectorDatabase vectorDb; // 向量数据库,如Milvus、Chroma
privatefinalint topK = 5; // 每次检索几条最相关的历史
public VectorMemory(EmbeddingClient embeddingClient, VectorDatabase vectorDb) {
this.embeddingClient = embeddingClient;
this.vectorDb = vectorDb;
}
// 存储一条历史消息(每个消息单独存储,带上元数据)
public void saveMessage(String role, String content, Map<String, Object> metadata) {
// 1. 调用embedding接口,将文本转为向量
float[] vector = embeddingClient.embed(content);
// 2. 存入向量数据库
VectorRecord record = new VectorRecord(vector, content, metadata);
vectorDb.insert(record);
}
// 检索与当前问题最相关的历史记忆
public List<Message> retrieveRelevantHistory(String currentQuestion) {
// 将当前问题向量化
float[] queryVector = embeddingClient.embed(currentQuestion);
// 在数据库中做相似度搜索,返回topK条最相似的历史消息
List<VectorRecord> results = vectorDb.search(queryVector, topK);
// 转换成Message对象
return results.stream()
.map(r -> new Message((String)r.getMetadata().get("role"), r.getContent()))
.collect(Collectors.toList());
}
// 构建上下文:检索结果 + 最近几轮(可选)
public String buildContext(String userQuestion) {
List<Message> relevantHistory = retrieveRelevantHistory(userQuestion);
StringBuilder context = new StringBuilder("相关历史记忆:\n");
for (Message msg : relevantHistory) {
context.append(msg.getRole()).append(": ").append(msg.getContent()).append("\n");
}
return context.toString();
}
}
代码详解:
- 每条消息单独存储,调用
embeddingClient.embed()将其转为高维向量(比如1536维)。 - 向量数据库存储向量+原始文本+元数据(角色、时间戳等)。
- 当用户发来新问题时,同样将问题向量化,然后到数据库中做余弦相似度搜索,找到最相似的
topK条历史消息。 - 这些检索出的历史消息就是“与当前问题最相关的记忆”,拼接进上下文。
优点:
- token消耗极低:每次只带5-10条最相关的历史,而不是几百条
- 可以访问非常久远的记忆:只要存储了,就能检索到,不受窗口限制
- 灵活性高:可以混入知识库、FAQ等外部知识
缺点:
- 检索可能不准确:如果embedding模型质量差,或者问题与历史的相关性未被捕捉到,就会漏掉关键信息
- 需要额外组件:向量数据库、embedding服务,增加系统复杂度
- 有延迟:embedding调用+向量检索,大约增加50-200ms
适用场景:绝大多数生产环境——智能客服、AI助手、个性化推荐等。
这是目前最推荐的方案。
六、方案五:分层混合记忆
它是工业级最强方案。
没有单一方案是完美的。真正的工业级系统,往往会组合多种策略,形成分层记忆。
下面这张图展示了一个典型的混合记忆架构:

Java实现的核心骨架:
public class HierarchicalMemory {
private SlidingWindowMemory shortTerm; // L1 短期
private SummaryMemory midTerm; // L2 中期摘要
private VectorMemory longTerm; // L3 长期向量
privatefinalint SUMMARY_INTERVAL = 10; // 每10轮触发一次摘要压缩
privateint turnCount = 0;
public HierarchicalMemory(LLMClient llm, EmbeddingClient embed, VectorDatabase db) {
this.shortTerm = new SlidingWindowMemory(5); // 保留最近5轮
this.midTerm = new SummaryMemory(llm, 2000); // token超2000压缩
this.longTerm = new VectorMemory(embed, db);
}
public void addTurn(String userMsg, String assistantMsg) {
turnCount++;
// 存入三层记忆
shortTerm.addTurn(userMsg, assistantMsg);
midTerm.addTurn(userMsg, assistantMsg);
longTerm.saveMessage("user", userMsg, Map.of("turn", turnCount));
longTerm.saveMessage("assistant", assistantMsg, Map.of("turn", turnCount));
// 每10轮额外触发一次摘要同步(可选)
if (turnCount % SUMMARY_INTERVAL == 0) {
midTerm.compress(); // 强制压缩
}
}
public String buildContext(String currentQuestion) {
// 1. 短期记忆(最近对话)—— 最重要,直接拼接
String shortContext = shortTerm.buildContext();
// 2. 检索长期记忆(基于当前问题)
List<Message> longMemory = longTerm.retrieveRelevantHistory(currentQuestion);
String longContext = formatMessages(longMemory);
// 3. 中期摘要(如果摘要非空)
String midContext = midTerm.getCurrentSummary();
// 4. 按重要性组装:短期 > 检索结果 > 摘要
StringBuilder finalContext = new StringBuilder();
finalContext.append("【最近对话】\n").append(shortContext).append("\n");
if (!longContext.isEmpty()) {
finalContext.append("【相关历史】\n").append(longContext).append("\n");
}
if (midContext != null && !midContext.isEmpty()) {
finalContext.append("【历史摘要】\n").append(midContext).append("\n");
}
return finalContext.toString();
}
}
代码解析:
- L1 短期:滑动窗口保留最近5轮,保证对话连贯性,延迟最低。
- L2 中期:摘要压缩,当消息积累到一定程度(比如token超2000或每10轮)就压缩一次,保留全局脉络。
- L3 长期:向量数据库存储每条消息,支持按语义检索,解决“长尾记忆”问题。
- 构建上下文时:优先保证短期(最可靠),然后加上向量检索出的相关历史(弥补窗口丢弃的),最后补充摘要(作为兜底)。
优点:
- 兼具短时连贯、长时检索、全局摘要,覆盖几乎所有场景
- token消耗可控(短期固定+检索topK+摘要)
- 即使检索失败,摘要和短期窗口也能兜底
缺点:
- 实现复杂,需要维护多个组件
- 需要精细调参(窗口大小、摘要频率、检索数量)
适用场景:大型生产系统、企业级AI应用,对体验和成本都有高要求的场景。
七、方案六:状态变量提取
该方案需要极致的结构化压缩。
有些场景下,真正需要记忆的不是整个对话,而是几个关键状态变量。
比如订票机器人只需要知道:{目的地: "北京", 日期: "2026-05-01", 人数: 2}。
public class StateVariableMemory {
private Map<String, Object> state = new HashMap<>(); // 核心状态
// 通过LLM从对话中提取结构化状态
public void updateState(String userMsg, String assistantMsg, LLMClient llm) {
String extractPrompt = """
从以下对话中提取关键状态变量,以JSON格式输出。
当前已有状态:%s
用户最新消息:%s
AI回复:%s
请更新状态,只输出JSON,不要其他内容。
""".formatted(toJson(state), userMsg, assistantMsg);
String jsonResponse = llm.chat(extractPrompt);
Map<String, Object> newState = parseJson(jsonResponse);
state.putAll(newState); // 合并更新
}
public String buildContext() {
// 上下文只需要展示当前状态,而不是历史对话
return"当前会话状态:" + toJson(state);
}
}
优点:
- 极致省token:几KB的状态就能代替几十KB的对话
- 结构化,模型更容易理解
缺点:
- 只适合高度结构化的任务(订票、填表、参数收集)
- 提取状态本身需要调用LLM,有额外成本
适用场景:任务型对话、表单填写、配置向导。
八、方案七:工具/函数调用
把记忆“外包”给外部系统。
大模型不是万能的,记忆完全可以交给外部数据库。
模型只需要学会调用“保存记忆”和“查询记忆”的工具。
public class ToolBasedMemory {
// 定义两个工具函数
@Tool(name = "save_memory", description = "保存一条重要信息到长期记忆")
public void saveMemory(String key, String value) {
externalDB.put(key, value);
}
@Tool(name = "recall_memory", description = "根据关键词回忆之前保存的信息")
public String recallMemory(String key) {
return externalDB.get(key);
}
// 在对话循环中,让模型自主决定何时调用这些工具
}
这种方案让模型自主管理记忆——它觉得重要就存,需要就用。这是目前AI Agent的主流做法。
优点:极其灵活,模型可以按需存取;token消耗几乎为零(只传工具调用结果)。缺点:依赖模型自身的函数调用能力,容易出错或漏存。
适用场景:Agent系统、自主决策类应用。
九、终极对比
| 方案 | token节省效果 | 信息保留能力 | 实现复杂度 | 推荐指数 |
|---|---|---|---|---|
| 全量记忆 | 0%(无节省) | 100% | ⭐ | ❌ 不推荐 |
| 滑动窗口 | 极高(固定) | 差(只留近期) | ⭐ | ⭐⭐ 短对话可用 |
| 摘要压缩 | 高(70-90%) | 中(可能失真) | ⭐⭐⭐ | ⭐⭐⭐⭐ 长对话 |
| 向量检索(RAG) | 高(每次topK) | 高(语义检索) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ 首选 |
| 分层混合 | 高 | 极高 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ 工业级 |
| 状态变量 | 极高(近乎0) | 中(仅结构化) | ⭐⭐ | ⭐⭐⭐ 任务型 |
| 工具调用 | 极高 | 中(靠模型) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ Agent场景 |
总结
回到最初的问题:有没有方案既能保留上下文记忆,又能省token?
我的答案是:有,但不存在“免费午餐”。
每一分token的节省,都换来了系统复杂度的增加或记忆精度的下降。
根据我的实战经验,给你几条直接的建议:
- 如果你刚开始做MVP:直接用滑动窗口(最近10轮),上线跑起来再说。先验证产品价值,再优化成本。
- 如果你做的是通用客服/AI助手:首选向量检索(RAG)。这是当前最成熟、性价比最高的方案。配合一个小的滑动窗口(3-5轮)保证对话连贯性,效果已经很好了。
- 如果你的对话轮次非常长(100+)且信息密度高:上分层混合记忆。短期窗口+中期摘要+长期向量,三者配合才能既省token又不丢信息。
- 如果你做的是表单/订票/参数收集:状态变量提取是王道。几十个字段就能代表整个会话,token几乎不增长。
- 永远不要在生产环境用全量记忆——除非你预算无限且用户只聊5句话。
最后
对于正在迷茫择业、想转行提升,或是刚入门的程序员、编程小白来说,有一个问题几乎人人都在问:未来10年,什么领域的职业发展潜力最大?
答案只有一个:人工智能(尤其是大模型方向)
当下,人工智能行业正处于爆发式增长期,其中大模型相关岗位更是供不应求,薪资待遇直接拉满——字节跳动作为AI领域的头部玩家,给硕士毕业的优质AI人才(含大模型相关方向)开出的月基础工资高达5万—6万元;即便是非“人才计划”的普通应聘者,月基础工资也能稳定在4万元左右。
再看阿里、腾讯两大互联网大厂,非“人才计划”的AI相关岗位应聘者,月基础工资也约有3万元,远超其他行业同资历岗位的薪资水平,对于程序员、小白来说,无疑是绝佳的转型和提升赛道。

对于想入局大模型、抢占未来10年行业红利的程序员和小白来说,现在正是最好的学习时机:行业缺口大、大厂需求旺、薪资天花板高,只要找准学习方向,稳步提升技能,就能轻松摆脱“低薪困境”,抓住AI时代的职业机遇。
如果你还不知道从何开始,我自己整理一套全网最全最细的大模型零基础教程,我也是一路自学走过来的,很清楚小白前期学习的痛楚,你要是没有方向还没有好的资源,根本学不到东西!
下面是我整理的大模型学习资源,希望能帮到你。

👇👇扫码免费领取全部内容👇👇

1、大模型学习路线

2、从0到进阶大模型学习视频教程
从入门到进阶这里都有,跟着老师学习事半功倍。

3、 入门必看大模型学习书籍&文档.pdf(书面上的技术书籍确实太多了,这些是我精选出来的,还有很多不在图里)

4、 AI大模型最新行业报告
2026最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

5、面试试题/经验

【大厂 AI 岗位面经分享(107 道)】

【AI 大模型面试真题(102 道)】

【LLMs 面试真题(97 道)】

6、大模型项目实战&配套源码

适用人群

四阶段学习规划(共90天,可落地执行)
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
-
硬件选型
-
带你了解全球大模型
-
使用国产大模型服务
-
搭建 OpenAI 代理
-
热身:基于阿里云 PAI 部署 Stable Diffusion
-
在本地计算机运行大模型
-
大模型的私有化部署
-
基于 vLLM 部署大模型
-
案例:如何优雅地在阿里云私有部署开源大模型
-
部署一套开源 LLM 项目
-
内容安全
-
互联网信息服务算法备案
-
…
👇👇扫码免费领取全部内容👇👇

3、这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)