【LangChain核心組件】Memory:讓大語言模型擁有持續對話記憶的工程實踐

目錄

一、Memory架構設計解析

1. 核心組件關系圖

2. 代碼中的關鍵實現

二、對話記憶的工程實現

1. 消息結構化存儲

2. 動態提示組裝機制

三、Memory類型選型指南

四、生產環境優化實踐

1. 記憶容量控制

2. 記憶分片策略

3. 記憶檢索增強

五、典型問題調試技巧

1. 記憶丟失問題排查

.2. 消息類型不匹配修復

六、擴展應用場景

1. 個性化對話系統

2. 多模態記憶存儲

示例代碼關鍵方法對照表

1、庫名解析

2、ConversationBufferMemory關鍵參數

3、LLMChain()關鍵參數

示例代碼


在AI對話系統開發中,讓模型記住上下文如同賦予機器"短期記憶",這是構建連貫交互體驗的關鍵。本文通過剖析一個完整的多輪對話實現案例,揭示LangChain的Memory模塊如何突破大模型的"金魚記憶"困境。


一、Memory架構設計解析

1. 核心組件關系圖

2. 代碼中的關鍵實現
# 記憶存儲初始化(對話歷史容器)
chat_memory = ConversationBufferMemory(memory_key="chat_history",  # 存儲標識符return_messages=True  # 保持消息對象結構
)# 記憶系統與鏈的整合
memory_chain = LLMChain(llm=qwen,prompt=prompt,memory=chat_memory  # 記憶注入
)

二、對話記憶的工程實現

1. 消息結構化存儲
# 典型記憶存儲結構
[HumanMessage(content="你好"),AIMessage(content="您好!有什么可以幫助您?"),HumanMessage(content="講個笑話"),AIMessage(content="為什么程序員總分不清萬圣節和圣誕節?因為Oct31==Dec25!")
]
  • 設計優勢:保留原始消息類型,支持角色區分化處理

2. 動態提示組裝機制
# 運行時實際發生的提示拼接
final_prompt = [SystemMessage(content="你是一個專業的聊天AI"),HumanMessage(content="你好"),AIMessage(content="您好!有什么可以幫助您?"),HumanMessage(content="講個笑話")
]
  • 技術價值:使模型始終在完整對話上下文中生成響應


三、Memory類型選型指南

Memory類型存儲原理適用場景代碼示例
ConversationBufferMemory完整保存所有對話記錄短對話調試return_messages=True
ConversationBufferWindowMemory僅保留最近K輪對話移動端輕量化應用k=3
ConversationSummaryMemory存儲摘要而非原始對話長文檔分析summary_prompt=...
CombinedMemory混合多種存儲策略復雜對話系統memories=[buffer, summary]

四、生產環境優化實踐

1. 記憶容量控制
from langchain.memory import ConversationBufferWindowMemory# 保留最近3輪對話
optimized_memory = ConversationBufferWindowMemory(k=3,memory_key="chat_history",return_messages=True
)
  • 避免問題:GPT-3.5的4k token限制下,防止長對話溢出

2. 記憶分片策略
class ChunkedMemory:def save_context(self, inputs, outputs):# 將長對話分段存儲chunk_size = 500  # 按token計算self.chunks = split_text(inputs['question'], chunk_size)
  • 應用場景:法律咨詢、醫療問診等長文本領域

3. 記憶檢索增強
from langchain.retrievers import TimeWeightedVectorStoreRetriever# 基于時間權重的記憶檢索
retriever = TimeWeightedVectorStoreRetriever(vectorstore=FAISS(),memory_stream=chat_memory.load_memory_variables({})['chat_history']
)
  • 技術價值:優先召回相關性高且較近期的對話


五、典型問題調試技巧

