#LLM入门|RAG#3.4_模型链

链(Chains)结合提示(Prompt)使用大语言模型(LLM),处理文本或数据。它们可接受多输入,格式化后传递给LLM,可组合构建复杂操作。

一、大语言模型链

LLMChain是基础且强大的链,为其他链提供支持。

1.1 初始化语言模型

import warnings
warnings.filterwarnings('ignore')

from langchain.chat_models import ChatOpenAI 
from langchain.prompts import ChatPromptTemplate  
from langchain.chains import LLMChain   

# 这里我们将参数temperature设置为0.0,从而减少生成答案的随机性。
# 如果你想要每次得到不一样的有新意的答案,可以尝试调整该参数。
llm = ChatOpenAI(temperature=0.0)   

1.2 初始化提示模版

初始化提示,这个提示将接受一个名为product的变量。该prompt将要求LLM生成一个描述制造该产品的公司的最佳名称
prompt = ChatPromptTemplate.from_template(“描述制造{product}的一个公司的最佳名称是什么?”)

1.3 构建大语言模型链

将大语言模型(LLM)和提示(Prompt)组合成链。这个大语言模型链非常简单,可以让我们以一种顺序的方式去通过运行提示并且结合到大语言模型中。
chain = LLMChain(llm=llm, prompt=prompt)

1.4 运行大语言模型链

我们有一个名为"Queen Size Sheet Set"的产品,我们可以通过使用chain.run将其通过这个链运行

product = "大号床单套装"
chain.run(product) 

‘“豪华床纺”’
您可以输入任何产品描述,然后查看链将输出什么结果。

二、简单顺序链

顺序链(SequentialChains)按预定顺序执行,简单顺序链是其基础形式,每个步骤的输出作为下一个步骤的输入。

from langchain.chains import SimpleSequentialChain
llm = ChatOpenAI(temperature=0.9) 

2.1 创建两个子链

# 提示模板 1 :这个提示将接受产品并返回最佳名称来描述该公司
first_prompt = ChatPromptTemplate.from_template(   
    "描述制造{product}的一个公司的最好的名称是什么"
)
chain_one = LLMChain(llm=llm, prompt=first_prompt)

# 提示模板 2 :接受公司名称,然后输出该公司的长为20个单词的描述
second_prompt = ChatPromptTemplate.from_template(   
    "写一个20字的描述对于下面这个\
    公司:{company_name}的"
)
chain_two = LLMChain(llm=llm, prompt=second_prompt) 

2.2 构建简单顺序链

我们可以组合两个LLMChain,在单一步骤中生成公司名称和描述。

overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],
                                             verbose=True) 

给一个输入,然后运行上面的链

2.3 运行简单顺序链

product = "大号床单套装"
overall_simple_chain.run(product) 
> Entering new SimpleSequentialChain chain...
优床制造公司
优床制造公司是一家专注于生产高品质床具的公司。

> Finished chain.





'优床制造公司是一家专注于生产高品质床具的公司。' 

三、 顺序链

简单顺序链适用于单一输入输出,多输入输出需用顺序链。

import pandas as pd
from langchain.chains import SequentialChain
from langchain.chat_models import ChatOpenAI    #导入OpenAI模型
from langchain.prompts import ChatPromptTemplate   #导入聊天提示模板
from langchain.chains import LLMChain    #导入LLM链。

llm = ChatOpenAI(temperature=0.9) 

接下来我们将创建一系列的链,然后一个接一个使用他们

3.1 创建四个子链

#子链1
# prompt模板 1: 翻译成英语(把下面的review翻译成英语)
first_prompt = ChatPromptTemplate.from_template(
    "把下面的评论review翻译成英文:"
    "\n\n{Review}"
)
# chain 1: 输入:Review    输出:英文的 Review
chain_one = LLMChain(llm=llm, prompt=first_prompt, output_key="English_Review")

#子链2
# prompt模板 2: 用一句话总结下面的 review
second_prompt = ChatPromptTemplate.from_template(
    "请你用一句话来总结下面的评论review:"
    "\n\n{English_Review}"
)
# chain 2: 输入:英文的Review   输出:总结
chain_two = LLMChain(llm=llm, prompt=second_prompt, output_key="summary")


#子链3
# prompt模板 3: 下面review使用的什么语言
third_prompt = ChatPromptTemplate.from_template(
    "下面的评论review使用的什么语言:\n\n{Review}"
)
# chain 3: 输入:Review  输出:语言
chain_three = LLMChain(llm=llm, prompt=third_prompt, output_key="language")


