收藏!9种大模型上下文记忆方案,帮你省token又不丢信息(小白程序员必备)

张开发
2026/4/17 8:50:38 15 分钟阅读

分享文章

收藏!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 ListMessagefullHistorynew ArrayList();public void addTurn(String userMsg, String assistantMsg){fullHistory.add(new Message(user, userMsg));fullHistory.add(new Message(assistant, assistantMsg));}public StringbuildContext(){StringBuilder sbnew StringBuilder();for(Message msg:fullHistory){sb.append(msg.getRole()).append(: ).append(msg.getContent()).append(\n);}returnsb.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 QueueMessagewindow;// 用队列自动淘汰旧数据 public SlidingWindowMemory(int windowSize){this.windowSizewindowSize;this.windownew 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 StringbuildContext(){returnwindow.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 ListMessagerecentMessagesnew ArrayList();// 未压缩的新消息 privatefinalint compressThreshold;// 触发压缩的token阈值 privatefinal LLMClient llm;// 大模型客户端 public SummaryMemory(LLMClient llm, int compressThreshold){this.llmllm;this.compressThresholdcompressThreshold;}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 voidcompress(){// 构建待压缩的内容旧摘要 新消息 String toCompresssummary \n formatMessages(recentMessages);String prompt 请将以下对话历史压缩成一段简洁的摘要保留1. 用户的关键信息姓名、偏好、身份、已做出的决定2. 重要的任务状态和上下文3. 任何后续对话可能需要的事实 原始对话 %s 摘要.formatted(toCompress);// 调用大模型生成摘要 String newSummaryllm.chat(prompt);this.summarynewSummary;// 压缩后清空近期消息但可以保留最后一轮作为锚点防止断层 this.recentMessages.clear();}public StringbuildContext(){// 上下文摘要 最近未压缩的消息if(summary.isEmpty()){returnformatMessages(recentMessages);}return【历史摘要】\n summary \n\n【最近对话】\n formatMessages(recentMessages);}private intestimateTokenCount(){// 简单估算中文1字≈2token英文1词≈1.3token这里粗略用字符数/2 int totalCharssummary.length() formatMessages(recentMessages).length();returntotalChars /2;}private String formatMessages(ListMessagemsgs){returnmsgs.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 topK5;// 每次检索几条最相关的历史 public VectorMemory(EmbeddingClient embeddingClient, VectorDatabase vectorDb){this.embeddingClientembeddingClient;this.vectorDbvectorDb;}// 存储一条历史消息每个消息单独存储带上元数据 public void saveMessage(String role, String content, MapString, Objectmetadata){//1. 调用embedding接口将文本转为向量 float[]vectorembeddingClient.embed(content);//2. 存入向量数据库 VectorRecord recordnew VectorRecord(vector, content, metadata);vectorDb.insert(record);}// 检索与当前问题最相关的历史记忆 public ListMessageretrieveRelevantHistory(String currentQuestion){// 将当前问题向量化 float[]queryVectorembeddingClient.embed(currentQuestion);// 在数据库中做相似度搜索返回topK条最相似的历史消息 ListVectorRecordresultsvectorDb.search(queryVector, topK);// 转换成Message对象returnresults.stream().map(r -new Message((String)r.getMetadata().get(role),r.getContent())).collect(Collectors.toList());}// 构建上下文检索结果 最近几轮可选 public String buildContext(String userQuestion){ListMessagerelevantHistoryretrieveRelevantHistory(userQuestion);StringBuilder contextnew StringBuilder(相关历史记忆\n);for(Message msg:relevantHistory){context.append(msg.getRole()).append(: ).append(msg.getContent()).append(\n);}returncontext.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_INTERVAL10;// 每10轮触发一次摘要压缩 privateint turnCount0;public HierarchicalMemory(LLMClient llm, EmbeddingClient embed, VectorDatabase db){this.shortTermnew SlidingWindowMemory(5);// 保留最近5轮 this.midTermnew SummaryMemory(llm,2000);// token超2000压缩 this.longTermnew 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_INTERVAL0){midTerm.compress();// 强制压缩}}public String buildContext(String currentQuestion){//1. 短期记忆最近对话—— 最重要直接拼接 String shortContextshortTerm.buildContext();//2. 检索长期记忆基于当前问题 ListMessagelongMemorylongTerm.retrieveRelevantHistory(currentQuestion);String longContextformatMessages(longMemory);//3. 中期摘要如果摘要非空 String midContextmidTerm.getCurrentSummary();//4. 按重要性组装短期检索结果摘要 StringBuilder finalContextnew 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);}returnfinalContext.toString();}}代码解析L1 短期滑动窗口保留最近5轮保证对话连贯性延迟最低。L2 中期摘要压缩当消息积累到一定程度比如token超2000或每10轮就压缩一次保留全局脉络。L3 长期向量数据库存储每条消息支持按语义检索解决“长尾记忆”问题。构建上下文时优先保证短期最可靠然后加上向量检索出的相关历史弥补窗口丢弃的最后补充摘要作为兜底。优点兼具短时连贯、长时检索、全局摘要覆盖几乎所有场景token消耗可控短期固定检索topK摘要即使检索失败摘要和短期窗口也能兜底缺点实现复杂需要维护多个组件需要精细调参窗口大小、摘要频率、检索数量适用场景大型生产系统、企业级AI应用对体验和成本都有高要求的场景。七、方案六状态变量提取该方案需要极致的结构化压缩。有些场景下真正需要记忆的不是整个对话而是几个关键状态变量。比如订票机器人只需要知道{目的地: 北京, 日期: 2026-05-01, 人数: 2}。public class StateVariableMemory{private MapString, Objectstatenew 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 jsonResponsellm.chat(extractPrompt);MapString, ObjectnewStateparseJson(jsonResponse);state.putAll(newState);// 合并更新}public StringbuildContext(){// 上下文只需要展示当前状态而不是历史对话return当前会话状态 toJson(state);}}优点极致省token几KB的状态就能代替几十KB的对话结构化模型更容易理解缺点只适合高度结构化的任务订票、填表、参数收集提取状态本身需要调用LLM有额外成本适用场景任务型对话、表单填写、配置向导。八、方案七工具/函数调用把记忆“外包”给外部系统。大模型不是万能的记忆完全可以交给外部数据库。模型只需要学会调用“保存记忆”和“查询记忆”的工具。public class ToolBasedMemory{// 定义两个工具函数 Tool(namesave_memory, description保存一条重要信息到长期记忆)public void saveMemory(String key, String value){externalDB.put(key, value);}Tool(namerecall_memory, description根据关键词回忆之前保存的信息)public String recallMemory(String key){returnexternalDB.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%免费】

更多文章