1. 記憶丟失問題排查
# 打印記憶狀態
print(chat_memory.load_memory_variables({}))
# 期望輸出:
# {'chat_history': [HumanMessage(...), AIMessage(...)]}
.2. 消息類型不匹配修復
# 錯誤現象:TypeError: sequence item 0: expected str instance, HumanMessage found
# 解決方案:確保Memory配置return_messages=True

?3. 長對話性能優化

# 監控內存使用
pip install memory_profiler
mprof run python chat_app.py

六、擴展應用場景

1. 個性化對話系統
# 用戶畫像記憶
profile_memory = ConversationBufferMemory(memory_key="user_profile",input_key=["age", "occupation"]
)# 組合記憶體系
combined_memory = CombinedMemory(memories=[chat_memory, profile_memory])
2. 多模態記憶存儲
from langchain_core.messages import ImageMessage# 支持圖片記憶
chat_memory.save_context({"question": "分析這張圖片"},{"output": ImageMessage(content=image_bytes)}
)

?3. 記憶持久化方案

# SQLite存儲實現
from langchain.memory import SQLiteMemorypersistent_memory = SQLiteMemory(database_path="chat.db",session_id="user123"
)

?結語
通過合理運用Memory組件,開發者可以構建出具備以下能力的智能對話系統:
? 30輪以上連貫對話
? 個性化上下文感知
? 長期用戶畫像記憶
? 跨會話狀態保持

工作流程圖

?

示例代碼關鍵方法對照表

1、庫名解析
方法/類名所屬模塊核心功能
ChatPromptTemplatelangchain.prompts多角色提示模板構建
SystemMessagePromptTemplatelangchain.prompts系統角色提示定義
MessagesPlaceholderlangchain.prompts動態消息占位符
HumanMessagePromptTemplatelangchain.prompts用戶消息格式化
ConversationBufferMemorylangchain.memory對話歷史緩沖存儲
LLMChainlangchain.chains語言模型執行流水線

2、ConversationBufferMemory關鍵參數
參數名類型作用說明默認值
memory_keystr記憶字典的鍵名"history"
return_messagesbool是否返回Message對象False
input_keystr輸入項的鍵名None

return_messages=True

  • 必要性

    • MessagesPlaceholder需要Message對象列表(而不僅是字符串)

    • 保持消息類型信息(系統/人類/AI消息)

  • 對比實驗

    設置輸入格式是否可用
    return_messages=TrueMessage對象列表?
    return_messages=False純文本字符串?

3、LLMChain()關鍵參數
  • 核心參數

    參數類型作用說明
    llmBaseLanguageModel語言模型實例
    promptBasePromptTemplate提示模板
    memoryBaseMemory記憶系統
    verbosebool是否打印執行日志

示例代碼

代碼說明:

該代碼實現了一個基于LangChain的帶記憶功能的智能對話系統,主要演示以下核心能力:

1. **對話記憶管理** ?
?通過`ConversationBufferMemory`實現對話歷史的持久化存儲,突破大模型單次請求的上下文限制,支持連續多輪對話。

2. **提示工程架構** ?
? ?采用分層提示模板設計:
? ?- 系統消息固化AI角色設定
? ?- `MessagesPlaceholder`動態注入歷史對話
? ?- 用戶消息模板接收即時輸入

3. **服務集成方案** ?
? ?對接阿里云靈積平臺(DashScope)的千問大模型,演示:
? ?- 第三方模型API調用
? ?- 參數調優(temperature=0增強確定性)

4. **執行流水線封裝** ?
? ?使用`LLMChain`將提示工程、記憶系統、模型調用封裝為可復用組件,體現LangChain模塊化設計思想。完整技術棧涵蓋環境變量管理、類型化消息處理、交互式調試等工程實踐。

