LangChain(0.0.340)官方文档六:Output parsers

LangChain官网LangChain官方文档langchain Githublangchain API文档llm-universe

一、简介

  langchain是一个语言模型框架,它的语言模型会输出文本。但在许多情况下,你可能希望获得比纯文本更结构化的信息,这就是输出解析器的作用。

  输出解析器是帮助结构化语言模型响应的类。它需要实现两个主要方法及一个可选方法:

  • Get format instructions:返回一个字符串,包含有关如何格式化语言模型输出的指令
  • Parse:获取语言模型的响应字符串,并解析成某种结构
  • Parse with prompt(可选):获取语言模型的响应和生成该响应的提示,并解析成某种结构。提供提示主要是为了 OutputParser 可以在需要时重试或修正输出,提示中包含了完成这些操作所需的信息。
常用Output Parser描述
SimpleJsonOutputParser将输出解析为JSON格式
PydanticAttrOutputFunctionsParser将输出解析为Pydantic对象的属性
PydanticOutputFunctionsParser将输出解析为Pydantic对象
DatetimeOutputParser将LLM输出解析为datetime格式
RegexParser/RegexDictParser使用正则表达式解析LLM调用的输出,后者解析为字典
RetryOutputParser/RetryWithErrorOutputParser包装一个解析器,并尝试修复解析错误
StructuredOutputParser将LLM调用的输出解析为结构化输出
XMLOutputParser使用XML格式解析输出

1.1 Pydantic (JSON) parser

  Pydantic是一个Python库,用于声明数据模型并进行类型检查和强制转换。PydanticOutputParser是一种输出解析器,它允许您指定一个Pydantic模型(使用Pydantic的BaseModel来定义),并将语言模型的输出解析为符合该模型的结构化数据,这样可以确保输出的数据符合预期的格式和类型。

  • 使用 Pydantic 的 BaseModel 来定义所需的 JSON 数据结构和 schema
  • 可以自定义验证逻辑来确保 JSON 输出符合预期格式
  • PydanticOutputParser 可以将 LLM 的文本输出解析成 Pydantic 模型
  • 通过 PromptTemplate 可以将解析说明注入到 prompt 中,指导 LLM 输出符合格式的 JSON

示例一:定义简单的Actor数据模型

from langchain.llms import OpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.pydantic_v1 import BaseModel, Field, validator

model = OpenAI(model_name="text-davinci-003", temperature=0.0)
# Here's another example, but with a compound typed field.
class Actor(BaseModel):
    name: str = Field(description="name of an actor")
    film_names: List[str] = Field(description="list of names of films they starred in")


actor_query = "Generate the filmography for a random actor."
parser = PydanticOutputParser(pydantic_object=Actor)

prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

_input = prompt.format_prompt(query=actor_query)
output = model(_input.to_string())
parser.parse(output)
Actor(name='Tom Hanks', film_names=['Forrest Gump', 'Saving Private Ryan', 'The Green Mile', 'Cast Away', 'Toy Story'])

示例二:定义Joke数据模型并验证s问题是否以问号结尾

#  定义所需的数据结构(Joke),使用 Pydantic 进行数据验证
class Joke(BaseModel):
    setup: str = Field(description="question to set up a joke")
    punchline: str = Field(description="answer to resolve the joke")

    # 你可以很容易地使用Pydantic添加自定义验证逻辑
    @validator("setup")
    def question_ends_with_question_mark(cls, field):
        if field[-1] != "?":
            raise ValueError("Badly formed question!")
        return field


# 设置一个解析器,并在提示模板中注入指令
parser = PydanticOutputParser(pydantic_object=Joke)

prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

  以上代码定义了一个Joke的数据结构,并使用PydanticOutputParser将语言模型的响应解析成这个结构。同时利用Pydantic进行了自定义验证。验证器的逻辑是检查setup(question)结束的字符是否为"?",如果是,则直接返回setup字段的值,否则抛出ValueError异常,也就是验证提出的Joke的问题必须以问号结尾,避免无效或格式错误的输入。

joke_query = "Tell me a joke."
_input = prompt.format_prompt(query=joke_query)
output = model(_input.to_string())
parser.parse(output)
Joke(setup='Why did the chicken cross the road?', punchline='To get to the other side!')

  语言模型是一个不完美的黑盒,它会反映或泄露出其训练过程中的部分数据集、偏见等因素,其内部的训练数据、结构可能会对其输出产生意想不到的影响。尤其是在让语言模型生成特定格式的结构化输出时,低能力的语言模型更容易产生格式错误、不一致的情况。所以使用Pydantic (JSON) parserXML parserAuto-fixing parser等解析器时,必须使用具有足够能力的LLM来生成正确的响应。

