当前位置: 首页 > news >正文

LangChain 中 Output Parsers 是什么?

在这里插入图片描述

什么是 Output Parsers?

Output Parsers 是 LangChain 中负责将语言模型(LLM)输出的原始、非结构化的文本转换为结构化、可编程的数据格式的组件。

为什么需要它?

LLM 的原始输出是字符串文本。虽然人类可以轻松阅读,但程序很难可靠地从中提取信息。Output Parser 解决了这个问题:

  1. 结构化数据:将文本转换为 Python 对象(如 Pydantic 模型、字典、列表等),方便代码后续处理。
  2. 指令一致性:指导 LLM 按照特定的格式(如 JSON、XML、逗号分隔)生成文本,极大提高了输出的可靠性和一致性。
  3. 验证与重试:如果 LLM 的输出不符合预期格式,一些解析器可以自动触发重试,自我修正错误。
  4. 简化开发:开发者无需编写复杂且脆弱的字符串解析逻辑(如正则表达式)。

Output Parsers 的工作流程

一个典型的包含 Output Parser 的链的工作流程如下:

  1. 指令(Instruction):在给 LLM 的提示(Prompt)中,解析器会自动添加格式说明(例如:“请用以下 JSON 格式回复…”)。
  2. 解析(Parsing):接收 LLM 的原始文本输出,并尝试将其转换为目标结构。
  3. 验证与修正(Validation & Retry):如果解析失败,某些解析器可以将错误和原始输出一起发送给另一个 LLM,让它纠正格式,然后再次尝试解析。

常用的 Output Parsers 及示例

以下是 LangChain 中几种最常用的输出解析器。

在开始之前,假设我们已经设置好了 LLM:

from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo")
1. PydanticOutputParser(最强大、最推荐)

将输出解析成自定义的 Pydantic 模型。这是最结构化的方式,能定义复杂的模式并进行严格的验证。

示例:从一段描述中提取结构化信息

from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from typing import List# 1. 定义你希望输出的数据结构
class Person(BaseModel):name: str = Field(description="人物的姓名")age: int = Field(description="人物的年龄")hobbies: List[str] = Field(description="人物的爱好列表")# 2. 初始化一个为此模型定制的解析器
parser = PydanticOutputParser(pydantic_object=Person)# 3. 创建提示模板,并使用 `get_format_instructions()` 方法自动获取格式说明
prompt = PromptTemplate(template="根据用户输入,提取信息。\n{format_instructions}\n用户输入: {query}\n",input_variables=["query"],partial_variables={"format_instructions": parser.get_format_instructions()}
)# 让我们看看提示模板生成什么,这很重要!
print(parser.get_format_instructions())
# 输出会告诉LLM必须使用怎样的JSON格式,并且包含字段描述。# 4. 组成链并运行
chain = prompt | llm | parser # 使用 LangChain 表达式语法 (LCEL)# 运行链,解析器会自动将字符串输出转换为 Person 对象
result = chain.invoke({"query": "我叫张三,今年30岁了,喜欢读书和爬山。"})
print(result)
# 输出: Person(name='张三', age=30, hobbies=['读书', '爬山'])
print(type(result))
# 输出: <class '__main__.Person'>
print(f"姓名:{result.name}, 年龄:{result.age}")
# 输出: 姓名:张三, 年龄:30
2. StructuredOutputParser(另一种结构化解析器)

PydanticOutputParser 类似,但使用一个字典来定义结构,而不是 Pydantic 模型。

from langchain.output_parsers import StructuredOutputParser, ResponseSchema# 1. 定义响应模式
response_schemas = [ResponseSchema(name="answer", description="对用户问题的回答"),ResponseSchema(name="source", description="回答所依据的来源"),
]# 2. 初始化解析器
parser = StructuredOutputParser.from_response_schemas(response_schemas)# 3. 创建提示模板(同样会自动添加格式指令)
prompt = PromptTemplate(template="回答用户问题。\n{format_instructions}\n问题: {question}",input_variables=["question"],partial_variables={"format_instructions": parser.get_format_instructions()}
)chain = prompt | llm | parser
result = chain.invoke({"question": "LangChain是什么?"})
print(result)
# 输出: {'answer': '...', 'source': '...'} 一个字典
3. CommaSeparatedListOutputParser

将 LLM 的输出解析为一个 Python 列表。适用于需要模型生成列表的场景。

from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplateparser = CommaSeparatedListOutputParser()prompt = PromptTemplate(template="列出一些{subject}。\n{format_instructions}",input_variables=["subject"],partial_variables={"format_instructions": parser.get_format_instructions()}
)chain = prompt | llm | parser
result = chain.invoke({"subject": "水果"})
print(result)
# 输出: ['苹果', '香蕉', '橙子', '草莓', '葡萄']
4. DatetimeOutputParser

将输出解析为 Python 的 datetime 对象

