• (一)、基于 LangChain 实现大模型应用程序开发 | 模型调用 + 提示模版构建 + 输出解析器


    ⭐ 下面我们开始入门下LangChain框架,LangChain 是用于构建大模型应用程序的开源框架,有Python和JavaScript两个不同版本的包。LangChain 也是一个开源项目,社区活跃,新增功能快速迭代。LangChain基于模块化组合,有许多单独的组件,可以一起使用或单独使用。

    该专栏将重点介绍 LangChain 的常用组件:

    • 模型(Models):集成各种语言模型与向量模型。
    • 提示(Prompts):向模型提供指令的途径。
    • 索引(Indexes):提供数据检索功能。
    • 链(Chains):将组件组合实现端到端应用。
    • 代理(Agents):扩展模型的推理能力。

    通过学习使用这些组件构建链式应用,你将可以快速上手 LangChain,开发出功能强大的语言模型程序。让我们开始探索LangChain的魅力吧!

    1、openai 环境初始化 - 声明api key

    通过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']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、模型调用 + 提示模版构建

    • 在一些复杂的场景,prompt可能写的比较长,不利于管理,使用这种模版的形式可以方便的重复使用。
    • LangChain还提供了提示模版用于一些常用场景。比如summarization, Question answering, or connect to sql databases等。 通过使用LongChain内置的提示模版,你可以快速建立自己的大模型应用,而不需要花时间去设计和构造提示。
    • 对于如何设计更好的prompt,我不做介绍,可参考我的prompt engineering专题进行学习:https://blog.csdn.net/weixin_43646592/category_12329055.html?spm=1001.2014.3001.5482
    • langchain专题主要讲如何基于langchain进行大模型的开发与应用。
    # 这里我们将参数temperature设置为0.0,从而减少生成答案的随机性。
    # 如果你想要每次得到不一样的有新意的答案,可以尝试调整该参数。
    # 以下的对话均无记忆,即每次调用预测不会记得之前的对话。(想要有记忆功能请看下一节的langchain的Memory模块)
    chat = ChatOpenAI(temperature=0,
                      model_name="gpt-3.5-turbo")
    chat
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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']
    
    • 1
    • 2
    query = '这喜茶新出的桑葚葡萄太好喝里吧,而且才19块一杯,太值啦,高性价比!'
    format_instructions = """\
    将输出组织成带有如下key的json形式:
    饮料
    产品名
    价格与价值"""
    
    prompt = prompt_template.format_messages(format_instructions=format_instructions, query=query)
    print(prompt)
    print(prompt[0])
    # prompt一个HumanMessage的类,也就是人类的提问
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • [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

    3、人设设定 - SystemMessage

    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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    {
    “饮料”: true,
    “产品名”: “桑葚葡萄”,
    “价格与价值”: [“19块一杯”, “高性价比”]
    }

    msg = [HumanMessage(content='你是谁?')]
    res = chat([system_msg]+msg) # 用人设,因为prompt本身就是个列表
    res = res.content
    print(res)
    # 我是一个语文老师。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4、构造输出解析器

    前面的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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    输出:

    The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":
    ```json
    {
    	"饮料": string  // 
    	"产品名": string  // 
    	"价格与价值": list  // 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    prompt = prompt_template.format_messages(format_instructions=format_instructions, query=query)
    print(prompt)
    print(prompt[0].content)
    
    • 1
    • 2
    • 3

    输出:

    [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块一杯,太值啦,高性价比!```
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    res = chat(prompt)
    res = res.content
    print(res)
    print(type(res))
    
    ```json
    {
    	"饮料": true,
    	"产品名": "桑葚葡萄",
    	"价格与价值": ["19块一杯", "太值啦", "高性价比"]
    }
    ```
    <class 'str'>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    解析器解析一波:

    format_res = output_parser.parse(res)
    print(format_res)
    print(type(format_res))
    
    {'饮料': True, '产品名': '桑葚葡萄', '价格与价值': ['19块一杯', '太值啦', '高性价比']}
    <class 'dict'>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Reference

    • [1] 吴恩达老师的教程
    • [2] DataWhale组织
  • 相关阅读:
    计算机网络知识点汇总(二)
    [GXYCTF2019]禁止套娃
    GeoGebra:数学动画制作工具重磅来袭
    关于项目管理的若干建议
    Redis集群高可用架构
    canvas 系列学习笔记三《样式和颜色》
    R语言ggplot2可视化:使用ggpubr包的ggline函数可视化分组折线图(点线图、line plot)、linetype参数指定不同分组线型不同
    你知道吗?chrome自动更新到104版本,居然引起Java服务内存泄漏
    QFluentWidgets: 基于 C++ Qt 的 Fluent Design 组件库
    0x21_LinuxKernel_内核活动(一)之系统调用
  • 原文地址:https://blog.csdn.net/weixin_43646592/article/details/134499576