LangChain 输出解析器使用详解
LangChain 输出解析器用于将语言模型的原始输出转换为结构化数据。本文介绍了 CSV、日期时间、枚举、JSON、Pydantic 等多种解析器的使用方法及结构原理。通过结合提示模板与解析器,可实现模型输出的标准化处理,支持自动修复格式错误及重试机制,提升大模型应用的数据处理能力与稳定性。

LangChain 输出解析器用于将语言模型的原始输出转换为结构化数据。本文介绍了 CSV、日期时间、枚举、JSON、Pydantic 等多种解析器的使用方法及结构原理。通过结合提示模板与解析器,可实现模型输出的标准化处理,支持自动修复格式错误及重试机制,提升大模型应用的数据处理能力与稳定性。

在 LangChain 中,Model I/O 被称为模型的输入与输出,其包含 输入提示 (Format)、调用模型 (Predict)、输出解析 (Parse) 等三部分组成。
在 LangChain 的 Model I/O 中,输出解析器是其组成之一,这里主要记录 输出解析 (Parse) 的使用。
输出解析器负责获取 LLM 的输出并将其转换为更合适的格式。借助 LangChain 的输出解析器重构程序,使模型能够生成结构化回应,并可以直接解析这些回应。
输出解析器是专用于处理和构建语言模型响应的类。一个基本输出解析器类通常需要实现两个核心方法:
get_format_instructions: 返回指导如何格式化语言模型输出的字符串,指导如何构建和组织回答。parse: 接受一个字符串(语言模型输出),将其解析为特定的数据结构或格式。parse_with_prompt: 可选方法,接受一个字符串(语言模型输出)和一个提示(生成输出的提示),将其解析为特定数据结构。OutputParser 输出解析器结构如下:
class OutputParser:
def __init__(self):
pass
def get_format_instructions(self):
# 返回一个字符串,指导如何格式化模型的输出
pass
def parse(self, model_output):
# 解析模型的输出,转换为某种数据结构或格式
pass
def parse_with_prompt(self, model_output, prompt):
# 基于原始提示解析模型的输出,转换为某种数据结构或格式
pass
LangChain 有许多不同类型的输出解析器。
| 名称 | 类名 | 描述 |
|---|---|---|
| CSV 解析器 | CommaSeparatedListOutputParser | 模型的输出以逗号分隔,以列表形式返回输出 |
| 日期时间解析器 | DatetimeOutputParser | 可用于将 LLM 输出解析为日期时间格式 |
| 枚举解析器 | EnumOutputParser | 用于处理预定义的一组值,确保模型的输出在这些预定义值之中 |
| JSON 解析器 | JsonOutputParser | 确保输出符合特定 JSON 对象格式。利用 Pydantic 库,解析器能验证数据并构建复杂数据模型,以确保输出符合预期数据模型 |
| OpenAI 函数中的解析器 | JsonOutputFunctionsParser / PydanticOutputFunctionsParser / JsonKeyOutputFunctionsParser / PydanticAttrOutputFunctionsParser | 使用 OpenAI 函数调用来结构化其输出。只能与支持函数调用的模型一起使用 |
| OpenAI 工具中的解析 | JsonOutputToolsParser / JsonOutputKeyToolsParser / PydanticToolsParser | 从 OpenAI 的函数调用 API 响应中提取工具调用。只能用于支持函数调用的模型 |
| 自动修复解析器 | OutputFixingParser | 输出解析器包装了另一个输出解析器,如果第一个解析器失败,它会调用另一个 LLM 来修复任何错误 |
| Pandas DataFrame 解析器 | PandasDataFrameOutputParser | 允许用户指定任意的 Pandas DataFrame,并查询 LLMs 以获取以格式化字典形式提取数据的数据 |
| Pydantic 解析器 | PydanticOutputParser | 允许指定任意的 Pydantic 模型并查询 LLM 以获得符合该架构的输出 |
| 重试解析器 | RetryWithErrorOutputParser | 在模型的初次输出不符合预期时,尝试修复或重新生成新的输出 |
| 结构化输出解析器 | StructuredOutputParser | 用于处理复杂的、结构化的输出。当应用需要模型生成具有特定结构的复杂回答时,可使用结构化输出解析器来实现 |
| XML 解析器 | XMLOutputParser | 允许以流行的 XML 格式从 LLM 获取结果 |
| YAML 解析器 | YamlOutputParser | 允许指定任意的模式,并查询兼容该模式的 LLMs 输出,使用 YAML 格式化响应 |
import os
os.environ["OPENAI_BASE_URL"] = "https://api.openai.com/v1"
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
使用一个简单的方法来解析逗号分隔值的列表。
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
from langchain.output_parsers import CommaSeparatedListOutputParser
# 初始化语言模型
model = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.0)
# 创建解析器
output_parser = CommaSeparatedListOutputParser()
# 提示模板
template = "Generate a list of 5 {text}.\n\n{format_instructions}"
chat_prompt = PromptTemplate.from_template(template)
chat_prompt = chat_prompt.partial(format_instructions=output_parser.get_format_instructions())
# 将提示和模型合并以进行调用
chain = chat_prompt | model | output_parser
res = chain.invoke({"text": "colors"})
print(res)
输出示例:
['red', 'blue', 'green', 'yellow', 'purple']
用于处理日期和时间相关的输出,确保模型的输出是正确的日期或时间格式。
from langchain.output_parsers import DatetimeOutputParser
from langchain.prompts import PromptTemplate
from langchain_openai import OpenAI
template = """
回答用户的问题:{question}
{format_instructions}
"""
output_parser = DatetimeOutputParser()
prompt = PromptTemplate.from_template(
template,
partial_variables={"format_instructions": output_parser.get_format_instructions()},
)
chain = prompt | OpenAI() | output_parser
output = chain.invoke({"question": "比特币是什么时候成立的?"})
print(output) # 2009-01-03 18:15:05
from langchain.output_parsers.enum import EnumOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from enum import Enum
class Colors(Enum):
RED = "红色"
GREEN = "绿色"
BLUE = "蓝色"
parser = EnumOutputParser(enum=Colors)
prompt = PromptTemplate.from_template(
"""这个人的眼睛是什么颜色的?
> 人物:{person}
指示:{instructions}"""
).partial(instructions=parser.get_format_instructions())
chain = prompt | ChatOpenAI() | parser
res = chain.invoke({"person": "Frank Sinatra"})
print(res)
有以下几种输出解析器:
JsonOutputFunctionsParser: 以 JSON 形式返回函数调用的参数PydanticOutputFunctionsParser: 将函数调用的参数作为 Pydantic 模型返回JsonKeyOutputFunctionsParser: 以 JSON 形式返回函数调用中特定键的值PydanticAttrOutputFunctionsParser: 以 Pydantic 模型的形式返回函数调用中特定键的值from langchain_core.utils.function_calling import convert_pydantic_to_openai_function
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langchain_openai import ChatOpenAI
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
class Joke(BaseModel):
setup: str = Field(description="设置笑话的问题")
punchline: str = Field(description="解决笑话的答案")
openai_functions = [convert_pydantic_to_openai_function(Joke)]
model = ChatOpenAI(temperature=0)
prompt = ChatPromptTemplate.from_messages(
[("system", "你是一个乐于助人的助手"), ("user", "{input}")]
)
parser = JsonOutputFunctionsParser()
chain = prompt | model.bind(functions=openai_functions) | parser
res = chain.invoke({"input": "给我讲个笑话"})
print(res)
输出示例:
{'setup': '为什么鱼不喜欢唱歌?', 'punchline': '因为它们会唱歌会泡沫!'}
Pydantic 是一个 Python 库,它旨在简化数据验证和解析的过程。它提供了一种简单而强大的方式来定义数据模型,并使用这些模型来验证数据的有效性并进行解析。Pydantic 通过在数据类中定义属性的类型和验证规则,使得数据模型的创建和验证变得非常容易。
from langchain_openai import OpenAI
from pydantic import BaseModel, Field
from langchain.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
model = OpenAI(model_name='gpt-3.5-turbo-instruct')
class TextInfo(BaseModel):
text: str = Field(description="文本信息")
object: str = Field(description="对象是谁")
description: str = Field(description="人物描述")
output_parser = PydanticOutputParser(pydantic_object=TextInfo)
format_instructions = output_parser.get_format_instructions()
prompt_template = """您是一位专业的文案写手。对于信息 {text} 进行简短生动描述 {format_instructions}"""
prompt = PromptTemplate.from_template(prompt_template, partial_variables={"format_instructions": format_instructions})
input_text = prompt.format(text='猪八戒吃人参果')
output = model.invoke(input_text)
parsed_output = output_parser.parse(output)
parsed_output_dict = parsed_output.dict()
print("输出的数据:", parsed_output_dict)
当模型输出格式不正确时,可以使用 OutputFixingParser 来尝试修复错误。它包装了另一个输出解析器,如果第一个解析器失败,它会调用另一个 LLM 来修复任何错误。
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langchain_openai import OpenAI
class Joke(BaseModel):
setup: str = Field(description="用于建立笑话的问题部分")
punchline: str = Field(description="回答笑话的部分")
@validator("setup")
def question_ends_with_question_mark(cls, field):
if field[-1] != "?":
raise ValueError("问题格式不正确!")
return field
parser = PydanticOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="回答用户的查询。\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
model = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.0)
prompt_and_model = prompt | model
output = prompt_and_model.invoke({"query": "给我讲个笑话."})
print(output)
setup, punchline = parser.invoke(output)
print(f"问题:{setup} 回答:{punchline}")
有时候可以通过查看输出修复解析错误,但并非所有情况下都适用。LangChain 的重试解析器利用大型模型的推理能力,根据原始提示来找回相关信息,帮助解析数据。
from pydantic import BaseModel, Field
from langchain.output_parsers import PydanticOutputParser, OutputFixingParser, RetryWithErrorOutputParser
from langchain_openai import ChatOpenAI, OpenAI
from langchain.prompts import PromptTemplate
class Action(BaseModel):
action: str = Field(description="要采取的操作")
action_input: str = Field(description="操作的输入")
parser = PydanticOutputParser(pydantic_object=Action)
prompt = PromptTemplate(
template="回答用户查询.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
prompt_value = prompt.format_prompt(query="猪八戒是谁?")
bad_response = '{"action": "search"}'
fix_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
parse_result = fix_parser.parse(bad_response)
print('OutputFixingParser 的 parse 结果:', parse_result)
retry_parser = RetryWithErrorOutputParser.from_llm(
parser=parser, llm=OpenAI(temperature=0)
)
parse_result = retry_parser.parse_with_prompt(bad_response, prompt_value)
print('RetryWithErrorOutputParser 的 parse 结果:', parse_result)
用于处理复杂的、结构化的输出。当应用需要模型生成具有特定结构的复杂回答时,可使用结构化输出解析器来实现。
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
template = "您是一位专业的文案写手。\n对于信息 {text} 进行简短描述.{format_instructions}"
model = OpenAI()
response_schemas = [
ResponseSchema(name="info", description="信息"),
ResponseSchema(name="description", description="扩展描述")
]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate.from_template(template, partial_variables={"format_instructions": format_instructions})
inputData = prompt.format(text="猪八戒吃人参果")
output = model.invoke(inputData)
parsed_output = output_parser.parse(output)
print(parsed_output)
LangChain 的输出解析器是构建可靠大模型应用的关键组件。通过选择合适的解析器,开发者可以将非结构化的文本输出转化为程序可直接使用的结构化数据(如 JSON、Pydantic 模型、列表等)。在实际开发中,建议优先使用 Pydantic 或 JSON 解析器以确保数据一致性,并结合 OutputFixingParser 或 RetryWithErrorOutputParser 增强系统的容错能力。此外,理解不同解析器的底层机制有助于在遇到复杂场景时进行自定义扩展,从而提升整体应用的稳定性和用户体验。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online