LangChain 输出解析器:把模型回复变成你要的数据

LangChain 输出解析器:把模型回复变成你要的数据

读完你会什么

上一篇学了 Input(模板拼接)Model(invoke / stream / batch)。大模型返回的是 AIMessage 对象,业务里往往要 字符串、JSON、结构化对象

本文讲 Model I/O 的第三环 ------ Output 输出解析器:它是什么、为什么要用、常用有哪些、各自怎么用。

记忆口诀 :模型吐 AIMessage → 解析器 .invoke() → 得到 str / dict / Pydantic 对象。结构化输出还可直接用 llm.with_structured_output(),跳过 Parser 这一步。

注意先 申请大模型的秘钥和配置环境(与系列前文相同)。


一、总览:输出解析器是什么?为什么要用?

它在 Model I/O 里扮演什么角色?

LangChain 把调大模型拆成三段:

css 复制代码
Input(Prompt 模板)  →  Model(LLM)  →  Output(输出解析器)
     拼问题                 生成回复            转成可用数据

输出解析器(Output Parser) 负责最后一步:把 AIMessage 转成程序方便用的 字符串、字典、强类型对象

python 复制代码
response = llm.invoke(messages)   # AIMessage
text = parser.invoke(response)    # str / dict / Pydantic 对象

解析器 = 模型输出 → 业务数据的适配器。 价值不只是少写一行 .content,而是 统一接口、可替换、可接 chain

常用解析器一览

解析器 / 方式 产出类型 常用度 典型场景
StrOutputParser str ⭐⭐ 必学 聊天、摘要、任何要纯文本
JsonOutputParser dict / list ⭐ 常用 抽信息、对接 API 的 JSON
PydanticOutputParser Pydantic 模型 ⭐ 常用 固定字段 + 类型校验(学习用)
with_structured_output Pydantic 模型 ⭐ 生产推荐 同上,由 API 约束 schema
CommaSeparatedListOutputParser list[str] ✓ 特定 Prompt 要求「逗号分隔列表」
XMLOutputParser XML / 工具 JSON 了解即可 老 Prompt、Agent

学习路径StrOutputParserJsonOutputParserPydanticOutputParser + Fieldwith_structured_output


二、分述:各解析器怎么用?

以下示例均省略环境变量配置。硅基流动可先配置:

python 复制代码
import os
from langchain.chat_models import init_chat_model

os.environ["OPENAI_API_KEY"] = os.getenv("SILICON_KEY")
os.environ["OPENAI_BASE_URL"] = os.getenv("SILICON_BASE_URL")
llm = init_chat_model("openai:deepseek-ai/DeepSeek-V3")

2.1 StrOutputParser --- 拿纯文本(默认首选)

场景 :聊天、问答、写文章------下游只要 字符串

python 复制代码
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你现在是一个小学{subject}老师,尽量用两三句话解释"),
    ("human", "请介绍{question}"),
]).invoke({"subject": "数学", "question": "数独是啥"})

answer = llm.invoke(prompt)
answerFormated = StrOutputParser().invoke(answer)  # 等同于 answer.content
print(answerFormated)

流式

python 复制代码
for chunk in StrOutputParser().transform(llm.stream(prompt)):
    print(chunk, end="")

2.2 JsonOutputParser --- 拿 JSON 字典或数组

场景 :下游要 dictlist,不是字符串。

python 复制代码
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你只输出 JSON 不要 markdown 不要解释。"),
    ("human", "用 JSON 描述城市,字段:name, population。城市:{city}"),
]).invoke({"city": "北京"})

data = JsonOutputParser().invoke(llm.invoke(prompt))
print(data)  # {'name': '北京', 'population': '2189万'}