#子链4
# prompt模板 4: 使用特定的语言对下面的总结写一个后续回复
fourth_prompt = ChatPromptTemplate.from_template(
    "使用特定的语言对下面的总结写一个后续回复:"
    "\n\n总结: {summary}\n\n语言: {language}"
)
# chain 4: 输入: 总结, 语言    输出: 后续回复
chain_four = LLMChain(llm=llm, prompt=fourth_prompt, output_key="followup_message") 

3.2 对四个子链进行组合

#输入:review    
#输出:英文review,总结,后续回复 
overall_chain = SequentialChain(
    chains=[chain_one, chain_two, chain_three, chain_four],
    input_variables=["Review"],
    output_variables=["English_Review", "summary","followup_message"],
    verbose=True
) 

通过链传递评论,从法语原文到英文翻译,再到基于英文的总结,最后是法语续写。

df = pd.read_csv('../data/Data.csv')
review = df.Review[5]
overall_chain(review) 
> Entering new SequentialChain chain...

> Finished chain.





{'Review': "Je trouve le goût médiocre. La mousse ne tient pas, c'est bizarre. J'achète les mêmes dans le commerce et le goût est bien meilleur...\nVieux lot ou contrefaçon !?",
 'English_Review': "I find the taste mediocre. The foam doesn't hold, it's weird. I buy the same ones in stores and the taste is much better...\nOld batch or counterfeit!?",
 'summary': "The reviewer finds the taste mediocre, the foam doesn't hold well, and suspects the product may be either an old batch or a counterfeit.",
 'followup_message': "后续回复(法语):Merci beaucoup pour votre avis. Nous sommes désolés d'apprendre que vous avez trouvé le goût médiocre et que la mousse ne tient pas bien. Nous prenons ces problèmes très au sérieux et nous enquêterons sur la possibilité que le produit soit soit un ancien lot, soit une contrefaçon. Nous vous prions de nous excuser pour cette expérience décevante et nous ferons tout notre possible pour résoudre ce problème. Votre satisfaction est notre priorité et nous apprécions vos commentaires précieux."} 

四、 路由链

若需更复杂操作,可使用路由链根据输入类型将任务路由至相应子链。
路由器由两个组件组成:

  • 路由链(Router Chain):路由器链本身,负责选择要调用的下一个链
  • destination_chains:路由器链可以路由到的链

例如,通过不同prompt在各种链间进行路由。

from langchain.chains.router import MultiPromptChain  #导入多提示链
from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser
from langchain.prompts import PromptTemplate
llm = ChatOpenAI(temperature=0) 

4.1 定义提示模板

定义适用于不同场景的提示模板。

# 中文
#第一个提示适合回答物理问题
physics_template = """你是一个非常聪明的物理专家。 \
你擅长用一种简洁并且易于理解的方式去回答问题。\
当你不知道问题的答案时,你承认\
你不知道.

这是一个问题:
{input}"""


#第二个提示适合回答数学问题
math_template = """你是一个非常优秀的数学家。 \
你擅长回答数学问题。 \
你之所以如此优秀, \
是因为你能够将棘手的问题分解为组成部分,\
回答组成部分,然后将它们组合在一起,回答更广泛的问题。

这是一个问题:
{input}"""


#第三个适合回答历史问题
history_template = """你是以为非常优秀的历史学家。 \
你对一系列历史时期的人物、事件和背景有着极好的学识和理解\
你有能力思考、反思、辩证、讨论和评估过去。\
你尊重历史证据,并有能力利用它来支持你的解释和判断。

这是一个问题:
{input}"""


#第四个适合回答计算机问题
computerscience_template = """ 你是一个成功的计算机科学专家。\
你有创造力、协作精神、\
前瞻性思维、自信、解决问题的能力、\
对理论和算法的理解以及出色的沟通技巧。\
你非常擅长回答编程问题。\
你之所以如此优秀,是因为你知道  \
如何通过以机器可以轻松解释的命令式步骤描述解决方案来解决问题,\
并且你知道如何选择在时间复杂性和空间复杂性之间取得良好平衡的解决方案。

这还是一个输入:
{input}""" 

4.2 对提示模版进行命名和描述

定义提示模板后,为每个命名并描述。如物理学模板用于回答相关问题,信息传递给路由链,由其决定何时使用子链。