1.2 LCEL

  同prompt和model一样,Output parsers也实现了Runnable 接口,这意味着它们也支持 invoke/ainvoke,stream/astream,batch/abatch,astream_log 等方法的调用。Output parsers接受字符串或BaseMessage 作为输入,并可以返回任意类型。

prompt_and_model = prompt | model
output = prompt_and_model.invoke({"query": "Tell me a joke."})
# 解析模型输出
parser.invoke(output)
Joke(setup='Why did the chicken cross the road?', punchline='To get to the other side!')

我们也可以将其添加到 Runnable 序列中,而不是手动调用解析器

chain = prompt | model | parser
chain.invoke({"query": "Tell me a joke."})
Joke(setup='Why did the chicken cross the road?', punchline='To get to the other side!')

1.3 流式输出

  尽管所有解析器都支持流式接口(Runnable实现stream/astream方法),但有些类型可以流式传输(比如字符串或JSON格式),有些类型不可以,所以只有某些解析器可以流式传递解析的对象。无法构造部分对象的解析器将简单地生成完全解析的输出。

  比如SimpleJsonOutputParser可以进行流式传输:

from langchain.output_parsers.json import SimpleJsonOutputParser

json_prompt = PromptTemplate.from_template(
    "Return a JSON object with an `answer` key that answers the following question: {question}"
)
json_parser = SimpleJsonOutputParser()
json_chain = json_prompt | model | json_parser

list(json_chain.stream({"question": "Who invented the microscope?"}))
[{},
 {'answer': ''},
 {'answer': 'Ant'},
 {'answer': 'Anton'},
 {'answer': 'Antonie'},
 {'answer': 'Antonie van'},
 {'answer': 'Antonie van Lee'},
 {'answer': 'Antonie van Leeu'},
 {'answer': 'Antonie van Leeuwen'},
 {'answer': 'Antonie van Leeuwenho'},
 {'answer': 'Antonie van Leeuwenhoek'}]

显然PydanticOutputParser 并不能:

list(chain.stream({"query": "Tell me a joke."}))
[Joke(setup='Why did the chicken cross the road?', punchline='To get to the other side!')]

二、列表解析器(List parser)

当您想要返回以逗号分隔的列表输出时,可以使用此输出解析器。

from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

output_parser = CommaSeparatedListOutputParser()

format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
    template="List five {subject}.\n{format_instructions}",
    input_variables=["subject"],
    partial_variables={"format_instructions": format_instructions}
)

model = OpenAI(temperature=0)

_input = prompt.format(subject="ice cream flavors")
output = model(_input)

output_parser.parse(output)
['Vanilla',
 'Chocolate',
 'Strawberry',
 'Mint Chocolate Chip',
 'Cookies and Cream']
  • get_format_instructions()方法:获取格式化指令
  • {format_instructions}是一个占位符,会被格式化指令替换。
  • partial_variables:用于在初始化PromptTemplate时进行部分变量替换,即在生成提示语时,将使用format_instructions的值替换模板中的{format_instructions}占位符。

通过以上提示模板的部分格式化(List parser),告诉模型列出5种subject,并且结果以列表列出。

关于部分格式化(Partial prompt templates)相关内容详见《LangChain(0.0.339)官方文档四:Prompts下——prompt templates的存储、加载、组合和部分格式化》

三、Datetime parser

此 OutputParser 可用于将 LLM 输出解析为datetime格式。

from langchain.chains import LLMChain
from langchain.llms import OpenAI
from langchain.output_parsers import DatetimeOutputParser
from langchain.prompts import PromptTemplate
output_parser = DatetimeOutputParser()
template = """Answer the users question:

{question}

{format_instructions}"""
prompt = PromptTemplate.from_template(
    template,
    partial_variables={"format_instructions": output_parser.get_format_instructions()},
)
chain = LLMChain(prompt=prompt, llm=OpenAI())
output = chain.run("around when was bitcoin founded?")
output
'\n\n2008-01-03T18:15:05.000000Z'
output_parser.parse(output)
datetime.datetime(2008, 1, 3, 18, 15, 5)

