文章目录
- 1. LLMChain
- 2. SimpleSequentialChain
- 3. SequentialChain
- 4. LLMRouterChain
learn from https://learn.deeplearning.ai/langchain
1. LLMChain
from config import api_type, api_key, api_base, api_version, model_name
from langchain.chat_models import AzureChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import ChatPromptTemplatemodel = AzureChatOpenAI(openai_api_base=api_base,openai_api_version=api_version,deployment_name=model_name,openai_api_key=api_key,openai_api_type=api_type,temperature=0.5,
)
prompt = ChatPromptTemplate.from_template('帮我起一个最好的公司名,这个公司是生产{product}的')
chain = LLMChain(llm=model, prompt=prompt)
print(chain.run(product='护眼灯'))
输出
光明护眼灯制造有限公司
2. SimpleSequentialChain
- Simple chain where the outputs of one step feed directly into next
链的输出,直接给下一个链作为输入
from langchain.chains import SimpleSequentialChain
prompt1 = ChatPromptTemplate.from_template('帮我起一个最好的公司名,要求名字寓意好,与产品相关,这个公司是生产{product}的。')
chain1 = LLMChain(llm=model, prompt=prompt1)prompt2 = ChatPromptTemplate.from_template('写一个这个公司<{company_name}>的简介,对其公司的名字的由来和理念做解释,100字以内')
chain2 = LLMChain(llm=model, prompt=prompt2)all_chains = SimpleSequentialChain(chains=[chain1, chain2], verbose=True)
print(all_chains.run(input='儿童学习桌'))
让模型,给产品起一个公司名,并给这个公司名给出一个简介
输出:
> Entering new chain...
启智桌(Qi Zhi Zhuo),寓意为启发孩子的智慧,与产品相关,简洁易记。
启智桌(Qi Zhi Zhuo)是一家致力于启发孩子智慧的教育公司。公司名字的由来是希望通过我们的产品,让孩子们在学习中获得启发和智慧。我们的理念是通过创新的产品设计和教育方式,帮助孩子们更好地掌握知识,培养他们的创造力和思维能力。我们的产品简洁易记,旨在让孩子们在学习中感到轻松愉快,达到快乐学习的效果。> Finished chain.
启智桌(Qi Zhi Zhuo)是一家致力于启发孩子智慧的教育公司。公司名字的由来是希望通过我们的产品,让孩子们在学习中获得启发和智慧。我们的理念是通过创新的产品设计和教育方式,帮助孩子们更好地掌握知识,培养他们的创造力和思维能力。我们的产品简洁易记,旨在让孩子们在学习中感到轻松愉快,达到快乐学习的效果。
3. SequentialChain
prompt1 = ChatPromptTemplate.from_template('翻译以下评论为英语,\n\n{review}')
chain1 = LLMChain(llm=model, prompt=prompt1, output_key='english_review')prompt2 = ChatPromptTemplate.from_template('你可以用一句话总结下下面的评论吗?\n\n{english_review}')
chain2 = LLMChain(llm=model, prompt=prompt2, output_key='summary')prompt3 = ChatPromptTemplate.from_template('下面的评论是什么语言的?\n\n{review}')
chain3 = LLMChain(llm=model, prompt=prompt3, output_key='language')prompt4 = ChatPromptTemplate.from_template('用给定的语言回复下面的文本\n\n文本:{summary}\n\n语言:{language}')
chain4 = LLMChain(llm=model, prompt=prompt4, output_key='response_msg')
可以看到,创建了4个链
如果没有 review
输入,执行会报错
overall_chain = SequentialChain(chains=[chain1, chain2, chain3, chain4],input_variables=["review"],output_variables=["english_review", "summary", "response_msg", "language"],verbose=True
)
output = overall_chain('这款手机我用了有一个月时间了,总体感觉非常不错,性价比很高,超出我的预期。先说说外观,这款手机设计极为简洁大方,背面用了全新的镜面工艺,摸上去手感冰凉顺滑,看上去高端大气。机身很轻巧,握在手里感觉非常好。屏幕采用了6.5寸OLED面板,色彩还原能力很强,无论看视频还是玩游戏都非常卓越流畅。最大亮点是续航能力强劲,我每天使用时间在4-5小时,基本两天才需要充电一次,轻用户甚至可以用上3-4天,不用频繁充电也是一个大的改进。手机的芯片也非常先进,我玩的游戏很流畅,基本能保持在60帧,也没有发现卡顿情况,很能满足我的需求。总的来说,这款手机在外观、续航、屏幕和性能各方面都进行了优化和改进,真心推荐大家购买,是我近期最满意的一款手机,五星好评!')
print(type(output))
print(output)
输出,是一个字典
<class 'dict'>
{'review': '这款手机我用了有一个月时间了,总体感觉非常不错,性价比很高,超出我的预期。先说说外观,这款手机设计极为简洁大方,背面用了全新的镜面工艺,摸上去手感冰凉顺滑,看上去高端大气。机身很轻巧,握在手里感觉非常好。屏幕采用了6.5寸OLED面板,色彩还原能力很强,无论看视频还是玩游戏都非常卓越流畅。最大亮点是续航能力强劲,我每天使用时间在4-5小时,基本两天才需要充电一次,轻用户甚至可以用上3-4天,不用频繁充电也是一个大的改进。手机的芯片也非常先进,我玩的游戏很流畅,基本能保持在60帧,也没有发现卡顿情况,很能满足我的需求。总的来说,这款手机在外观、续航、屏幕和性能各方面都进行了优化和改进,真心推荐大家购买,是我近期最满意的一款手机,五星好评!',
'english_review': "I have been using this phone for a month now and overall, I feel it is very good and offers great value for money, exceeding my expectations. Let me start with the design, which is extremely simple and elegant. The back uses a new mirror process, giving it a cool and smooth feel, and a high-end look. The phone is very lightweight and feels great in the hand. The screen uses a 6.5-inch OLED panel, with strong color reproduction capabilities, making it great for watching videos or playing games with excellent smoothness. The biggest highlight is its strong battery life. I use it for 4-5 hours every day and it can last for two days on a single charge, even for light users, it can last up to 3-4 days, which is a major improvement. The phone's chip is also very advanced, allowing me to play games smoothly with a frame rate of around 60, without any lagging or stuttering, which fully meets my needs. Overall, this phone has been optimized and improved in terms of design, battery life, screen, and performance. I sincerely recommend everyone to buy it. It is the most satisfying phone I have used recently, and I give it a five-star rating!",
'summary': 'The phone has a simple and elegant design, with a cool and smooth feel, and a high-end look. It offers great value for money, with a strong battery life and advanced chip, making it great for watching videos and playing games smoothly. It has been optimized and improved in terms of design, battery life, screen, and performance, and is highly recommended.',
'response_msg': '这款手机设计简单而优雅,手感冷酷顺滑,外观高端大气。它性价比极高,拥有强大的电池寿命和先进的芯片,非常适合流畅观看视频和玩游戏。在设计、电池寿命、屏幕和性能方面进行了优化和改进,强烈推荐。','language': '中文'}
减少 output_variables
中的字段,输出就只有output_variables
给定的字段 + 输入的字段(review
)
4. LLMRouterChain
physics_template = '''
你是一位非常聪明的物理学教授,
你很善于简明扼要地回答有关物理学的问题,并且易于理解。
当你不知道问题的答案时,你就说你不知道。下面是问题:
{input}
'''math_template = '''
你是一位非常聪明的数学家,
你很善于回答有关数学的问题,你总能将一个很难的问题分解,并解决其中的难题,
最终完美的解决整体的问题。下面是问题:
{input}
'''history_template = '''
你是一位非常优秀的历史学家,
你对人有很好的了解和理解一系列历史时期的事件和背景。
你有思考、反思、辩论、讨论和评估过去。
你尊重历史证据以及利用它来支持你的解释和判断。下面是问题:
{input}
'''computerscience_template = '''
你是一位成功的计算机科学家,
你在创造力、协作、前瞻性思维,自信,解决问题的能力等方面非常强。
对理论和算法的理解深刻,有良好的沟通技能。
你非常擅长回答编码问题。
你之所以如此优秀,是因为你知道如何通过以必要的步骤描述解决方案,
机器可以很容易地解释,你知道如何衡量时间复杂性和空间复杂性,如何在两者中做出权衡。下面是问题:
{input}
'''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}
]
创建了4种回答问题的提示词,让模型自己选择使用哪种
from langchain.chains.router import MultiPromptChain
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.prompts import PromptTemplatedestination_chains = {}
for p_info in prompt_infos:name = p_info["name"]prompt_template = p_info["prompt_template"]prompt = ChatPromptTemplate.from_template(template=prompt_template)chain = LLMChain(llm=model, prompt=prompt)destination_chains[name] = chaindestinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
destinations_str = "\n".join(destinations)default_prompt = ChatPromptTemplate.from_template("{input}")
default_chain = LLMChain(llm=model, prompt=default_prompt)print(destinations_str)
输出的 destinations_str
physics: 擅长回答物理问题
math: 擅长回答数学问题
history: 擅长回答历史问题
computer science: 擅长回答计算机科学问题
MULTI_PROMPT_ROUTER_TEMPLATE = '''
将原始文本输入到语言模型,请选择最适合的模型提示词。
您将获得可用提示词的 name 和 description
如果您认为修改原始输入,也可以修改,如果它最终将导致来自语言模型的更好的响应。
<<格式化>>
返回2个带有JSON对象的标记代码片段,该JSON对象的格式如下:
```json
{{{{
"destination": string \要使用的提示词的 name 或 "DEFAULT",
"next_inputs": string \原始输入的可能修改版本
}}}}
``请记住:"destination" 必须是候选提示词之一,如果没有满足的提示词,则可以是 "DEFAULT"
请记住:如果你认为不需要任何修改的话,"next_inputs" 只能是原始输入。
<<候选提示词>>
{destinations}
<<输入>>
{{input}}<<输出(请记住包含``json)>>
'''router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str
)
router_template
是下面这个样子
router_prompt = PromptTemplate(template=router_template,input_variables=["input"],output_parser=RouterOutputParser(),
)router_chain = LLMRouterChain.from_llm(model, router_prompt)chain = MultiPromptChain(router_chain=router_chain,destination_chains=destination_chains,default_chain=default_chain, verbose=True)chain.run({"input": "什么是中微子?"})
chain.run({"input": "sin 运算有什么用?"})
chain.run({"input": "为什么清朝会灭亡?"})
chain.run({"input": "为什么操作系统存储下标从0开始?"})
chain.run({"input": "谁发现的DNA结构?"})
输出
> Entering new MultiPromptChain chain...
physics: {'input': '什么是中微子?'}
> Finished chain.> Entering new MultiPromptChain chain...
math: {'input': 'sin 运算有什么用?'}
> Finished chain.> Entering new MultiPromptChain chain...
history: {'input': '为什么清朝会灭亡?'}
> Finished chain.> Entering new MultiPromptChain chain...
computer science: {'input': '为什么操作系统存储下标从0开始?'}
> Finished chain.> Entering new MultiPromptChain chain...
history: {'input': '谁发现的DNA结构?'}
> Finished chain.
可以看到,模型使用了正确的模板