LangChain 结构化输出详解:彻底告别大模型文本手动解析

前言

日常开发中调用大模型,相信大家都踩过同一个坑:

调用模型返回一大段自由文本,人看着通俗易懂,但程序根本没法直接用。

想要从中提取关键词、数据字段、业务信息,只能手写正则、字符串分割、各种暴力匹配,不仅代码臃肿,还极易因为大模型话术变化直接解析报错。

而 LangChain 为聊天模型提供的结构化输出能力,完美解决了这个痛点。

简单来说:让大模型不再随心所欲说话,严格按照我们定义好的格式返回数据,从自由字符串输出,直接升级为程序可直接使用的结构化对象,开发效率直接拉满。

一、为什么一定要用结构化输出?

在没有结构化输出之前,我们调用聊天模型的代码十分简单:

python 复制代码
from langchain_openai import ChatOpenAI

model = ChatOpenAI(model="gpt-4o-mini")
res = model.invoke("说说苹果公司近期动态")
print(res.content)

最终拿到手的只是一串纯文本字符串。

传统自由文本三大痛点

  • 解析成本极高:想要提取公司名称、股价、发布产品等信息,必须手写大量解析逻辑

  • 稳定性极差:大模型回答语序、措辞稍有改动,解析代码直接失效

  • 无法对接业务:文本无法直接入库、无法直接参与后续业务逻辑判断、无法做字段校验

结构化输出核心思想

提前定义好输出字段、字段类型、字段含义,强制大模型遵循预设规则返回结果,最终直接得到字典、Pydantic 对象等程序原生可识别数据,彻底抛弃手动解析。

二、核心 API:with_structured_output

LangChain 中实现结构化输出最主流、最稳定的方式,就是 with_structured_output() 方法。

整体使用流程

  1. 自定义输出数据结构(Pydantic / TypedDict / JsonSchema)

  2. 调用模型绑定该结构,生成支持结构化输出的可运行实例

  3. 直接调用实例发起对话,自动返回格式化好的数据

方法核心参数详解

python 复制代码
def with_structured_output(
    schema: 输出结构,
    method: 生成策略,
    include_raw: bool = False,
    strict: bool | None = None,
    **kwargs
)

schema

必传参数,支持三种格式:Pydantic 模型、TypedDict、标准 JSON Schema

method

  • json_schema(默认):调用模型原生结构化输出 API,稳定性最强

  • function_calling:基于函数调用能力实现结构化返回

  • json_mode:强制返回 JSON 字符串,需自行在提示词中约束格式

include_raw

  • False 默认:只返回解析完成后的结构化数据,解析失败直接抛异常

  • True:同时返回原始模型消息、解析结果、解析异常,方便调试排错

strict

  • True:强制严格匹配结构,字段、类型缺一不可

  • False:宽松匹配,允许字段缺失

三、三种主流结构化输出实战写法

3.1 首选方案:Pydantic 模型输出(企业开发最常用)

优势:自带数据类型校验、默认值、字段描述、嵌套结构,类型提示完善,代码可读性最强,后端项目首选。

python 复制代码
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from typing import Optional, List

# 1. 定义结构化输出模型
class JokeInfo(BaseModel):
    """笑话结构化数据"""
    setup: str = Field(description="笑话开头引子")
    punchline: str = Field(description="笑话点睛结尾")
    score: Optional[int] = Field(default=None, description="笑话评分 1-10")

# 2. 初始化模型并绑定结构
llm = ChatOpenAI(model="gpt-4o-mini")
struct_llm = llm.with_structured_output(JokeInfo)

# 3. 直接调用
result = struct_llm.invoke("讲一个唱歌相关的笑话")
print(result.setup)
print(result.punchline)
print(result.score)

支持嵌套复杂结构

日常业务中多层级数据也能轻松实现:

python 复制代码
class JokeInfo(BaseModel):
    setup: str
    punchline: str

class JokeList(BaseModel):
    theme: str
    joke_list: List[JokeInfo]

struct_llm = llm.with_structured_output(JokeList)
res = struct_llm.invoke("分别讲唱歌、跳舞两个笑话")

直接拿到列表嵌套对象,业务处理无比顺畅。

3.2 轻量方案:TypedDict 字典结构化输出

适合简单字典场景,仅做类型约束,轻量无依赖,快速定义键名与类型。

python 复制代码
from typing_extensions import TypedDict, Annotated
from langchain_openai import ChatOpenAI

class JokeDict(TypedDict):
    setup: Annotated[str, "笑话开头"]
    punchline: Annotated[str, "笑话结尾"]
    score: Annotated[int | None, "笑话评分"]

llm = ChatOpenAI(model="gpt-4o-mini")
struct_llm = llm.with_structured_output(JokeDict)
res = struct_llm.invoke("讲一个搞笑小笑话")
# 直接返回标准字典
print(res["setup"])

开启 include_raw=True 可调试原始返回内容,排查格式异常问题:

python 复制代码
struct_llm = llm.with_structured_output(JokeDict, include_raw=True)

返回结果包含 raw 原始消息、parsed 解析数据、parsing_error 异常信息