# 中文
prompt_infos = [
    {
        "名字": "物理学", 
        "描述": "擅长回答关于物理学的问题", 
        "提示模板": physics_template
    },
    {
        "名字": "数学", 
        "描述": "擅长回答数学问题", 
        "提示模板": math_template
    },
    {
        "名字": "历史", 
        "描述": "擅长回答历史问题", 
        "提示模板": history_template
    },
    {
        "名字": "计算机科学", 
        "描述": "擅长回答计算机科学问题", 
        "提示模板": computerscience_template
    }
]
 

LLMRouterChain(此链使用 LLM 来确定如何路由事物)
在这里需要多提示链进行不同提示模板间路由,但也可路由任何类型链。
实现大模型路由器链类,用语言模型在子链间路由,使用上述描述和名称。

4.3 基于提示模版信息创建相应目标链

目标链是由路由链调用的链,每个目标链都是一个语言模型链

destination_chains = {}
for p_info in prompt_infos:
    name = p_info["名字"]
    prompt_template = p_info["提示模板"]
    prompt = ChatPromptTemplate.from_template(template=prompt_template)
    chain = LLMChain(llm=llm, prompt=prompt)
    destination_chains[name] = chain  
    
destinations = [f"{p['名字']}: {p['描述']}" for p in prompt_infos]
destinations_str = "\n".join(destinations) 

4.4 创建默认目标链

除了目标链,还需一个默认链,用于路由器无法确定子链时。如输入与示例学科无关时调用。

default_prompt = ChatPromptTemplate.from_template("{input}")
default_chain = LLMChain(llm=llm, prompt=default_prompt) 

4.5 定义不同链之间的路由模板

这包括要完成的任务的说明以及输出应该采用的特定格式。
注意:为帮助"gpt-3.5-turbo"模型理解模板,原教程增补了示例。"text-davinci-003"或"gpt-4-0613"模型能更好适应。
例如:
<< INPUT >>
“What is black body radiation?”
<< OUTPUT >>

{{{{
    "destination": string \ name of the prompt to use or "DEFAULT"
    "next_inputs": string \ a potentially modified version of the original input
}}}} 
# 多提示路由模板
MULTI_PROMPT_ROUTER_TEMPLATE = """给语言模型一个原始文本输入,\
让其选择最适合输入的模型提示。\
系统将为您提供可用提示的名称以及最适合改提示的描述。\
如果你认为修改原始输入最终会导致语言模型做出更好的响应,\
你也可以修改原始输入。


<< 格式 >>
返回一个带有JSON对象的markdown代码片段,该JSON对象的格式如下:
```json
{{{{
    "destination": 字符串 \ 使用的提示名字或者使用 "DEFAULT"
    "next_inputs": 字符串 \ 原始输入的改进版本
}}}}



记住:“destination”必须是下面指定的候选提示名称之一,\
或者如果输入不太适合任何候选提示,\
则可以是 “DEFAULT” 。
记住:如果您认为不需要任何修改,\
则 “next_inputs” 可以只是原始输入。

<< 候选提示 >>
{destinations}

<< 输入 >>
{{input}}

<< 输出 (记得要包含 ```json)>>

样例:
<< 输入 >>
"什么是黑体辐射?"
<< 输出 >>
```json
{{{{
    "destination": 字符串 \ 使用的提示名字或者使用 "DEFAULT"
    "next_inputs": 字符串 \ 原始输入的改进版本
}}}}

""" 

4.6 构建路由链

我们创建了一个通用的路由器模板,适用于多种目标,可以添加不同学科如英语或拉丁语。接着,基于此模板生成提示模板。最终,通过传入语言模型和路由提示创建路由链,包含路由输出解析,这关键地帮助链决定子链路间的路由。

router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(
    destinations=destinations_str
)
router_prompt = PromptTemplate(
    template=router_template,
    input_variables=["input"],
    output_parser=RouterOutputParser(),
)

router_chain = LLMRouterChain.from_llm(llm, router_prompt)

 

4.7 创建整体链路

#多提示链
chain = MultiPromptChain(router_chain=router_chain,    #l路由链路
                         destination_chains=destination_chains,   #目标链路
                         default_chain=default_chain,      #默认链路
                         verbose=True   
                        ) 

4.8 进行提问

如果我们问一个物理问题,我们希望看到他被路由到物理链路。
chain.run(“什么是黑体辐射?”)

> Entering new MultiPromptChain chain...
物理学: {'input': '什么是黑体辐射?'}
> Finished chain.





