LangChain 的结构化输出

LangChain 结构化输出核心笔记

1. 结构化输出的作用

结构化输出就是让大模型按照指定格式返回数据,而不是随便输出自然语言。

例如用户问:

我想查一下订单 123456

希望模型返回:

{
  "intent": "query_order",
  "order_id": "123456"
}

这样后端代码可以直接读取字段,并继续执行查询订单、调用工具、判断意图等逻辑。

核心作用:

把大模型的回答变成程序可以直接处理的数据。


2. LangChain 中的基本写法

structured_model = model.with_structured_output(Person)

result = structured_model.invoke("生成一个人的信息")

含义:

model:大模型对象
Person:定义好的输出结构
with_structured_output(Person):让模型按照 Person 的格式输出
structured_model.invoke(...):调用结构化输出模型

with_structured_output() 的作用是:

把普通模型包装成一个“按指定格式输出”的模型。


3. TypedDict

TypedDict 用来描述字典结构。

from typing import TypedDict

class Person(TypedDict):
    name: str
    age: int

表示希望模型返回类似:

{
    "name": "张三",
    "age": 18
}

结果一般按字典方式取值:

result["name"]
result["age"]

特点:

轻量
适合简单结构
主要用于描述字段
运行时校验能力弱

适合场景:

简单结构化输出、快速实验、字段较少的结果。


4. Annotated

Annotated 用来给类型添加额外说明。

from typing import Annotated

age: Annotated[int, "年龄,范围0-150"]

含义:

age 是 int 类型
补充说明:年龄,范围是 0-150

注意:

Annotated 本身不负责校验,只是给类型附加说明信息。

在 LangChain 中,Annotated 的价值主要是让大模型更清楚字段含义。


5. Pydantic

Pydantic 是 Python 的数据校验库。

它不仅能定义数据结构,还能检查数据是否合法。

from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

如果使用 Pydantic,结果一般是对象,取值方式是:

result.name
result.age

特点:

更严格
适合正式项目
可以运行时校验
支持类型检查和类型转换
适合复杂结构化输出

适合场景:

正式项目、复杂结构、需要字段校验、后端要继续处理模型结果。


6. BaseModel

BaseModel 是 Pydantic 的核心父类。

from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

只要类继承了 BaseModel,就具备 Pydantic 的能力:

字段校验
类型检查
类型转换
生成 JSON Schema
配合 LangChain 做结构化输出

简单理解:

BaseModel 让普通类变成一个 Pydantic 数据模型。


7. Field

Field 用来给字段添加规则和说明。

from pydantic import BaseModel, Field

class Person(BaseModel):
    age: int = Field(ge=0, le=150, description="年龄,范围0-150")

含义:

ge=0:大于等于 0
le=150:小于等于 150
description:字段说明

常见用途:

设置默认值
设置字段描述
设置范围约束
设置字符串长度
设置字段校验规则

8. Annotated + Field

Annotated + Field 可以把类型和校验规则封装起来复用。

from typing import Annotated
from pydantic import BaseModel, Field

Age = Annotated[int, Field(ge=0, le=150, description="年龄,范围0-150")]

class Person(BaseModel):
    name: str
    age: Age

这里的 Age 表示:

int 类型
范围 0-150
字段说明:年龄,范围0-150

适合多个地方复用同一种字段规则。


9. TypedDict 和 Pydantic 对比

对比项 TypedDict Pydantic
本质 字典结构说明 数据模型
返回结果 dict 对象
访问方式 result["name"] result.name
校验能力
适合场景 简单结构、快速实验 正式项目、复杂结构
是否适合正式项目 一般 推荐

简单理解:

TypedDict:告诉模型应该输出哪些字段。
Pydantic:告诉模型应该输出哪些字段,并且程序会校验结果是否合法。

10. LangChain 中怎么选择

简单实验可以用 TypedDict

from typing import TypedDict

class IntentResult(TypedDict):
    intent: str
    order_id: str

正式项目更推荐用 Pydantic:

from pydantic import BaseModel, Field

class IntentResult(BaseModel):
    intent: str = Field(description="用户意图")
    order_id: str = Field(description="订单号,没有则为空字符串")

绑定模型:

structured_model = model.with_structured_output(IntentResult)

result = structured_model.invoke("我想查订单 123456")

使用结果:

result.intent
result.order_id

11. 智能客服中的典型用法

from pydantic import BaseModel, Field

class CustomerServiceIntent(BaseModel):
    intent: str = Field(description="用户意图:query_order、query_coupon、query_shop、unknown")
    order_id: str = Field(description="订单号,没有则为空字符串")
    shop_keyword: str = Field(description="商户关键词,没有则为空字符串")
    coupon_keyword: str = Field(description="优惠券关键词,没有则为空字符串")

绑定结构化输出:

structured_model = model.with_structured_output(CustomerServiceIntent)

调用:

result = structured_model.invoke("我想查一下订单 123456")

后端处理:

if result.intent == "query_order":
    query_order(result.order_id)

elif result.intent == "query_shop":
    search_shop(result.shop_keyword)

elif result.intent == "query_coupon":
    search_coupon(result.coupon_keyword)

else:
    answer_directly()

12. 最终总结

LangChain 结构化输出的核心流程:

先定义输出格式
再用 with_structured_output 绑定到模型
最后调用 structured_model 得到结构化结果

几个核心概念:

TypedDict:定义简单字典结构
Annotated:给字段加说明
Pydantic:定义并校验数据结构
BaseModel:Pydantic 模型的父类
Field:给字段加规则和描述
with_structured_output:让大模型按指定结构输出

使用建议:

简单结构:TypedDict
正式项目:Pydantic
需要校验:Pydantic + Field
需要字段说明:Annotated 或 Field(description=...)

LangChain 结构化输出就是用 TypedDictPydantic 定义模型输出格式,再通过 model.with_structured_output(...) 让大模型按这个格式返回。正式项目中一般优先使用 Pydantic。

posted @ 2026-06-29 22:25  柳成荫y  阅读(4)  评论(0)    收藏  举报