关键点

  1. Prompt 必须约束 JSON------解析器只负责解析,不能保证模型不乱写。
  2. 自动处理 markdown 代码块 ------包了 ```````json```` 通常仍能解析。
  3. 不做类型校验 ------要强校验用 Pydantic 或 with_structured_output

2.3 PydanticOutputParser --- 强类型结构化

场景 :字段固定、要 类型校验 ------下游要 Pydantic 对象 ,不是裸 dict

标准三步
python 复制代码
from pydantic import BaseModel, Field, RootModel
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import ChatPromptTemplate

# ① 定义 schema
class Animal(BaseModel):
    name: str = Field(description="动物中文名称,不超过8个字", min_length=1, max_length=8)
    emoji: str = Field(description="单个 emoji 表情")
    age: int = Field(default=0, ge=0, le=150, description="年龄,0~150 整数")

class AnimalArray(RootModel[list[Animal]]):
    pass

# ② 先建 parser,注入 format_instructions
parser = PydanticOutputParser(pydantic_object=AnimalArray)
prompt = ChatPromptTemplate.from_messages([
    ("system", "只输出 JSON,不要 markdown。\n{format_instructions}"),
    ("human", "用 JSON 数组描述三个动物"),
]).invoke({"format_instructions": parser.get_format_instructions()})

# ③ 调模型 → 解析
result = parser.invoke(llm.invoke(prompt))
print(result.model_dump())
get_format_instructions() 是什么?

把 Pydantic 模型的 JSON Schema 自动生成 成说明文字,塞进 Prompt 的 {format_instructions}

易错点 :必须先建 parser,再传入 get_format_instructions();顺序反了或传空字典,模型看不到 schema。

解析结果怎么用?
python 复制代码
result.root[0].name       # RootModel:数组在 .root 里
result.model_dump()       # 转 list[dict],方便打印/存库
result.model_dump_json()  # 转 JSON 字符串
Field 常规用法

Field 必须从 pydantic 导入(不是 dataclasses.Field)。做两件事:

  1. 写给模型看 ------ description 进入 format_instructions
  2. 写给程序看 ------ 类型、范围、默认值用于解析后校验
参数 用途 建议
description 字段说明 → 进 Prompt ⭐ 每个字段都写
default / default_factory 缺字段时的默认值 可选字段时用
ge / le / min_length / max_length 解析后硬校验 配合 description 一起写
python 复制代码
name: str = Field(description="动物中文名称,不超过8个字", min_length=1, max_length=8)
age: int = Field(default=0, ge=0, le=150, description="年龄,0~150 整数")

对比 Json:Json 在 Prompt 里手写字段名;Pydantic 把说明写在 Field 里,不用维护两套文案

接 chain
python 复制代码
chain = prompt.partial(format_instructions=parser.get_format_instructions()) | llm | parser
result = chain.invoke({"city": "上海"})  # 按你的 prompt 变量调整

2.4 with_structured_output --- 生产更推荐

场景 :和 Pydantic 一样要结构化输出,但 不想手写 format_instructions

python 复制代码
from pydantic import BaseModel, Field, RootModel

# Animal / AnimalArray 定义同上一节,此处省略

llm_struct = llm.with_structured_output(AnimalArray)
result = llm_struct.invoke("用 JSON 数组描述三个动物,每项含名称、emoji 和年龄")
print(result.model_dump())

PydanticOutputParser 的对比

维度 PydanticOutputParser with_structured_output
原理 模型输出文本 → 后解析 模型/API 按 schema 约束输出
Prompt 必须注入 {format_instructions} 不用
典型写法 parser.invoke(llm.invoke(prompt)) llm_struct.invoke(prompt)
chain `prompt llm
适用 学习 Output 环、兼容弱 API 生产环境优先

硅基等 OpenAI 兼容接口一般可用。若报 tool/schema 错误,试 method="json_mode",或退回 PydanticOutputParser

常见失败
现象 处理
忘了传 format_instructions 检查 Prompt;或改用 with_structured_output
字段缺失 / 类型错误 加强 Field(description=...);降低 temperature
Prompt 手写 JSON 又用了 Pydantic 统一用 {format_instructions} 或改用 with_structured_output
with_structured_output 报 schema 错误 method="json_mode" 或退回 Parser

2.5 CommaSeparatedListOutputParser --- 逗号分隔列表

场景:Prompt 明确要求「用逗号分隔返回多个词」。

python 复制代码
from langchain_core.output_parsers import CommaSeparatedListOutputParser

items = CommaSeparatedListOutputParser().invoke(llm.invoke(messages))
print(items)  # ['苹果', '香蕉', '橙子']

适合标签、关键词;结构复杂时用 Json 或 Pydantic。


三、总结

3.1 选型决策

javascript 复制代码
只要文字?           → StrOutputParser                         ⭐ 默认
要 JSON / dict?     → JsonOutputParser + Prompt 约束
要固定字段 + 校验?  → 学习:PydanticOutputParser + Field
                      生产:with_structured_output              ⭐ 推荐
逗号分隔列表?       → CommaSeparatedListOutputParser
你的目标 用哪个
聊天、日志、纯文本 StrOutputParser
抽实体、对接 API JSON JsonOutputParser
结构化 + 校验(学习) PydanticOutputParser
结构化 + 校验(生产) with_structured_output
标签 / 关键词 CommaSeparatedListOutputParser

3.2 记住这些

python 复制代码
模板 → llm.invoke → parser.invoke        → str / dict / Model
模板 → llm.with_structured_output(...).invoke → Model(跳过 Parser)

新手路径:Str 跑通 → Json → Pydantic + Field → with_structured_output。

相关推荐
Warson_L12 小时前
Python `Annotated` 与 LangGraph Reducer 学习笔记
python
韩师傅12 小时前
海天线算法的前世今生
python·计算机视觉
韩师傅12 小时前
当你的甲方设备过烂,要如何快速出效果?
python·计算机视觉
Warson_L12 小时前
LangGraph的MessageState and HumanMessage
python
韩师傅12 小时前
当你的甲方吐槽天空不够蓝,你应该如何应对
python·计算机视觉
Warson_L13 小时前
python的类&继承
python
Warson_L13 小时前
类型标注/type annotation
python
ThreeS15 小时前
手搓MiniVLA全实战教程-一步一步用pytorch解释原理与思路
人工智能·python
金銀銅鐵17 小时前
[Python] 模 n 乘法的逆元计算器
python·数学·游戏