LangChain 大模型输出结构化解析指南
简介
在大语言模型(LLM)的应用开发中,无论模型能力多么强大,其输入和输出本质上都是文本格式。虽然纯文本对人类阅读友好,但在需要与程序交互、存入数据库或进行后续逻辑处理时,非结构化的文本往往带来解析困难和稳定性问题。
LangChain 提供了多种输出解析器,用于将大语言模型的文本输出转换为结构化数据。涵盖列表、日期时间、枚举、Pydantic JSON 及结构化输出解析器,并包含错误修复与重试机制。通过示例展示如何配置提示词以获取符合格式的响应,以及自定义解析器以满足特定业务需求,实现稳定的模型交互与数据提取。

在大语言模型(LLM)的应用开发中,无论模型能力多么强大,其输入和输出本质上都是文本格式。虽然纯文本对人类阅读友好,但在需要与程序交互、存入数据库或进行后续逻辑处理时,非结构化的文本往往带来解析困难和稳定性问题。
为了确保应用能够稳定地获取机器可读的数据,LangChain 提供了完善的 Output Parsers 解决方案。这些解析器能够将 LLM 的自然语言回复转换为 Python 对象、JSON 字典、列表或其他特定数据结构,从而简化集成流程。
LangChain 中所有的输出解析器都继承自 BaseOutputParser。这是一个抽象基类,定义了输出解析的核心接口。
class BaseOutputParser(BaseModel, ABC, Generic[T]):
@abstractmethod
def parse(self, text: str) -> T:
"""将 LLM 输出的字符串解析为特定结构。
Args:
text: 语言模型的输出文本
Returns:
结构化后的数据
"""
pass
def parse_with_prompt(self, completion: str, prompt: PromptValue) -> Any:
"""可选方法,结合提示词解析输出。
Args:
completion: LLM 输出
prompt: 原始提示词
Returns:
结构化输出
"""
return self.parse(completion)
def get_format_instructions(self) -> str:
"""返回指导 LLM 如何格式化输出的指令。
"""
raise NotImplementedError
@property
def _type(self) -> str:
"""返回解析器的类型标识,用于序列化。
"""
raise NotImplementedError
CommaSeparatedListOutputParser 是最常用的列表解析器,它将逗号分隔的字符串转换为 Python 列表。
使用示例:
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
template="列出几种{subject}。\n{format_instructions}",
input_variables=["subject"],
partial_variables={"format_instructions": format_instructions + "用中文回答"}
)
_input = prompt.format(subject="水果")
# 假设 model 已初始化
# output = model(_input)
# print(output_parser.parse(output))
注意事项:
默认情况下,get_format_instructions 返回的是英文指令,可能导致模型输出英文。建议在提示词中显式要求使用目标语言。
DatetimeOutputParser 用于将文本转换为 Python 的 datetime 对象。它支持自定义日期格式。
配置示例:
from langchain.output_parsers import DatetimeOutputParser
parser = DatetimeOutputParser()
# 设置格式为 ISO 8601
parser.format = "%Y-%m-%dT%H:%M:%S.%fZ"
instructions = parser.get_format_instructions()
在解析时,如果 LLM 输出的日期格式与预设不符,会抛出 OutputParserException。因此,确保提示词中包含明确的格式示例至关重要。
当业务逻辑需要限定选项范围时,可以使用 EnumOutputParser。它强制 LLM 从预定义的枚举值中选择。
实现逻辑:
from enum import Enum
from langchain.output_parsers import EnumOutputParser
class Color(Enum):
RED = "red"
GREEN = "green"
BLUE = "blue"
parser = EnumOutputParser(enum=Color)
该解析器会自动生成包含有效值的提示词,并在 parse 阶段验证返回值是否在枚举范围内,否则抛出异常。
对于复杂的嵌套数据结构,PydanticOutputParser 是最佳选择。它基于 Pydantic 模型定义 JSON Schema,并自动进行类型校验。
完整示例:
from pydantic import BaseModel, Field
from langchain.output_parsers import PydanticOutputParser
class Student(BaseModel):
name: str = Field(description="学生的姓名")
age: int = Field(description="学生的年龄")
is_active: bool = Field(default=True, description="是否在读")
parser = PydanticOutputParser(pydantic_object=Student)
prompt = PromptTemplate(
template="根据以下信息生成学生数据。\n{format_instructions}\n{query}",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
优势:
如果不需要完整的 Pydantic 模型定义,仅需要简单的键值对结构,可以使用 StructuredOutputParser。它通过 ResponseSchema 定义字段。
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
response_schemas = [
ResponseSchema(name="name", description="姓名"),
ResponseSchema(name="age", description="年龄")
]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
此方式比 Pydantic 更轻量,适合快速原型开发,但缺乏强类型校验能力。
对于遗留系统或特定协议交互,XMLOutputParser 可将输出解析为 XML 格式。用法与 JSON 类似,只需指定根标签和子标签结构。
在实际生产中,LLM 偶尔会忽略格式指令。LangChain 提供了专门的工具来处理此类情况。
当标准解析失败时,OutputFixingParser 会将错误信息反馈给 LLM,请求其修正输出。
from langchain.output_parsers import OutputFixingParser
from langchain.chat_models import ChatOpenAI
new_parser = OutputFixingParser.from_llm(parser=base_parser, llm=ChatOpenAI())
try:
result = new_parser.parse(misformatted_output)
except Exception as e:
# 处理最终无法修复的情况
pass
类似于修复器,但侧重于在解析前重试生成过程,适用于模型频繁违反约束的场景。
当内置解析器无法满足需求时,可以继承 BaseOutputParser 创建自定义解析器。
步骤:
BaseOutputParser。parse 方法,编写具体的解析逻辑(如正则匹配、字符串分割)。get_format_instructions,生成引导提示词。_type 属性。示例:提取特定关键词
import re
from typing import List
from langchain.output_parsers import BaseOutputParser
class KeywordExtractor(BaseOutputParser[List[str]]):
keywords: List[str]
def parse(self, text: str) -> List[str]:
found = []
for kw in self.keywords:
if kw in text:
found.append(kw)
return found
def get_format_instructions(self) -> str:
return f"请确保回复中包含以下关键词之一:{', '.join(self.keywords)}"
@property
def _type(self) -> str:
return "keyword_extractor"
get_format_instructions 基础上,可追加具体约束(如'不要输出多余解释')。temperature=0 可减少随机性,提高格式遵循度。parse 调用,防止因格式错误导致整个 Chain 中断。LangChain 的输出解析器极大地降低了结构化数据处理的门槛。从简单的列表分割到复杂的 Pydantic 模型校验,开发者可以根据业务需求灵活选择。同时,结合错误修复机制和自定义解析能力,能够有效应对生产环境中的不确定性,构建更加稳健的 AI 应用系统。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 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