当前位置: 首页 > news >正文

【LangChain】P18 LangChain 之 Chain 深度解析(三):基于 LCEL 语法的数据库与文档处理新型 Chain

目录

  • 前言
  • create_sql_query_chain —— 让语言模型成为你的 SQL 专家
    • 环境准备与数据库连接
    • 准备大语言模型(LLM)
    • 创建并运行 Chain
    • 工作原理揭秘
    • 高级技巧
  • create_stuff_documents_chain —— 文档内容填充的艺术
    • 适用场景分析
    • 完整实例
  • 总结

在这里插入图片描述

前言

在 LangChain 的世界里,LangChain 表达式语言(LCEL)的出现无疑是一场革命。它以其标志性的管道符(|),不仅为我们提供了一种声明式、可组合且可流式传输的方式来构建强大的语言模型应用,还促使许多 LangChain 中与封装的高级 Chains 重新基于 LCEL 重构,使得其内部逻辑更加透明,并赋予了开发者前所未有的灵活性。

本博文将深入探讨两个基于 LCEL 构建的基础且极为强大的 Chain:

  • create_sql_query_chain
  • create_stuff_documents_chain

前者是连接自然语言与结构化数据库(Database)的桥梁,我们将使用 MySQL 数据库作为示例。后者则是处理文档内容、进行问答与总结的基础。让我们一同揭开它们的神秘面纱。


create_sql_query_chain —— 让语言模型成为你的 SQL 专家

想象一下,如果你的业务人员或数据分析师不再需要编写复杂的 SQL,只需用自然语言提问,就能从数据库中获取所需数据,这将是多么高效的场景。create_sql_query_chain 正是为此而生,它的核心使命就是将人类的自然语言问题精准地转换成特定方言的 SQL 查询语句。

环境准备与数据库连接

首先,我们需要一个可以交互的数据库。本文将以 MySQL 为例。为了让 LangChain 能够连接并操作 MySQL,请确保你已经安装了必要的 Python 包。

pip install pymysql

接下来,我们使用 LangChain 提供的 SQLDatabase 工具类来连接数据库。这个工具类非常方便,它不仅能执行查询,还能智能地获取数据库的元信息(如表结构、字段名等),为后续 LLM 生成查询提供关键上下文。

注:假设你的 user 数据库中有一个名为 employees 的表。

from langchain_community.utilities import SQLDatabase
import os# --- 数据库连接配置 ---
# 建议将敏感信息存储在环境变量 .env 中
db_user = "root"
db_password = "abc123"
db_host = "localhost"
db_port = "3306"
db_database = "emp" # 假设我们有一个名为 'emp' 的数据库# 使用 from_uri 方法可以方便地创建连接
# URI 格式: mysql+pymysql://<user>:<password>@<host>:<port>/<database>
db = SQLDatabase.from_uri(f"mysql+pymysql://{db_user}:{db_password}@{db_host}:{db_port}/{db_database}"
)# --- 验证连接 ---
print(f"数据库方言 (Dialect): {db.dialect}")
# get_usable_table_names() 会获取数据库中所有可用的表名
print(f"可用的数据表: {db.get_usable_table_names()}")
# 尝试执行一个简单的SQL查询来验证
employee_count = db.run("SELECT COUNT(*) FROM employees;")
print(f"employees 表中的记录总数: {employee_count}")

准备大语言模型(LLM)

我们需要一个强大的语言模型来理解自然语言并生成 SQL。这里我们使用 Deepseek-R1 的模型作为示例,相关内容已封装在 .env 文件中。

import dotenv
from langchain_openai import ChatOpenAI# 加载 .env 文件中的环境变量
dotenv.load_dotenv()os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["OPENAI_BASE_URL"] = os.getenv("OPENAI_BASE_URL")# 初始化模型
llm = ChatOpenAI(model=os.getenv("CHAT_MODEL")
)

创建并运行 Chain

现在,万事俱备。创建 create_sql_query_chain 实例非常简单,只需将 LLM 和数据库连接实例传递给它即可。

