1. 从“健忘”到“健谈”为什么大模型需要记忆如果你用过像 DeepSeek 这样的主流大模型 API一定有过这样的体验你问它“我上一句话说了什么”它大概率会一脸茫然地告诉你“抱歉我无法访问之前的对话历史”。或者在一个多轮对话中你费尽心思地介绍了项目背景、技术栈和需求到了第五轮你问“那么基于我们刚才讨论的架构数据库选型你有什么建议”它可能会给你一个非常通用、完全忽略了你前面提到的“高并发写入”和“地理空间查询”需求的答案。这就是典型的“无状态”困局。每一次 API 调用对于大模型来说都是一次全新的、孤立的“邂逅”。它不记得几秒前你说了什么更不用说几分钟、几小时甚至几天前的对话上下文了。这种设计在技术上有其合理性比如保证了请求的独立性和可扩展性但对于构建连贯、智能、能真正理解用户意图和背景的对话应用来说这无疑是一个巨大的障碍。我们真正想要的不是一个每次都要从头开始解释的“金鱼脑”助手而是一个能记住关键信息、理解对话脉络、甚至能基于长期互动形成个性化认知的“伙伴”。这就是为 DeepSeek 这类大模型注入“记忆”能力的核心诉求。它不仅仅是把历史对话文本拼接起来再喂给模型那么简单而是涉及对信息的筛选、存储、检索和有效利用的一整套工程体系。最近围绕 LangChain、LangGraph 等框架的讨论非常火热大家的核心痛点都指向了如何让 AI 应用变得更“聪明”、更“持久”。无论是想构建一个能记住用户偏好的客服机器人还是一个能持续跟进项目进度的编程助手抑或是一个能进行深度、多轮分析的数据洞察工具“记忆”都是不可或缺的基石。本文将抛开那些空洞的概念直接切入实战手把手带你用 LangChain 这套目前最流行的工具链为 DeepSeek 大模型搭建起从短期对话记忆到长期知识记忆的完整能力破解无状态困局。2. 记忆系统的核心架构不止是“记住聊天记录”在开始敲代码之前我们必须先理清“记忆”到底包含什么。一个健壮的记忆系统远非一个简单的历史消息列表。根据 LangChain 的实践和社区共识我们可以将其粗略分为几个层次这比简单地讨论“短期”和“长期”更有操作性。2.1 对话记忆让聊天连贯起来这是最基础、最直接的需求。目标就是让模型能“看到”当前对话中已经发生过的内容。LangChain 提供了几种开箱即用的方案ConversationBufferMemory最简单粗暴把整个对话历史包括用户输入和AI输出都存成一个长字符串每次调用时全部附加上去。优点是信息完整缺点是上下文长度爆炸Token 费用和模型处理能力都有限制而且无关信息会干扰当前回答。ConversationBufferWindowMemory只保留最近 K 轮对话。这解决了上下文长度问题但“健忘”得更快可能丢失掉对话早期的重要前提。ConversationSummaryMemory一个非常巧妙的思路。它并不保存原始对话而是随着对话进行动态地生成并更新一个“摘要”。每次新的交互都基于之前的摘要和最新对话来生成新的摘要。这样无论对话多长传递给模型的始终是一个精炼的、包含核心信息的摘要极大地节省了 Token。这是处理长对话的利器。在实际项目中我通常不会直接使用最基础的BufferMemory。对于大多数客服或问答场景BufferWindowMemory比如只保留最近5轮结合一个清晰的系统提示词如“请基于最近几轮的对话内容回答”就已经能解决80%的连贯性问题。而对于需要回顾大量背景信息的深度分析或创作场景SummaryMemory是更优的选择。2.2 实体记忆记住关于“你”的关键信息对话记忆是关于“我们说了什么”而实体记忆则是关于“你是谁”。想象一个场景用户在第一轮说“我叫张三是一名后端工程师主要用 Go 语言。” 在第十轮用户问“那我刚才说的那种技术方案用我熟悉的语言实现有什么坑吗” 一个仅有对话记忆的系统可能需要在上下文中保留长达十轮的记录才能关联上“Go语言”。而实体记忆系统则能主动提取并存储“用户职业后端工程师”、“擅长语言Go”这样的结构化信息。LangChain 的ConversationEntityMemory就是干这个的。它利用一个小型语言模型或规则从对话中提取实体人、地点、事物、属性及其关系存储在一个类似知识图谱的结构中。当新的查询到来时它会先检索相关的实体信息并将其作为补充上下文注入。这相当于为模型配备了一个便签本专门记录关于用户或讨论对象的关键事实。2.3 长期记忆与向量检索构建专属知识库当我们需要模型记住超出单次会话范围的信息时比如公司内部文档、产品手册、历史会议纪要就需要引入长期记忆。其核心是RAG检索增强生成架构。知识入库将你的文档PDF、Word、网页、Notion页面等进行切分转换成文本片段。向量化使用嵌入模型如 OpenAI 的text-embedding-3-small或开源的BGE、M3E等将这些文本片段转换为高维向量一串数字并存入向量数据库如Chroma,Weaviate,Qdrant,Milvus。检索增强当用户提问时先将问题本身也向量化然后在向量数据库中搜索与之最相似的文本片段即“记忆”。生成回答将检索到的相关文本片段作为上下文连同用户问题一起发送给 DeepSeek 大模型让它基于这些“记忆”生成答案。这才是真正意义上的“注入记忆”。模型本身并没有被修改或训练但它获得了一个可以实时查询的、海量的、专属的外部大脑。这也是目前让大模型落地于私有知识场景最主流、最有效的方法。LangChain 在文档加载、切分、向量化、检索等每个环节都提供了丰富的组件和极简的接口让搭建一个 RAG 系统变得像搭积木一样简单。3. 实战为 DeepSeek API 搭建三层记忆系统理论说再多不如一行代码。下面我将以一个“技术顾问助手”为例展示如何结合 LangChain 为 DeepSeek 构建一个包含对话记忆、实体记忆和长期知识记忆的完整系统。假设我们已有一个 DeepSeek 的 API Key并且端点兼容 OpenAI SDK 格式这是目前最通用的方式。注意以下示例基于 LangChain 的主流版本确保你的langchain和langchain-community等包已更新。DeepSeek 的 API 调用方式可能与 OpenAI 有细微差别主要在于base_url和model参数的设置。3.1 环境准备与基础连接首先安装必要的库并设置好 DeepSeek 的 LLM 对象。这里我们使用langchain_openai中的ChatOpenAI因为它兼容 OpenAI 协议。pip install langchain langchain-community langchain-openai chromadb tiktokenimport os from langchain_openai import ChatOpenAI from langchain.memory import ConversationBufferWindowMemory, ConversationEntityMemory from langchain.memory.entity import SQLiteEntityStore from langchain.chains import ConversationChain from langchain.prompts import PromptTemplate # 设置你的 DeepSeek API Key 和 Base URL os.environ[DEEPSEEK_API_KEY] your-deepseek-api-key-here # 初始化 DeepSeek LLM # 注意model 名称请根据 DeepSeek 官方文档填写例如 deepseek-chat # base_url 指向 DeepSeek 的 API 端点 llm ChatOpenAI( modeldeepseek-chat, openai_api_keyos.environ[DEEPSEEK_API_KEY], base_urlhttps://api.deepseek.com/v1, # 请以官方文档为准 temperature0.7, max_tokens2000 )3.2 实现对话记忆与实体记忆的融合我们将结合ConversationBufferWindowMemory和ConversationEntityMemory创建一个既能记住近期对话又能捕捉关键实体的记忆体。EntityMemory需要一个地方来存储实体信息这里我们用轻量级的SQLiteEntityStore。# 初始化一个 SQLite 数据库来存储实体会在当前目录生成 .sqlite 文件 entity_store SQLiteEntityStore() # 创建融合记忆 memory ConversationBufferWindowMemory( memory_keychat_history, # 对话历史在 prompt 中的变量名 k3, # 只保留最近3轮对话 return_messagesTrue # 返回 Message 对象列表而不是字符串 ) entity_memory ConversationEntityMemory( llmllm, # 实体记忆需要一个 LLM 来提取实体这里可以用同一个 DeepSeek 实例但为节省成本实践中常用小模型 entity_storeentity_store, k5 # 在提示词中注入最多5个相关实体信息 ) # 在实际的 Chain 中我们需要自定义一个逻辑来合并两种记忆。 # 这里为了演示清晰我们先分别展示它们的作用。让我们先测试一下对话记忆# 创建一个简单的对话链使用对话记忆 conversation_with_memory ConversationChain( llmllm, memorymemory, verboseTrue # 打印详细日志方便理解 ) print(--- 测试对话记忆 ---) response1 conversation_with_memory.predict(input你好我叫李雷是一名 DevOps 工程师。) print(fAI: {response1}\n) response2 conversation_with_memory.predict(input我最近在关注 Kubernetes 的自动伸缩。) print(fAI: {response2}\n) # 此时记忆里应该有前两轮对话。 # 第三轮问题依赖之前的上下文。 response3 conversation_with_memory.predict(input对于我这种角色你有什么学习建议吗) print(fAI: {response3}) # 观察输出AI 应该能关联到“DevOps 工程师”和“Kubernetes”。接下来我们单独测试实体记忆是如何工作的# 使用实体记忆进行对话 prompt_with_entity PromptTemplate( input_variables[entities, input], template以下是当前已知的相关信息\n{entities}\n\n用户的最新问题{input}\n请根据已知信息回答 ) # 模拟一个多轮过程手动展示实体记忆的存储和检索 entity_memory.save_context( {input: 我叫韩梅梅是公司的产品经理。}, {output: 你好韩梅梅产品经理需要很好的沟通能力。} ) entity_memory.save_context( {input: 我们团队主要使用 Figma 和 Jira。}, {output: Figma 和 Jira 是产品设计和项目管理的常用工具。} ) # 在回答新问题前检索实体 entities entity_memory.load_memory_variables({input: 我该如何提高原型设计效率})[entities] print(--- 检索到的实体信息 ---) print(entities) print(--- 基于实体信息的回答 ---) # 这里简化处理实际应将 entities 和 input 填入 prompt 再调用 llm # 可以看到实体记忆里存储了“韩梅梅”、“产品经理”、“Figma”、“Jira”等实体及其关系。在实际的复杂应用中你需要设计更精巧的 Chain 或使用LangGraph来编排对话流决定在每一步如何使用和更新不同的记忆组件。一个常见的模式是用户输入 - 用实体记忆检索相关事实 - 结合对话历史和检索到的事实 - 生成提示词 - 调用 LLM 生成回答 - 将本轮交互更新到对话记忆和实体记忆中。3.3 集成长期记忆构建 RAG 知识库假设我们想为助手注入公司内部的“技术栈选型指南”作为长期记忆。步骤一准备知识文档并向量化我们使用Chroma作为本地向量数据库它简单易用。from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma # 1. 加载文档这里用文本文件示例 loader TextLoader(./tech_stack_guide.txt, encodingutf-8) documents loader.load() # 2. 分割文档 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个片段大小 chunk_overlap50 # 片段间重叠部分避免割裂语义 ) texts text_splitter.split_documents(documents) # 3. 初始化嵌入模型。DeepSeek 可能也提供嵌入模型这里以 OpenAI 为例你需要替换为可用的嵌入模型。 # 如果 DeepSeek 未提供可以使用开源的 embedding 模型如 from langchain.embeddings import HuggingFaceEmbeddings embeddings OpenAIEmbeddings( openai_api_keyos.environ.get(OPENAI_API_KEY), # 注意这里可能需要另一个 API Key modeltext-embedding-3-small ) # 4. 创建向量数据库 vectorstore Chroma.from_documents( documentstexts, embeddingembeddings, persist_directory./chroma_db # 持久化到本地目录 ) # 之后加载可以直接用 Chroma(persist_directory./chroma_db, embedding_functionembeddings)步骤二创建检索链与对话结合现在我们将检索能力加入到对话流程中。这里使用RetrievalQA链它封装了检索和问答。from langchain.chains import RetrievalQA # 创建检索问答链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 将检索到的文档“塞”进提示词 retrievervectorstore.as_retriever(search_kwargs{k: 3}), # 检索最相关的3个片段 return_source_documentsTrue # 返回源文档用于解释 ) # 测试长期记忆 print(--- 测试长期记忆RAG---) result qa_chain.invoke({query: 我们公司对于微服务通信推荐使用什么协议}) print(f回答{result[result]}) print(\n来源文档) for doc in result[source_documents][:2]: # 打印前两个来源 print(f- {doc.page_content[:200]}...)步骤三融合短期、实体与长期记忆这是最复杂的一步需要设计一个决策逻辑用户的问题是关于私有知识长期记忆还是关于当前对话或个人信息短期/实体记忆或者是混合一个简单的路由方案如下from langchain.agents import Tool, AgentExecutor, create_react_agent from langchain import hub # 定义工具 tools [ Tool( nameCompany_Knowledge_Base, funcqa_chain.run, # 调用 RAG 链 description当问题涉及公司内部技术规范、指南、文档时使用此工具。 ), # 理论上对话和实体记忆也可以封装为工具但这里我们将其作为 Agent 的默认记忆。 ] # 从 LangChain Hub 拉取一个 ReAct 风格的提示词这是一个智能代理框架 prompt hub.pull(hwchase17/react) # 创建代理 agent create_react_agent(llm, tools, prompt) # 创建代理执行器并传入我们之前定义的对话记忆 agent_executor AgentExecutor( agentagent, toolstools, memorymemory, # 代理可以拥有对话记忆 verboseTrue, handle_parsing_errorsTrue ) # 现在这个代理可以智能地决定何时查询知识库何时仅基于对话历史回答。 # 例如 # 问题“Kubernetes 的 HPA 怎么配置” - 可能触发知识库工具。 # 问题“我上一句说了什么” - 直接利用对话记忆回答。 # 问题“基于我 DevOps 工程师的身份刚才说的方案可行吗” - 结合对话记忆和实体记忆如果配置了回答。这个代理只是一个起点。在真实的高阶应用中你会使用LangGraph来绘制更精细、可循环、带状态的工作流图精确控制记忆的读取、更新和工具调用的顺序从而构建出真正强大、稳定、可控的 AI 应用。LangGraph允许你定义复杂的循环、分支和状态管理是构建具备复杂记忆和推理能力 Agent 的终极武器。4. 避坑指南记忆系统实战中的常见陷阱在实际部署中为 DeepSeek 或其他模型添加记忆绝非一帆风顺。下面是我在多个项目中总结出的关键陷阱和应对策略。4.1 上下文窗口与 Token 消耗的平衡DeepSeek 和其他模型一样有上下文长度限制例如 32K、128K Token。ConversationBufferMemory会无限制增长很快会触顶导致最开始的对话被“遗忘”实际上是被截断或者触发 API 的 Token 超限错误。解决方案优先使用ConversationSummaryMemory对于长对话这是首选。但要注意摘要可能丢失细节。设定合理的BufferWindow根据场景调整k值。快速问答场景k3-5足够深度讨论可能需要k10。主动管理上下文在对话关键节点如话题切换时通过编程方式清理或总结旧记忆。例如当用户说“我们聊点别的吧”你可以调用 LLM 对之前的对话生成一个最终摘要并存入长期记忆如果重要然后清空短期对话缓冲区。Token 计数与预警使用tiktoken库计算每次请求的 Token 数设置阈值报警并在 UI 上给用户提示“对话历史过长正在优化记忆”。4.2 实体记忆的噪声与幻觉ConversationEntityMemory依赖一个小型 LLM 来提取实体。这个提取过程可能出错提取出无关实体或者建立错误的关系如将“苹果”错误地关联到“公司”而不是“水果”。更糟糕的是如果用于提取实体的 LLM 本身有幻觉它会向知识库中注入虚假信息污染后续所有回答。解决方案使用更可靠的提取模型如果成本允许使用 GPT-4 等更强模型进行实体提取比使用小模型或同一个大模型在节省模式下更准确。设置置信度过滤对于提取出的实体和关系可以设计一个置信度评分过滤掉低置信度的条目。提供人工审核或修正接口对于关键应用记录下 AI 记忆的“事实”并提供给用户确认或修正的机会。例如“您提到您是‘后端工程师’对吗”定期清理为实体存储设置 TTL生存时间或者定期扫描并清理长时间未被引用的孤立实体。4.3 RAG 长期记忆的检索质量瓶颈RAG 的效果严重依赖于检索质量。“垃圾进垃圾出”如果检索不到相关文档或者检索到不相关的文档大模型再强也无力回天。解决方案文档预处理是重中之重智能分块不要简单按字符或段落分。尝试按语义分块使用SemanticChunker或按标题结构分块。添加元数据为每个文本块添加来源、标题、页码、章节等元数据。检索时可以利用元数据过滤。优化索引为关键段落生成摘要或问题并将其与原始文本一起索引这能提升检索的召回率。检索策略优化混合搜索结合向量搜索语义相似和关键词搜索如 BM25。Chroma和Weaviate都支持混合检索。语义搜索找“意思像的”关键词搜索找“字面有的”互补性强。重排序先用向量数据库召回 Top K比如20个文档再用一个更精细的交叉编码器模型对它们进行重排序选出 Top N比如3个最相关的。这能显著提升精度。查询转换/扩展在检索前用 LLM 对用户原始查询进行改写、扩展或生成假设性答案。例如将“怎么配置”扩展为“配置步骤、配置方法、配置教程”。针对 DeepSeek 的适配确保你的嵌入模型与 DeepSeek 的理解能力在语义空间上对齐。如果可能使用 DeepSeek 官方推荐的或同系列的嵌入模型或者用 DeepSeek 生成的数据对开源嵌入模型进行微调。4.4 记忆的隔离与冲突在多用户、多会话场景下记忆不能“串台”。用户 A 的对话历史和实体信息绝对不能泄露给用户 B。同时同一个用户在不同主题的对话中可能希望记忆有所隔离比如工作模式和闲聊模式。解决方案会话级隔离这是最基本的。为每个对话会话Session创建独立的记忆对象memory实例和向量数据库索引或至少使用不同的命名空间namespace。Web 应用中通常将会话 ID 作为隔离键。使用LangGraph的状态管理LangGraph的StateGraph天然支持多线程、带状态的工作流。你可以将每个用户会话的状态包括所有记忆封装在一个状态对象中由LangGraph的检查点机制来持久化和恢复完美解决隔离和持久化问题。命名空间在使用如Chroma或Weaviate时为不同用户或不同主题的知识库使用不同的collection_name或namespace。5. 进阶思考从记忆到“认知架构”当我们解决了基础的记忆问题后下一个挑战是如何让记忆“活”起来形成更高层次的认知。这不仅仅是存储和检索而是关于信息的整合、推理和规划。5.1 记忆的主动管理与摘要高级的 AI 助手不应该被动地记录一切而应该像人类一样主动总结、提炼和遗忘。我们可以设计这样的逻辑周期性摘要每对话 N 轮后自动触发一个摘要任务将详细的对话记忆压缩成一段精炼的要点并存入一个“长期摘要”存储区。原始的详细记录则可以部分清空。重要性打分为对话中的陈述或实体赋予重要性分数。例如用户明确说“这一点非常重要”的语句其得分应该更高在记忆检索和摘要中占据更大权重。遗忘机制模仿人脑的遗忘曲线为记忆条目设置衰减权重。长时间未被提及或使用的信息其检索优先级逐渐降低。5.2 基于记忆的规划与反思这是LangGraph等框架大显身手的地方。一个具备规划能力的 Agent其工作流可能是接收目标用户说“帮我制定一个学习 Go 微服务的三个月计划”。检索记忆从长期记忆中检索用户已有的技能“熟悉 Python”、“了解 Docker”从对话记忆中检索用户的偏好“希望以项目驱动”。制定计划LLM 基于目标和记忆生成一个初步的计划步骤列表。执行与反思Agent 开始执行计划的第一步比如“推荐第一周的学习资源”。执行后将结果和用户反馈存入记忆。然后Agent 可以进入一个“反思”节点评估第一步的效果并决定是继续第二步还是调整计划。持续迭代在整个多轮交互中记忆在不断更新计划也在动态调整。最终形成的计划是高度个性化的。5.3 与外部系统的记忆同步真正的企业级应用AI 助手的记忆不能只存在于对话中。它需要与外部系统打通同步到 CRM如果用户说“我对企业版套餐感兴趣”这条“销售线索”记忆应该能自动创建或更新 CRM 中的客户记录。从项目管理系统读取当用户问“我当前的 Bug 修复进度如何”Agent 应该能通过 API 去查询 Jira 或 Asana并将查询结果作为“临时记忆”用于生成回答。记忆的导出与审计出于合规和调试目的需要能够导出和查看 AI 在某个会话中形成的所有“记忆”对话、实体、检索记录了解其决策依据。为 DeepSeek 这类大模型注入记忆从技术上看是组合使用LangChain的各种Memory类和RAG链。但从产品角度看这是一个将通用 AI 转化为专用、个性化、可持续交互的智能体的过程。核心在于理解不同记忆组件的适用场景和局限并在架构设计上做好隔离、优化和扩展。