四、Enum parser (枚举解析器)

  EnumOutputParser可以将模型的响应解析为预定义的枚举值。假设我们有一个语言模型,用于生成颜色的描述,我们希望输出结果只能是红色、绿色或蓝色。那么我们可以先定义一个颜色的枚举类:

from langchain.output_parsers.enum import EnumOutputParser
from enum import Enum

class Colors(Enum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

然后,我们可以使用EnumOutputParser来解析模型的输出,并将其转换为预定义的枚举值(Colors.RED)

# 创建了一个EnumOutputParser对象,并指定其枚举类为Color
parser = EnumOutputParser(enum=Colors)
parser.parse("red")							
<Colors.RED: 'red'>
# And raises errors when appropriate
parser.parse("yellow")
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

File ~/workplace/langchain/langchain/output_parsers/enum.py:25, in EnumOutputParser.parse(self, response)
     24 try:
---> 25     return self.enum(response.strip())
     26 except ValueError:


File ~/.pyenv/versions/3.9.1/lib/python3.9/enum.py:315, in EnumMeta.__call__(cls, value, names, module, qualname, type, start)
    314 if names is None:  # simple value lookup
--> 315     return cls.__new__(cls, value)
    316 # otherwise, functional API: we're creating a new Enum type


File ~/.pyenv/versions/3.9.1/lib/python3.9/enum.py:611, in Enum.__new__(cls, value)
    610 if result is None and exc is None:
--> 611     raise ve_exc
    612 elif exc is None:


ValueError: 'yellow' is not a valid Colors


During handling of the above exception, another exception occurred:


OutputParserException                     Traceback (most recent call last)

Cell In[8], line 2
      1 # And raises errors when appropriate
----> 2 parser.parse("yellow")


File ~/workplace/langchain/langchain/output_parsers/enum.py:27, in EnumOutputParser.parse(self, response)
     25     return self.enum(response.strip())
     26 except ValueError:
---> 27     raise OutputParserException(
     28         f"Response '{response}' is not one of the "
     29         f"expected values: {self._valid_values}"
     30     )


OutputParserException: Response 'yellow' is not one of the expected values: ['red', 'green', 'blue']

五、Auto-fixing parser(使用OutputFixingParser修复语法、格式等错误)

  解析器用于将输入数据转换为结构化的表示。在一般的解析过程中,如果遇到语法错误或其他问题,传统的解析器通常会抛出错误并停止解析。而Auto-fixing parser不仅能够检测错误,还能够调用LLM来尝试自动修复这些错误,使解析过程能够继续进行,其工作流程为:

  • 检测错误,例如语法错误、格式错误或其他不符合预期的问题。
  • 错误诊断:根据错误的上下文、数据结构或其他相关信息,以确定错误的类型和位置。
  • 自动修复:基于错误的诊断结果,Auto-fixing parser会选择适当的错误修复策略尝试修复,以使数据符合预期的格式或结构:
    • 语法错误修复:例如,在解析一个JSON文件时,如果发现缺少逗号或引号不匹配等语法错误,Auto-fixing parser可以自动添加逗号或修复引号,使其符合JSON语法规范。
    • 数据格式修复:例如,当解析日期字段时,如果日期格式不正确,Auto-fixing parser可以尝试根据常见的日期格式模式进行修复,使其符合预期的日期格式。
    • 缺失信息修复:例如,在解析一个XML文件时,如果某个元素缺少必需的属性,Auto-fixing parser可以自动添加该属性,并保持数据的完整性。
    • 数据清洗修复:例如,当解析网页内容时,如果发现HTML标签不正确闭合或存在其他格式问题,Auto-fixing parser可以自动修复这些问题,使解析后的文本更加干净和可用。
  • 验证修复,以确保修复成功并生成了正确的结构化表示。
  • 继续解析:如果修复成功,Auto-fixing parser会继续解析修复后的数据。如果仍然存在其他错误,它可能会重复上述步骤,直到解析完成或无法修复为止。

  现在举例演示一下Auto-fixing parser的使用方式。我们先使用1.1节中的Pydantic 输出解析器,定义一个演员数据模型class Actor(BaseModel),它包含两个字段。name字段是一个字符串类型,表示演员的姓名,film_names字段是一个字符串列表类型,表示演员出演的电影列表。

from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.pydantic_v1 import BaseModel, Field
from typing import List

class Actor(BaseModel):
    name: str = Field(description="name of an actor")
    film_names: List[str] = Field(description="list of names of films they starred in")

actor_query = "Generate the filmography for a random actor."

然后使用PydanticOutputParser,将语言模型的输出解析为符合Actor模型的结构化数据:

parser = PydanticOutputParser(pydantic_object=Actor)
misformatted = "{'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}"
# 正常解析misformatted
parser.parse(misformatted)

  此时会报错Got: Expecting property name enclosed in double quotes,即期望misformatted中的属性名用双引号括起来。因为根据JSON规范,属性名必须使用双引号而不是单引号。

---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
...
----> 1 parser.parse(misformatted)

File ~/workplace/langchain/langchain/output_parsers/pydantic.py:29, in PydanticOutputParser.parse(self, text)
     27 name = self.pydantic_object.__name__
     28 msg = f"Failed to parse {name} from completion {text}. Got: {e}"
---> 29 raise OutputParserException(msg)


OutputParserException: 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)

  我们可以将其改为misformatted = '{"name": "Tom Hanks", "film_names": ["Forrest Gump"]}',更通用的做法是使用 OutputFixingParser,它可以指定参数来使用另一个解析器,同时使用一个 LLM 来尝试纠正任何格式错误。

