⭐ 下面我们开始入门下LangChain框架,LangChain 是用于构建大模型应用程序的开源框架,有Python和JavaScript两个不同版本的包。LangChain 也是一个开源项目,社区活跃,新增功能快速迭代。LangChain基于模块化组合,有许多单独的组件,可以一起使用或单独使用。
该专栏将重点介绍 LangChain 的常用组件:
通过学习使用这些组件构建链式应用,你将可以快速上手 LangChain,开发出功能强大的语言模型程序。让我们开始探索LangChain的魅力吧!
通过langchain调用chatgpt接口,需先声明一下OPENAI_API_KEY环境变量,即你的api key。在当前目录下创建一个.env文件,里面的内容存你的api key,写法如下:
OPENAI_API_KEY = ‘sk-xxx’
这样,跑下面的代码时就可以调接口了。
import os
import openai
# 运行此API配置,需要将目录中的.env中api_key替换为自己的
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key = os.environ['OPENAI_API_KEY']
# 这里我们将参数temperature设置为0.0,从而减少生成答案的随机性。
# 如果你想要每次得到不一样的有新意的答案,可以尝试调整该参数。
# 以下的对话均无记忆,即每次调用预测不会记得之前的对话。(想要有记忆功能请看下一节的langchain的Memory模块)
chat = ChatOpenAI(temperature=0,
model_name="gpt-3.5-turbo")
chat
ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, client=
, model_name=‘gpt-3.5-turbo’, temperature=0.0, model_kwargs={}, openai_api_key=‘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’, openai_api_base=‘’, openai_organization=‘’, openai_proxy=‘’, request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None, tiktoken_model_name=None)
# \在字符串里就是取消换行符的意思
template_string = """\
对与如下三个反引号括住的评论,我需要提取如下信息。
饮料:这个产品是饮料吗?如果是,返回True,否则返回答False。
产品名:提取出产品的名字,如果没有,返回-1。
价格与价值:提取出关于该产品的价格或价值的所有信息,将他们存入python list中,并返回。
{format_instructions}
```{query}```"""
prompt_template = ChatPromptTemplate.from_template(template_string)
prompt_template
ChatPromptTemplate(input_variables=[‘query’, ‘format_instructions’], output_parser=None, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=[‘format_instructions’, ‘query’], output_parser=None, partial_variables={}, template=‘对与如下三个反引号括住的评论,我需要提取如下信息。\n饮料:这个产品是饮料吗?如果是,返回True,否则返回答False。\n产品名:提取出产品的名字,如果没有,返回-1。\n价格与价值:提取出关于该产品的价格或价值的所有信息,将他们存入python list中,并返回。\n{format_instructions}\n
{query}
’, template_format=‘f-string’, validate_template=True), additional_kwargs={})])
prompt_template.input_variables
['query', 'format_instructions']
query = '这喜茶新出的桑葚葡萄太好喝里吧,而且才19块一杯,太值啦,高性价比!'
format_instructions = """\
将输出组织成带有如下key的json形式:
饮料
产品名
价格与价值"""
prompt = prompt_template.format_messages(format_instructions=format_instructions, query=query)
print(prompt)
print(prompt[0])
# prompt一个HumanMessage的类,也就是人类的提问
- [HumanMessage(content=‘对与如下三个反引号括住的评论,我需要提取如下信息。\n饮料:这个产品是饮料吗?如果是,返回True,否则返回答False。\n产品名:提取出产品的名字,如果没有,返回-1。\n价格与价值:提取出关于该产品的价格或价值的所有信息,将他们存入python list中,并返回。\n将输出组织成带有如下key的json形式:\n饮料\n产品名\n价格与价值\n
这喜茶新出的桑葚葡萄太好喝里吧,而且才19块一杯,太值啦,高性价比!
’, additional_kwargs={}, example=False)]- content=‘对与如下三个反引号括住的评论,我需要提取如下信息。\n饮料:这个产品是饮料吗?如果是,返回True,否则返回答False。\n产品名:提取出产品的名字,如果没有,返回-1。\n价格与价值:提取出关于该产品的价格或价值的所有信息,将他们存入python list中,并返回。\n将输出组织成带有如下key的json形式:\n饮料\n产品名\n价格与价值\n
这喜茶新出的桑葚葡萄太好喝里吧,而且才19块一杯,太值啦,高性价比!
’ additional_kwargs={} example=False
from langchain.schema import HumanMessage, SystemMessage
# 可以通过SystemMessage类来设置机器人的人设,即让它角色扮演
system_msg = SystemMessage(content="你是一个语文老师。")
system_msg
# SystemMessage(content='你是一个语文老师。', additional_kwargs={})
# res = chat(prompt) # 不用人设
res = chat([system_msg]+prompt) # 用人设,因为prompt本身就是个列表
res = res.content
print(res)
print(type(res))
{
“饮料”: true,
“产品名”: “桑葚葡萄”,
“价格与价值”: [“19块一杯”, “高性价比”]
}
msg = [HumanMessage(content='你是谁?')]
res = chat([system_msg]+msg) # 用人设,因为prompt本身就是个列表
res = res.content
print(res)
# 我是一个语文老师。
前面的res.content,无论你prompt返里让他返回什么,如json格式,它回的都是字符串类型。
而使用如下langchain提供的输出解析器,则方便将输出格式化为我们想要的格式,以便处理下游任务。
# 🔥构造输出解析器
from langchain.output_parsers import ResponseSchema
from langchain.output_parsers import StructuredOutputParser
gift_schema = ResponseSchema(name="饮料",
description='',
type="string")
delivery_days_schema = ResponseSchema(name="产品名",
description='',
type="string")
price_value_schema = ResponseSchema(name="价格与价值",
description='',
type="list")
response_schemas = [gift_schema,
delivery_days_schema,
price_value_schema]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = output_parser.get_format_instructions()
print(format_instructions)
输出:
The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":
```json
{
"饮料": string //
"产品名": string //
"价格与价值": list //
}
prompt = prompt_template.format_messages(format_instructions=format_instructions, query=query)
print(prompt)
print(prompt[0].content)
输出:
[HumanMessage(content='对与如下三个反引号括住的评论,我需要提取如下信息。\n饮料:这个产品是饮料吗?如果是,返回True,否则返回答False。\n产品名:提取出产品的名字,如果没有,返回-1。\n价格与价值:提取出关于该产品的价格或价值的所有信息,将他们存入python list中,并返回。\nThe output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":\n\n```json\n{\n\t"饮料": string // \n\t"产品名": string // \n\t"价格与价值": list // \n}\n```\n```这喜茶新出的桑葚葡萄太好喝里吧,而且才19块一杯,太值啦,高性价比!```', additional_kwargs={}, example=False)]
对与如下三个反引号括住的评论,我需要提取如下信息。
饮料:这个产品是饮料吗?如果是,返回True,否则返回答False。
产品名:提取出产品的名字,如果没有,返回-1。
价格与价值:提取出关于该产品的价格或价值的所有信息,将他们存入python list中,并返回。
The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":
```json
{
"饮料": string //
"产品名": string //
"价格与价值": list //
}
```
```这喜茶新出的桑葚葡萄太好喝里吧,而且才19块一杯,太值啦,高性价比!```
res = chat(prompt)
res = res.content
print(res)
print(type(res))
```json
{
"饮料": true,
"产品名": "桑葚葡萄",
"价格与价值": ["19块一杯", "太值啦", "高性价比"]
}
```
<class 'str'>
解析器解析一波:
format_res = output_parser.parse(res)
print(format_res)
print(type(format_res))
{'饮料': True, '产品名': '桑葚葡萄', '价格与价值': ['19块一杯', '太值啦', '高性价比']}
<class 'dict'>