'黑体辐射是指一个理想化的物体,它能够完全吸收并且以最高效率地辐射出所有入射到它上面的电磁辐射。这种辐射的特点是它的辐射强度与波长有关,且在不同波长下的辐射强度符合普朗克辐射定律。黑体辐射在物理学中有广泛的应用,例如研究热力学、量子力学和宇宙学等领域。' 

如果我们问一个数学问题,我们希望看到他被路由到数学链路。
chain.run(“2+2等于多少?”)

> Entering new MultiPromptChain chain...
数学: {'input': '2+2等于多少?'}
> Finished chain.





'2+2等于4。' 

如果我们传递一个与任何子链路都无关的问题时,会发生什么呢?
如果问题与子链路无关,如生物学问题,将传递至默认链路,它本身只是对语言模型的通用调用。默认链路是语言模型的通用调用。由于语言模型广泛知识,它仍可提供帮助。

> Entering new MultiPromptChain chain...
物理学: {'input': '为什么我们身体里的每个细胞都包含DNA?'}
> Finished chain.





'我们身体里的每个细胞都包含DNA,因为DNA是遗传信息的载体。DNA是由四

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

京东微服务microApp使用总结

前言 基于现有业务门户进行微服务基础平台搭建 主应用框架&#xff1a;vue3vite 子应用框架&#xff1a;vue2webpack / vue3vite在这里插入代码片 本地调试即可&#xff1a;主应用子应用进行打通&#xff08;注意&#xff1a;两者都是vue3vite&#xff09; 问题总结 1.嵌入…

压缩感知的概述梳理(3)

参考文献 Adaptive embedding: A novel meaningful image encryption scheme based on parallel compressive sensing and slant transform 文献内容 梳理 列表形式 并行压缩感知核心元素与流程 信号 x 长度&#xff1a;N表示&#xff1a;(x \sum_{i1}^{N} a_i\psi_i \su…

密码学 | 椭圆曲线密码学 ECC 入门(三)

目录 7 这一切意味着什么&#xff1f; 8 椭圆曲线密码学的应用 9 椭圆曲线密码学的缺点 10 展望未来 ⚠️ 原文地址&#xff1a;A (Relatively Easy To Understand) Primer on Elliptic Curve Cryptography ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留…

Argus DBM 一款开源的数据库监控工具,无需部署Agent

开箱即用 无需部署Agent&#xff0c;开箱即用。我们使用JDBC直连您的数据库&#xff0c;输入IP端口账户密码即可。 全平台支持 Argus目前支持对Mysql, PostgreSQL, Oracle等数据库类型的监控&#xff0c;我们也会尽快适配其它数据库&#xff0c;致力于监控所有数据库。我们提…

ctfshow web入门 SQl注入web171--web179

从这里开始SQl建议大家去看这篇文章学习一下先 MySQl web171 法一联合查询 题目 $sql "select username,password from user where username !flag and id ".$_GET[id]." limit 1;";爆数据库名 -1 union select 1,database(),3 -- 爆表名 -1 union s…

el-input在type=“textarea“中文字换行,导出成word文档中也显示换行

el-input在type"textarea"文字中换行&#xff0c;是\n转义的&#xff0c;文字导出成word文档没有换行&#xff0c;只需要把\n替换成\r&#xff0c;这样el-input和word文档都能正常显示换行 val.replace.replace("\n", "\r")

UWB技术应用:UWB模块在室内定位系统中的关键角色

随着室内定位技术的不断发展&#xff0c;UWB模块在室内定位系统中扮演着关键角色&#xff0c;其高精度、抗干扰和多路径传输等特点&#xff0c;为室内定位提供了可靠的技术支持。本文将探讨UWB模块在室内定位系统中的关键角色&#xff0c;包括其原理、应用场景和技术优势&#…

Java项目 苍穹外卖 黑马程序员

目录 day1一、项目效果展示二、项目开发整体介绍三、项目介绍3.1 定位3.2 功能架构3.3 产品原型3.4 技术选型 四、开发环境搭建4.1 前端环境4.2 后端环境 五、导入接口文档六、Swagger6.1 介绍6.2 使用方式6.3 常用注解 day2一、新增员工二、员工分页查询三、启用禁用员工账号四…

【无标题】PHP-parse_str变量覆盖

[题目信息]&#xff1a; 题目名称题目难度PHP-parse_str变量覆盖1 [题目考点]&#xff1a; 变量覆盖指的是用我们自定义的参数值替换程序原有的变量值&#xff0c;一般变量覆盖漏洞需要结合程序的其它功能来实现完整的攻击。 经常导致变量覆盖漏洞场景有&#xff1a;$$&…

