【动手学Langchain】初级篇5-记忆组件

Posted by Orchid on February 19, 2025

什么是记忆组件

在此之前,我们实现的大模型应用程序虽然已经能使用工具进行搜索,但它仍然是无状态的,即在对话中无法跟踪与用户的交互信息,这意味着它无法引用过去的消息,也就无法根据过去的交互理解新的消息。

LangChain 提供了一个名为“记忆”的组件,用于维护应用程序的状态(记住历史对话信息)。这个组件不仅允许用户根据最新的输入和输出来更新应用状态,还支持使用已存储的会话状态来调整或修改即将输人的内容。这样,它能为实现更复杂的对话管理和信息跟踪提供基础设施。

记忆组件具有两个基本操作:读取(Reading)和写人(Writing)。在执行核心逻辑之前(将 prompt 输入给 LLM 之前),系统会从记忆组件中读取信息以增强用户输人。执行核心逻辑之后(LLM给出回答之后),返回最终答案之前,系统会将当前运行的输入和输出写人记忆组件,以便在未来的运行中引用。这种设计方式提供了一种灵活且可扩展的方法,使得 LangChain 可以更有效地管理对话和应用状态。

记忆组件的简单使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder

# 初始化存储对话历史的字典
store = {}  # memory is maintained outside the chain

# 定义获取会话历史的函数
def get_session_history(session_id: str) -> InMemoryChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

# 定义聊天提示模板
chat_prompt = ChatPromptTemplate(
    [
        MessagesPlaceholder(variable_name="history"),  # 占位符,用于插入对话历史
        HumanMessagePromptTemplate.from_template("{input}")  # 用户输入
    ]
)

# 将提示模板与语言模型结合
chain = chat_prompt | tongyi_chat

# 使用 RunnableWithMessageHistory 包装链
chain_with_history = RunnableWithMessageHistory(
    chain,
    get_session_history=get_session_history,
    input_messages_key="input",  # 用户输入的键名
    history_messages_key="history"  # 对话历史的键名
)

# 第一轮对话
response = chain_with_history.invoke(
    {"input": "Hi I'm Orchid."},
    config={"configurable": {"session_id": "1"}}  # 使用会话 ID 确定对话线程
)
print(response.content)

# 第二轮对话
response = chain_with_history.invoke(
    {"input": "what is my name?"},
    config={"configurable": {"session_id": "1"}}  # 同一会话 ID,继续对话
)
print(response.content)