🎯 课程主题
@dataclass 是 LangChain 支持的第四种结构化输出格式,通过 Python 标准库的装饰器简化以字段为核心的数据类定义,自动生成 __init__、__repr__、__eq__ 方法。
📝 核心知识点
1. @dataclass 概述
- 概念说明:
@dataclass是 Python 标准库dataclasses中的装饰器,用于简化数据类的定义,自动添加初始化、表示和相等性比较方法。 - 关键细节:
- 自动生成三个魔术方法:
__init__(初始化)、__repr__(输出格式)、__eq__(相等判断) - 被装饰的类仍然是普通 Python 类,但被标记为数据类(data class)
- 数据类携带字段元信息,近似于手写这些方法的普通类,但存在细微区别
- 自动生成三个魔术方法:
2. 与 Pydantic 和 TypedDict 的对比
- 概念说明:四种格式各有定位——Pydantic 输出类类型且强校验,其余三种(TypedDict、JSON Schema、@dataclass)均输出 dict 类型且不做强校验。
- 关键细节:
- Pydantic:输出 类类型(class instance),运行时有强校验
- TypedDict / JSON Schema / @dataclass:输出 dict 类型,运行时不做强校验
- 推荐组合:类类型用 Pydantic,字典类型用 TypedDict
3. 使用方式
- 概念说明:使用
@dataclass修饰一个类,在类中声明字段及其类型,然后通过with_structured_output()绑定到模型。 - 关键细节:
- 需从
dataclasses导入dataclass - 字段声明方式与普通类相同:
field_name: type - 同样支持
Annotated添加字段描述
- 需从
🏗️ 架构与工作流
- 使用
@dataclass装饰器定义数据类 - 通过
model.with_structured_output(Movie)绑定结构 - 调用
invoke()传入自然语言获取结果 - 输出结果为
dict类型
💻 代码实战
from dataclasses import dataclass
from typing import Annotated
@dataclass
class Movie:
"""电影信息"""
title: Annotated[str, "电影名称"]
year: Annotated[int, "上映年份"]
director: Annotated[str, "导演"]
rating: Annotated[float, "评分"]
# 绑定结构到模型
structured_model = model.with_structured_output(Movie)
# 调用
response = structured_model.invoke("给我介绍一下盗梦空间的信息")
print(response) # dict 类型
print(type(response)) # <class 'dict'>
⚠️ 常见问题与避坑指南
- @dataclass 不是首选:虽然语法简洁,但实际推荐用 TypedDict 控制字典类型输出,用 Pydantic 控制类类型输出。
- 输出为 dict 而非 dataclass 实例:与 Pydantic 不同,@dataclass 在 LangChain 结构化输出中得到的仍然是 dict。
- 无运行时校验:@dataclass 与 TypedDict 一样,不做运行时的类型强校验,字段不匹配时不会报错。
💡 个人总结与延伸
@dataclass 在 LangChain 结构化输出中定位略尴尬——它输出 dict 类型却要定义类,不如 TypedDict 语义更直接;想做类实例又不如 Pydantic 有强校验。了解其存在即可,实际项目中优先使用 Pydantic(类类型)和 TypedDict(字典类型)的组合。