from langchain.output_parsers import OutputFixingParser

new_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
new_parser.parse(misformatted)
Actor(name='Tom Hanks', film_names=['Forrest Gump'])

六、Pandas DataFrame Parser

  Pandas DataFrame Parser可以帮助将不同格式的数据(如CSV、Excel、数据库查询结果等)解析为Pandas DataFrame对象,以便进行数据分析、数据清洗、数据转换等操作。要注意的是,它用于解析和处理数据,而不是用于解析和处理文本或其他非结构化数据。比如您需要解析和处理文本数据,可以考虑使用其他文本解析器或库(如正则表达式,nlp工具等)。

import pprint
from typing import Any, Dict

import pandas as pd
from langchain.llms import OpenAI
from langchain.output_parsers import PandasDataFrameOutputParser
from langchain.prompts import PromptTemplate

df = pd.DataFrame(
    {
        "num_legs": [2, 4, 8, 0],
        "num_wings": [2, 0, 0, 0],
        "num_specimen_seen": [10, 2, 1, 8],
    }
)

model_name = "text-davinci-003"
temperature = 0.5
model = OpenAI(model_name=model_name, temperature=temperature)

6.1 列操作示例

  定义format_parser_output函数,该函数遍历解析后的输出(字典格式),并将每个键对应的值转换为字典形式。然后,使用pprint.PrettyPrinter对格式化后的输出进行漂亮的打印。

# Solely for documentation purposes.
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)

  使用partial_variables方法在初始化PromptTemplate时进行部分格式化,也就是只格式化template中的{format_instructions}parser.get_format_instructions(){query}不变。

# 设置一个解析器,并在提示模板中注入指令
parser = PandasDataFrameOutputParser(dataframe=df)
df_query = "Retrieve the num_wings column."  			# 提取num_wings列的数据

# 设置prompt
prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

_input = prompt.format_prompt(query=df_query)
output = model(_input.to_string())
print("LLM Output:", output)
# 将输出解析为DataFrame格式
parser_output = parser.parse(output)
format_parser_output(parser_output)
LLM Output: column:num_wings
{'num_wings': {0: 2,
               1: 0,
               2: 0,
               3: 0}}

6.2 行操作示例

df_query = "Retrieve the first row."

_input = prompt.format_prompt(query=df_query)
output = model(_input.to_string())
print("LLM Output:", output)
parser_output = parser.parse(output)

format_parser_output(parser_output)
LLM Output: row:1
{'1': {'num_legs': 4,
       'num_specimen_seen': 2,
       'num_wings': 0}}

6.3 随机DataFrame操作示例

  1. 获取num_legs 列1到3行的均值
df_query = "Retrieve the average of the num_legs column from rows 1 to 3."

_input = prompt.format_prompt(query=df_query)
output = model(_input.to_string())
print("LLM Output:", output)
parser.parse(output)
LLM Output: mean:num_legs[1..3]





{'mean': 4.0}
  1. 获取num_fingers 列的平均值
df_query = "Retrieve the mean of the num_fingers column."

