桐城市住房城乡建设局网站,图文设计,网站备案 座机号码,网站建设拓客有什么方法LangChain是一个基于大语言模型#xff08;如ChatGPT#xff09;用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口#xff0c;可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互#x…
LangChain是一个基于大语言模型如ChatGPT用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互将多个组件链接在一起以便在不同的应用程序中使用。
今天我们来学习DeepLearning.AI的在线课程:LangChain for LLM Application Development的第三门课Chains该门课程主要讲解LangChain的核心组件:链即Chain, chain可以将大型语言模型(LLM)和提示语(prompt)结合在一起, 你还可以创建多种不同功能的Chain然后将这些chain组合在一起对文本或其他数据执行一系列操作。
目录 LLMChain Sequential Chains SimpleSequentialChain SequentialChain Router Chain
下面我们导入本地环境配置文件.env, 在.env文件中我们存放了opai的api key 。
import osfrom dotenv import load_dotenv, find_dotenv
_ load_dotenv(find_dotenv()) # read local .env file 下面我们导入一个csv文件该文件存放了用户对产品的评论信息。
import pandas as pd
df pd.read_csv(Data.csv)
df LLMChain
LLMChain是最基本的chain他将LLM和prompt组合在一起下面我们要实现一个让LLM给生产不同产品的公司取名字的功能
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.chains import LLMChain#定义大型语言模型
llm ChatOpenAI(temperature0.9)prompt ChatPromptTemplate.from_template(描述生产{product}的公司的一个最佳名称是什么
)#将llm和prompt组合在一起创建一个LLMChain的实例
chain LLMChain(llmllm, promptprompt)#执行chain
product 床上用品
chain.run(product) 这里我们定义llm时使用的温度参数temperature为0.9该参数的取值范围为0-1之所以这里要设置为0.9因为temperature的值越大那么llm返回结果的随机性就越大这里我们要实现的功能是给公司取名字的功能因此我们需要LLM具有较大的灵活性和多样性所以llm每次返回的结果可能都会不一样这也就是我们希望llm实现的功能。
Sequential Chains
Sequential chain 是另一种类型的chain。它可以将多个chain组合在一起其中一个chain的输出是下一个chain的输入。 SimpleSequentialChain
SimpleSequentialChain是最基本的一种Sequential Chains,因为它只有一个输入和一个输出其中前一个chain的输出为后一个chain的输入如下图所示 下面我们看个例子在这个例子中我们除了要执行之前LLMChain的给公司取名的功能外我们还要需要llm生成20个字左右的公司名称的描述信息所以在这里需要创建两个chain, 一个chain负责给公司取名字另一个chain负责就公司的名字生成20个字左右的描述信息最后我们需要将这两个chain组合在一起,创建一个新的chain,对于这个新的chain它只有一个输入和一个输出输入就是公司生产的产品输出则是对公司名称的20字左右的描述信息。
from langchain.chains import SimpleSequentialChainllm ChatOpenAI(temperature0.9)# prompt template 1
first_prompt ChatPromptTemplate.from_template(描述生产{product}的公司的一个最佳名称是什么
)# Chain 1
chain_one LLMChain(llmllm, promptfirst_prompt)# prompt template 2
second_prompt ChatPromptTemplate.from_template(为以下公司编写 20 个字的描述{company_name}”
)
# chain 2
chain_two LLMChain(llmllm, promptsecond_prompt)# 将chain1和chain2组合在一起生成一个新的chain.
overall_simple_chain SimpleSequentialChain(chains[chain_one, chain_two],verboseTrue)
#执行新的chain
overall_simple_chain.run(product) SequentialChain
SequentialChain与SimpleSequentialChain的区别在于它可以有多个输入和输出而SimpleSequentialChain只有一个输入和输出如下图所示 在下面的例子中我对官方课件的代码做了修改原来官方的代码只有4个chain, 而我在此基础上增加了一个chain,这样的修改主要是让大家更好的理解该案例中涉及的prompt的含义原先的prompt使用的都是英语我都将其翻译成了中文这样大家就比较能看懂这些prompt了该案例主要功能是要让llm对前面导入的用户评语进行分析并给出回复因为用户的评语可能使用的是多种不同的语言为此我们需要让chain能够识别用户评语使用的是那种语言并将其翻译成中文最后给出回复具体来说包含以下功能和步骤
将用户评论翻译成中文用一句话概括用户评论识别出用户评论使用的语言按原始评论语言生成回复将回复翻译成中文
from langchain.chains import SequentialChain#定义llm
llm ChatOpenAI(temperature0.9)# prompt template 1: 将评论翻译成中文
first_prompt ChatPromptTemplate.from_template(将下面的评论翻译成中文:\n\n{Review}
)
# chain 1: input Review and output Chinese_Review
chain_one LLMChain(llmllm, promptfirst_prompt, output_keyChinese_Review)
#概括评论
second_prompt ChatPromptTemplate.from_template(你能用 1 句话概括以下评论吗\n\n{Chinese_Review}
)
# chain 2: input Chinese_Review and output summary
chain_two LLMChain(llmllm, promptsecond_prompt, output_keysummary)# prompt template 3: 识别评论使用的语言
third_prompt ChatPromptTemplate.from_template(下面的评论使用的是什么语言:\n\n{Review}
)
# chain 3: input Review and output language
chain_three LLMChain(llmllm, promptthird_prompt,output_keylanguage)# prompt template 4: 生成回复信息
fourth_prompt ChatPromptTemplate.from_template(使用指定语言编写对以下摘要的后续回复\n\n摘要{summary}\n\n语言{language})
# chain 4: input summary, language and output followup_message
chain_four LLMChain(llmllm, promptfourth_prompt,output_keyfollowup_message)# prompt template 5: 将回复信息翻译成中文
five_prompt ChatPromptTemplate.from_template(将下面的评论翻译成中文:\n\n{followup_message}
)
# chain 5: input followup_message and output Chinese_followup_message
chain_five LLMChain(llmllm, promptfive_prompt, output_keyChinese_followup_message)# overall_chain: input Review
# output language,Chinese_Review,summary, followup_message,#Chinese_followup_message
overall_chain SequentialChain(chains[chain_one, chain_two, chain_three, chain_four,chain_five],input_variables[Review],output_variables[language,Chinese_Review, summary,followup_message,Chinese_followup_message],verboseTrue
)
这里我们看到我们在定义最后的overall_chain 时设置了输入变量和输出变量因此这些输入和输出变量最后会作为中间结果被输出。
下面我们看一下用户的评语
review df.Review[5]
print(review) 接下来我们执行SequentialChain
overall_chain(review) Router Chain
有一种应用场景就是我们有时候希望根据信息的内容将其传送到不同的chain,而每个chain的职能是只擅长回答自己所属领域的问题那么在这种场景下我们就需要一种具有路由器功能的chain来将信息传输到不同职能的chain. 在下面的例子中我们有多个不同职能的chain它们负责回复关于不同学科领域的用户问题比如数学chain,历史chain,物理chain,计算机chain,每个chain都只擅长回复自己专业领域的问题这里我们还有一个路由chain, 它的作用是识别用户问题属于哪个领域然后将问题传输给那个领域的chain,让其来完成回答用户问题的功能。下面我们首先定义4个专业领域的prompt模板在这些模板中我们将告知llm它的职责与定位
physics_template你是一位非常聪明的物理学教授。\
你擅长以简洁易懂的方式回答有关物理的问题。 \
当你不知道某个问题的答案时你就承认你不知道。这里有一个问题
{input}math_template你是一位非常优秀的数学家。\
你很擅长回答数学问题。 \
你之所以如此出色是因为你能够将难题分解为各个组成部分\
回答各个组成部分然后将它们组合起来回答更广泛的问题。这里有一个问题
{input}history_template 你是一位非常优秀的历史学家。\
你对各个历史时期的人物、事件和背景有深入的了解和理解。 \
你有能力思考、反思、辩论、讨论和评价过去。 \
你尊重历史证据并有能力利用它来支持你的解释和判断。这里有一个问题
{input}computerscience_template你是一位成功的计算机科学家。\
你有创造力协作精神前瞻性思维自信有很强的解决问题的能力\
对理论和算法的理解以及出色的沟通能力。\
你很擅长回答编程问题。
你是如此优秀因为你知道如何通过描述一个机器可以很容易理解的命令步骤来解决问题\
你知道如何选择一个解决方案在时间复杂度和空间复杂度之间取得良好的平衡。这里有一个问题
{input}
接下来我们还还需要对这些模板功能进行结构化的解释说明这样便于后面的路由chain能找到它们为此我们要定义一个模板的索引结构
prompt_infos [{name: physics, description: 擅长回答有关物理方面的问题, prompt_template: physics_template},{name: math, description: 擅长回答有关数学方面的问题, prompt_template: math_template},{name: history, description: 擅长回答有关历史方面的问题, prompt_template: history_template},{name: computer science, description: 擅长回答有关计算机科学方面的问题, prompt_template: computerscience_template}
]
接下来我们还需要定义一个目标chain的集合所谓的目标chain就是指回答单一领域问题的chai成它们都是基本的LLMChain
from langchain.chains import LLMChain
from langchain.chains.router import MultiPromptChain
from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser
from langchain.prompts import PromptTemplate
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI#定义llm
llm ChatOpenAI(temperature0)#创建目标chain
destination_chains {}
for p_info in prompt_infos:name p_info[name]prompt_template p_info[prompt_template]prompt ChatPromptTemplate.from_template(templateprompt_template)chain LLMChain(llmllm, promptprompt)destination_chains[name] chain destinations [f{p[name]}: {p[description]} for p in prompt_infos]
destinations_str \n.join(destinations)
print(destinations_str) 这里我们还生成了一个目标字符串destinations_str它会在后面别嵌入到路由chain的prompt模板中来为定位目标chain提供索引。
接下来我们还需要定义default_chain这个chain的作用是当用户的问题与现有的所有目标chain都无法匹配时那么就由default_chain来回答用户的问题
default_prompt ChatPromptTemplate.from_template({input})
default_chain LLMChain(llmllm, promptdefault_prompt)
这里我们看到default_prompt 中只包含了一个变量{input},没有包含任何的前缀信息这是因为default_chain回答的是哪些无法被识别的属于领域的问题所以这里就让LLM自由发挥了。
下面我们要创建一个路由prompt模板这是给后续的路由chain使用的
MULTI_PROMPT_ROUTER_TEMPLATE 给定一个原始文本输入到\
一个语言模型并且选择最适合输入的模型提示语。
你将获得可用的提示语的名称以及该提示语最合适的描述。
如果你认为修改原始输入最终会导致语言模型得到更好的响应你也可以修改原始输入。 FORMATTING
返回一个 Markdown 代码片段其中 JSON 对象的格式如下
json
{{{{
destination: string \ 要使用的提示语的名称或DEFAULT
next_inputs: string \ 原始输入的可能修改版本
}}}}
记住:destination必须是下面指定的候选提示语中的一种\
如果输入语句不适合任何候选提示语则它就是DEFAULT。记住:next_inputs可以只是原始输入如果你认为不需要做任何修改的话。 CANDIDATE PROMPTS
{destinations} INPUT
{{input}} OUTPUT (remember to include the json)
这上面的模板里我们允许LLM修改用户的原始输入如果修改后的输入能产生更好的输出效果的话也就是说LLM会先判断是否需要修改用户的prompt如果觉得有必要修改用户的prompt那么就会把修改过的prompt传送给后续处理特定领域问题的chain如果没必要修改那么就直接把用户的prompt传送给后续的chain。下面还需要在路由prompt模板中嵌入destinations_str它是为识别领域chain提供索引
router_template MULTI_PROMPT_ROUTER_TEMPLATE.format(destinationsdestinations_str
)print(router_template) 接下来我们要定义最核心的MultiPromptChain它的三个主要参数为路由chain, 领域chain(集合)默认chain。由这3个主要的参数我们也能猜测出MultiPromptChain的主要处理逻辑首先让路由chain来识别用户prompt并将其传送给特定领域chain,如果没找到合适的领域chain,则由默认chain来处理用户prompt这里我们给MultiPromptChain的verbose设置为True,这样MultiPromptChain在处理用户prompt的时候会输出一些中间结果,这些中间结果有助于我们观察llm的思维过程是否和我们给它的设定的业务逻辑是一致的。如果不想显示中间结果可以把verbose参数设置为False
router_chain LLMRouterChain.from_llm(llm, router_prompt)chain MultiPromptChain(router_chainrouter_chain, destination_chainsdestination_chains, default_chaindefault_chain, verboseTrue)
下面我们来设计一些简单的问题这些问题可能涉及到不同的领域我们看看llm是怎么来回答用户问题的
response chain.run(22等于几)
print(response) 这里我们可以看到LLM能按照我们的router_template模板内的要求识别出该问题属于math领域然后由该领域的chain来回答这个问题并最后返回了正确的答案。
response chain.run(成吉思汗是谁)
print(response) 对于“成吉思汗是谁?”这个问题我们发现LLM对问题进行了修改它把用户的问题改成了“成吉思汗是哪个历史时期的重要人物”可能是LLM觉得修改后的prompt更有助于后续的领域chain来回答这个问题吧。
response chain.run(什么是黑体辐射)
print(response) response chain.run(为什么学习机器学习都要使用python语言)
print(response) response chain.run(天上一共有多少颗星星)
print(response) 对于“天上一共有多少颗星星”这个问题我们看到LLM并没有识别出来它属于哪个领域因此它返回的领域值为None, 然后该问题交由默认chain来回答。
总结
今天我们学习了Langchain的核心组件chain。主要分为LLMChainSequential ChainsRouter Chain其中LLMChain是最基本的chain它简单的组合了LLM和promt, Sequential Chains主要包含SimpleSequentialChain和SequentialChain对于SimpleSequentialChain来说它只是简单的将多个LLMChain串联在一起前一个chain的输出是后一个chain的输入所以总体上来说SimpleSequentialChain只有一个输入和一个输出而SequentialChain则具体多个输入或输出。而Router Chain则是具有路由功能的chain ,它可以将用户的问题进行分类从而将问题传递给特定的chain。
参考资料
https://learn.deeplearning.ai/langchain/lesson/4/chains