from langchain.chains import create_sql_query_chain# 创建 Text-to-SQL Chain
sql_chain = create_sql_query_chain(llm, db)# 发起调用
question = "数据表employees中有多少员工?"
response = sql_chain.invoke({"question": question})print("自然语言问题:", question)
print("生成的SQL查询:", response)

输出的SQL语句如下。可以看到,Chain 成功地将我们的问题转换为了准确的 SQL 查询。

自然语言问题: 数据表employees中有多少员工?
生成的SQL查询: SELECT count(*) FROM employees

工作原理揭秘

create_sql_query_chain 的背后,是一个精心设计的 Prompt。当你调用它时,它会:

  1. 自动从 db 对象中提取数据库的表结构信息(表名、字段、类型等)。
  2. 将这些结构信息连同你的问题(question)一起,填充到一个为 Text-to-SQL 任务优化的 Prompt 模板中。
  3. 将这个完整的 Prompt 发送给 LLM,LLM 则基于这些上下文生成最终的 SQL 语句。

高级技巧

如果你的数据库中有很多表,但某个查询只涉及其中一两个,为了提高准确性并节省 Token,你可以在调用时使用 table_names_to_use 参数指定表的范围。

response_with_tables = sql_chain.invoke({"question": "列出部门'IT'中所有员工的名字","table_names_to_use": ["employees", "departments"]
})

这只是第一步。在实际应用中,你可以将这个 sql_chain 的输出(即 SQL 字符串)通过管道传递给 db.run 来执行,从而构成一个完整的“自然语言提问 -> SQL生成 -> SQL执行 -> 返回结果”的完整流程。这就是 LCEL 的魅力所在!


create_stuff_documents_chain —— 文档内容填充的艺术

当我们处理 RAG(检索增强生成)或文档问答任务时,经常需要将检索到的多个文档片段整合起来,作为上下文提供给 LLM。create_stuff_documents_chain 是实现这一目标最直接、最基础的方法。

它的工作方式正如其名——“Stuff”(填充)。它会粗暴但有效地将所有文档的内容(page_content)连接成一个单一的长文本,然后将其插入到 Prompt 的指定位置。

适用场景分析

优点:

  • 上下文完整: LLM 在一次调用中就能看到所有相关文档的全部内容,非常适合需要全局理解才能完成的任务,如对一组报告进行全面总结。
  • 实现简单: 逻辑清晰,易于理解和调试。

缺点:

  • 上下文窗口限制: 这是其最大的局限。如果所有文档的总长度超过了 LLM 的上下文窗口限制,调用将会失败。因此,它只适合处理少量或中等长度的文档。

完整实例

让我们构建一个完整的例子,用 create_stuff_documents_chain 来总结几篇关于人工智能的短文。

from langchain_core.documents import Document
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain# --- Step 1: 准备文档 ---
# 在实际应用中,这些文档通常来自一个 Retriever 的检索结果
docs = [Document(page_content="LangChain是一个用于开发由语言模型驱动的应用程序的框架。它提供了模块化的组件和链式调用的思想,极大地简化了复杂应用的构建。"),Document(page_content="LCEL,即LangChain表达式语言,是LangChain的核心。它允许开发者通过管道符 `|` 灵活地组合不同的组件,代码更简洁,可读性更强。"),Document(page_content="RAG(检索增强生成)是当前LLM应用的主流范式,它将外部知识库的检索与LLM的生成能力相结合,有效减少了模型幻觉。")
]# --- Step 2: 定义 Prompt ---
# 这个 Prompt 必须包含一个变量,用于接收被“填充”后的文档内容。
# 我们将其命名为 "context"。
prompt_template_str = """
请根据以下上下文内容,写出一个简洁的总结:上下文:
{context}总结:
"""
prompt = ChatPromptTemplate.from_template(prompt_template_str)# --- Step 3: 创建并运行 Chain ---
# 注意这里的三个核心参数:
# 1. llm: 我们之前已经初始化好的大模型实例
# 2. prompt: 刚刚创建的提示词模板
# 3. document_variable_name: 这个参数的值必须与 prompt 中定义的变量名("context")完全一致!
stuff_chain = create_stuff_documents_chain(llm=llm,prompt=prompt,document_variable_name="context" # 关键参数
)# --- 发起调用 ---
# 输入是一个字典,key 必须与 prompt 中的变量名匹配,value 是我们的文档列表
result = stuff_chain.invoke({"context": docs})print(result)