_input = prompt.format_prompt(query=df_query)
output = model(_input.to_string())  # Expected Output: "Invalid column: num_fingers".
print("LLM Output:", output)
parser.parse(output)  # Expected Output: Will raise an OutputParserException.

七、Retry parser(使用RetryWithErrorOutputParser修复query缺失错误)

  当输出不仅格式不正确,而且部分不完整时,可能无法仅仅通过查看输出来修复解析错误,而需要重新获取正确的响应。Retry parser通过将原始输出和提示传递给语言模型来尝试再次获取更好的响应,可以处理这种情况,避免了手动补充query。

  Auto-fixing parser和Retry parser都可以修复解析错误,但是前者是调用另一个语言模型来修复错误(将错误的输出以及格式化指令传递给模型,要求模型修复错误);后者是对模型进行重试请求获取新的响应。

from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
from langchain.output_parsers import OutputFixingParser,PydanticOutputParser,
from langchain.prompts import PromptTemplate,
from pydantic import BaseModel, Field

template = """Based on the user question, provide an Action and Action Input for what step should be taken.
{format_instructions}
Question: {query}
Response:"""

  使用Action 类定义一个 Pydantic 的模型(BaseModel),用来定义需要解析得到的 JSON 数据结构。其包含两个字段:

  • action:要执行的动作
  • action_input:动作的输入
class Action(BaseModel):
    action: str = Field(description="action to take")
    action_input: str = Field(description="input to the action")

parser = PydanticOutputParser(pydantic_object=Action)
prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

  如果尝试解析以下响应,会得到一个错误,因为bad_response 中只包含了 action 字段,没有 action_input(必须)

prompt_value = prompt.format_prompt(query="who is leo di caprios gf?")
bad_response = '{"action": "search"}'
parser.parse(bad_response)
OutputParserException: Failed to parse Action from completion {"action": "search"}. Got: 1 validation error for Action
action_input
  field required (type=value_error.missing)

  如果尝试使用OutputFixingParser进行修复,它会感到困惑,因为OutputFixingParser 依赖内部的语言模型(如 ChatOpenAI)来尝试修复解析错误。在该例子中,问题在于缺失action_input字段的值,所以即使让语言模型重试生成输出,但它并不知道应该输入什么作为action_input。所以它只能简单地把 action_input 放为空字符串,以让输出变得语法完整,但并没有实际修复错误。

fix_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
fix_parser.parse(bad_response)
Action(action='search', action_input='')

  相反,我们可以使用 RetryOutputParser,它在重试时会再次提供原始的Prompt(包括用户查询语句)给模型,这样语言模型就可以根据同样的查询语句,生成一个符合要求的新响应,来修正之前不完整的响应。

from langchain.output_parsers import RetryWithErrorOutputParser

retry_parser = RetryWithErrorOutputParser.from_llm(
    parser=parser, llm=OpenAI(temperature=0))

retry_parser.parse_with_prompt(bad_response, prompt_value)
Action(action='search', action_input='who is leo di caprios gf?')

八、Structured output parser

  Structured output parser可以根据特定的规则和模式,将文本解析为特定的数据类型,例如JSON、XML或自定义的数据结构。

8.1 LLM示例

from langchain.output_parsers import StructuredOutputParser, ResponseSchema
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI

定义响应模式:

response_schemas = [
    ResponseSchema(name="answer", description="answer to the user's question"),
    ResponseSchema(name="source", description="source used to answer the user's question, should be a website.")
]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)

定义提示模板,其中包含如何格式化响应的说明:

format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
    template="answer the users question as best as possible.\n{format_instructions}\n{question}",
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions}
)
model = OpenAI(temperature=0)
_input = prompt.format_prompt(question="what's the capital of france?")
output = model(_input.to_string())
output_parser.parse(output)
{'answer': 'Paris',
 'source': 'https://www.worldatlas.com/articles/what-is-the-capital-of-france.html'}

8.2 chat model示例

chat_model = ChatOpenAI(temperature=0)

prompt = ChatPromptTemplate(
    messages=[
        HumanMessagePromptTemplate.from_template("answer the users question as best as possible.\n{format_instructions}\n{question}")
    ],
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions}
)
_input = prompt.format_prompt(question="what's the capital of france?")
output = chat_model(_input.to_messages())
output_parser.parse(output.content)
{'answer': 'Paris', 'source': 'https://en.wikipedia.org/wiki/Paris'}

