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

news2024/11/23 8:44:14

链(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是由四

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“低价竞争”仍在继续,分期免息成商家新武器

近日&#xff0c;在京东618商家生态伙伴大会上&#xff0c;京东推出各项政策&#xff0c;尽全力让所有合作伙伴赢在京东618、赢在京东。京东金融也将在618大促期间&#xff0c;为各位商家带来极具竞争力的金融产品和大促政策。 举例来说&#xff0c;大促期间&#xff0c;“京东…

分类预测 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据…

小试牛刀!

1.从双倍数组中还原原数组&#xff08;力扣&#xff0c;vector&#xff09; java式c解法。 class Solution { public:vector<int> findOriginalArray(vector<int>& changed) {int n changed.size();if(n % 2 1) return {};map<int, int> mp;for(int c…

02 - Git 之命令 + 删除 + 版本控制 + 分支 + 标签 + 忽略文件 + 版本号

1 Git相关概念 1.1 以下所谈三个区&#xff0c;文件并不只是简单地在三个区转移&#xff0c;而是以复制副本的方式转移 使用 Git 管理的项目&#xff0c;拥有三个区域&#xff0c;分别是 Working area工作区&#xff08;亦称为 工作树Working Tree&#xff09;、stage area …

【Web】HTML基础

专栏文章索引&#xff1a;Web 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、HTML介绍 1.HTML 定义 2.标签语法 3.HTML 基本骨架 4.标签的关系 5.HTML 注释 二、标签 1.排版标签 1.1 标题标签 1.2 段落标签 1.3 换行标签 1.4 水平线标签 1.5 文本格…

【Spring】之基础概念和使用

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1. Spring的概述1.1 什么是容器&#xff1f;1.2 什么是IoC&#xff1f;1.3 什么是DI&#xff1f…

(二十八)Flask之wtforms库【上手使用篇】

目录&#xff1a; 每篇前言&#xff1a;用户登录验证&#xff1a;用户注册验证&#xff1a;使用示例&#xff1a; 抽象解读使用wtforms编写的类&#xff1a;简单谈一嘴&#xff1a;开始抽象&#xff1a; 每篇前言&#xff1a; &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;【…

多任务学习,在共享层,究竟在共享什么?

在多任务学习中&#xff0c;共享层所共享的主要是网络结构和参数。具体来说&#xff0c;当多个任务在共享层进行参数硬共享时&#xff0c;它们使用的是相同的网络结构&#xff08;例如三层全连接神经网络&#xff09;&#xff0c;并且这些网络层的权重&#xff08;weights&…

Java工具类:批量发送邮件(带附件)

​ 不好用请移至评论区揍我 原创代码,请勿转载,谢谢! 一、介绍 用于给用户发送特定的邮件内容,支持附件、批量发送邮箱账号必须要开启 SMTP 服务(具体见下文教程)本文邮箱设置示例以”网易邮箱“为例,其他如qq邮箱或企业邮箱均可,只要在设置中对应开启SMTP及授权码等操…

css中设置元素大小的属性block-size

block-size 是 CSS 中的一个属性&#xff0c;它用于设置元素的块级尺寸&#xff08;即元素的高度&#xff09;。这个属性是 height 和 max-height 的逻辑组合&#xff0c;允许你同时设置元素的最小和最大高度。 这些属性旨在让布局不再依赖于传统的物理方向&#xff08;如上下左…

爬虫 | 基于 Python 实现有道翻译工具

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本项目旨在利用 Python 语言实现一个简单的有道翻译工具。有道翻译是一款常用的在线翻译服务&#xff0c;能够实现多种语言的互译&#xff0c;提供高质量的翻译结果。 目录 一、项目功能 二、注意事项 三、代码解析 1. 导入…

eclipse配置SVN和Maven插件

3、 安装SVN插件 使用如下方法安装 Help–Install New Software 注意&#xff1a;目前只能安装1.8.x这个版本的SVN&#xff0c;如果使用高版本的SVN&#xff0c;在安装SVN和maven整合插件的时候就会报错&#xff0c;这应该是插件的bug。 点击Add name: subclipse location…

隐式/动态游标的创建与使用

目录 将 emp 数据表中部门 10 的员工工资增加 100 元&#xff0c;然后使用隐式游标的 %ROWCOUNT 属性输出涉及的员工数量 动态游标的定义 声明游标变量 打开游标变量 检索游标变量 关闭游标变量 定义动态游标&#xff0c;输出 emp 中部门 10 的所有员工的工号和姓名 Orac…

编程入门(四)【计算机网络基础(由一根网线连接两个电脑开始)】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言两个电脑如何互连呢&#xff1f;集线器、交换机与路由器总结 前言 当你有…

【IC前端虚拟项目】接口分析与agent组件生成

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 到目前为止关于环境的准备工作都已经完成了,甚至验证环境的大体结构我们也已经画好了,再来看一下: 于是乎呢就可以大张旗鼓的开始咱们验证环境的搭建了!看上面这个结构图,里面除了mvu作为DUT,其他…

【C语言】冒泡排序算法详解

目录 一、算法原理二、算法分析时间复杂度空间复杂度稳定性 三、C语言实现四、Python实现 冒泡排序&#xff08;Bubble Sort&#xff09;是一种基础的排序算法。它重复地遍历要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。遍历数列…

HackMyVM-BaseME

目录 信息收集 arp nmap WEB web信息收集 gobuster hydra 目录检索 ssh 提权 get user sudo base64提权 get root 信息收集 arp ┌─[rootparrot]─[~/HackMyVM] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168…

机器人的非接触式充电和无线充电有什么区别?

文 | BFT机器人 在日新月异的技术浪潮中&#xff0c;接触式与非接触式无线充电之间的微妙差异变得愈发重要&#xff0c;这如同在纷繁复杂的迷雾中增添了一层难以捉摸的迷离。而今&#xff0c;一些所谓的“无线”充电站纷纷涌入市场&#xff0c;它们自诩为无需线缆束缚的新时代…

在线预约家政服务小程序上门服务源码系统 带完整的安装代码包以及搭建教程

随着互联网的快速发展&#xff0c;家政服务行业也逐渐向线上化、智能化转型。为了满足广大用户的需求&#xff0c;罗峰给大家分享一款在线预约家政服务小程序上门服务源码系统。该系统不仅功能完善&#xff0c;而且操作简单&#xff0c;是您打造高效、便捷的家政服务平台的首选…

【uniapp踩坑记】——微信小程序转发保存图片

关于微信小程序转发&保存图片 微信小程序图片转发保存简单说明网络图片的转发保存base64流形式图片转发保存 已经好多年没写博客了&#xff0c;最近使用在用uniapp开发一个移动版管理后台&#xff0c;记录下自己踩过的一些坑 吃相别太难看&#xff0c;搞一堆下头僵尸号来点…