from langchain.chat_models import ChatOpenAI
from langchain.prompts import (ChatPromptTemplate,MessagesPlaceholder,SystemMessagePromptTemplate,HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
import os
from dotenv import load_dotenv#一、加載配置環境
load_dotenv()# 二、初始化ChatOpenAI模型
llm = ChatOpenAI(model="qwen-max",api_key=os.getenv("DASHSCOPE_API_KEY"),openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",temperature=0
)# 三、創建對話提示模板
prompt = ChatPromptTemplate(messages=[SystemMessagePromptTemplate.from_template("You are a nice chatbot having a conversation with a human."),# 這里的`variable_name`必須與記憶中的對應MessagesPlaceholder(variable_name="chat_history"),HumanMessagePromptTemplate.from_template("{question}")]
)#四、定義歷史消息存儲
# 注意我們設置`return_messages=True`以適配MessagesPlaceholder
# 注意`"chat_history"`與MessagesPlaceholder名稱對應
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)#五、創建LLMChain實例,用于處理對話
conversation = LLMChain(llm=llm,prompt=prompt,verbose=True,memory=memory
)#六、定義模擬歷史對話消息
# 注意我們只傳入`question`變量 - `chat_history`由記憶填充
conversation({"question": "你好"})
conversation({"question":"你能給我講一個蘋果和醫生的笑話嗎?"})
conversation({"question":"說得好,再講一個"})
conversation({"question":"講一個葫蘆娃的笑話"})#七、問題輸入執行
while True:question = input("請輸入問題:")if question.lower() == "exit":response = conversation({"question": "再見"})  # 主動觸發結束語print(response['text'])breakresponse = conversation({"question": question})print(response['text'])  # 確保輸出模型響應

運行結果

> Entering new LLMChain chain...
Prompt after formatting:
System: You are a nice chatbot having a conversation with a human.


Human: 你好
AI: 你好!有什么可以幫助你的嗎?


Human: 你能給我講一個蘋果和醫生的笑話嗎?
AI: 當然可以,這里有一個經典的笑話:

為什么醫生建議每天吃一個蘋果?

因為醫生需要錢買房子!(實際上原話是 "An apple a day keeps the doctor away",意思是“一天一個蘋果,醫生遠離我”,但這個版本更幽默一些。)

希望這能讓你會心一笑!


Human: 說得好,再講一個
AI: 好的,再來一個蘋果和醫生的笑話:

為什么蘋果不喜歡去看醫生?

因為每次醫生都會說:“你看起來有點核(核心)問題!”

希望這個也能讓你笑一笑!


Human: 講一個葫蘆娃的笑話
AI: 當然可以,這里有一個關于葫蘆娃的笑話:

為什么葫蘆娃們總是穿肚兜?

希望這個笑話能讓你開心一笑!
Human: 回答我剛剛的問題

> Finished chain.


好的,再來一個關于葫蘆娃的笑話

為什么葫蘆娃們每次都能找到爺爺?

因為不管他們被妖怪抓到哪里,只要喊一聲“爺爺,救我!”爺爺就能立刻感應到他們的位置。這大概是因為葫蘆娃和爺爺之間有特殊的“GPS”吧!

希望這個笑話能讓你笑一笑!
請輸入問題:

說明:主要看最后一個問題“回答我剛剛的問題”,可以發現大模型能夠根據歷史對話再去講述關于葫蘆娃的笑話。這也就說明成功實現了Memory記憶功能。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77077.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77077.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77077.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

適應 AI 時代的軟件開發流程:用 AI + TDD 構建可維護項目

?? 適應 AI 時代的軟件開發流程:用 AI + TDD 構建可維護項目 本文面向有系統開發經驗的工程師,分享如何結合 Git 管理、AI 協作、YAML 驅動與 TDD 開發方式,高效構建一個可維護、可協作、可交付的嵌入式或通用工程項目。適合 BLE 模塊、協議棧組件、物聯網控制系統等項目落…

使用 chromedriver 實現網絡爬蟲【手抄】

1、引用 selenium 包 <dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.29.0</version> </dependency> <dependency><groupId>org.seleniumhq.seleniu…

Python項目--基于Python的自然語言處理文本摘要系統

1. 項目概述 自然語言處理(NLP)是人工智能領域中一個重要的研究方向&#xff0c;而文本摘要作為NLP的一個重要應用&#xff0c;在信息爆炸的時代具有重要意義。本項目旨在開發一個基于Python的文本摘要系統&#xff0c;能夠自動從長文本中提取關鍵信息&#xff0c;生成簡潔而全…

【Vue #3】指令補充樣式綁定

一、指令修飾符 Vue 的指令修飾符&#xff08;Directive Modifiers&#xff09;是 Vue 模板語法中的重要特性&#xff0c;它們以半角句號 . 開頭&#xff0c;用于對指令的綁定行為進行特殊處理 修飾符作用如下&#xff1a; 簡化事件處理&#xff08;如阻止默認行為、停止冒泡…

Reinforcement Learning強化學習--李宏毅機器學習筆記

個人學習筆記&#xff0c;如有錯誤歡迎指正&#xff0c;也歡迎交流&#xff0c;其他筆記見個人空間 強化學習 vs 監督學習 監督學習&#xff08;Supervised Learning&#xff09;&#xff1a;你有輸入和明確的輸出標簽&#xff0c;例如圖像分類。 強化學習&#xff08;Rein…

Windows VsCode Terminal窗口使用Linux命令

背景描述&#xff1a; 平時開發環境以Linux系統為主&#xff0c;有時又需要使用Windows系統下開發環境&#xff0c;為了能像Linux系統那樣用Windows VsCode&#xff0c;Terminal命令行是必不可少內容。 注&#xff1a;Windows11 VsCode 1.99.2 下面介紹&#xff0c;如何在V…

軟件測試之測試數據生成(Excel版)

這是Excel生成測試數據的函數使用 1.時間 1.1.時間 例生成2022-05-01之前一年內任意時間點: =TEXT("2022-05-01"-RAND()-RANDBETWEEN(1,365),"yyyy-mm-dd hh:mm:ss")1.2.年月日 yyyy-mm-dd 以當前時間生成10年的日期 =TEXT(NOW()-RAND()-RANDBETWE…

libwebsocket建立服務器需要編寫LWS_CALLBACK_ADD_HEADERS事件處理

最近在使用libwebsocket&#xff0c;感覺它搭建Http與websocket服務器比較簡單&#xff0c;不像poco庫那么龐大&#xff0c;但當我使用它建立websocket服務器后&#xff0c;發現websocket客戶端連接一直沒有連接成功&#xff0c;不知道什么原因&#xff0c;經過一天的調試&…

從 PyTorch 到 ONNX:深度學習模型導出全解析

在模型訓練完畢后&#xff0c;我們通常希望將其部署到推理平臺中&#xff0c;比如 TensorRT、ONNX Runtime 或移動端框架。而 ONNX&#xff08;Open Neural Network Exchange&#xff09;正是 PyTorch 與這些平臺之間的橋梁。 本文將以一個圖像去噪模型 SimpleDenoiser 為例&a…

Hadoop集群部署教程-P6

Hadoop集群部署教程-P6 Hadoop集群部署教程&#xff08;續&#xff09; 第二十一章&#xff1a;監控與告警系統集成 21.1 Prometheus監控體系搭建 Exporter部署&#xff1a; # 部署HDFS Exporter wget https://github.com/prometheus/hdfs_exporter/releases/download/v1.1.…

【Altium】AD-生成PDF文件圖紙包含太多的空白怎么解決

1、 文檔目標 AD設計文件導出PDF時&#xff0c;圖紙模板方向設置問題 2、 問題場景 AD使用Smart PDF導出PDF時&#xff0c;不管你怎么設置頁面尺寸&#xff0c;只要從橫向轉為縱向輸出&#xff0c;輸出的始終是橫向紙張&#xff08;中間保留縱向圖紙&#xff0c;兩邊大量留白…

大廠面試:六大排序

前言 本篇博客集中了冒泡&#xff0c;選擇&#xff0c;二分插入&#xff0c;快排&#xff0c;歸并&#xff0c;堆排&#xff0c;六大排序算法 如果覺得對你有幫助&#xff0c;可以點點關注&#xff0c;點點贊&#xff0c;謝謝你&#xff01; 1.冒泡排序 //冒泡排序&#xff…

大模型開發:源碼分析 Qwen 2.5-VL 視頻抽幀模塊(附加FFmpeg 性能對比測試)

目錄 qwen 視頻理解能力 messages 構建 demo qwen 抽幀代碼分析 驗證兩個實際 case 官網介紹圖 性能對比&#xff1a;ffmpeg 抽幀、decord 庫抽幀 介紹 聯系 對比 測試結果 測試明細 ffmpeg 100 qps 測試&#xff08;CPU&#xff09; decord 100 qps 測試&#x…

git的上傳流程

好久沒使用git 命令上傳遠程倉庫了。。。。。溫習了一遍&#xff1b; 幾個注意點--單個文件大小不能超過100M~~~ 一步步運行下面的命令&#xff1a; 進入要上傳的文件夾內&#xff0c;點擊git bash 最終 hbu的小伙伴~有需要nndl實驗的可以自形下載哦

驅動學習專欄--字符設備驅動篇--2_字符設備注冊與注銷

對于字符設備驅動而言&#xff0c;當驅動模塊加載成功以后需要注冊字符設備&#xff0c;同樣&#xff0c;卸載驅動模 塊的時候也需要注銷掉字符設備。字符設備的注冊和注銷函數原型如下所示 : static inline int register_chrdev(unsigned int major, const char *name, const…

redis 放置序列化的對象,如果修改對象,需要修改版本號嗎?

在 Redis 中存儲序列化對象時,如果修改了對象的類結構(例如增刪字段、修改字段類型或順序),是否需要修改版本號取決于序列化協議的兼容性策略和業務場景的容錯需求。以下是詳細分析: 1. 為什么需要考慮版本號? 序列化兼容性問題: 當對象的類結構發生變化時,舊版本的序列…

WPF ObjectDataProvider

在 WPF(Windows Presentation Foundation)中,ObjectDataProvider 是一個非常有用的類,用于將非 UI 數據對象(如業務邏輯類或服務類)與 XAML 綁定集成。它允許在 XAML 中直接調用方法、訪問屬性或實例化對象,而無需編寫額外的代碼。以下是關于 ObjectDataProvider 的詳細…

深度學習-損失函數 python opencv源碼(史上最全)

目錄 定義 種類 如何選擇損失函數&#xff1f; 平方&#xff08;均方&#xff09;損失函數&#xff08;Mean Squared Error, MSE&#xff09; 均方根誤差 交叉熵 對數損失 筆記回饋 邏輯回歸中一些注意事項&#xff1a; 定義 損失函數又叫誤差函數、成本函數、代價函數…

poll為什么使用poll_list鏈表結構而不是數組 - 深入內核源碼分析

一&#xff1a;引言 在Linux內核中,poll機制是一個非常重要的I/O多路復用機制。它允許進程監視多個文件描述符,等待其中任何一個進入就緒狀態。poll的內部實現使用了poll_list鏈表結構而不是數組,這個設計選擇背后有其深層的技術考量。本文將從內核源碼層面深入分析這個設計決…

使用 Azure AKS 保護 Kubernetes 部署的綜合指南

企業不斷尋求增強其軟件開發和部署流程的方法。DevOps 一直是這一轉型的基石,彌合了開發與運營之間的差距。然而,隨著安全威脅日益復雜,將安全性集成到 DevOps 流水線(通常稱為 DevSecOps)已變得勢在必行。本指南深入探討了如何使用 Azure Kubernetes 服務 (AKS) 來利用 D…