上一篇讲了 prompt——怎么把输入喂给模型。这一篇讲它的对偶问题:怎么把模型的输出,变成程序能消费的东西

模型返回的是一段自由文本(自然语言),但程序几乎从不需要一段「自然语言」——程序要的是结构化数据:一个对象、一个列表、一个有明确字段的东西。prompt 和 parser 就像 Model I/O 的两端:一头把结构变成文本喂进去,一头把文本变回结构吐出来。

问题:模型说人话,程序要数据

举个例子,你让模型抽取一段订单信息:

模型回答:"订单编号是 A123,客户是张三,金额 299 元,已支付。"

这是给人看的。但你的程序要的是:

{"order_id": "A123", "customer": "张三", "amount": 299, "paid": True}

模型吐自由文本,程序要结构化数据

这段「从自然语言到结构」的转换,就是输出解析要干的事。如果手写,你得写正则、切字符串、处理各种「模型这次没按格式来」的边界情况——脆弱、易错、难维护。

两种解析姿势

LangChain 提供两条路解决这个问题,而且强烈推荐第二条。

姿势一:手写解析器(OutputParser)

OutputParser 是最传统的做法:给模型一段 prompt,要求它「按 JSON 格式输出」,然后用解析器去解析这段文本。

parser = JsonOutputParser()
# 模型输出 '{"order_id":"A123",...}' 这种文本
parser.invoke(model_output)  # → dict

问题在于:模型不一定听话。你让它输出 JSON,它可能在前面加一句「好的,这是结果:」,或者在 JSON 后面加一句解释。解析器得处理这些「不纯」的输出。这种方式能跑,但脆弱。

姿势二:结构化输出(推荐)

v1.0 主推的方式是 with_structured_output你给模型一个结构定义(schema),模型直接返回结构化对象,跳过文本解析这一步

from pydantic import BaseModel

class Order(BaseModel):
    order_id: str
    customer: str
    amount: float
    paid: bool

# 模型绑定结构,直接吐 Order 对象
structured_model = model.with_structured_output(Order)
result = structured_model.invoke("订单 A123,张三,299 元已付")
# result 直接是 Order 实例,不是文本

手写解析 vs 结构化输出

为什么这个方式更稳?因为它绕开了「模型吐自由文本」这个不可靠环节。现代模型(GPT-4o、Claude 等)原生支持「约束输出」——给定 schema,它们在生成时就保证输出符合结构。LangChain 的 with_structured_output 就是统一封装了各家模型的这个能力。

维度 手写 OutputParser with_structured_output
可靠性 脆弱,要处理各种格式漂移 稳,模型原生约束输出
写法 prompt 要求格式 + 解析器 给 schema,拿对象
v1.0 地位 保留,但只做兜底 主推

结构定义:Pydantic 或 JSON Schema

with_structured_output 接受两种结构定义方式:

  • Pydantic(Python 生态主流):用类定义字段和类型,最直观
  • JSON Schema:语言无关的结构描述,跨语言场景用

Pydantic 的额外好处是自带校验:你定义 amount: float,模型返回字符串会被 Pydantic 自动转换或报错。等于解析 + 校验一步到位。

和链的配合

输出解析器是 Runnable,所以它能自然进管道:

chain = prompt | model.with_structured_output(Order) | 下游处理

这里有个细节值得注意:model.with_structured_output(Order) 返回的还是一个 Runnable,只是它的输出类型从「文本」变成了「Order 对象」。所以它依然能被管道符串联、能流式(流式的是结构化结果的逐步构造)、能被追踪。

解析器是 Runnable,自然进链

这就是为什么说 prompt 和 parser 是 Model I/O 的两端:它们都是 Runnable,分别处理「输入结构化→文本」和「文本→输出结构化」,夹住中间的模型,构成完整的「结构进、结构出」链路。

收束:让模型吐结构,而不是解析文本

这一篇讲了输出解析:

  • 模型吐自由文本,程序要结构化数据,中间需要转换
  • 传统 OutputParser 靠「要求模型按格式 + 解析文本」,脆弱
  • v1.0 主推 with_structured_output:给 schema,直接拿对象,绕开文本解析
  • 解析器是 Runnable,自然进链

到这里,Model I/O 三件套——prompt、model、parser——都拆完了。下一篇把它们串起来,讲完整的「Model I/O 闭环」:一条链怎么从结构化输入,经过模型,回到结构化输出,以及怎么加上重试、fallback 这些工程能力。


关于十三Tech

我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。我相信 AI 是程序员的最佳搭档。

如果你想跟完这套「图解 LangChain」,欢迎关注公众号 「十三Tech」。全系列 42 篇,会按认识基础、LangGraph 状态机、Agent 与 middleware、RAG 检索、Tools/MCP/记忆、生产化收束这条线更新。

十三Tech公众号二维码