LangChain基础篇 (02)

news/2025/2/4 20:14:48/文章来源:https://www.cnblogs.com/nmblr/p/18698435

LangChain 核心模块学习:Chains

对于简单的大模型应用,单独使用语言模型(LLMs)是可以的。

但更复杂的大模型应用需要将 LLMsChat Models 链接在一起。 要么彼此链接,要么与其他组件链接。

LangChain 为这种“链式”应用程序提供了 Chain 接口。

LangChain 以通用方式定义了 Chain,它是对组件进行调用序列的集合,其中可以包含其他链。

Chain Class 基类

类继承关系:

Chain --> <name>Chain  # Examples: LLMChain, MapReduceChain, RouterChain
# 定义一个名为Chain的基础类
class Chain(Serializable, Runnable[Dict[str, Any], Dict[str, Any]], ABC):"""为创建结构化的组件调用序列的抽象基类。链应该用来编码对组件的一系列调用,如模型、文档检索器、其他链等,并为此序列提供一个简单的接口。Chain接口使创建应用程序变得容易,这些应用程序是:- 有状态的:给任何Chain添加Memory可以使它具有状态,- 可观察的:向Chain传递Callbacks来执行额外的功能,如记录,这在主要的组件调用序列之外,- 可组合的:Chain API足够灵活,可以轻松地将Chains与其他组件结合起来,包括其他Chains。链公开的主要方法是:- `__call__`:链是可以调用的。`__call__`方法是执行Chain的主要方式。它将输入作为一个字典接收,并返回一个字典输出。- `run`:一个方便的方法,它以args/kwargs的形式接收输入,并将输出作为字符串或对象返回。这种方法只能用于一部分链,不能像`__call__`那样返回丰富的输出。"""# 调用链def invoke(self, input: Dict[str, Any], config: Optional[runnableConfig] = None) -> Dict[str, Any]:"""传统调用方法。"""return self(input, **(config or {}))# 链的记忆,保存状态和变量memory: Optional[BaseMemory] = None"""可选的内存对象,默认为None。内存是一个在每个链的开始和结束时被调用的类。在开始时,内存加载变量并在链中传递它们。在结束时,它保存任何返回的变量。有许多不同类型的内存,请查看内存文档以获取完整的目录。"""# 回调,可能用于链的某些操作或事件。callbacks: Callbacks = Field(default=None, exclude=True)"""可选的回调处理程序列表(或回调管理器)。默认为None。在对链的调用的生命周期中,从on_chain_start开始,到on_chain_end或on_chain_error结束,都会调用回调处理程序。每个自定义链可以选择调用额外的回调方法,详细信息请参见Callback文档。"""# 是否详细输出模式verbose: bool = Field(default_factory=_get_verbosity)"""是否以详细模式运行。在详细模式下,一些中间日志将打印到控制台。默认值为`langchain.verbose`。"""# 与链关联的标签tags: Optional[List[str]] = None"""与链关联的可选标签列表,默认为None。这些标签将与对这个链的每次调用关联起来,并作为参数传递给在`callbacks`中定义的处理程序。你可以使用这些来例如识别链的特定实例与其用例。"""# 与链关联的元数据metadata: Optional[Dict[str, Any]] = None"""与链关联的可选元数据,默认为None。这些元数据将与对这个链的每次调用关联起来,并作为参数传递给在`callbacks`中定义的处理程序。你可以使用这些来例如识别链的特定实例与其用例。"""

LLMChain

LLMChain 是 LangChain 中最简单的链,作为其他复杂 Chains 和 Agents 的内部调用,被广泛应用。

一个LLMChain由PromptTemplate和语言模型(LLM or Chat Model)组成。它使用直接传入(或 memory 提供)的 key-value 来规范化生成 Prompt Template(提示模板),并将生成的 prompt (格式化后的字符串)传递给大模型,并返回大模型输出。

(图片)

from langchain_openai import OpenAI
from langchain.prompts import PromptTemplatellm = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.9, max_tokens=500)prompt = PromptTemplate(input_variables=["product"],template="给制造{product}的有限公司取10个好名字,并给出完整的公司名称",
)from langchain.chains import LLMChainchain = LLMChain(llm=llm, prompt=prompt)
print(chain.invoke({'product': "性能卓越的GPU"}))