九、XML parser

XMLOutputParser提供了一些方法和功能,将模型输出的XML格式文本转换为结构化的数据对象,以便更方便地处理和使用,例如:

  • parse(text: str) -> Any:将XML文本解析为结构化的数据对象。
  • parse_result(result: List[Generation], partial: bool = False) -> Any:将模型生成的候选结果解析为特定的格式。
  • stream(input: Input, config: Optional[RunnableConfig] = None, **kwargs: Optional[Any]) -> AsyncIterator[Output]:支持流式处理XML数据的方法。

下面先进行简单的请求:

from langchain.llms import Anthropic
from langchain.output_parsers import XMLOutputParser
from langchain.prompts import PromptTemplate

model = Anthropic(model="claude-2", max_tokens_to_sample=512, temperature=0.1)
actor_query = "Generate the shortened filmography for Tom Hanks."
output = model(
    f"""

Human:
{actor_query}
Please enclose the movies in <movie></movie> tags
Assistant:
"""
)
print(output)
 Here is the shortened filmography for Tom Hanks enclosed in <movie> tags:

<movie>Splash (1984)</movie>
<movie>Big (1988)</movie> 
<movie>A League of Their Own (1992)</movie>
<movie>Sleepless in Seattle (1993)</movie>  
<movie>Forrest Gump (1994)</movie>
<movie>Apollo 13 (1995)</movie>
<movie>Toy Story (1995)</movie>
<movie>Saving Private Ryan (1998)</movie>
<movie>Cast Away (2000)</movie>
<movie>The Da Vinci Code (2006)</movie>
<movie>Toy Story 3 (2010)</movie>
<movie>Captain Phillips (2013)</movie>
<movie>Bridge of Spies (2015)</movie>
<movie>Toy Story 4 (2019)</movie>

现在我们将使用 XMLOutputParser 来获取结构化输出:

parser = XMLOutputParser()

prompt = PromptTemplate(
    template="""
    
    Human:
    {query}
    {format_instructions}
    Assistant:""",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

chain = prompt | model | parser

output = chain.invoke({"query": actor_query})
print(output)
{'filmography': [{'movie': [{'title': 'Splash'}, {'year': '1984'}]}, {'movie': [{'title': 'Big'}, {'year': '1988'}]}, {'movie': [{'title': 'A League of Their Own'}, {'year': '1992'}]}, {'movie': [{'title': 'Sleepless in Seattle'}, {'year': '1993'}]}, {'movie': [{'title': 'Forrest Gump'}, {'year': '1994'}]}, {'movie': [{'title': 'Toy Story'}, {'year': '1995'}]}, {'movie': [{'title': 'Apollo 13'}, {'year': '1995'}]}, {'movie': [{'title': 'Saving Private Ryan'}, {'year': '1998'}]}, {'movie': [{'title': 'Cast Away'}, {'year': '2000'}]}, {'movie': [{'title': 'Catch Me If You Can'}, {'year': '2002'}]}, {'movie': [{'title': 'The Polar Express'}, {'year': '2004'}]}, {'movie': [{'title': 'Bridge of Spies'}, {'year': '2015'}]}]}

最后,让我们添加一些标签来根据我们的需要定制输出。

parser = XMLOutputParser(tags=["movies", "actor", "film", "name", "genre"])
chain = prompt | model | parser
output = chain.invoke({"query": actor_query})

print(output)
{'movies': [{'actor': [{'name': 'Tom Hanks'}, {'film': [{'name': 'Splash'}, {'genre': 'Comedy'}]}, {'film': [{'name': 'Big'}, {'genre': 'Comedy'}]}, {'film': [{'name': 'A League of Their Own'}, {'genre': 'Comedy'}]}, {'film': [{'name': 'Sleepless in Seattle'}, {'genre': 'Romance'}]}, {'film': [{'name': 'Forrest Gump'}, {'genre': 'Drama'}]}, {'film': [{'name': 'Toy Story'}, {'genre': 'Animation'}]}, {'film': [{'name': 'Apollo 13'}, {'genre': 'Drama'}]}, {'film': [{'name': 'Saving Private Ryan'}, {'genre': 'War'}]}, {'film': [{'name': 'Cast Away'}, {'genre': 'Adventure'}]}, {'film': [{'name': 'The Green Mile'}, {'genre': 'Drama'}]}]}]}
  • 24
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神洛华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值