赞
踩
在LangChain中,JSON解析器用于将大型语言模型(LLM)的输出解析为JSON格式。JSON解析器允许用户指定任意的JSON模式,并查询LLM以获取符合该模式的输出。这对于需要从LLM获取结构化数据的场景非常有用。
在使用JSON解析器时,需要注意大型语言模型是“有漏洞的抽象”(leaky abstractions),这意味着它们可能无法总是生成完全符合预期的JSON格式的输出。因此,选择具有足够能力生成格式良好的JSON的LLM是很重要的,在此有如下所示的建议。
实例4-1:使用JSON解析器(源码路径:codes\4\json01.py)
实例文件json01.py的具体实现代码如下所示。
- from typing import List
-
- from langchain.prompts import PromptTemplate
- from langchain_core.output_parsers import JsonOutputParser
- from langchain_core.pydantic_v1 import BaseModel, Field
- from langchain_openai import ChatOpenAI
-
- # 创建一个ChatOpenAI模型实例
- model = ChatOpenAI(temperature=0)
-
- # 定义你希望的数据结构
- class Joke(BaseModel):
- setup: str = Field(description="question to set up a joke")
- punchline: str = Field(description="answer to resolve the joke")
-
- # 定义一个查询意图,用于提示语言模型填充数据结构
- joke_query = "Tell me a joke."
-
- # 设置一个解析器,并在提示模板中注入指令
- parser = JsonOutputParser(pydantic_object=Joke)
-
- # 创建一个提示模板
- prompt = PromptTemplate(
- template="Answer the user query.\n{format_instructions}\n{query}",
- input_variables=["query"],
- partial_variables={"format_instructions": parser.get_format_instructions()},
- )
-
- # 创建一个处理链:提示模板 -> 模型 -> 解析器
- chain = prompt | model | parser
-
- # 调用处理链,获取一个笑话
- output = chain.invoke({"query": joke_query})
- print(output)
-
- # 使用流式方法逐个打印输出
- for s in chain.stream({"query": joke_query}):
- print(s)
上述代码的实现流程如下所示:
如果不使用Pydantic,也可以创建一个JSON解析器实例,但不指定具体的模式。这将提示LLM返回JSON格式的输出,但不会提供关于模式的具体信息。在这种情况下,LLM生成的JSON可能会有不同的结构,这需要开发者根据实际情况进行处理。
执行上述代码后将得到两种类型的输出:一种是直接调用chain.invoke方法得到的完整JSON对象,另一种是通过流式调用chain.stream方法逐步得到的JSON片段。
1. 完整输出(使用chain.invoke)
当使用chain.invoke方法时,将得到一个完整的JSON对象,它包含了LLM生成的数据,下面是输出结果:
- {
-
- "setup": "Why don't scientists trust atoms?",
-
- "punchline": "Because they make up everything!"
-
- }
这个JSON对象对应于Joke Pydantic模型,其中setup字段包含了笑话的铺垫,punchline字段包含了笑话的笑点。
2. 流式输出(使用chain.stream)
当使用chain.stream方法时,将逐步得到LLM生成的数据片段。这是因为流式输出支持逐步处理输出,而不是等待整个输出生成完毕。下面是流式输出结果:
- {'setup': ''}
- {'setup': 'Why'}
- {'setup': 'Why don'}
- {'setup': "Why don't"}
- {'setup': "Why don't scientists"}
- {'setup': "Why don't scientists trust"}
- {'setup': "Why don't scientists trust atoms"}
- {'setup': "Why don't scientists trust atoms?", 'punchline': ''}
- {'setup': "Why don't scientists trust atoms?", 'punchline': 'Because'}
- {'setup': "Why don't scientists trust atoms?", 'punchline': 'Because they'}
- {'setup': "Why don't scientists trust atoms?", 'punchline': 'Because they make'}
- {'setup': "Why don't scientists trust atoms?", 'punchline': 'Because they make up'}
- {'setup': "Why don't scientists trust atoms?", 'punchline': 'Because they make up everything'}
上面的输出结果展示了LLM生成的笑话是如何逐步构建的,每个片段都是一个包含部分或全部笑话的JSON对象。
注意:这些输出结果是基于假设LLM能够准确地理解提示并生成符合预期格式的响应。在实际应用中,LLM的输出可能会有所不同,并且需要根据实际情况进行验证和调整。此外,流式输出的顺序和内容可能会根据LLM的具体实现和响应而有所不同。
OpenAI函数解析器是一组特殊的输出解析器,它们利用OpenAI的语言模型的功能调用来结构化和解析输出。这些解析器设计用来与支持函数调用功能的OpenAI模型一起工作,如DaVinci。它们允许用户定义请求的预期格式,并从模型生成的文本中提取和验证数据。
在LangChain中,常用的OpenAI函数解析器如下所示。
在使用这些解析器时,需要定义一个函数调用模板,这个模板将告诉OpenAI模型你期望的输出格式。然后,LangChain会将这个模板与模型的输出结合起来,生成结构化的数据。例如,如果想要获取一个笑话,可以定义一个Joke Pydantic模型,并创建一个函数调用模板来请求这个笑话。当模型生成输出时,OpenAI函数解析器会根据你定义的模板来解析和验证数据,确保它符合Joke模型的预期格式。
OpenAI函数解析器提供了一种强大的方式来处理和验证从OpenAI模型中生成的数据,使得与这些模型的交互更加灵活和可靠。通过使用OpenAI函数解析器,开发者可以确保他们得到的数据是结构化和可用的,从而更容易地集成到各种应用程序中。
假设有一个大型语言模型(LLM),它能够回答用户提出的关于天气的问题。请看下面的例子,解析模型的输出结果,提取其中的关键信息,比如温度和天气状况,此时可以使用OpenAI函数解析器来实现这一目标。
实例4-1:获取北京的天气信息(源码路径:codes\4\open01.py)
实例文件open01.py的具体实现代码如下所示。
- from langchain_core.pydantic_v1 import BaseModel, Field
- from langchain_openai import ChatOpenAI
- from langchain.prompts import PromptTemplate
- from langchain.output_parsers.openai_functions import PydanticOutputFunctionsParser
- from langchain_community.utils.openai_functions import convert_pydantic_to_openai_function
-
- # 定义天气信息的Pydantic模型
- class Weather(BaseModel):
- temperature: float = Field(description="当前温度(摄氏度)")
- condition: str = Field(description="天气状况")
-
- # 设置OpenAI模型
- weather_model = ChatOpenAI(temperature=0)
-
- # 定义提示模板
- prompt = PromptTemplate.from_template(
- """请问您想了解哪个城市的天气?
- """
- )
-
- # 将Pydantic模型转换为OpenAI函数
- openai_functions = [convert_pydantic_to_openai_function(Weather)]
-
- # 创建OpenAI函数解析器
- parser = PydanticOutputFunctionsParser(pydantic_schema=Weather)
-
- # 创建处理链
- chain = prompt | weather_model.bind(functions=openai_functions) | parser
-
- # 调用处理链并传入用户提出的问题,以获取天气信息
- output = chain.invoke({"input": "明天北京的天气如何?"})
- print(output)
上述代码的实现流程如下所示:
{"date": "2024-04-12", "temperature": "22°C", "condition": "晴"}
在LangChain中,修正解析器(Output-fixing parser)是LangChain中一种特殊的输出解析器,它包裹了另一个输出解析器。如果原始解析器失败,它将调用另一个大型语言模型(LLM)来修复任何格式错误。可以将格式错误的输出以及格式指令一起传递给模型,并要求它修复这些错误。例如在下面代码中定义了一个Pydantic模型来表示演员及其电影作品,并尝试使用Pydantic输出解析器来解析一个格式错误的JSON字符串。
- from typing import List
-
- from langchain.output_parsers import PydanticOutputParser
- from langchain_core.pydantic_v1 import BaseModel, Field
- from langchain_openai import ChatOpenAI
-
- # 定义一个Pydantic模型来表示演员和他们的电影作品
- class Actor(BaseModel):
- name: str = Field(description="演员的名字")
- film_names: List[str] = Field(description="他们主演的电影名称列表")
-
- # 定义一个查询,要求生成一个随机演员的电影作品列表
- actor_query = "为一个随机演员生成电影作品列表。"
-
- # 创建一个Pydantic输出解析器实例
- parser = PydanticOutputParser(pydantic_object=Actor)
-
- # 一个格式错误的JSON字符串
- misformatted = "{'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}"
-
- # 尝试使用Pydantic输出解析器解析格式错误的JSON字符串
- try:
- parser.parse(misformatted)
- except Exception as e:
- print(f"解析错误:{e}")
执行这段代码后,由于JSON字符串格式错误,将抛出异常,并在控制台中打印出异常信息:
解析错误:Failed to parse Actor from completion {'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}. Got: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
这条异常信息表明,Pydantic输出解析器无法将给定的JSON字符串解析为Actor模型,因为JSON字符串中的属性名称没有用双引号包围。如果使用修正解析器OutputFixingParser进行及处理,它将尝试使用另一个LLM来修复格式错误,例如下面的代码。
- from langchain.output_parsers import OutputFixingParser
- # 创建一个输出修正解析器实例,传入原始的Pydantic输出解析器和LLM
- new_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
-
- # 使用输出修正解析器尝试解析格式错误的JSON字符串
- try:
- fixed_actor = new_parser.parse(misformatted)
- print(fixed_actor)
- except Exception as e:
- print(f"修复失败:{e}")
在上述代码中,OutputFixingParser将接收到格式错误的JSON字符串,并尝试使用ChatOpenAI LLM来修复它。如果LLM能够理解问题并生成正确的格式,OutputFixingParser将返回一个符合Actor模型的结构化数据,那么最终的输出将是一个符合Actor Pydantic模型的结构化数据对象。具体来说,输出将是:
Actor(name='Tom Hanks', film_names=['Forrest Gump'])
这个输出表示已经成功地将原始的格式错误的JSON字符串 {'name': 'Tom Hanks', 'film_names': ['Forrest Gump']} 修正为一个Actor对象,其中包含了演员的名字和他们主演的电影名称列表。
如果LLM无法正确地修复格式错误,OutputFixingParser会抛出一个异常,表明修复失败。在这种情况下,输出将不是预期的Actor对象,而是异常信息。因此,在使用OutputFixingParser时,应该准备好处理可能出现的异常情况。
Pandas DataFrame 是 Python 编程中常用的数据结构,用于数据操作和分析。它提供了丰富的工具,用于处理结构化数据,如数据清洗、转换和分析。Pandas DataFrame解析器是LangChain中用于处理和分析结构化数据的一个输出解析器,它允许用户指定一个任意的Pandas DataFrame,并查询LLM以获取格式化字典形式的数据,这些数据从相应的DataFrame中提取。
Pandas DataFrame解析器允许用户指定一个 Pandas DataFrame,并查询大型语言模型(LLMs)以从 DataFrame 中提取数据,并以字典格式返回。在使用过程中,需要确保选择具有足够容量的 LLM,以生成符合指定格式的查询结果。使用类PandasDataFrameOutputParser来解析 Pandas DataFrame 的输出。使用类PromptTemplate 类来设置查询的提示模板,注入解析器的格式指令,并与 ChatOpenAI 模型一起使用。
Pandas DataFrame解析器可以执行多种操作,如对列和行进行操作,以及对数据进行汇总操作。如果查询格式不正确,将会引发 OutputParserException 错误,需要在处理代码中进行错误处理。例如下面是一个使用 Pandas DataFrame 解析器的例子,假设有一个包含动物信息的 Pandas DataFrame,包括动物的名称、腿的数量和是否能飞,在实例中想要查询该 DataFrame 中的数据,例如获取动物的名称和腿的数量。
实例4-1:获取动物的名称和腿的数量(源码路径:codes\4\fra.py)
实例文件fra.py的具体实现代码如下所示。
- import pprint
- from typing import Any, Dict
-
- import pandas as pd
- from langchain.output_parsers import PandasDataFrameOutputParser
- from langchain.prompts import PromptTemplate
- from langchain_openai import ChatOpenAI
-
- # 创建 Pandas DataFrame 包含动物信息
- df = pd.DataFrame({
- "名称": ["狗", "猫", "鸟", "蛇"],
- "腿的数量": [4, 4, 2, 0],
- "能飞吗": [False, False, True, False]
- })
-
- # 设置解析器,指定使用 PandasDataFrameOutputParser,并传入 DataFrame
- parser = PandasDataFrameOutputParser(dataframe=df)
-
- # 设置提示模板
- prompt = PromptTemplate(
- template="查询动物的信息:\n{format_instructions}\n{query}\n",
- input_variables=["query"],
- partial_variables={"format_instructions": parser.get_format_instructions()},
- )
-
- # 创建 ChatOpenAI 模型实例
- model = ChatOpenAI(temperature=0)
-
- # 定义用于格式化解析结果的函数
- def format_parser_output(parser_output: Dict[str, Any]) -> None:
- for key in parser_output.keys():
- parser_output[key] = parser_output[key].to_dict()
- return pprint.PrettyPrinter(width=4, compact=True).pprint(parser_output)
-
- # 执行查询
- df_query = "获取动物名称和腿的数量。"
- chain = prompt | model | parser
- parser_output = chain.invoke({"query": df_query})
-
- # 格式化并打印解析结果
- format_parser_output(parser_output)
在上述代码中,定义了一个包含动物信息的 Pandas DataFrame,并设置了一个查询,以获取动物的名称和腿的数量。然后,使用 Pandas DataFrame 解析器执行查询,并格式化输出结果。执行后会根据给定的查询"获取动物名称和腿的数量。",输出结果是一个字典,包含动物的名称和对应的腿的数量执行后会输出:
- {'名称': {'0': '狗', '1': '猫', '2': '鸟', '3': '蛇'},
- '腿的数量': {'0': 4, '1': 4, '2': 2, '3': 0}}
这个字典表示了查询结果,其中包含了动物的名称和对应的腿的数量。
LangChain中的XML解析器是一种特殊的输出解析器,其主要作用是将大型语言模型(LLM)的文本输出转换为XML(可扩展标记语言)格式。XML是一种用于存储和传输数据的标准文本格式,它通过使用标签(tags)来描述数据的结构和语义。XML解析器的主要特点如下所示:
使用XML解析器的步骤如下所示:
(1)定义数据结构:首先,需要定义希望从LLM获取的数据的结构。这通常涉及到创建一个XML模式(schema),它描述了数据的预期布局和格式。
(2)设置提示模板:创建一个提示模板(PromptTemplate),它将指导LLM如何生成符合你定义的数据结构的输出。提示模板可以包含特定的格式指令,告诉LLM如何使用XML标签来格式化其响应。
(3)创建解析器实例:实例化XMLOutputParser类,并将XML模式或其他相关参数传递给它。
(4)构建处理链:将提示模板、LLM模型和XML解析器连接起来,形成一个处理链,这个处理链将负责生成、格式化和解析数据。
(5)调用解析器:通过调用处理链的invoke方法,可以获取LLM的输出,并将其转换为XML格式。如果LLM的输出不符合预期格式,你可能需要调整提示模板或数据结构。
例如下面是一个使用XML解析器的例子,创建一个能够从大型语言模型(LLM)获取数据并以XML格式输出的系统,这个系统可以用于生成产品信息、新闻摘要信息等场景。
实例4-1:生成手机产品信息(源码路径:codes\4\xml01.py)
实例文件xml01.py的具体实现代码如下所示。
- from langchain.output_parsers import XMLOutputParser
- from langchain.prompts import PromptTemplate
- from langchain_openai import ChatOpenAI
-
- # 创建一个LLM模型实例,这里我们使用OpenAI的Chat模型
- model = ChatOpenAI(temperature=0)
-
- # 定义一个查询,要求生成一个产品的简要信息
- product_query = "请提供一款智能手机的详细信息。"
-
- # 创建一个XML解析器实例,用于将LLM的输出解析为XML格式
- parser = XMLOutputParser()
-
- # 设置提示模板,包含查询和格式指令
- prompt_template = PromptTemplate(
- template="""{query}
- 请将产品信息以以下XML标签格式化:<product>, <name>, <brand>, <price>, <features>。""",
- input_variables=["query"],
- partial_variables={"format_instructions": parser.get_format_instructions()}
- )
-
- # 构建处理链:提示模板 -> LLM模型 -> XML解析器
- chain = prompt_template | model | parser
-
- # 调用处理链并获取输出
- output = chain.invoke({"query": product_query})
-
- # 打印XML格式的输出
- print(output)
上述代码的实现流程如下所示:
执行后会输出:
- <product>
- <name>小米11</name>
- <brand>小米</brand>
- <price>3999元</price>
- <features>120Hz屏幕刷新率, 108MP主摄像头, 55W快充</features>
- </product>
这个XML数据可以直接用于网页展示、数据交换或其他需要XML格式的场合。通过使用XML解析器,可以确保从LLM获得的数据是结构化和格式化的,这样就可以在应用程序中轻松使用这些数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。