大模型 LangChain 开发框架:Runable 与 LCEL 初探

大模型 LangChain 开发框架:Runable 与 LCEL 初探

一、引言

在大模型开发领域,LangChain 作为一款强大的开发框架,为开发者提供了丰富的工具和功能。其中,Runnable 接口和 LangChain 表达式语言(LCEL)是构建高效、灵活应用程序的关键要素。本文将初步探讨 Runnable 和 LCEL 的概念、功能以及如何在实际应用中运用它们来构建简单的工作流程。
(https://python.langchain.com/docs/how_to/lcel_cheatsheet/#invoke-a-runnable)参考LangChain 表达语言速查表
在这里插入图片描述

二、Runnable 接口详解

(一)接口定义与功能概述

Runnable 接口是 LangChain 众多组件以及 LangChain 表达语言构建的基础抽象。它定义了一系列标准方法,使得 Runnable 组件具备多种强大的功能:

  1. invoke 方法:该方法能够将单个输入转换为相应的输出,是实现基本功能的核心。例如,在一个简单的文本处理任务中,输入一段文本,通过 invoke 方法可以得到处理后的结果,如文本分类、摘要生成等。
  2. batched 方法:支持多个输入高效地转换为输出。这在处理批量数据时非常有用,能够显著提高处理效率。比如,同时对多篇文档进行关键词提取,使用 batched 方法可以一次性处理多个文档,减少处理时间。
  3. steramed 方法:实现输出在生成时以流式传输形式进行。在处理大文本或实时数据时,流式传输可以让用户及时获取部分结果,提升用户体验。例如,在实时翻译场景中,随着源文本的输入,翻译结果可以逐句或逐段地流式输出。
  4. Inspected 方法:提供了访问有关 Runnable 的输入、输出和配置的示意图信息的能力。这有助于开发者在调试和优化过程中深入了解组件的运行情况,快速定位问题。
  5. Composed 方法:允许组合多个 Runnable,通过 LangChain 表达语言(LCEL)协同工作,从而创建复杂的管道。这是构建复杂应用程序的关键特性,能够将多个简单的组件组合成一个强大的系统。

(二)接口的重要性与应用场景

Runnable 接口的标准化使得不同的 LangChain 组件能够相互协作,实现更高级的功能。在自然语言处理任务中,如文档处理、问答系统、机器翻译等,都可以利用 Runnable 接口构建高效的处理流程。例如,在构建一个智能客服系统时,可以将语音识别、文本处理、意图识别、回答生成等多个 Runnable 组件组合起来,实现从用户提问到回答的完整流程。

三、LangChain 表达式语言(LCEL)解析

(一)LCEL 的概念与语法

LangChain 表达式语言(LCEL)是一种用于编排 LangChain 组件的语法。它提供了一种声明式的方法来组合 Runnable 组件,使得构建复杂的工作流程变得更加简单和直观。LCEL 的主要组合原语包括 RunnableSequence 和 RunnableParallel。

(二)RunnableSequence 的使用

RunnableSequence 用于按顺序调用一系列 Runnable,其中一个 Runnable 的输出作为下一个 Runnable 的输入。可以使用 “|” 运算符或将 Runnable 列表传递给 RunnableSequence 来构造。例如,在一个文档处理流程中,首先进行文本加载(loader_pdf),然后进行文本分割(text_splitter),接着进行向量化(embedding),最后进行存储(save),这些步骤可以通过 RunnableSequence 依次连接起来,形成一个完整的文档预处理管道。

(三)RunnableParallel 的使用

RunnableParallel 则同时调用可运行程序,为每个程序提供相同的输入。可以使用序列中的字典文字或通过将字典传递给 RunnableParallel 来构造它。例如,在一个搜索和翻译的应用中,同时进行文档搜索(search)和将搜索结果翻译为英文(translateToEnglish)的操作,这两个任务可以通过 RunnableParallel 并行执行,提高处理效率。

(四)LCEL 的优势与适用场景

LCEL 的优势在于它能够以优化的方式处理链的运行时执行,自动获得同步、异步、批处理和流式支持。对于简单的应用程序,LCEL 是一个理想的选择,能够快速构建起有效的工作流程。例如,在构建一个小型的文档搜索和翻译工具时,使用 LCEL 可以方便地组合各个组件,实现基本功能。

四、案例分析:PDF 内容搜索结果后翻译为英文

(一)需求分析

本案例旨在实现对 PDF 文档的内容搜索,并将搜索到的中文内容翻译为英文。具体步骤包括加载 PDF 文件、分词、向量化存储、问题查询、获取相似答案并进行翻译。

(二)代码实现与详细解释

  1. 组件导入与模型初始化
from langchain_community.embeddings import VolcanoEmbeddings, FastEmbedEmbeddings
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_core.runnables import RunnableLambda, RunnableParallel
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplatemodel = ChatOpenAI(model="deepseek-chat",api_key='<api-key>',base_url='https://api.deepseek.com'
)

这里导入了所需的各种组件,包括用于加载 PDF 的PyPDFLoader、文本分割器RecursiveCharacterTextSplitter、向量化工具FastEmbedEmbeddings、内存向量存储InMemoryVectorStore、Runnable 相关的类和函数、消息类、ChatOpenAI 模型以及提示模板类。同时,初始化了 ChatOpenAI 模型,指定了模型名称、API 密钥和基础 URL。

  1. 函数定义
def save(embeddings):vector_store = InMemoryVectorStore(embeddings)vector_store.add_documents(documents=splits)return vector_storedef embedding(all_splits):global splitsfastembed = FastEmbedEmbeddings()for split in all_splits:v = fastembed.embed_query(split.page_content)splits = all_splitsreturn fastembeddef text_splitter(docs):text_splitter = RecursiveCharacterTextSplitter(chunk_size=50, chunk_overlap=10, add_start_index=True)all_splits = text_splitter.split_documents(docs)return all_splitsdef loader_pdf(file_path):loader = PyPDFLoader(file_path)docs = loader.load()return docsdef search(store, query):results = store.similarity_search_with_score(query)document_obj, score = results[0]return document_obj.page_contentdef translateToEnglish(store, query):content = search(store, query)system_template = "你是一名资深的翻译大师,把中文翻译为{language}"prompt_template = ChatPromptTemplate.from_messages([("system", system_template), ("user", "{text}")])prompt = prompt_template.invoke({"language": "英文", "text": content})return model.invoke(prompt)
  • save函数:用于将向量化后的文档存储到内存向量存储中。它接受向量化结果作为输入,创建一个InMemoryVectorStore对象,并将文档添加到其中,最后返回存储对象。
  • embedding函数:负责对文档进行向量化处理。它使用FastEmbedEmbeddings对文档的每个片段进行向量化,并将结果存储在全局变量splits中,最后返回向量化工具对象。
  • text_splitter函数:将加载后的文档进行文本分割。使用RecursiveCharacterTextSplitter按照指定的块大小、重叠量和是否添加起始索引进行分割,返回分割后的文档片段列表。
  • loader_pdf函数:实现加载 PDF 文件的功能。通过PyPDFLoader加载指定路径的 PDF 文件,并返回加载后的文档对象。
  • search函数:在向量存储中进行相似性搜索。根据输入的查询,在向量存储中查找最相似的文档,并返回文档的内容。
  • translateToEnglish函数:将搜索到的中文内容翻译为英文。它首先调用search函数获取中文内容,然后根据给定的系统模板和用户输入构建提示模板,通过模型进行翻译,并返回翻译结果。
  1. 链的构建与执行
if __name__ == '__main__':q = "docker的配置?"file_path = "./ragflow文档.pdf"chain = (RunnableLambda(loader_pdf) | RunnableLambda(text_splitter) | RunnableLambda(embedding) | RunnableLambda(save) |RunnableParallel(first=RunnableLambda(search).bind(query=q), second=RunnableLambda(translateToEnglish).bind(query=q)))chain.get_graph().print_ascii()  # 流程图result = chain.invoke(file_path)print(q)print(result['first'])print(result['second'].content)

在主函数中,首先定义了查询问题q和 PDF 文件路径file_path。然后,使用 RunnableLambda 和 RunnableParallel 构建了一个复杂的链。通过|运算符将loader_pdftext_splitterembeddingsave按顺序连接起来,形成文档预处理的序列。接着,使用RunnableParallel并行执行searchtranslateToEnglish操作,并将查询问题q绑定到这两个操作上。最后,通过chain.invoke方法执行整个链,传入 PDF 文件路径作为输入,并获取结果。打印出查询问题、搜索到的文档内容以及翻译后的英文内容。

流程图示:

      +------------------+        | loader_pdf_input |        +------------------+        *                 *                 *                 +------------+           | loader_pdf |           +------------+           *                 *                 *                 +---------------+         | text_splitter |         +---------------+         *                 *                 *                 +-----------+           | embedding |           +-----------+           *                 *                 *                 +------+              | save |              +------+              *                 *                 *                 
+-----------------------------+   
| Parallel<first,second>Input |   
+-----------------------------+   *         *            **           **          *               *         +--------+        +------------+ | search |        | ChatOpenAI | +--------+        +------------+ *         *            **     **             *   *               
+------------------------------+  
| Parallel<first,second>Output |  
+------------------------------+  

结果:

docker的配置?
根据官方文档启动后,访问主页   http://127.0.0.1
After starting according to the official documentation, access the homepage at http://127.0.0.1

五、LCEL 的指导原则与应用建议

(一)不同场景下的选择策略

  1. 单个 LLM 调用:如果仅进行单个大语言模型(LLM)调用,不需要使用 LCEL,直接调用底层聊天模型即可。这种情况下,使用 LCEL 会增加不必要的复杂性。
  2. 简单链构建:当有一个简单的链,如提示 + LLM + 解析器或简单的检索设置等,并且希望利用 LCEL 的优势,如自动获得多种执行方式的支持,那么 LCEL 是一个合理的选择。它可以快速构建起有效的工作流程,提高开发效率。
  3. 复杂链构建:对于构建复杂的链,如具有分支、循环、多个代理等情况,建议使用 LangGraph。LangGraph 能够更好地处理复杂的编排逻辑,提供更强大的状态管理和流程控制能力。同时,在 LangGraph 的各个节点内仍然可以使用 LCEL 来处理具体的任务。

(二)实际应用中的注意事项

  1. 组件兼容性:在组合 Runnable 组件时,要确保各个组件之间的兼容性。例如,输入和输出的数据类型要匹配,否则可能导致链的执行失败。
  2. 资源管理:注意资源的使用情况,特别是在处理大规模数据或长时间运行的任务时。合理配置模型参数、向量存储大小等资源,避免资源耗尽或性能下降。
  3. 可维护性:编写清晰、可读的代码,合理命名变量和函数,添加必要的注释,以便于后续的维护和扩展。特别是在构建复杂的链时,良好的代码结构和注释能够大大降低维护成本。

六、总结

本文介绍了 LangChain 开发框架中的 Runnable 接口和 LangChain 表达式语言(LCEL)。通过对 Runnable 接口功能的深入剖析以及对 LCEL 语法和组合原语的详细解释,结合 PDF 内容搜索与翻译的案例分析,展示了如何在实际应用中运用这些特性构建复杂的工作流程。同时,提供了 LCEL 的指导原则和应用建议,帮助开发者在不同场景下选择合适的工具和方法,提高大模型应用程序的开发效率和质量。在未来的开发中,开发者可以根据具体需求灵活运用 Runnable 和 LCEL,构建出更加强大、高效的大模型应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501250.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flash Attention V3使用

Flash Attention V3 概述 Flash Attention 是一种针对 Transformer 模型中注意力机制的优化实现&#xff0c;旨在提高计算效率和内存利用率。随着大模型的普及&#xff0c;Flash Attention V3 在 H100 GPU 上实现了显著的性能提升&#xff0c;相比于前一版本&#xff0c;V3 通…

《Vue3实战教程》34:Vue3状态管理

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》 状态管理​ 什么是状态管理&#xff1f;​ 理论上来说&#xff0c;每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了。我们以一个简单的计数器组件为例&#xff1a; vue <script setup> import { r…

电脑找不到mfc110.dll文件要如何解决?Windows缺失mfc110.dll文件快速解决方法

一、mfc110.dll文件的重要性 mfc110.dll&#xff0c;全称Microsoft Foundation Class Library 110&#xff0c;是Microsoft Visual C Redistributable for Visual Studio 2012的一部分。这个动态链接库&#xff08;DLL&#xff09;文件对于支持基于MFC&#xff08;Microsoft F…

OSPF特殊区域(open shortest path first LSA Type7)

一、区域介绍 1、Stub区域 Stub区域是一种可选的配置属性。通常来说&#xff0c;Stub区域位于自治系统的边界&#xff0c;例如&#xff0c;只有一 个ABR的非骨干区域。在这些区域中&#xff0c;设备的路由表规模以及路由信息传递的数量都会大量减少。 kill 4 5类type 传递1 …

浏览器选中文字样式

效果 学习 Chrome: 支持 ::selection。Firefox: 支持 :-moz-selection 和 ::selection。Safari: 支持 ::selection。Internet Explorer: 支持 :-ms-selection。Microsoft Edge: 支持 ::-ms-selection 和 ::selection。 代码 <!DOCTYPE html> <html lang"en&qu…

Rabbitmq追问1

如果消费端代码异常&#xff0c;未手动确认&#xff0c;那么这个消息去哪里 2024-12-31 21:19:12 如果消费端代码发生异常&#xff0c;未手动确认&#xff08;ACK&#xff09;的情况下&#xff0c;消息的处理行为取决于消息队列的实现和配置&#xff0c;以下是基于 RabbitMQ …

Ansys Discovery 中的网格划分方法:探索模式

本篇博客文章将介绍 Ansys Discovery 中可用于在探索模式下进行分析的网格划分方法。我们将在下一篇博客中介绍 Refine 模式下的网格划分技术。 了解 Discovery Explore 模式下的网格划分 网格划分是将几何模型划分为小单元以模拟系统在不同条件下的行为的过程。这是通过创建…

Golang的并发编程实战经验

## Golang的并发编程实战经验 并发编程是什么 并发编程是指程序的多个部分可以同时执行&#xff0c;这样可以提高程序的性能和效率。在Golang中&#xff0c;并发编程是通过goroutine来实现的&#xff0c;goroutine是一种轻量级线程&#xff0c;可以在一个程序中同时运行成千上万…

vue2实现excel文件预览

一、插件 通过xlsx插件解析excel数据&#xff0c;对解析后的html组件进行渲染展示。 npm install xlsx 二、完整代码 <template><!-- excel文件预览 --><divelement-loading-text"拼命加载中"element-loading-spinner"el-icon-loading"…

低代码引擎插件开发:开启开发的便捷与创新之路

OneCode授权演示 一、低代码引擎与插件开发的概述 在当今快节奏的软件开发领域&#xff0c;低代码引擎正逐渐崭露头角。低代码引擎旨在让开发人员能够以最少的代码量创建功能丰富的应用程序&#xff0c;而其中的关键组成部分便是插件开发。低代码引擎通过提供可视化的开发环境…

Golang的代码质量分析工具

Golang的代码质量分析工具 一、介绍 作为一种高效、简洁、可靠的编程语言&#xff0c;被越来越多的开发者所喜爱和采用。而随着项目规模的增长和团队人员的扩大&#xff0c;代码质量的管理变得尤为重要。为了保障代码的可维护性、健壮性和可扩展性&#xff0c;我们需要借助代码…

JVM实战—9.线上FGC的几种案例

大纲 1.如何优化每秒十万QPS的社交APP的JVM性能(增加S区大小 优化内存碎片) 2.如何对垂直电商APP后台系统的FGC进行深度优化(定制JVM参数模版) 3.不合理设置JVM参数可能导致频繁FGC(优化反射的软引用被每次YGC回收) 4.线上系统每天数十次FGC导致频繁卡顿的优化(大对象问题…

蓝耘平台使用InstantMesh‌生成高质量的三维网格模型!3D内容创作!小白入门必看!!!

目录 引言 InstantMesh应用介绍 蓝耘平台与InstantMesh结合使用 如何部署&#xff08;超简单&#xff09; 第一步登录蓝耘平台 第二步点击应用商城 ​编辑 第三步选择InstantMesh 第四步点击部署 第五步点击快速启动应用 第六步即可体验该产品 总结 注册链接 引言…

LeetCode:106.从中序与后序遍历序列构造二叉树

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;106.从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder …

aardio —— 虚表 —— 模拟属性框

写了个简单的属性框例程&#xff0c;抛砖引玉&#xff0c;期待你做出更丰富强大的功能。 可折叠行、可输入文本、可下拉选择、支持下拉选择图片、颜色等功能。 只有想不到&#xff0c;没有做不到&#xff0c;发挥你的想象力吧。 import win.ui; import godking.comboboxEx im…

word文档中的文档网格——解决相同行间距当显示出不同行间距的情况

1 问题 被一个行间距调疯了&#xff0c;就是样式改了没用&#xff0c;格式刷刷了没用。就是肉眼可以看出行间距完全不一样。 2 解决方法 1&#xff09;修改论文正文(即出现问题文本的样式)样式&#xff1a;样式>修改>格式>段落>缩进和间距>取消"如果定义了…

CDP集群安全指南-静态数据加密

[一]静态数据加密的架构 CDP 支持两种加密组件&#xff0c;这些组件可以组合成独特的解决方案。在选择密钥管理系统&#xff08;KMS&#xff09;时&#xff0c;您需要决定哪些组件能够满足企业的密钥管理和加密需求。 CDP 加密组件 以下是 Cloudera 用于静态数据加密的组件描…

ACM算法模板

ACM算法模板 起手式基础算法前缀和与差分二分查找三分查找求极值分治法&#xff1a;归并排序 动态规划基本线性 d p dp dp最长上升子序列I O ( n 2 ) O(n ^ 2) O(n2)最长上升子序列II O ( n l o g n ) O(nlogn) O(nlogn) 贪心二分最长公共子序列 背包背包求组合种类背包求排列…

AcWing练习题:差

读取四个整数 A,B,C,D&#xff0c;并计算 (AB−CD)的值。 输入格式 输入共四行&#xff0c;第一行包含整数 A&#xff0c;第二行包含整数 B&#xff0c;第三行包含整数 C&#xff0c;第四行包含整数 D。 输出格式 输出格式为 DIFERENCA X&#xff0c;其中 X 为 (AB−CD) 的…

前端路由 Hash 和 History 模式原理对比区别

前端路由 Hash 和 History 模式原理对比区别 1. 基本概念 1.1 什么是前端路由 前端路由是指在单页应用&#xff08;SPA&#xff09;中&#xff0c;通过 JavaScript 来实现页面的切换和状态管理&#xff0c;而无需向服务器请求新的页面。主要有两种实现方式&#xff1a;Hash …