from langchain.output_parsers import DatetimeOutputParser
from langchain.prompts import PromptTemplateparser = DatetimeOutputParser()prompt = PromptTemplate(template="将以下时间描述转换为一个准确的时间点。\n{format_instructions}\n用户输入: {query}",input_variables=["query"],partial_variables={"format_instructions": parser.get_format_instructions()},
)chain = prompt | llm | parser
result = chain.invoke({"query": "2024年新年"})
print(result)
# 输出: 2024-01-01 00:00:00 (一个datetime对象)
5. 处理解析错误:自动重试

OutputFixingParserRetryOutputParser 可以在初始解析失败时,自动调用另一个 LLM 来修复格式错误。

from langchain.output_parsers import OutputFixingParser# 假设我们有一个格式错误的输出
bad_output = "{'name': 'Alice', 'age': 'twenty-five'}" # age应该是数字,不是字符串# 用 OutputFixingParser 包裹原来的解析器
fix_parser = OutputFixingParser.from_llm(parser=parser, llm=llm)# 尝试修复
fixed_result = fix_parser.parse(bad_output)
print(fixed_result)
# 可能会输出: Person(name='Alice', age=25, hobbies=[]) 
# 它成功将 'twenty-five' 转换成了 25

总结

解析器功能输出类型
PydanticOutputParser最强大,解析为自定义的 Pydantic 模型Pydantic Model
StructuredOutputParser解析为结构化的字典Dictionary
CommaSeparatedListOutputParser解析为列表List
DatetimeOutputParser解析为日期时间对象datetime
OutputFixingParser包裹其他解析器,在失败时尝试自动修复与原解析器相同

核心价值:Output Parsers 将 LLM 纳入了软件工程的“管道”中,使其输出不再是难以预测的文本,而是稳定、可靠、类型明确的数据结构。这是构建复杂、生产级 LLM 应用不可或缺的一环。通过将 PromptTemplateLLMOutputParser 链接在一起,你创建了一个强大且健壮的自动化流程。

(注:文档部分内容可能由 AI 生成)


文章转载自:

http://Ep16aSJF.gmmxh.cn
http://nadZ1BUL.gmmxh.cn
http://WzFaFQz5.gmmxh.cn
http://qDfwSXiC.gmmxh.cn
http://7is4AXkW.gmmxh.cn
http://qzHOCPn9.gmmxh.cn
http://JMTtfK6T.gmmxh.cn
http://wp9qNjir.gmmxh.cn
http://IhuBtKAg.gmmxh.cn
http://NxnZKsDj.gmmxh.cn
http://0vmB4xhm.gmmxh.cn
http://SAueh2QZ.gmmxh.cn
http://xeERQYsZ.gmmxh.cn
http://6wdfNgt7.gmmxh.cn
http://d0lSkXv3.gmmxh.cn
http://ZZLjudsR.gmmxh.cn
http://uUNFDdYj.gmmxh.cn
http://trTAOrpA.gmmxh.cn
http://VYvxUXw6.gmmxh.cn
http://RzUJp9lC.gmmxh.cn
http://h3g3bBmV.gmmxh.cn
http://U9LvX3oV.gmmxh.cn
http://mQnWUGGP.gmmxh.cn
http://cqY6tN4n.gmmxh.cn
http://X2A21X6O.gmmxh.cn
http://y8otoEWZ.gmmxh.cn
http://DV4H8CSF.gmmxh.cn
http://0S340LNS.gmmxh.cn
http://j0VTbMyw.gmmxh.cn
http://COSrec11.gmmxh.cn
http://www.dtcms.com/a/382642.html

相关文章:

  • Wolfspeed重组计划已确认
  • 【C++】继承机制深度解析:多继承与菱形继承
  • 如何用Maxscript在选择样条线顶点放置球体?
  • (LeetCode 面试经典 150 题) 190. 颠倒二进制位(位运算)
  • P1043题解
  • 如何用 Rust 重写 SQLite 数据库(二):项目探索
  • SQLI-labs[Part 2]
  • 如何安装 Prometheus 2.20.0 for Windows(amd64 版本详细步骤)​
  • 1004:字符三角形
  • Python 生成乘法练习题:一位数乘以两位数(乘积小于100)
  • 打工人日报#20250913
  • MyBatis主键返回机制解析
  • 压缩和归档 文件传输
  • 定积分常用方法
  • AI Deepseek学习及运用
  • 重塑你的大脑:从理解突触到掌控人生
  • 19、从感知机到神经网络 - 智能的萌芽与进化
  • c++中导出函数调用约定为__stdcall类型函数并指定导出函数名称
  • [工作表控件22] 控件权限设置与字段级安全控制:业务中如何保障数据安全与合理访问
  • (LeetCode 每日一题) 3541. 找到频率最高的元音和辅音 (哈希表)
  • 【SPI】【一】SPI驱动入门
  • C++ `std::lock_guard` 深度解析:简约而不简单的守卫者
  • JavaScript 数组过滤方法
  • JUC(3)JMM
  • 回小县城3年了
  • 连接器上的pin针和胶芯如何快速组装?
  • String、StringBuffer 和 StringBuilder 的区别
  • 测试抽奖系统,设计测试case
  • vue的响应式原理深度解读
  • Python核心技术开发指南(061)——常用魔术方法