大模型输出如下。这个例子清晰地展示了 create_stuff_documents_chain 的工作流程:

  • 它接收一个文档列表,将它们的内容合并
  • 然后作为一个名为 context 的变量传递给 Prompt
  • 最后由 LLM 完成指定的任务

读者可能对这个的感觉并不深,但是等后期博文涉及到 RAG 部分时,我们会深度应用。

LangChain是一个利用LCEL(LangChain表达式语言)来简化语言模型应用开发的框架。它通过模块化组件和管道式组合,使得构建如RAG(检索增强生成)这类先进应用变得更加高效和直观。RAG结合了外部知识检索与模型生成,有效提升了回答的准确性。

总结

create_sql_query_chaincreate_stuff_documents_chain 体现了 LangChain LCEL 的设计哲学:将复杂任务拆解为一系列标准化的、可组合的步骤。

  • create_sql_query_chain 为我们打通了从自然语言到结构化数据的查询路径,是构建企业级智能数据应用的关键一环。
  • create_stuff_documents_chain 则是处理文档集合的基础工具,是构建文档问答、摘要等功能的核心组件之一。

理解并掌握这两个基础 Chain,你就能开启构建更复杂、更强大应用的大门。例如,你可以将一个 create_retrieval_chain(检索链)的输出直接用管道符传递给 create_stuff_documents_chain,轻松构建起一个完整的 RAG 应用。

LCEL 的世界充满了无限可能,期待你在实践中探索出更多创新的组合!


2025.10.09 金融街

http://www.dtcms.com/a/460693.html

相关文章:

  • 2.0 Labview自定义控件中的队列引用句柄从哪拖来?
  • 【LabVIEW实用开发】--- LabVIEW调用python脚本
  • 碰一碰系统源码搭建与发视频、发文案和写好评定制化开发:支持OEM
  • 安徽建设工程信息网站简单的个人网页制作html
  • iBizModel 全文检索体系(PSSYSSEARCHSCHEME)模型详解
  • Django REST Framework `Request` 对象
  • 易班班级网站建设展示PPT公司网站建设怎么做
  • 易讯网站建设凤翔网站制作
  • 湘潭找工作网站如何将wordpress上传
  • 做企业网站注意些啥太原网络营销
  • Redis 缓存与数据库谁先更新?
  • 网站备案要营业执照原件吗怎么做一个小程序app
  • 网站里的横幅广告怎么做商城网站 html模板
  • 金坛网站开发河南瑞达建设工程有限公司网站
  • 临淄网站设计可以做网站的公司
  • 做视频网站程序多少钱网站 注册模块怎么做
  • 做电影网站需要告诉网络网络营销方式有哪几种有哪些
  • 免保证金入驻电商平台wordpress摘要seo
  • 最低价网站建设建设企业网站公司
  • 旅游网站开发的背景及意义怎么在手机上设计网站
  • 网站搜索引擎收录百度一下百度首页官网
  • 南京品牌网站设计网站权重是什么
  • 有没有免费注册域名的网站淄博网站建设
  • php英文商城网站建设株洲新区发布
  • 长丰县建设局网站郑州做网站推广电
  • 谷歌有做网站建设合肥网站专业制作
  • 网站建设合同 技术合同房产做网站吸引
  • 长沙有什么做试卷的网站企业营销型网站建设费用
  • 主视觉设计网站wordpress 招聘 插件
  • 南宁会制作网站的技术人员无锡城乡建设局网站