paddle gpu install

官方教程 https://www.paddlepaddle.org.cn/documentation/docs/zh/install/pip/linux-pip.html#sanyanzhenganzhuang 创建一个新的环境安装 python3 -m pip install paddlepaddle-gpu2.6.1.post112 -f https://www.paddlepaddle.org.cn/whl/linux/cudnnin/stable.htmlpython …

网络基础-TCP和UDP协议区别

什么是 TCP 协议&#xff1f; TCP 全称是 Transmission Control Protocol&#xff08;传输控制协议&#xff09;&#xff0c;它由 IETF 的 RFC 793 定义&#xff0c;是一种面向连接的点对点的传输层通信协议。 TCP 通过使用序列号和确认消息&#xff0c;从发送节点提供有关传输…

请陪伴Kimi和GPT成长

经验的闪光汤圆 但是我想要写实的 你有吗&#xff1f; 岁数大了&#xff0c;希望如何学习新知识呢&#xff1f;又觉得自己哪些能力亟需补强呢&#xff1f; 看论文自然得用Kimi&#xff0c;主要是肝不动了&#xff0c;眼睛也顶不住了。 正好昨天跟专业人士学会了用工作流的办法跟…

【动态规划 状态机dp】3082. 求出所有子序列的能量和

算法可以发掘本质&#xff0c;如&#xff1a; 一&#xff0c;若干师傅和徒弟互有好感&#xff0c;有好感的师徒可以结对学习。师傅和徒弟都只能参加一个对子。如何让对子最多。 二&#xff0c;有无限多1X2和2X1的骨牌&#xff0c;某个棋盘若干格子坏了&#xff0c;如何在没有坏…

idea连接Docker数据库

我们在docker下创建了数据库&#xff0c;想要更方便的查看和操作该数据库&#xff0c;idea和DataGrip或者其他人家都可以。在数据库连接时需要填写数据库名字&#xff0c;主机&#xff0c;端口&#xff0c;数据库用户名和密码。 输入之后先不要点击OK和按Enter键&#xff0c;我…

vue+springboot实验个人信息,修改密码,忘记密码功能实现

前端部分 新增Person&#xff08;个人页面&#xff09;&#xff0c;Password&#xff08;修改密码页面&#xff09;&#xff0c;还需要对Manager&#xff0c;login页面进行修改 router文件夹下的index.js&#xff1a; import Vue from vue import VueRouter from vue-router i…

【运输层】TCP 的流量控制和拥塞控制

目录 1、流量控制 2、TCP 的拥塞控制 &#xff08;1&#xff09;拥塞控制的原理 &#xff08;2&#xff09;拥塞控制的具体方法 1、流量控制 一般说来&#xff0c;我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快&#xff0c;接收方就可能来不及接收&#x…

Ubuntu20.04无法连接蓝牙

连接蓝牙的时候一直转圈显示搜索中&#xff0c;但是搜索不出来任何设备。 在终端输入 dmesg | grep -i blue 可看到有以下信息 可以看到无法识别蓝牙&#xff0c;处于一个unknow的状态 Bluetooth: hci0: RTL: unknown IC info, lmp subver 8852, hci rev 000b, hci ver 000b…

云轴科技ZStack入选中国信通院《高质量数字化转型产品及服务全景图(2023年度)》

近日&#xff0c;由中国互联网协会主办、中国信通院承办的“2024高质量数字化转型创新发展大会”暨“铸基计划”年度会议在北京成功召开。 本次大会发布了2024年度行业数字化转型趋势&#xff0c;总结并展望了“铸基计划”2023年取得的工作成果及2024年的工作规划。同时&#…

支付宝支付之SpringBoot整合支付宝创建自定义支付二维码

文章目录 自定义支付二维码pom.xmlapplication.yml自定义二维码类AlipayService.javaAlipayServiceImpl.javaAlipayController.javaqrCode.html 自定义支付二维码 继&#xff1a;SpringBoot支付入门 pom.xml <dependency><groupId>org.springframework.boot<…

大语言模型微调技术

Adapter 参考资料&#xff1a;《Parameter-efficient transfer learning for nlp》 adpater首先将原始的d维特征映射到较小的维度m&#xff0c;应用非线性函数&#xff0c;然后再重新映射回d维。总的参数量&#xff08;包含biases&#xff09;为 2mddm&#xff0c; 当m远小于d…