输出:

{'product': '性能卓越的GPU', 'text': '\n\n1. 星火卓越科技有限公司\n2. 利益达太空科技有限公司\n3. 未来视界智能科技有限公司\n4. 强力算力科技有限公司\n5. 极速计算科技有限公司\n6. 无限创想智能科技有限公司\n7. 高能创新科技有限公司\n8. 天马行空科技有限公司\n9. 极致计算科技有限公司\n10. 全能加速科技有限公司'}

Sequential Chain

串联式调用语言模型(将一个调用的输出作为另一个调用的输入)。

顺序链(Sequential Chain )允许用户连接多个链并将它们组合成执行特定场景的流水线(Pipeline)。有两种类型的顺序链:

  • SimpleSequentialChain:最简单形式的顺序链,每个步骤都具有单一输入/输出,并且一个步骤的输出是下一个步骤的输入。
  • SequentialChain:更通用形式的顺序链,允许多个输入/输出。

使用 SimpleSequentialChain 实现戏剧摘要和评论(单输入/单输出)

(图片)

# 这是一个 LLMChain,用于根据剧目的标题撰写简介。llm = OpenAI(temperature=0.7, max_tokens=1000)template = """你是一位剧作家。根据戏剧的标题,你的任务是为该标题写一个简介。标题:{title}
剧作家:以下是对上述戏剧的简介:"""prompt_template = PromptTemplate(input_variables=["title"], template=template)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template)
# 这是一个LLMChain,用于根据剧情简介撰写一篇戏剧评论。
# llm = OpenAI(temperature=0.7, max_tokens=1000)
template = """你是《纽约时报》的戏剧评论家。根据剧情简介,你的工作是为该剧撰写一篇评论。剧情简介:
{synopsis}以下是来自《纽约时报》戏剧评论家对上述剧目的评论:"""prompt_template = PromptTemplate(input_variables=["synopsis"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template)

(图片)

# 这是一个SimpleSequentialChain,按顺序运行这两个链
from langchain.chains import SimpleSequentialChainoverall_chain = SimpleSequentialChain(chains=[synopsis_chain, review_chain], verbose=True)
review = overall_chain.invoke("星球大战第九季")

输出:

> Entering new SimpleSequentialChain chain...《星球大战第九季》是一部充满惊险刺激的科幻戏剧,它延续了《星球大战》系列的传奇故事。在这一季中,我们将见证新的冒险和挑战,因为银河系再次陷入战争的深渊。反抗军和第一秩序之间的战争仍在继续,但这一次,他们将面临着更加强大的敌人。新的角色和老朋友将再次出现,与我们的英雄们一起并肩作战。随着战争的进展,我们也将见证力量和黑暗的永恒对抗,以及对自由和正义的不懈追求。在这场史诗般的战役中,我们将看到勇气、牺牲和爱的力量,同时也会思考我们对未来的选择和命运。《星球大战第九季》将带给观众无与伦比的视觉盛宴和感人心弦的故事,让我们一起来见证这一壮丽的星际冒险!《星球大战第九季》是一部不容错过的史诗般的科幻戏剧。该剧延续了《星球大战》系列的传奇故事,将观众带入一个充满惊险和刺激的银河系。在这一季中,我们将再次与我们熟悉的英雄们一起并肩作战,同时也会见证新的挑战和冒险。该剧不仅仅是一场视觉盛宴,更是一部让人思考的故事。通过力量和黑暗的永恒对抗,以及对自由和正义的追求,观众将被带入一个关于命运和选择的深刻思考。在这场史诗般的战役中,我们将见证勇气、牺牲和爱的力量,这些都是《星球大战》系列一直探讨的重要主题。该剧不仅有着令人惊叹的特效和精彩的动作场面,更重要的是它成功地将这些元素与深刻的人物关系和情感表达相结合。观众将会被带入一个充满希望和感动的星际冒险,与角色们一起经历他们的成长和转变。总的来说,《星球大战第九季》是一部充满情感和故事的出色作品,它将让观众沉浸在一个充满惊喜和挑战的星际世界。无论您是《星球大战》系列的忠实粉丝,还是对科幻题材感兴趣的观众,这部戏剧都会给您带来一场令人难忘的体验。不容错过!> Finished chain.

Router Chain: 实现条件判断的大模型调用

这段代码构建了一个可定制的链路系统,用户可以提供不同的输入提示,并根据这些提示获取适当的响应。

主要逻辑:从prompt_infos创建多个LLMChain对象,并将它们保存在一个字典中,然后创建一个默认的ConversationChain,最后创建一个带有路由功能的MultiPromptChain

(图片)

from langchain.chains.router import MultiPromptChain
from langchain_openai import OpenAI
from langchain.chains import ConversationChain
from langchain.chains.llm import LLMChain
from langchain.prompts import PromptTemplate
physics_template = """你是一位非常聪明的物理教授。
你擅长以简洁易懂的方式回答关于物理的问题。
当你不知道某个问题的答案时,你会坦诚承认。这是一个问题:
{input}"""math_template = """你是一位很棒的数学家。你擅长回答数学问题。
之所以如此出色,是因为你能够将难题分解成各个组成部分,
先回答这些组成部分,然后再将它们整合起来回答更广泛的问题。这是一个问题:
{input}"""
prompt_infos = [{"name": "物理","description": "适用于回答物理问题","prompt_template": physics_template,},{"name": "数学","description": "适用于回答数学问题","prompt_template": math_template,},
]

llm = OpenAI(model_name="gpt-3.5-turbo-instruct")

# 创建一个空的目标链字典,用于存放根据prompt_infos生成的LLMChain。
destination_chains = {}# 遍历prompt_infos列表,为每个信息创建一个LLMChain。
for p_info in prompt_infos:name = p_info["name"]  # 提取名称prompt_template = p_info["prompt_template"]  # 提取模板# 创建PromptTemplate对象prompt = PromptTemplate(template=prompt_template, input_variables=["input"])# 使用上述模板和llm对象创建LLMChain对象chain = LLMChain(llm=llm, prompt=prompt)# 将新创建的chain对象添加到destination_chains字典中destination_chains[name] = chain# 创建一个默认的ConversationChain
default_chain = ConversationChain(llm=llm, output_key="text")

使用 LLMRouterChain 实现条件判断调用

这段代码定义了一个chain对象(LLMRouterChain),该对象首先使用router_chain来决定哪个destination_chain应该被执行,如果没有合适的目标链,则默认使用default_chain。

from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE
# 从prompt_infos中提取目标信息并将其转化为字符串列表
destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
# 使用join方法将列表转化为字符串,每个元素之间用换行符分隔
destinations_str = "\n".join(destinations)
# 根据MULTI_PROMPT_ROUTER_TEMPLATE格式化字符串和destinations_str创建路由模板
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str)
# 创建路由的PromptTemplate
router_prompt = PromptTemplate(template=router_template,input_variables=["input"],output_parser=RouterOutputParser(),
)
# 使用上述路由模板和llm对象创建LLMRouterChain对象
router_chain = LLMRouterChain.from_llm(llm, router_prompt)

print(destinations)
输出:['物理: 适用于回答物理问题', '数学: 适用于回答数学问题']

# 创建MultiPromptChain对象,其中包含了路由链,目标链和默认链。
chain = MultiPromptChain(router_chain=router_chain,destination_chains=destination_chains,default_chain=default_chain,verbose=True,
)

print(chain.invoke("黑体辐射是什么??"))
输出:

> Entering new MultiPromptChain chain...
物理: {'input': 'What is blackbody radiation?'}
> Finished chain.
{'input': 'What is blackbody radiation?', 'text': '\n\n黑体辐射是一种物理现象,指的是由于物体内部的热运动导致的电磁辐射。简单来说,物体在受热时会发出电磁波,这些波的频率和强度取决于物体的温度。黑体辐射的特点是它的辐射频率与物体的温度无关,而只与物体的结构和性质有关。这个概念在热力学和量子力学中都有重要的应用。'}

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

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

相关文章

09. Shell脚本

一、什么是ShellShell 是操作系统中的一个 命令行解释器,主要功能是接收用户命令,然后将这些命令传递给操作系统内核去执行。 Shell 是用户与操作系统内核之间的接口,它允许用户通过命令行或脚本来与操作系统进行交互。同时,Shell 也是一种脚本语言,允许用户编写一系列命令…

Maven安装、配置以及Idea使用本地Maven仓库

Maven的安装和配置 Maven是Java项目常用的依赖管理和构建工具,项目使用Maven的一个特点就是包含一个pom.xml文件。实际上,Idea在安装时会集成一个Maven,这里不使用这个集成的,而是记录一下如何在机器上单独安装并配置好。 首先,需要安装好jdk。然后,到搜索引擎上搜索Mave…

DeepSeek逆天,核心是 知识蒸馏(Knowledge Distillation, KD),一项 AI 领域的关键技术

本文原文链接 文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 …

Java初学者笔记-12、前端开发基础

未完待续 Web 三个组成部分:HTML:负责网页的结构(页面元素和内容)。 CSS:负责网页的表现(页面元素的外观、位置等页面样式,如:颜色、大小等)。 Javascript:负责网页的行为(交互效果)。高级技术:基于JS封装而来的高级框架——vue。 基于vue的桌面端组件库——Eleme…

Java笔记-13、Web后端基础 Maven

Maven是一款用于管理和构建Java项目的工具,是apache旗下的一个开源项目。基于项目对象模型(POM),通过一小段描述信息管理项目构建。依赖管理:方便快捷地管理项目依赖的资源(jar包)。 项目构建:标准化的跨平台自动化项目构建方式。Maven面板中Lifecycle中的compile用于编译…

直流有刷电机.

一、基础知识回顾 1.1 电路定律 1.1.1 基尔霍夫电流定律 在集总参数电路中的任一节点处,所有支路电流的代数和在任何时刻恒等于零,即\(\sum i=0\)。 对于正弦稳态交流电路,其相量形式为\(\sum {\dot I}=0\)。 其中,当支路电路的参考方向为流入、流出节点时,支路电流分别取…

用C# GDI编写粒子效果

C#语言能不能画一动画呢?闲来无事,特过一把编程瘾。一共写了6个例子特效动画,界面如下,程序在文末供下载。拿一个粒子效果“鼓泡泡效果”的类讲解,其他类似:using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; usi…

你说得对,但是我怎么没学过后缀科技啊???

后缀数组 (SA) 后缀数组(SA,Suffix Array)最基础的应用是,可以将给定串 \(S\) 的所有后缀串排序。 一点定义:\(sa_i\) 表示第 \(i\) 小的后缀的编号,\(rk_i\) 表示后缀 \([i,n]\) 的排名。显然 \(sa_{rk[i]}=rk_{sa[i]}=i\)。 后缀数组就是 \(sa\) 数组,我们可以利用后缀…

2025.2.4 鲜花

交通网络 题解?hzoi898 交通网络 题解?Underground 是那个纯音乐啦~Ans 注意到:一个只能说真话,一个绝不说假话。这题有四样读法,你知道么?出一个毒瘤 ds 的最好方式就是把序列问题直接出到树上,考察选手树剖能力。正确的题意:给定一棵树,在时刻 \([tl, tr]\) 链加,查…

云手机和模拟器究竟有什么区别?一分钟带你理清楚

云手机和模拟器究竟有什么区别?一分钟带你理清楚概念 云手机:是在云端运行的虚拟手机,基于云计算技术和端云一体虚拟化技术,通过云服务器实现云服务。具备真实的ARM硬件,和真实手机的架构几乎一样,用户通过网络连接,在不同终端设备上远程操作,可轻松安装、管理APP。 模…

函数笔记

想了很久还是来更这个了。 0x00 一次函数 一般式 \(y=kx+b\),特殊的,当 \(b=0\),称作正比例函数。 图象 一次函数的图像是过\(\left(0,b\right)\)、\(\left( -\dfrac{b}{k},0\right)\)的直线。 而正比例函数的图像则是过原点的一条直线。 根据参数的符号,我们可以确定图象…

java基础(中)

java基础 Scanner对象Scanner类是用于获取用户输入的import java.util.Scanner;public class Hello {public static void main(String[] args){// 创建一个scanner对象来接收键盘数据Scanner scanner = new Scanner(System.in);System.out.println("Enter your name: &qu…