首页 > 其他分享 >LangChain 记忆组件深度解析:Chain 组件与 Runnable 深入学习

LangChain 记忆组件深度解析:Chain 组件与 Runnable 深入学习

时间:2024-11-11 15:01:51浏览次数:6  
标签:Runnable Chain chain langchain print query 组件 import

在构建复杂的 AI 应用时,有效管理对话历史和上下文信息至关重要。LangChain 框架提供了多种记忆组件,使得开发者能够轻松实现具有记忆功能的聊天机器人。本文将深入探讨 LangChain 中的记忆组件、Chain 组件以及 Runnable 接口,帮助开发者更好地理解和使用这些强大的工具。

LangChain 缓冲记忆组件的使用与解析

缓冲记忆组件的类型

LangChain 提供了多种缓冲记忆组件,每种组件都有其特定的用途和优势:

  1. ConversationBufferMemory:最简单的缓冲记忆,将所有对话信息全部存储作为记忆。

  2. ConversationBufferWindowMemory:通过设定 k 值,只保留一定数量(2*k)的对话信息作为历史。

  3. ConversationTokenBufferMemory:通过设置最大标记数量(max_token_limits)来决定何时清除交互信息,当对话信息超过 max_token_limits 时,抛弃旧对话信息。

  4. ConversationStringBufferMemory:等同于缓冲记忆,固定返回字符串(这是早期 LangChain 封装的记忆组件)。

缓冲窗口记忆示例

以下是一个使用 ConversationBufferWindowMemory 实现 2 轮对话记忆的示例:

from operator import itemgetter
import dotenv
from langchain.memory import ConversationBufferWindowMemory
from langchain_community.chat_message_histories import FileChatMessageHistory
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

memory = ConversationBufferWindowMemory(
    input_key="query",
    return_messages=True,
    k=2,
)

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是OpenAI开发的聊天机器人,请帮助用户解决问题"),
    MessagesPlaceholder("history"),
    ("human", "{query}")
])

llm = ChatOpenAI(model="gpt-3.5-turbo-16k")

chain = RunnablePassthrough.assign(
    history=RunnableLambda(memory.load_memory_variables) | itemgetter("history")
) | prompt | llm | StrOutputParser()

while True:
    query = input("Human: ")
    if query == "q":
        exit(0)
    chain_input = {"query": query}
    print("AI: ", flush=True, end="")
    response = chain.stream(chain_input)
    output = ""
    for chunk in response:
        output += chunk
        print(chunk, flush=True, end="")
    print("\nhistory:", memory.load_memory_variables({}))
    memory.save_context(chain_input, {"output": output})

LangChain 摘要记忆组件的使用与解析

摘要记忆组件的类型

LangChain 提供了两种主要的摘要记忆组件:

  1. ConversationSummaryMemory:将传递的历史对话记录总结成摘要进行保存,使用时填充的记忆为摘要,而非对话数据。

  2. ConversationSummaryBufferMemory:在不超过 max_token_limit 的限制下保存对话历史数据,对于超过的部分进行信息的提取与总结。

摘要缓冲混合记忆示例

以下是一个使用 ConversationSummaryBufferMemory 的示例,限制 max_token_limit 为 300:

from operator import itemgetter
import dotenv
from langchain.memory import ConversationSummaryBufferMemory
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个强大的聊天机器人,请根据对应的上下文回复用户问题"),
    MessagesPlaceholder("history"),
    ("human", "{query}"),
])
memory = ConversationSummaryBufferMemory(
    return_messages=True,
    input_key="query",
    llm=ChatOpenAI(model="gpt-3.5-turbo-16k"),
    max_token_limit=300,
)

llm = ChatOpenAI(model="gpt-3.5-turbo-16k")

chain = RunnablePassthrough.assign(
    history=RunnableLambda(memory.load_memory_variables) | itemgetter("history")
) | prompt | llm | StrOutputParser()

while True:
    query = input("Human: ")
    if query == "q":
        exit(0)
    chain_input = {"query": query, "language": "中文"}
    response = chain.stream(chain_input)
    print("AI: ", flush=True, end="")
    output = ""
    for chunk in response:
        output += chunk
        print(chunk, flush=True, end="")
    memory.save_context(chain_input, {"output": output})
    print("")
print("history: ", memory.load_memory_variables({}))

