7. 記憶(Memory)機制:讓AI擁有“短期記憶”與“長期記憶”

引言:當AI學會"記住你"

2025年某銀行智能客服因無法記住用戶身份,每次對話都要求重復驗證,引發大量投訴。引入LangChain 記憶系統后,客戶滿意度提升62%。本文將基于MemorySaverFAISS本地存儲,教你構建符合最新標準的記憶系統。


一、新版記憶架構核心變化
1.1 記憶存儲方案對比(LangChain 0.3+)
組件適用場景關鍵特性
MemorySaver短期會話狀態自動序列化,支持JSON/二進制
FAISS長期知識存儲本地化部署,毫秒級檢索
PostgreSQL企業級記憶管理事務支持,高可用
1.2 新舊API遷移指南
# 舊版(已廢棄)
# from langgraph.checkpoint import FileCheckpointer
?
# 新版(推薦)
from langgraph.checkpoint.memory import MemorySaver
from langchain_community.vectorstores import FAISS

二、構建新一代記憶系統
2.1 短期記憶
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_ollama import ChatOllama
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import START, MessagesState, StateGraph
?
?
llm = ChatOllama(model="deepseek-r1")
?
workflow = StateGraph(state_schema=MessagesState)
?
?
# 定義模型調用函數
def call_model(state: MessagesState):system_prompt = ("你是一個有禮貌的助手. ""回答盡可能多的細節.")messages = [SystemMessage(content=system_prompt)] + state["messages"]response = llm.invoke(messages)return {"messages": response}
?
?
# 定義節點和邊
workflow.add_node("model", call_model)
workflow.add_edge(START, "model")
?
# 添加簡單的內存檢查點
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)
?
response = app.invoke({"messages": [HumanMessage(content="你是誰?")]},config={"configurable": {"thread_id": "1"}},
)
print(response)
response = app.invoke({"messages": [HumanMessage(content="我剛才問你什么了?")]},config={"configurable": {"thread_id": "1"}},
)
print(response)

輸出為:

{'messages': [HumanMessage(content='你是誰?', additional_kwargs={}, response_metadata={}, id='03ed2cbb-59df-42c2-b865-bcd177e30833'), AIMessage(content='<think>\n好,我需要回答用戶的問題:“你是誰?” 用戶希望得到詳細的回應,并且我應該以禮貌的方式呈現。\n\n首先,我要確認自己的身份是DeepSeek-R1-Lite-Preview。這表明我是由深度求索公司開發的智能助手。接下來,我需要解釋我的功能和用途:通過算法處理信息并生成回答,幫助用戶解決問題或提供信息。\n\n然后,強調我沒有個人意識或情感,只是一個工具,以確保用戶的期望與實際功能相符。此外,提到遵守嚴格的倫理準則和隱私保護措施,這會增加用戶的信任感。\n\n最后,表達愿意隨時提供幫助的意愿,并詢問是否需要進一步的幫助或有其他問題,這樣可以讓用戶感到被重視和支持。\n</think>\n\n您好!我是DeepSeek-R1-Lite-Preview,一個由深度求索公司開發的智能助手,我通過算法處理信息并生成回答。我無法自主學習或更新,我的知識和能力是基于訓練數據設計的。我會以專業和誠懇的態度為您提供幫助,同時遵守嚴格的倫理準則和隱私保護措施。請問有什么可以幫您的?', additional_kwargs={}, response_metadata={'model': 'deepseek-r1:32B', 'created_at': '2025-04-05T08:31:13.718524566Z', 'done': True, 'done_reason': 'stop', 'total_duration': 32779446334, 'load_duration': 17223924, 'prompt_eval_count': 21, 'prompt_eval_duration': 148000000, 'eval_count': 228, 'eval_duration': 32612000000, 'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-939ed366-2088-4d99-97e4-f5e936ecc3c2-0', usage_metadata={'input_tokens': 21, 'output_tokens': 228, 'total_tokens': 249})]}
?
{'messages': [HumanMessage(content='你是誰?', additional_kwargs={}, response_metadata={}, id='03ed2cbb-59df-42c2-b865-bcd177e30833'), AIMessage(content='<think>\n好,我需要回答用戶的問題:“你是誰?” 用戶希望得到詳細的回應,并且我應該以禮貌的方式呈現。\n\n首先,我要確認自己的身份是DeepSeek-R1-Lite-Preview。這表明我是由深度求索公司開發的智能助手。接下來,我需要解釋我的功能和用途:通過算法處理信息并生成回答,幫助用戶解決問題或提供信息。\n\n然后,強調我沒有個人意識或情感,只是一個工具,以確保用戶的期望與實際功能相符。此外,提到遵守嚴格的倫理準則和隱私保護措施,這會增加用戶的信任感。\n\n最后,表達愿意隨時提供幫助的意愿,并詢問是否需要進一步的幫助或有其他問題,這樣可以讓用戶感到被重視和支持。\n</think>\n\n您好!我是DeepSeek-R1-Lite-Preview,一個由深度求索公司開發的智能助手,我通過算法處理信息并生成回答。我無法自主學習或更新,我的知識和能力是基于訓練數據設計的。我會以專業和誠懇的態度為您提供幫助,同時遵守嚴格的倫理準則和隱私保護措施。請問有什么可以幫您的?', additional_kwargs={}, response_metadata={'model': 'deepseek-r1:32B', 'created_at': '2025-04-05T08:31:13.718524566Z', 'done': True, 'done_reason': 'stop', 'total_duration': 32779446334, 'load_duration': 17223924, 'prompt_eval_count': 21, 'prompt_eval_duration': 148000000, 'eval_count': 228, 'eval_duration': 32612000000, 'message': {'role': 'assistant', 'content': '', 'images': None, 'tool_calls': None}}, id='run-939ed366-2088-4d99-97e4-f5e936ecc3c2-0', usage_metadata={'input_tokens': 21, 'output_tokens': 228, 'total_tokens': 249}), HumanMessage(content='我剛才問你什么了?', additional_kwargs={}, response_metadata={}, id='83a142cc-ad9a-4a76-baa3-675508cd70fb'), AIMessage(content='<think>\n好的,用戶現在問:“我剛才問你什么了?” 這可能是因為他想確認自己之前的問題或者只是隨便一問。\n\n首先,我要回憶之前的對話內容。上一次用戶的問題是“你是誰?”,而我的回答詳細介紹了我是DeepSeek-_lite版本的智能助手,并說明了我的功能和限制。\n\n現在,用戶詢問剛才的問題是什么,這可能表明他希望再次確認我的身份,或者他想繼續討論這個話題。也有可能他記不清了,只是想知道之前的對話內容。\n\n我需要禮貌地提醒他剛才問的是關于我的身份問題。同時,保持友好,邀請他提出更多的問題或進一步的討論。\n\n因此,在回復時,我會先簡單說明他之前的問題,然后詢問是否還有其他需求或想要繼續探討的內容。\n</think>\n\n您好!您剛才問的是:“你是誰?”如果您想了解更多或有其他問題,請隨時告訴我,我很樂意為您提供幫助。', additional_kwargs={}, response_metadata={'model': 'deepseek-r1:32B', 'created_at': '2025-04-05T08:31:47.33778896Z', 'done': True, 'done_reason': 'stop', 'total_duration': 33613724628, 'load_duration': 17323671, 'prompt_eval_count': 269, 'prompt_eval_duration': 5397000000, 'eval_count': 192, 'eval_duration': 28192000000, 'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-f86abc0a-3f22-47e0-8da6-f4c2bd22a157-0', usage_metadata={'input_tokens': 269, 'output_tokens': 192, 'total_tokens': 461})]}

2.2 長期記憶
from datetime import datetime
from langchain_community.vectorstores import FAISS
from langchain_ollama import OllamaEmbeddings, ChatOllama
from langchain_core.documents import Document
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
?
# 1. 初始化嵌入模型和向量數據庫
embeddings = OllamaEmbeddings(model="deepseek-r1")
?
# 初始化包含示例對話的向量庫
vectorstore = FAISS.from_documents(documents=[Document(page_content="用戶:如何重置密碼?",metadata={"type": "human", "timestamp": "2025-01-01"}),Document(page_content="AI:您可以訪問設置頁面,選擇'忘記密碼'選項。",metadata={"type": "ai", "timestamp": "2025-01-01"})],embedding=embeddings
)
?
# 2. 配置本地大模型
llm = ChatOllama(model="deepseek-r1")
?
# 3. 構建增強提示模板
template = """基于以下對話歷史和當前問題,用中文回答用戶:
歷史對話(最新在前):
{history}
當前問題:{question}
請給出專業解答:"""
prompt = ChatPromptTemplate.from_template(template)
?
?
# 4. 創建處理鏈
def build_chain():# 創建帶時間過濾的檢索器retriever = vectorstore.as_retriever(search_kwargs={"k": 2,"filter": lambda doc: doc.get("metadata", {}).get("type", "") in ["human", "ai"]})
?
?return (RunnablePassthrough.assign(# 獲取最近10條對話歷史history=lambda x: "\n".join([f"{doc.metadata['type']}:{doc.page_content}"for doc in retriever.invoke(x["question"])[:10]]))| prompt| llm)
?
?
# 5. 對話處理函數
def chat_loop():print("對話系統已啟動(輸入'exit'退出)")chain = build_chain()
?while True:user_input = input("你:").strip()if user_input.lower() == 'exit':break
?# 生成響應response = chain.invoke({"question": user_input})ai_response = response.contentprint(f"AI:{ai_response}")
?# 更新長期記憶new_docs = [Document(page_content=user_input,metadata={"type": "human", "timestamp": datetime.now().isoformat()}),Document(page_content=ai_response,metadata={"type": "ai", "timestamp": datetime.now().isoformat()})]vectorstore.add_documents(new_docs)vectorstore.save_local("chat_memory") ?# 持久化存儲
?
?
if __name__ == "__main__":chat_loop()

輸出為:

對話系統已啟動(輸入'exit'退出)
你:你好
AI:<think>
嗯,用戶發來了“你好”,看起來是一個問候。我應該禮貌地回應。首先,我可以用“你好!”來回復,這樣既簡潔又友好。然后,我可以進一步表示愿意提供幫助,比如問有什么可以幫忙的,或者詢問他們今天想聊些什么。這樣可以讓對話繼續下去,讓用戶感覺被重視和支持。
</think>
?
你好!很高興見到你,有什么我可以幫你的嗎?
你:怎么重置密碼
AI:<think>
好,我收到用戶的問題是“怎么重置密碼”。首先,我要考慮用戶的使用場景。可能是用戶忘記了原來的密碼,想要重新設置一個。接下來,我需要分析用戶的身份,可能是一個普通用戶,不太熟悉技術細節,所以回答要簡明易懂。
?
然后,我會思考用戶的真實需求。他們可能只是想快速解決問題,而不需要太多的技術術語。同時,可能會有更深層的需求,比如希望過程安全,確保密碼重置不會被他人惡意利用。
?
現在,我來組織一個專業的回答。首先,需要列出步驟:訪問登錄頁面,點擊“忘記密碼”,填寫注冊郵箱或手機號,按照提示操作,設置新密碼并保存。這樣分點說明清晰明了,用戶容易跟隨。
?
另外,我要考慮可能的安全問題,所以提醒用戶不要告訴他人驗證碼,并建議定期更換密碼以保護賬戶安全。這些額外的注意事項能夠幫助用戶更好地維護自己的賬號安全。
?
最后,整體語氣要友好且專業,讓用戶感受到被幫助和支持。
</think>
?
重置密碼通常需要按照以下步驟進行:
?
1. **訪問登錄頁面**:打開應用或網站的登錄界面。
?
2. **點擊“忘記密碼”**:在登錄頁面上找到并點擊“忘記密碼”或“找回密碼”的鏈接。
?
3. **輸入注冊郵箱或手機號**:根據提示,輸入你注冊時使用的郵箱地址或手機號碼。
?
4. **接收驗證碼或重置鏈接**:系統會發送一個驗證碼到你的郵箱或手機,或者直接提供一個鏈接讓你設置新密碼。
?
5. **按照提示操作**:使用收到的驗證碼完成身份驗證,然后按照系統的指示設置一個新的密碼。
?
6. **保存新密碼**:確保記住新的密碼,并妥善保管。
?
如果你在重置密碼過程中遇到任何問題,請聯系該服務的支持團隊獲取幫助。同時,確保不要將驗證碼告訴他人,以保護你的賬戶安全。
你:exit


三、企業級案例:金融客服系統
3.1 架構設計
3.2 關鍵性能指標
  • 響應延遲:平均210ms(P99<450ms)

  • 記憶準確率:用戶意圖識別提升58%

  • 擴展性:單節點支持10,000+并發會話


四、避坑指南:新版記憶系統六大陷阱
  1. 未顯式持久化:FAISS索引修改后需手動保存

    vector_db.save_local("./memory_index") ?# 關鍵操作!

  2. 會話ID沖突:未使用唯一標識導致記憶混淆

  3. 內存泄漏:MemorySaver未設置cache_size限制

  4. 版本不兼容:FAISS索引文件跨版本不兼容

  5. 權限問題:本地存儲目錄不可寫

  6. 監控缺失:未跟蹤記憶命中率


下期預告

《LangChain代理系統:讓AI自主決策與執行》

  • 揭秘:如何讓大模型自主調用工具鏈?

  • 實戰:構建能訂機票、查天氣的智能助手

  • 陷阱:無限遞歸與權限管控


新一代記憶系統讓AI真正擁有了"過去"。記住:優秀的記憶設計,是智能體從"工具"進化為"伙伴"的關鍵一躍!

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

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

相關文章

【Python使用】嘿馬云課堂web完整實戰項目第3篇:增加數據,修改數據【附代碼文檔】

教程總體簡介&#xff1a;項目概述 項目背景 項目的功能構架 項目的技術架構 CMS 什么是CMS CMS需求分析與工程搭建 靜態門戶工程搭建 SSI服務端包含技術 頁面預覽開發 4 添加“頁面預覽”鏈接 頁面發布 需求分析 技術方案 測試 環境搭建 數據字典 服務端 前端 數據模型 頁面原…

論文筆記(七十五)Auto-Encoding Variational Bayes

Auto-Encoding Variational Bayes 文章概括摘要1 引言2 方法2.1 問題場景2.2 變分下界2.3 SGVB估計器與AEVB算法2.4 重參數化技巧 3 示例&#xff1a;變分自編碼器&#xff08;Variational Auto-Encoder&#xff09;4 相關工作5 實驗6 結論7 未來工作 文章概括 引用&#xff1…

Python3 學習筆記

Python3 簡介 | 菜鳥教程 一 Python3 簡介 Python 是一個高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言。 Python 的設計具有很強的可讀性&#xff0c;相比其他語言經常使用英文關鍵字&#xff0c;其他語言的一些標點符號&#xff0c;它具有比其他語言更有特色…

Java實現N皇后問題的雙路徑探索:遞歸回溯與迭代回溯算法詳解

N皇后問題要求在NN的棋盤上放置N個皇后&#xff0c;使得她們無法互相攻擊。本文提供遞歸和循環迭代兩種解法&#xff0c;并通過圖示解釋核心邏輯。 一、算法核心思想 使用回溯法逐行放置皇后&#xff0c;通過沖突檢測保證每行、每列、對角線上只有一個皇后。發現無效路徑時回退…

前端判斷值相等的方法和區別

1. (寬松相等) 在比較之前會進行類型轉換 可能導致一些意外的結果 0 // true 0 0 // true false 0 // true null undefined // true [1,2,3]1,2,3 // true2. (嚴格相等) 不進行類型轉換 類型和值都必須相同 0 // false 0 0 // false false 0 /…

Socket編程UDP

Socket編程UDP 1、V1版本——EchoServer2、網絡命令2.1、ping2.2、netstat2.3、pidof 3、驗證UDP——Windows作為client訪問Linux4、V2版本——DictServer5、V3版本——簡單聊天室 1、V1版本——EchoServer 首先給出EchoServer目錄結構&#xff1a;服務器的類我們實現在UdpServ…

輔助查詢是根據查詢到的文檔片段再去生成新的查詢問題

&#x1f4a1; 輔助查詢是怎么來的&#xff1f; 它是基于你當前查詢&#xff08;query&#xff09;檢索到的某個文檔片段&#xff08;chunk_result&#xff09;&#xff0c;再去“反推”出新的相關問題&#xff08;utility queries&#xff09;&#xff0c;這些問題的作用是&a…

2025 年 4 月補丁星期二預測:微軟將推出更多 AI 安全功能

微軟正在繼續構建其 AI 網絡安全戰略&#xff0c;并于本月宣布在 Microsoft Security Copilot 中引入新代理。 他們引入了用于網絡釣魚分類的代理、用于數據丟失預防和內部風險管理的警報分類、條件訪問優化、漏洞修復和威脅情報簡報。 這些代理的目標是不斷從這些不同學科中…

【LLM系列】1.大模型簡介

1. 基礎 1.1 如何權衡模型的復雜度和性能&#xff1f; ├── a. 模型架構選擇 │ ├── 簡化架構 │ │ └── 選擇較小的網絡層數和寬度&#xff0c;降低復雜度&#xff1b; │ │ 可使用高性能基礎模型如 Transformers 作為起點&#xff0c;根據需求縮放模型。 │ └──…

【leetcode】記錄與查找:哈希表的題型分析

前言 &#x1f31f;&#x1f31f;本期講解關于力扣的幾篇題解的詳細介紹~~~ &#x1f308;感興趣的小伙伴看一看小編主頁&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的點贊就是小編不斷更新的最大動力 &#x1f386;那么廢話不…

優選算法的妙思之流:分治——快排專題

專欄&#xff1a;算法的魔法世界 個人主頁&#xff1a;手握風云 目錄 一、快速排序 二、例題講解 2.1. 顏色分類 2.2. 排序數組 2.3. 數組中的第K個最大元素 2.4. 庫存管理 III 一、快速排序 分治&#xff0c;簡單理解為“分而治之”&#xff0c;將一個大問題劃分為若干個…

二叉樹的ACM板子(自用)

package 二叉樹的中序遍歷;import java.util.*;// 定義二叉樹節點 class TreeNode {int val; // 節點值TreeNode left; // 左子節點TreeNode right; // 右子節點// 構造函數TreeNode(int x) {val x;} }public class DMain {// 構建二叉樹&#xff08;層序遍歷方式&…

Linux常用命令詳解:從基礎到進階

目錄 一、引言 二、文件處理相關命令 &#xff08;一&#xff09;grep指令 &#xff08;二&#xff09;zip/unzip指令 ?編輯 &#xff08;三&#xff09;tar指令 &#xff08;四&#xff09;find指令 三、系統管理相關命令 &#xff08;一&#xff09;shutdown指…

Qt多線程從基礎到性能優化

一、為什么需要多線程開發 現代應用程序的性能需求 CPU多核架構的有效利用 復雜任務的解耦與響應式界面保持 二、Qt線程創建四大方式 1. 繼承QThread重寫run() class WorkerThread : public QThread {void run() override {// 耗時操作qDebug() << "Thread ID…

【java】在 Java 中,獲取一個類的`Class`對象有多種方式

在 Java 中&#xff0c;獲取一個類的Class對象有多種方式。Class對象代表了 Java 中的一個類或接口的運行時類信息&#xff0c;可以用于反射操作。以下是獲取Class對象的幾種常見方法&#xff1a; 1.使用.class屬性 每個類都有一個.class屬性&#xff0c;可以直接獲取該類的Cl…

什么是RPC通信

RPC&#xff08;Remote Procedure Call&#xff0c;遠程過程調用&#xff09;通信是一種允許程序像調用本地函數一樣調用遠程服務器上函數的通信技術。它簡化了分布式系統中的網絡交互&#xff0c;隱藏了底層網絡通信的復雜性&#xff0c;使開發者能夠專注于業務邏輯。 一、RPC…

還是主題混合程序設計

以下是針對您現有代碼的完整主題化改造方案&#xff0c;實現跨QML/Qt Widgets的陰影主題系統&#xff1a; 一、主題管理系統核心 // thememanager.h #pragma once #include <QObject> #include <QColor> #include <QMap> #include <QQmlEngine>class…

BT-Basic函數之首字母T

BT-Basic函數之首字母T 文章目錄 BT-Basic函數之首字母Ttabtesttest conttest monitortest on boardstest scanworkstest shortstesthead cleanuptesthead configurationtesthead istesthead power on/offtesthead statustestjet print level istestordertestplan generationth…

7-9 趣味游戲

題目解析 在某個學校的趣味游戲活動中&#xff0c;N 名同學站成一排&#xff0c;他們的年齡恰好是 1 到 N &#xff0c;需要注意的是他們并不是按照年齡的大小排列的&#xff0c;而是隨機排列的。 游戲的規則是請同學們快速計算出&#xff0c;如果在這 N 名同學的小組中&…

Hugging Face模型微調訓練(基于BERT的中文評價情感分析)

文章目錄 學習視頻地址項目地址數據集的下載模型微調的基本概念與流程加載數據集數據集格式數據集信息 制作Dataset數據集字段數據集信息 vocab字典操作詞匯表文本轉換 下游任務模型設計模型訓練與保存數據加載優化器訓練循環 最終效果評估與測試模型加載和測試 學習視頻地址 …