在这里插入图片描述

1. 概念

输出解析器(Output Parser)的作用是将 LLM 的非结构化文本输出转换为结构化的格式

1.1 为什么需要输出解析器?

大型语言模型(LLM)的输出本质上是非结构化的文本,但在构建应用程序时,我们通常希望得到结构化的、机器可读的数据,比如:

  • JSON 对象
  • Python 字典或列表
  • 一个特定的 Pydantic 模型实例
  • 一个简单的布尔值或字符串枚举

输出解析器的作用就是架起这座桥梁:它们将 LLM 的"模糊的文本对话"变成了"精确的数据 API 调用",是构建可靠、高效 LLM 应用不可或缺的组件。

1.2 与 with_structured_output() 的区别

虽然它们都实现了相同的功能,但:

  • 维度不同

    • 输出解析器是 LangChain 中的一个功能性组件
    • with_structured_output() 是聊天模型的一个方法
  • 用法不同

    • 输出解析器的工作流程可以是链式的,可以将 Prompt、LLM 和 Parser 像管道一样连接起来:chain = prompt | llm | parser
    • with_structured_output(schema) 则不行,只能手动调用,返回一个新的、具备了结构化输出能力的 Runnable

可以根据自己的使用场景选择,如果想使用链式就选择输出解析器。


2. 解析文本输出

对于使用 StrOutputParser 输出解析器输出文本,我们已经使用过多次了。

StrOutputParser 也实现了标准的 Runnable 接口,示例如下:

from langchain_core.output_parsers import StrOutputParser
from langchain_deepseek import ChatDeepSeek
from langchain_core.prompts import PromptTemplate

# 提示词模板
prompt = PromptTemplate(
    input_variables=["question"],
    template="请回答:{question}"
)

# 大模型
llm = ChatDeepSeek(model="deepseek-chat")

# 输出解析器
parser = StrOutputParser()

# 构建链
chain = prompt | llm | parser

# 调用
result = chain.invoke({"question": "什么是LangChain?"})
print(result)  # 输出字符串

3. 解析结构化对象输出

要输出结构化对象,需要用到的输出解析器是 PydanticOutputParser

3.1 PydanticOutputParser 类

class langchain_core.output_parsers.pydantic.PydanticOutputParser

参数

  • pydantic_object:要解析的 pydantic 模型

内置方法

  • invoke():将单个输入转换为输出
  • get_format_instructions() → str重要!!
    • 作用:生成一个指令字符串,这个字符串会被添加到发送给 LLM 的提示(Prompt)的末尾
    • 目的:告诉 LLM 应该以什么样的格式返回它的响应。例如,“请将你的回复封装在 XML 标签中"或"请以 JSON 格式输出,包含 ‘name’ 和 ‘age’ 两个字段”

3.2 使用示例

# pydantic格式的输出解释器的runnable对象
from langchain_core.output_parsers import PydanticOutputParser
from langchain_deepseek import ChatDeepSeek
from pydantic import BaseModel, Field
from langchain_core.prompts import PromptTemplate

# 1. 构造pydantic对象
class Output(BaseModel):
    answer: str = Field(description="回答")
    reason: str = Field(description="回答的理由")

# 2. 构造输出解析器
parser = PydanticOutputParser(pydantic_object=Output)

# 3. 提示词模版 - 关键:必须包含 format_instructions
prompt_template = PromptTemplate(
    input_variables=["input"],
    template="请回答问题:{input}\n\n{format_instructions}",
    # 关键:使用 partial_variables 自动注入格式说明
    partial_variables={"format_instructions": parser.get_format_instructions()}
)

# 4. 大模型
llm = ChatDeepSeek(
    model="deepseek-chat",
    temperature=0.5,
)

# 5. 构建链
chain = prompt_template | llm | parser

# 6. 调用链
result = chain.invoke({"input": "为什么要学习langchain"})
print(result)
print(f"\n回答: {result.answer}")
print(f"理由: {result.reason}")

输出示例

