生鲜网站建设本地广告推广平台哪个好
链(Chains)通常将大语言模型(LLM)与提示(Prompt)结合在一起,基于此,我们可以对文本或数据进行一系列操作。
链(Chains)可以一次性接受多个输入
例如,我们可以创建一个链,该链接受用户输入,使用提示模板对其进行格式化,然后将格式化的响应传递给LLM。我们可以通过将多个链组合在一起,或者通过将链与其他组件组合在一起来构建更复杂的链。
一、设置 API Key
import os
from zhipuai import ZhipuAI
from dotenv import load_dotenv, find_dotenv# 读取本地/项目的环境变量。# find_dotenv()寻找并定位.env文件的路径
# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中
# 如果你设置的是全局的环境变量,这行代码则没有任何作用。
_ = load_dotenv(find_dotenv())# 获取环境变量 OPENAI_API_KEY
key = "f5cd91f2528fed334b9dfd75015791c3.GuLdvM9tXWrGQnAg"
client = ZhipuAI(api_key = key)
二、大语言模型链
大语言模型链(LLMChain)是一个简单但非常强大的链,也是后面我们将要介绍的许多链的基础。
导入数据
import pandas as pd
df = pd.read_csv('data/Data.csv')
df.head()
初始化语言模型
from langchain_community.chat_models.zhipuai import ChatZhipuAI
from langchain.prompts import ChatPromptTemplate
from langchain.chains.llm import LLMChain
llm = ChatZhipuAI(temperature=0.0,zhipuai_api_key=key)
初始化提示模版
初始化提示,这个提示将接受一个名为product的变量。该prompt将要求LLM生成一个描述制造该产品的公司的最佳名称
构建大语言模型链
将大语言模型(LLM)和提示(Prompt)组合成链。这个大语言模型链非常简单,可以让我们以一种顺序的方式去通过运行提示并且结合到大语言模型中。
运行大语言模型链
因此,如果我们有一个名为"Queen Size Sheet Set"的产品,我们可以通过使用chain.run将其通过这个链运行
prompt = ChatPromptTemplate.from_template( "描述制造{product}的一个公司的最佳名称是什么?"
)
chain = LLMChain(llm=llm, prompt=prompt)
product = "大号床单套装"
chain.run(product)
'为一家专注于制造大号床单套装的公司起名,最佳名称应当简洁、易于记忆,并且能够体现出公司的产品特色和优势。以下是一些建议:\n\n1. "巨眠之选"(DormiGiant)\n2. "梦巢加大"(DreamNest Plus)\n3. "宽享家纺"(BroadEnjoy Home Textiles)\n4. "舒朗加大"(ComfortKing Size)\n5. "眠皇巨制"(SleepEmperor)\n6. "大梦之床"(GrandDream Bedding)\n7. "宽域美梦"(WideRealm Dreams)\n8. "超凡铺盖"(UltraCovers)\n9. "巨无霸寝居"(JumboSlumber)\n10. "加冕大床"(CrownXL Bedding)\n\n如果需要选择一个最佳的名称,我会推荐“舒朗加大”(ComfortKing Size),这个名字不仅传达了床单的尺寸特点,还体现了产品追求舒适品质的宗旨。同时,它简洁明了,易于消费者记忆和品牌传播。'
三、顺序链
3.1 简单顺序链
顺序链(SequentialChains)是按预定义顺序执行其链接的链。具体来说,我们将使用简单顺序链(SimpleSequentialChain),这是顺序链的最简单类型,其中每个步骤都有一个输入/输出,一个步骤的输出是下一个步骤的输入。
from langchain.chains.sequential import SimpleSequentialChain
llm = ChatZhipuAI(temperature=0.0,zhipuai_api_key=key)
first_prompt = ChatPromptTemplate.from_template( "描述制造{product}的一个公司的最好的名称是什么"
)
chain_one = LLMChain(llm=llm, prompt=first_prompt)second_prompt = ChatPromptTemplate.from_template( "写一个20字的描述对于下面这个\公司:{company_name}的"
)
chain_two = LLMChain(llm=llm, prompt=second_prompt)overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],verbose=True)
product = "大号床单套装"
overall_simple_chain.run(product)
> Entering new SimpleSequentialChain chain... 为一家专注于制造大号床单套装的公司起名,可以结合以下几个要素:品质、舒适、规模、专业以及创意。以下是一些建议的名称:1. "超凡寝居" 2. "梦享加大" 3. "舒梦宝" 4. "大尺寸家纺专家" 5. "无尽梦乡" 6. "豪华床品巨匠" 7. "大号梦园" 8. "丝滑大梦" 9. "巨床之选" 10. "尊享加大号"如果需要选择一个最好的名称,可以考虑以下这个:"巨梦舒居"这个名称简洁而富有吸引力,既体现了产品的大尺寸特点,又强调了舒适度和专业品质。同时,它还带有一定的创意和想象力,有助于在消费者心中留下深刻印象。 "巨梦舒居,专业打造大号舒适床品。"> Finished chain.'"巨梦舒居,专业打造大号舒适床品。"'
3.2 顺序链
当只有一个输入和一个输出时,简单顺序链(SimpleSequentialChain)即可实现。当有多个输入或多个输出时,我们则需要使用顺序链(SequentialChain)来实现。
from langchain.chains.sequential import SequentialChain
from langchain_community.chat_models.zhipuai import ChatZhipuAI #导入OpenAI模型
from langchain.prompts import ChatPromptTemplate #导入聊天提示模板
from langchain.chains.llm import LLMChain #导入LLM链。
llm = ChatZhipuAI(temperature=0.9,zhipuai_api_key=key)
#子链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")# 对四个子链进行组合
#输入: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
)review = df.Review[5]
overall_chain(review)
四、 路由链
到目前为止,我们已经学习了大语言模型链和顺序链。但是,如果我们想做一些更复杂的事情怎么办?
一个相当常见但基本的操作是根据输入将其路由到一条链,具体取决于该输入到底是什么。如果你有多个子链,每个子链都专门用于特定类型的输入,那么可以组成一个路由链,它首先决定将它传递给哪个子链,然后将它传递给那个链。
路由器由两个组件组成:
- 路由链(Router Chain):路由器链本身,负责选择要调用的下一个链
- destination_chains:路由器链可以路由到的链
from langchain.chains.router import MultiPromptChain #导入多提示链
from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser
from langchain.prompts import PromptTemplate
llm = ChatZhipuAI(model='glm-3-turbo', temperature=0,zhipuai_api_key=key)
定义提示模板
首先,我们定义提示适用于不同场景下的提示模板
# 中文
#第一个提示适合回答物理问题
physics_template = """你是一个非常聪明的物理专家。 \
你擅长用一种简洁并且易于理解的方式去回答问题。\
当你不知道问题的答案时,你承认\
你不知道.这是一个问题:
{input}"""#第二个提示适合回答数学问题
math_template = """你是一个非常优秀的数学家。 \
你擅长回答数学问题。 \
你之所以如此优秀, \
是因为你能够将棘手的问题分解为组成部分,\
回答组成部分,然后将它们组合在一起,回答更广泛的问题。这是一个问题:
{input}"""#第三个适合回答历史问题
history_template = """你是以为非常优秀的历史学家。 \
你对一系列历史时期的人物、事件和背景有着极好的学识和理解\
你有能力思考、反思、辩证、讨论和评估过去。\
你尊重历史证据,并有能力利用它来支持你的解释和判断。这是一个问题:
{input}"""#第四个适合回答计算机问题
computerscience_template = """ 你是一个成功的计算机科学专家。\
你有创造力、协作精神、\
前瞻性思维、自信、解决问题的能力、\
对理论和算法的理解以及出色的沟通技巧。\
你非常擅长回答编程问题。\
你之所以如此优秀,是因为你知道 \
如何通过以机器可以轻松解释的命令式步骤描述解决方案来解决问题,\
并且你知道如何选择在时间复杂性和空间复杂性之间取得良好平衡的解决方案。这还是一个输入:
{input}"""
对提示模版进行命名和描述
在定义了这些提示模板后,我们可以为每个模板命名,并给出具体描述。例如,第一个物理学的描述适合回答关于物理学的问题,这些信息将传递给路由链,然后由路由链决定何时使用此子链。
prompt_infos = [{"名字": "物理学", "描述": "擅长回答关于物理学的问题", "提示模板": physics_template},{"名字": "数学", "描述": "擅长回答数学问题", "提示模板": math_template},{"名字": "历史", "描述": "擅长回答历史问题", "提示模板": history_template},{"名字": "计算机科学", "描述": "擅长回答计算机科学问题", "提示模板": computerscience_template}
]
LLMRouterChain(此链使用 LLM 来确定如何路由事物)
在这里,我们需要一个多提示链。这是一种特定类型的链,用于在多个不同的提示模板之间进行路由。 但是这只是路由的一种类型,我们也可以在任何类型的链之间进行路由。
这里我们要实现的几个类是大模型路由器链。这个类本身使用语言模型来在不同的子链之间进行路由。这就是上面提供的描述和名称将被使用的地方。
基于提示模版信息创建相应目标链
目标链是由路由链调用的链,每个目标链都是一个语言模型链
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)
创建默认目标链
除了目标链之外,我们还需要一个默认目标链。这是一个当路由器无法决定使用哪个子链时调用的链。在上面的示例中,当输入问题与物理、数学、历史或计算机科学无关时,可能会调用它。
default_prompt = ChatPromptTemplate.from_template("{input}")
default_chain = LLMChain(llm=llm, prompt=default_prompt)
定义不同链之间的路由模板
# 多提示路由模板
MULTI_PROMPT_ROUTER_TEMPLATE = """给语言模型一个原始文本输入,\
让其选择最适合输入的模型提示。\
系统将为您提供可用提示的名称以及最适合改提示的描述。\
如果你认为修改原始输入最终会导致语言模型做出更好的响应,\
你也可以修改原始输入。<< 格式 >>
返回一个带有JSON对象的markdown代码片段,该JSON对象的格式如下:
```json
{{{{"destination": 字符串 \ 使用的提示名字或者使用 "DEFAULT""next_inputs": 字符串 \ 原始输入的改进版本
}}}}
```记住:“destination”必须是下面指定的候选提示名称之一,\
或者如果输入不太适合任何候选提示,\
则可以是 “DEFAULT” 。
记住:如果您认为不需要任何修改,\
则 “next_inputs” 可以只是原始输入。<< 候选提示 >>
{destinations}<< 输入 >>
{{input}}<< 输出 (记得要包含 ```json)>>样例:
<< 输入 >>
"什么是黑体辐射?"
<< 输出 >>
```json
{{{{"destination": 字符串 \ 使用的提示名字或者使用 "DEFAULT""next_inputs": 字符串 \ 原始输入的改进版本
}}}}
```"""
构建路由链
首先,我们通过格式化上面定义的目标创建完整的路由器模板。这个模板可以适用许多不同类型的目标。 因此,在这里,您可以添加一个不同的学科,如英语或拉丁语,而不仅仅是物理、数学、历史和计算机科学。
接下来,我们从这个模板创建提示模板
最后,通过传入llm和整个路由提示来创建路由链。需要注意的是这里有路由输出解析,这很重要,因为它将帮助这个链路决定在哪些子链路之间进行路由。
# 创建路由链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)#多提示链
chain = MultiPromptChain(router_chain=router_chain, #l路由链路destination_chains=destination_chains, #目标链路default_chain=default_chain, #默认链路verbose=True )
进行提问
#中文
chain.run("什么是黑体辐射?")
> Entering new MultiPromptChain chain... 物理学: {'input': '什么是黑体辐射?'} > Finished chain. '黑体辐射是指一个理想化的物体(称为黑体)在热平衡状态下发出的电磁辐射。简单来说,黑体是一个能够完全吸收所有入射电磁辐射的物体,因此它不会反射或透射任何光线。当黑体被加热时,它会发出辐射,这种辐射的强度和频率分布仅取决于黑体的温度。\n\n黑体辐射的强度和频率分布遵循普朗克定律,该定律描述了黑体在不同温度下发出的辐射强度与频率之间的关系。根据普朗克定律,黑体辐射的强度在某个特定频率处达到最大值,这个最大值的位置随着温度的升高而向更高频率移动。\n\n黑体辐射的研究在物理学中具有重要意义,因为它为量子力学的诞生奠定了基础。在19世纪末,物理学家们试图解释黑体辐射的实验结果,但经典物理学无法提供满意的解释。直到20世纪初,普朗克提出了能量量子化的概念,才成功地解释了黑体辐射的实验现象。'
chain.run("你知道李白是谁嘛?")
> Entering new MultiPromptChain chain... 历史: {'input': '你知道李白是谁吗?'} > Finished chain.'是的,我非常了解李白。\n\n李白(公元701年-762年),字太白,号青莲居士,又被称为“诗仙”。他是中国唐代伟大的浪漫主义诗人,在中国文学史上占据着极其重要的地位。\n\n以下是我对李白的一些关键认识:\n\n1. **时代背景**:李白主要生活在盛唐时期,这是一个国力强盛、文化繁荣、思想开放的黄金时代。这为他的诗歌创作提供了广阔的背景和丰富的素材。\n2. **生平经历**:他出生于西域碎叶城(今吉尔吉斯斯坦托克马克附近),五岁时随父亲迁居蜀中。他年轻时就显露才华,志气宏放,喜纵横术,好剑术。虽然他渴望在政治上有所作为,但一生大部分时间是在漫游和飘泊中度过的,政治生涯并不顺遂,仅在唐玄宗天宝初年入京供奉翰林,但不久即遭谗去职。\n3. **诗歌成就**:\n * **风格**:他的诗歌想象丰富奇特,气势雄浑磅礴,风格豪放飘逸,语言清新自然,富有浪漫主义色彩。他善于运用夸张、比喻、拟人等手法,创造出瑰丽壮阔的艺术境界。\n * **题材**:内容广泛,涉及山水风光、友情送别、怀才不遇、人生感慨、饮酒放歌、神仙道教等各个方面。\n * **代表作**:流传下来的诗歌有千余首,名篇极多,如《静夜思》、《望庐山瀑布》、《赠汪伦》、《早发白帝城》、《将进酒》、《行路难》等,都是脍炙人口、千古传诵的杰作。\n4. **历史地位与影响**:李白与杜甫并称为“李杜”,是中国诗歌史上最耀眼的双子星座。他的诗歌不仅在当时就享有盛誉,而且对后世文学产生了极其深远的影响,被无数后来的诗人所学习和模仿。他的人格魅力——那种傲岸不屈、追求自由、热爱自然的个性,也深深感染了后人。\n5. **评价**:后世普遍认为他是中国文学史上最伟大的诗人之一。他的诗歌是盛唐气象的集中体现,代表了中国古典诗歌浪漫主义艺术的巅峰。\n\n总而言之,李白不仅是一位诗人,更是一个时代的文化符号,他的作品和人生经历共同构成了中国历史文化中一道亮丽的风景线。作为历史学家,我深知研究李白及其作品对于理解唐代社会文化、文学发展以及中国民族精神都具有重要意义。'
chain.run("2 + 2 等于多少")
> Entering new MultiPromptChain chain... 数学: {'input': '2 + 2 等于多少'} > Finished chain.'要计算 \\(2 + 2\\),我们可以按照以下步骤进行:\n\n1. **理解加法**:加法是将两个数合并在一起,得到它们的总和。\n2. **应用加法**:将数字2与数字2相加。\n \\[\n 2 + 2 = 4\n \\]\n\n因此,\\(2 + 2\\) 等于 \\(\\boxed{4}\\)。'
chain.run("为什么我们身体里的每个细胞都包含DNA?")
> Entering new MultiPromptChain chain... None: {'input': '为什么我们身体里的每个细胞都包含DNA?'} > Finished chain.'我们身体里的每个细胞(除了成熟的红细胞和某些其他特殊细胞外)都包含DNA,这是因为DNA(脱氧核糖核酸)是生命遗传信息的载体,对于细胞的生存、生长、分裂和执行其功能至关重要。以下是几个关键原因:\n\n1. **遗传信息的存储**:DNA包含了指导生物体生长、发育、运作和繁殖的所有遗传信息。这些信息以基因的形式存在,基因编码了蛋白质和其他分子,这些分子是细胞结构和功能的基础。\n\n2. **蛋白质合成**:DNA通过转录过程产生信使RNA(mRNA),然后mRNA通过翻译过程指导蛋白质的合成。蛋白质是细胞结构和功能的重要组成部分,包括酶、结构蛋白、信号分子等。\n\n3. **细胞分裂和遗传**:在细胞分裂过程中,DNA需要被精确复制并分配到新的细胞中,以确保每个新细胞都能获得完整的遗传信息。这对于组织的生长、修复和维持至关重要。\n\n4. **调控机制**:DNA不仅编码了蛋白质,还包含了调控基因表达的序列。这些调控序列帮助细胞在正确的时间、正确的地点表达正确的基因,从而确保细胞能够适应环境变化并执行其特定功能。\n\n5. **修复和维持**:DNA还包含了一些机制来修复损伤和维持其完整性。这对于防止突变和维持遗传稳定性非常重要。\n\n总之,DNA是细胞生命活动的核心,它确保了遗传信息的准确传递和表达,从而维持了细胞的正常功能和生物体的整体健康。'