【LangChain Chains及Memory 03】

一、Chains

1、Chains的基本使用

1.1、chains的基本概念

Chain:链,用于将多个组件(提示词模版、LLM模型、记忆、工具等)链接起来,形成可复用的工作流,完成复杂的工作

Chain的核心思想是通过组合不同的模块化单元,实现比单一组件更强大的功能。比如:

  • 将LLM与Prompt Template结合
  • 将LLLM与输出解析器结合
  • 将LLM与外部数据结合,例如用于问答
  • 将LLM与长期记忆结合,例如用于聊天历史记录
  • 通过将第一个LLM的输出作为第二个LLM的输入,将多个LLM按顺序结合在一起

1.2、LCEL及其基本构成

使用LCEL可以构造出结构最简单的Chain

LangChain表达式语音是一种声明式方式,可以轻松地将多个组件链接成AI工作流。它通过Python原生操作符(如:管道符 |)将组件链接成可执行流程,显著简化了AI应用的开发

LCEL的基本构成:提示词Prompt +  模型Model + 输出解释器OutputParser

# 在这个链条中,用户输入被传递给提示模板,然后提示模板的输出被传递给模型,然后模型的输出被传 递给输出解析器。
chain = prompt | model | output_parser
chain.invoke({"input":"What's your name?"})
  • Prompt:是一个BasePromptTemplate,这意味着它接受了一个模版变量的字典并生成一个PromptValue 。PromptValue可以传递给LLM(它以字符串作为输入)或ChatModel(它以消息序列作为输入)
  • Model:将PromptValue传递给model。如果我们的model是一个ChatModel,这意味着它将输出一个BaseMessage
  • OutputParser:将model的输出传递给outputParser,它是一个BaseOutputParser,意味着它可以接受字符串或BaseMessage作为输入
  • chain:我们可以使用 | 运算符轻松创建这个chain 。| 运算符在LangChain中用于 将两个元素组合在一起
  • invoke:所有LCEL对象都实现了Runable协议,保证一致的调用方式(invoke / batch / stream)

1.3、Runnable

Runnable是LangChain定义的一个抽象接口(Protocol),它强制要求所有LCEL组件实现一组标准方法:

class Runnable(Protocol):
  def invoke(self, input: Any) -> Any: ... # 单输入单输出
  def batch(self, inputs: List[Any]) -> List[Any]: ... # 批量处理
  def stream(self, input: Any) -> Iterator[Any]: ... # 流式输出
  # 还有其他方法如 ainvoke(异步)等...

目的是每个组件调用方式统一!(无论组件【提示词/模型/工具】多么的复杂,调用方式完全相同)

举例:使用LCEL将不同的组件组合成一个单一链条【这里就用到了管道符 | 】

from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
import os
import dotenv
from langchain_core.output_parsers import StrOutputParser

dotenv.load_dotenv()
base_url = os.getenv("OPENAI_BASE_URLS")
api_key = os.getenv("OPENAI_API_KEY1")

chat = ChatOpenAI(
    model="gpt-4o-mini",
    base_url=base_url,
    api_key=api_key,
)

template = PromptTemplate.from_template(
   template='将一段{name}小品中经典的台词'
)

parser = StrOutputParser()

chain = template|chat|parser
res = chain.invoke({"name":"赵本山和宋丹丹"})
print(res)

注意:使用chain调用时,template|chat|parser这三个组件之间的先后顺序是不能变的,因为每个组件都是需要上一个组件的输出作为输入进行处理

2、基于LCEL构建的Chains的类型

下面是一些常用的函数

 

 

  • create_sql_query_chain
  • create_stuff_documents_chain
  • create_openai_fn_runnable
  • create_structured_output_runnable
  • load_query_constructor_runnable
  • create_history_aware_retriever
  • create_retrieval_chain

2.1、create_sql_query_chain

sql查询链,是创建生成sql查询的链,用于将自然语言转换成数据库的sql语句

from langchain.chains.sql_database.query import create_sql_query_chain
from langchain_community.utilities import SQLDatabase

# 链接mysql数据库
from urllib.parse import quote_plus

db_user = 'root'
db_password = '123456'
db_host = 'localhost'
db_port = 3307
db_name = 'test'

# mysql+pymysql://<username>:<password>@<host>:<port>/<database>
# 如果密码含特殊字符(@ : / ? 等),请用 quote_plus
uri = (
    f"mysql+pymysql://{quote_plus(db_user)}:{quote_plus(db_password)}@{db_host}:{db_port}/{db_name}"
    "?charset=utf8mb4"
)

# 建议加上 pool_pre_ping,网络/空闲连接更稳定
db = SQLDatabase.from_uri(
    uri,
    engine_args={"pool_pre_ping": True, "pool_recycle": 3600},
)

# 快速连通性测试(能返回 1 就说明驱动+连接基本 OK)
try:
    print(db.run("SELECT 1"))
except Exception as e:
    print("DB connection test failed:", repr(e))

dotenv.load_dotenv()
base_url = os.getenv("OPENAI_BASE_URLS")
api_key = os.getenv("OPENAI_API_KEY1")

chat = ChatOpenAI(
    model="gpt-4o-mini",
    base_url=base_url,
    api_key=api_key,
)

# 调用 create_sql_query_chain 创建链条
chain = create_sql_query_chain(chat, db)
res = chain.invoke({"question": "往employees表插入5条数据"})
print(res)

 

posted @ 2026-02-02 11:04  尘封~~  阅读(3)  评论(0)    收藏  举报