3.3 通用方案:JSON Schema 结构化输出

不依赖任何 Python 实体类,直接编写标准 JSON 规则,跨语言通用,对接第三方系统十分友好。

python 复制代码
from langchain_openai import ChatOpenAI

json_schema = {
    "title": "JokeSchema",
    "type": "object",
    "properties": {
        "setup": {"type": "string", "description": "笑话开头"},
        "punchline": {"type": "string", "description": "笑话结尾"},
        "score": {"type": "integer", "description": "评分"}
    },
    "required": ["setup", "punchline"]
}

llm = ChatOpenAI(model="gpt-4o-mini")
struct_llm = llm.with_structured_output(json_schema)
res = struct_llm.invoke("讲一个职场笑话")

四、灵活适配:联合类型多格式输出

实际业务中,大模型回答可能分为问答回复、数据提取、指令执行多种形式,我们可以使用联合类型统一接收不同结构返回值。

python 复制代码
from typing import Union
from pydantic import BaseModel, Field

class ChatReply(BaseModel):
    content: str = Field(description="日常闲聊回复")

class WeatherData(BaseModel):
    city: str
    weather: str
    temp: str

# 统一聚合输出结构
class FinalResult(BaseModel):
    output: Union[ChatReply, WeatherData]

llm = ChatOpenAI(model="gpt-4o-mini")
struct_llm = llm.with_structured_output(FinalResult)

模型会自动根据用户问题,匹配对应结构返回数据。

五、企业级实用业务场景

场景 1:万能信息提取器

结构化输出最经典用法:从长文本中精准抽取指定字段,无需分词、无需正则。

python 复制代码
from langchain_core.messages import SystemMessage, HumanMessage

class PersonInfo(BaseModel):
    name: str | None = Field(default=None, description="人物姓名")
    hair_color: str | None = Field(default=None, description="发色")
    height: str | None = Field(default=None, description="身高")

llm = ChatOpenAI(model="gpt-4o-mini")
extract_llm = llm.with_structured_output(PersonInfo)

msg = [
    SystemMessage(content="仅提取文本内存在的信息,未知字段返回空"),
    HumanMessage(content="汤姆身高一米七五,有着一头黑色短发")
]
res = extract_llm.invoke(msg)

短短几行代码,完成高精度信息抽取,效率远超传统文本处理方案。

场景 2:结构化输出 + 工具调用搭配使用

很多同学会直接把工具和结构化输出绑定使用,这里划重点:

with_structured_output 不会自动执行工具,仅能让模型生成工具调用指令

正确使用流程:

  1. 模型绑定工具,生成工具调用请求

  2. 代码手动执行对应工具函数

  3. 将工具执行结果拼接进对话上下文

  4. 再通过结构化输出统一整理最终结果

这种写法流程偏繁琐,正式项目中不推荐原生组合,复杂工具 + 结构化输出业务,直接使用 LangGraph Agent 一站式实现,自动完成工具调用、结果汇总、结构化格式化全流程。

六、选型建议与开发总结

  • 后端正式项目:优先使用 Pydantic 结构化输出,类型安全、校验完善、维护成本最低

  • 快速脚本 / 简单项目:使用 TypedDict 轻量化字典结构

  • 跨语言对接 / 第三方交互:使用标准 JSON Schema

  • 需要调试排错:开启 include_raw=True 查看原始返回,快速定位格式错误

  • 复杂智能体、自动化流程:放弃原生组合,直接上手 LangGraph

结尾

结构化输出可以说是 LangChain 从玩具 demo 走向企业生产的核心能力之一。

彻底摆脱 "大模型回答不可控、文本解析难维护" 的历史难题,让大模型输出真正融入程序业务流程,无论是数据提取、智能表单填充、接口参数生成、知识库问答整理,都能做到简洁优雅、稳定可靠。

后续学习 LangChain 智能代理、流式输出、RAG 知识库开发时,结构化输出也会作为基础能力贯穿全程,提前吃透事半功倍。

相关推荐
拉拉拉拉拉拉拉马1 小时前
MCP 是什么?它为什么重要?
人工智能·github
Geoking.1 小时前
【MCP协议】AI 如何_连上_外部世界——Model Context Protocol 原理剖析
人工智能
Ricky05531 小时前
AgriDet:基于农业检测框架的植物叶片病害严重程度分类(印度2023年研究)
人工智能·分类·数据挖掘
AI人工智能+1 小时前
银行回单识别系统通过融合计算机视觉、深度学习和自然语言处理技术,实现了财务凭证的智能化处理
人工智能·深度学习·ocr·银行回单识别
啦啦啦_99991 小时前
案例之 PyTorch模拟线性回归
人工智能·pytorch·线性回归
戴西软件2 小时前
戴西软件入选2026年安徽省制造业数智化转型服务商名单
java·大数据·服务器·前端·人工智能
牧子川2 小时前
014-国产大模型API封装
人工智能·大模型·api 调用
Master_oid3 小时前
机器学习42:线性回归基础篇
人工智能·机器学习·线性回归
anthea_luo3 小时前
机器学习中的视觉与自然语言处理
人工智能