15天学会AI应用开发(十七)使用LangGraph实现会话记忆功能

上一篇文章采用langchain_community包协助LangChain实现了对话记忆功能,但langchain_community属于早期链式架构的临时补丁,仅适配简单线性对话。

LangChain官方推荐使用LangGraph实现复杂的会话记忆功能,LangGraph是从底层统一管理全流程状态、支持长短双记忆、原生持久化、适配复杂Agent的标准化记忆架构,常作为生产环境的首选方案。接下来介绍LangGraph在会话记忆方面的简单用法。

一、使用LangGraph的环境准备

在命令行窗口执行下面命令,即可安装LangChain及其用到的Ollama插件,以及记忆功能需要的LangGraph:

复制代码
pip install langchain langchain-core langchain-ollama langgraph

确保本地已经通过Ollama下载了离线大模型,比如在命令行窗口执行下面命令,即可下载大模型qwen2:1.5b:

复制代码
ollama pull qwen2:1.5b

等待大模型下载完毕,在命令行窗口执行下面命令,即可启动Ollama并加载大模型:

复制代码
ollama serve

二、使用LangGraph记住历史会话

在Python代码开头添加下面的导包语句,表示引入LangChain的智能体组件create_agent、LangChain的大模型工具OllamaLLM,以及LangGraph的内存保存器InMemorySaver:

复制代码
from langchain.agents import create_agent
from langchain_ollama import ChatOllama
from langgraph.checkpoint.memory import InMemorySaver  # 内存存储

在OllamaLLM的构造方法中填写model参数,指定当前引用的离线大模型名称,如下:

复制代码
llm = ChatOllama(model="qwen2:1.5b")  # 改成你本地的模型

然后编写下面的LangChain调用代码,先调用create_agent创建启用短期记忆的智能体实例,再通过智能体实例的invoke方法调用离线大模型,示例代码如下:

复制代码
agent = create_agent(
    model=llm,
    checkpointer=InMemorySaver(),  # 启用短期记忆
)

# 测试对话
print("=== 内存中的临时记忆 ===")
while True:
    user_input = input("用户:")
    if user_input in ["退出", "exit", "quit"]:
        print("对话结束")
        break

    # 调用离线大模型
    result = agent.invoke(
        {"messages": [{"role": "user", "content": user_input}]},
        {"configurable": {"thread_id": "session_001"}}
    )
    print(f"AI:{result['messages'][-1].content}\n")

运行上面的Python代码,根据提示先后输入问题内容"我叫张三"、"我叫什么?",输出日志结果如下:

复制代码
=== 内存中的临时记忆 ===
你:我叫张三
AI:你好,张三。有什么问题或需要帮助的吗?

你:我叫什么?
AI:你的名字是"张三"。

由日志信息发现,AI应用在第一个问答中得知用户叫做张三,在第二个问答中仍然记得用户叫做张三。可见通过LangGraph的内存保存器InMemorySaver,初步实现了简单的AI对话记忆功能。

三、使用SummarizationMiddleware压缩历史记忆

前面虽然实现了初步的记忆功能,但随着问答的交互次数增长,要记忆的历史会话也越来越多。为了节省大模型的Token消耗,势必精简历史记忆,以便保留最新的会话记录。

LangGraph提供了摘要中间件SummarizationMiddleware,支持在历史会话超出限制时自动压缩会话记录。引入SummarizationMiddleware之后,增加的代码部分说明如下:

在Python代码开头添加下面的导包语句,表示引入LangChain的摘要中间件SummarizationMiddleware:

复制代码
from langchain.agents.middleware import SummarizationMiddleware

另外声明新的大模型实例,用于压缩历史会话记录,如下:

复制代码
llm_summary = ChatOllama(model="qwen2:0.5b")  # 改成你本地的模型

调用create_agent创建智能体实例时,增加输入middleware参数,并设定摘要中间件用到的摘要大模型、Token个数限制、保留消息数等配置,示例代码如下:

复制代码
agent = create_agent(
    model=llm,
    checkpointer=InMemorySaver(),  # 启用短期记忆
    # 压缩历史记忆并移除早期记忆
    middleware=[
        SummarizationMiddleware(
            model=llm_summary,
            trigger=("tokens", 100),   # 超过 100 token 触发
            keep=("messages", 3),        # 保留最近 3 条消息
        )
    ]
)

重新运行修改后的Python代码,根据提示先后输入问题内容"我叫张三"、"我叫什么?"、"长江有多长?"、"黄河有多长?"、"珠江有多长?"、"黑龙江有多长?"、"我叫什么?",输出日志结果如下:

复制代码
=== 内存中的临时记忆 ===
你:我叫张三
AI:你好,张先生。有什么我可以帮助你的吗?

你:我叫什么?
AI:你好,张先生。你叫张三。

你:长江有多长?
AI:长江是中国最长的河流,全长约6300公里。

你:黄河有多长?
AI:黄河是中国第二长的河流,全长约5464公里。

你:珠江有多长?
AI:珠江是长江流域的一条重要河流,全长约2794公里。

你:黑龙江有多长?
AI:黑龙江是亚洲最长的河流之一,全长约1800公里。

你:我叫什么?
AI:根据您的描述,您似乎没有提供自己的名字。如果您有其他姓名,请告知我以便我能为您提供更准确的回答。

由日志信息发现,在第一次询问"我叫什么?"时,AI应用能够正确回答用户叫做张三;但多轮对话后再次询问"我叫什么?",AI应用已经忘记了用户叫什么。可见通过SummarizationMiddleware初步实现了压缩历史记忆,在会话记录超出限制后将只保留最新的问答信息。

本系列的AI应用开发文章目录为《15天学会AI应用开发全目录(零基础小白,零Token消耗)》。

相关推荐
第一程序员1 小时前
Rust Agent 子进程执行:Command 之前,先定义输入和超时
python·rust·github
xixixi777772 小时前
三大 AI 安全里程碑:Akamai 高危风险预警、智能体水印强制落地、PQC 量子安全全产业链统一
大数据·人工智能·安全·ai·大模型·智能体·政策
skywalk81632 小时前
设计并实现段言的 C FFI 绑定机制 @Trae
c语言·开发语言·python·编程
weixin_BYSJ19872 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
AI小码2 小时前
LLM 应用的缓存工程:当每次 API 调用都在燃烧成本
java·人工智能·spring·计算机·llm·编程·api
code 小楊2 小时前
AI函数调用:Function Calling从理论到实战全解析
人工智能
delishcomcn2 小时前
智切未来:AI算法如何重塑不干胶标签分切机的精度与效率边界
人工智能·神经网络·计算机视觉
观远数据2 小时前
ChatBI选型对比:从意图识别到SQL修复,六个维度打分决定是否值得投产
数据库·人工智能·sql
犀利豆2 小时前
AI in Harness(四)
人工智能·后端