answer='学习LangChain是为了高效构建基于大语言模型(LLM)的应用程序'
reason='LangChain提供了标准化组件,简化了与不同LLM的集成、外部数据源连接等'

3.3 get_format_instructions() 生成的内容

print(parser.get_format_instructions())

输出:

Here is the output schema:
{
  "properties": {
    "answer": {
      "description": "回答",
      "title": "Answer",
      "type": "string"
    },
    "reason": {
      "description": "回答的理由",
      "title": "Reason",
      "type": "string"
    }
  },
  "required": ["answer", "reason"]
}

4. 解析 JSON 输出

要输出 JSON 格式,需要用到的输出解析器是 JsonOutputParser

4.1 JsonOutputParser 类

class langchain_core.output_parsers.json.JsonOutputParser

参数

  • pydantic_object:用于验证的 Pydantic 对象。如果为空,则不执行任何验证

内置方法

  • invoke():将单个输入转换为输出
  • get_format_instructions() → str:重要!!
    • 作用:生成一个指令字符串,这个字符串会被添加到发送给 LLM 的提示(Prompt)的末尾
    • 目的:告诉 LLM 应该以什么样的格式返回它的响应

4.2 使用示例

# json格式的输出解释器的runnable对象
from langchain_core.output_parsers import JsonOutputParser
from langchain_deepseek import ChatDeepSeek
from pydantic import BaseModel, Field
from langchain_core.prompts import PromptTemplate

# 1. 构造pydantic对象,同样是pydantic对象构造json
class Output(BaseModel):
    answer: str = Field(description="回答")
    reason: str = Field(description="回答的理由")

# 2. 构造输出解析器
parser = JsonOutputParser(pydantic_object=Output)  # 转化成json格式

# 3. 提示词模版 - 关键:必须包含 format_instructions
prompt_template = PromptTemplate(
    input_variables=["input"],
    template="请回答问题:{input}\n\n{format_instructions}",
    # 关键:必须包含 format_instructions---按照上面的json格式
    partial_variables={"format_instructions": parser.get_format_instructions()}
)

# 4. 大模型
llm = ChatDeepSeek(
    model="deepseek-chat",
    temperature=0.5,
)

# 5. 构建链
chain = prompt_template | llm | parser

# 6. 调用链
result = chain.invoke({"input": "为什么要学习langchain"})
print(result)

输出示例

{
  'answer': '学习LangChain是为了高效地构建和集成基于大语言模型(LLM)的应用程序。',
  'reason': 'LangChain提供了一套标准化的接口、组件和工具链,能够简化LLM应用的开发流程'
}

4.3 PydanticOutputParser 与 JsonOutputParser 的区别

特性 PydanticOutputParser JsonOutputParser
返回类型 Pydantic 对象实例 Python 字典
类型验证 严格的类型验证 可选验证
使用场景 需要类型安全和数据验证 只需要 JSON 格式
示例 Output(answer="...", reason="...") {"answer": "...", "reason": "..."}

5. 其他类型的解析器

除了上面讲的文本、对象、JSON解析器,其实 LangChain 官方还提供了更多类型的解析器,如:

  • XML 解析器XMLOutputParser
  • Yaml 解析器YamlOutputParser
  • CSV 解析器CommaSeparatedListOutputParser
  • 枚举解析器EnumOutputParser
  • 日期解析器DatetimeOutputParser 等等

更多类型参考官方文档

除此之外,LangChain 还支持我们自定义输出解析器,以将模型输出结构化为自定义格式,详细情况参考这里


6. 完整工作流程

用户输入
  ↓
PromptTemplate (包含 format_instructions)
  ↓
LLM (按照格式说明生成结构化输出)
  ↓
OutputParser (解析为 Python 对象)
  ↓
结构化数据

8. 常见问题

Q1: 为什么 LLM 没有按格式返回?

A: 检查是否在模板中包含了 {format_instructions}

Q2: PydanticOutputParser 和 JsonOutputParser 选哪个?

A: 需要类型验证选 Pydantic,只需要字典选 Json

Q3: 如何自定义输出格式?

A: 可以继承 BaseOutputParser 实现自定义解析器


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