使用摘要记忆组件时,需要注意一些潜在的问题,如多个 System 角色消息的处理和某些聊天模型对消息格式的特殊要求。

LangChain 实体记忆组件的使用与解析

实体记忆组件用于跟踪对话中提到的实体,并记住关于特定实体的既定事实。LangChain 提供了 ConversationEntityMemory 类来实现这一功能。

以下是一个使用 ConversationEntityMemory 的示例:

import dotenv
from langchain.chains.conversation.base import ConversationChain
from langchain.memory import ConversationEntityMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()
llm = ChatOpenAI(model="gpt-4o", temperature=0)
chain = ConversationChain(
    llm=llm,
    prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,
    memory=ConversationEntityMemory(llm=llm),
)
print(chain.invoke({"input": "你好,我最近正在学习LangChain。"}))
print(chain.invoke({"input": "我最喜欢的编程语言是 Python。"}))
print(chain.invoke({"input": "我住在广州"}))
res = chain.memory.entity_store.store
print(res)

记忆组件的持久化与第三方集成

LangChain 的记忆组件本身没有持久化功能,但可以通过 chat_memory 来将对话信息历史持久化。LangChain 集成了近 50 多个第三方对话消息历史存储方案,包括 Postgres、Redis、Kafka、MongoDB、SQLite 等。

内置 Chain 组件的使用与解读

Chain 简介与使用

在 LangChain 中,Chain 用于将多个组件(如 LLM、提示词模板、向量存储、记忆、输出解析器等)串联起来一起使用。LangChain 支持两种类型的链:

  1. 使用 LCEL(LangChain Expression Language)构建的链
  2. 通过 Chain 类子类构建的链(遗产链)

以下是使用 LLMChain 的基础示例:

import dotenv
from langchain.chains.llm import LLMChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
prompt = ChatPromptTemplate.from_template("请讲一个关于{subject}的冷笑话")

chain = LLMChain(
    llm=llm,
    prompt=prompt,
)

print(chain("程序员"))
print(chain.run("程序员"))
print(chain.apply([{"subject": "程序员"}]))
print(chain.generate([{"subject": "程序员"}]))
print(chain.predict(subject="程序员"))
print(chain.invoke({"subject": "程序员"}))

内置的 Chain

LangChain 提供了多种内置的 Chain,包括 LCEL Chain 和遗产 Chain。例如,create_stuff_documents_chain 函数可以创建一个文档对话链:

import dotenv
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.documents import Document
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个强大的聊天机器人,能根据对应的上下文信息回复用户问题。\n\n<context>{context}</context>"),
    ("human", "{query}"),
])

llm = ChatOpenAI(model="gpt-3.5-turbo-16k")

chain = create_stuff_documents_chain(llm=llm, prompt=prompt)

documents = [
    Document(page_content="小明喜欢绿色,但不喜欢黄色"),
    Document(page_content="小王喜欢粉色,也有一点喜欢红色"),
    Document(page_content="小泽喜欢蓝色,但更喜欢青色")
]

resp = chain.invoke({"query": "大家都喜欢什么颜色", "context": documents})

print(resp)

RunnableWithMessageHistory 简化代码与使用

RunnableWithMessageHistory 是一个包装器,可以让链自动处理历史消息的填充和存储过程。

以下是一个使用 RunnableWithMessageHistory 的示例:

import dotenv
from langchain_community.chat_message_histories import FileChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

store = {}

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = FileChatMessageHistory(f"chat_history_{session_id}.txt")
    return store[session_id]

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个强大的聊天机器人,请根据用户的需求回复问题。"),
    MessagesPlaceholder("history"),
    ("human", "{query}"),
])
llm = ChatOpenAI(model="gpt-3.5-turbo-16k")

chain = prompt | llm | StrOutputParser()

with_message_chain = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="query",
    history_messages_key="history",
)

while True:
    query = input("Human: ")
    if query == "q":
        exit(0)
    response = with_message_chain.stream(
        {"query": query},
        config={"configurable": {"session_id": "muxiaoke"}}
    )
    print("AI: ", flush=True, end="")
    for chunk in response:
        print(chunk, flush=True, end="")
print("")

通过使用 RunnableWithMessageHistory,我们可以更方便地管理多个用户的对话历史,并在链中自动处理历史消息的加载和存储。

