在语言模型的实际应用中,生成的文本往往需要被解析成程序可用的格式化数据(如 JSON、列表、枚举等)。输出解析器(Output Parser)可以帮助开发者从模型生成的文本中提取结构化信息。
核心方法:
get_format_instructions: 提供格式化指令,用于提示模型生成符合期望的格式。parse: 将模型的生成结果解析为结构化数据。parse_with_prompt: 在给定原始提示的情况下,解析模型的生成输出(高级用法)。
常见解析器类型
以下是 LangChain 提供的一些常用解析器类型:
| 解析器 | 功能 | 应用场景 |
|---|---|---|
| 列表解析器 | 将文本解析为列表 | 适合需要返回多个结果的场景,比如关键词提取。 |
| 日期时间解析器 | 将文本解析为日期或时间格式 | 适用于时间信息提取场景。 |
| 枚举解析器 | 确保生成结果为预定义选项之一 | 用于严格控制模型输出类型的场景。 |
| 结构化输出解析器 | 生成多层次复杂结构的内容 | 适用于 JSON 等复杂格式需求。 |
| Pydantic 输出解析器 | 利用 Pydantic 定义 JSON 数据结构并解析生成结果 | 对格式有严格要求的场景,尤其适合 API 开发。 |
| 自动修复解析器 | 自动修复模型生成的格式错误 | 生成结果有时不规范时,可降低失败率。 |
| 重试解析器 | 当解析失败时重试模型生成输出 | 增强健壮性,降低解析失败对流程的影响。 |
Pydantic 输出解析器实战
1. 定义结构化输出的数据格式
首先利用 Pydantic 定义生成数据的结构。
from pydantic import BaseModel, Field
class FlowerDescription(BaseModel):
flower_type: str = Field(description="鲜花种类")
price: int = Field(description="价格,单位为元")
description: str = Field(description="吸引人的文案描述")
reason: str = Field(description="撰写该文案的理由")
2. 创建模型与输出解析器
定义生成模型和 Pydantic 输出解析器,并生成格式化说明。
from langchain import OpenAI
from langchain.output_parsers import PydanticOutputParser
# 创建 OpenAI 模型实例
model = OpenAI(model_name="gpt-3.5-turbo-instruct")
# 创建输出解析器
output_parser = PydanticOutputParser(pydantic_object=FlowerDescription)
# 获取格式化指令
format_instructions = output_parser.get_format_instructions()
3. 构建提示模板
将格式化指令嵌入提示模板中,让模型清楚按照指定格式输出结果。
from langchain import PromptTemplate
# 定义提示模板
prompt_template = """您是一位鲜花店专业文案撰写员。
请为售价为 {price} 元的 {flower} 撰写一段吸引人的描述。
需要按照以下格式输出:
{format_instructions}
"""
# 将格式化指令嵌入模板
prompt = PromptTemplate.from_template(
prompt_template,
partial_variables={"format_instructions": format_instructions}
)
4. 生成结果并解析
用循环处理多组输入,传递给模型,并使用解析器提取结构化数据。
# 输入数据
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
results = []
for flower, price in zip(flowers, prices):
# 格式化提示
input_prompt = prompt.format(flower=flower, price=price)
# 获取模型输出
output = model(input_prompt)
# 解析模型输出
parsed_output = output_parser.parse(output)
results.append(parsed_output.dict())
print(results)
示例输出:
[ {"flower_type": "玫瑰", "price": 50, "description": "浪漫优雅,传递真挚爱意。", "reason": "玫瑰象征爱情,是情侣之间的最佳选择。"}, {"flower_type": "百合", "price": 30, "description": "纯洁高贵,适合表达祝福。", "reason": "百合代表纯洁和美好,适合送亲友。"}, {"flower_type": "康乃馨", "price": 20, "description": "温馨亲切,传递感激之情。", "reason": "康乃馨象征母爱,适合表达感恩之情。"}]
自动修复解析器
当模型生成结果不完全符合预期格式时,可以使用 自动修复解析器 来修正格式。
1. 创建自动修复解析器
使用 OutputFixingParser 将解析器包裹起来。
from langchain.output_parsers import OutputFixingParser
# 创建自动修复解析器
auto_fixing_parser = OutputFixingParser.from_llm(parser=output_parser, llm=model)
2. 使用修复功能解析输出
即使模型输出格式错误,修复解析器也会尝试调整输出。这里的秘密在于,在OutputFixingParser内部,调用了原有的PydanticOutputParser,如果成功,就返回;如果失败,它会将格式错误的输出以及格式化的指令传递给大模型,并要求LLM进行相关的修复。
# 示例输出不符合格式的情况
invalid_output = "花的类型是玫瑰,价格50元,文案:'浪漫的选择',原因:'玫瑰是爱情的象征'。"
try:
parsed_output = auto_fixing_parser.parse(invalid_output)
print(parsed_output)
except Exception as e:
print("解析失败:", e)
提示模板技巧
- 添加格式说明:在提示中引入
get_format_instructions()返回的内容。 - 明确输出要求:提示语中强调模型必须输出可解析的格式。
- 逐步提示:如果格式复杂,可分步骤让模型生成部分内容。
总结与扩展
-
解析器的价值:有效减少手动处理模型生成结果的时间,特别是在复杂任务中(如 JSON API、数据库存储)。
-
推荐实践:
- 在复杂格式任务中优先考虑 PydanticOutputParser。
- 对不确定格式场景使用 自动修复解析器。
-
扩展应用:
- 多任务场景中,可以为不同任务配置不同的解析器。
- 利用解析器结合 LangChain 其他模块(如 Memory 或 Tools)构建复杂应用。