结论:

LangChain 提供了丰富的记忆组件和 Chain 组件,使得开发者能够轻松构建具有上下文感知能力的 AI 应用。通过合理使用这些组件,我们可以创建更智能、更个性化的对话系统。随着 LangChain 的不断发展,LCEL 表达式和 Runnable 接口的引入进一步简化了应用的构建过程。开发者应该根据具体需求选择合适的记忆组件和 Chain 类型,以实现最佳的应用性能和用户体验。

标签:Runnable,Chain,chain,langchain,print,query,组件,import
From: https://www.cnblogs.com/muzinan110/p/18539692

相关文章

  • LangChain Runnable 组件深度解析:灵活配置、错误处理与生命周期管理
    在LangChain框架中,Runnable组件是构建灵活、可配置的AI应用的核心。本文将深入探讨Runnable组件的高级特性,包括动态参数配置、组件替换、错误处理机制以及生命周期管理。通过掌握这些特性,开发者可以构建更加健壮和可维护的AI应用。1.Runnable组件动态添加默认调用参数......
  • LangChain记忆组件深度解析:运行流程与源码剖析
    在构建大型语言模型(LLM)应用时,记忆功能扮演着至关重要的角色。它使得AI能够保持上下文连贯性,提供更加智能和个性化的响应。本文将深入探讨LangChain框架中的记忆组件,详细分析其运行流程和源码实现,为开发者提供全面的技术洞察。1.LangChain-ChatMessageHistory组件解析1.1BaseCha......
  • vue.js组件开发实战:带图标的输入框组件
    1.效果展示2.组件页:icotxtbox.vue使用props:['img','wth']接收父页的参数,img为图标url地址,wth为输入框宽度。this.$emit('iptchange',e.target.value)回调父页方法并将输入值传回父页。<template> <viewclass="icotxtbx"style="display:flex;justify-......
  • Intro to LLM Agents with Langchain: When RAG is Not Enough
    https://towardsdatascience.com/intro-to-llm-agents-with-langchain-when-rag-is-not-enough-7d8c08145834Asalways,youcanfindthecodeonGitHub,andhereareseparateColabNotebooks:PlanningandreasoningDifferenttypesofmemoriesVarioustypesof......
  • Langchain ReAct
    officialhttps://python.langchain.com/v0.1/docs/modules/agents/agent_types/react/https://python.langchain.com/v0.2/api_reference/langchain/agents/langchain.agents.react.agent.create_react_agent.htmlfromlangchainimporthubfromlangchain_community.llm......
  • 鸿蒙自定义组件生命周期
    在开始之前,我们先明确自定义组件和页面的关系:自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个......
  • 【神经网络组件】Transformer Encoder
    【神经网络组件】TransformerEncoder目录【神经网络组件】TransformerEncoder1.seq2seq模型2.为什么只需要TransformerEncoder3.TransformerEncoder的结构1.seq2seq模型什么是sequence:sequence指由多个向量组成的序列。例如,有三个向量:\(\mathbf{a}=[1,0,0]^T,\math......
  • 使用react+copy-to-clipboard封装双击复制组件
    前言:最近在公司研发后台系统,用户反馈在双击某些信息时希望可以进行复制的操作,多处使用进而封装为组件首先:安装copy-to-clipboardnpmi--savecopy-to-clipboard其次:封装组件importReact,{memo,useCallback}from'react';import{notification}from"antd";......
  • 小北的字节跳动青训营与LangChain实战课:深入探索Chain的奥秘(上)写一篇完美鲜花推文?用Se
     前言    最近,字节跳动的青训营再次扬帆起航,作为第二次参与其中的小北,深感荣幸能借此机会为那些尚未了解青训营的友友们带来一些详细介绍。青训营不仅是一个技术学习与成长的摇篮,更是一个连接未来与梦想的桥梁~小北的青训营XMarsCode技术训练营——AI加码,字节跳......
  • Vue2中使用Element-ui封装表单(el-form)组件动态渲染数据
    1.创建一个searchForm组件,将需要封装的searchForm组件全局注册,为了方便下次直接使用在main.js文件中全局注册importSearchFormfrom'./components/SearchForm'Vue.component('SearchForm',SearchForm)2.在searchForm组件中创建基本结构<template><divclass="ces-......