🎯 课程主题
TypedDict 是 Python 3.8 引入的类型提示工具,用于定义带有类型声明的字典结构,是 Pydantic 之外的一种轻量级结构化输出方案。
📝 核心知识点
1. TypedDict 概念与定位
- 概念说明:TypedDict 是一种类型提示工具,可以为字典声明字段名及每个字段的类型,但不是运行时强校验器,仅做类型标注。
- 关键细节:
- 适合快速定义简单字典结构、无需 Pydantic 重量级应用的场景
- 普通 dict 没有类型声明,TypedDict 可明确字典包含哪些字段及类型
- 运行时不做强校验,仅提供 IDE 警告级别的类型检查
2. Annotated 元数据注解
- 概念说明:
Annotated用于在类型之外附加额外信息(元数据),类似于 Pydantic 的Field,但能同时表达类型和字段描述。 - 关键细节:
- 语法:
Annotated[类型, "描述信息", ...] - 需要从
typing包导入 - 与 Pydantic 的
Field不同,Annotated 既承载类型也承载元数据
- 语法:
3. 嵌套结构支持
- 概念说明:TypedDict 支持嵌套定义,比如在 Movie 结构中嵌套 Actor 列表。
- 关键细节:
- 嵌套的子结构也需定义为继承
TypedDict的类 - 外层使用
list[Actor]类型标注,需从typing导入List
- 嵌套的子结构也需定义为继承
4. ...(Ellipsis)的语义
- 概念说明:在 LangChain 的 Annotated 中,
...表示当前字段必须存在、不可省略。 - 关键细节:
...是 Python 的 Ellipsis 自变量,相当于占位符- LangChain 框架对其做了定制化处理
- 不同模型供应商对该语义的支持力度不同:OpenRouter 会强制填充(无信息时填 0),Claude 平台可能忽略该约束
🏗️ 架构与工作流
- 定义 TypedDict 结构类(继承
TypedDict),用Annotated标注字段类型与描述 - 通过
model.with_structured_output(MovieDict)将结构绑定到模型 - 调用
invoke()传入自然语言,模型返回符合结构的 dict 类型结果 - 输出结果为
dict类型(而非 Pydantic 的 class 类型)
💻 代码实战
from typing import TypedDict, Annotated, List
# 定义嵌套的 Actor 结构
class Actor(TypedDict):
"""演员信息"""
name: Annotated[str, "演员名字"]
role: Annotated[str, "饰演角色"]
# 定义 Movie 结构
class MovieDict(TypedDict):
"""电影信息"""
title: Annotated[str, "电影名称"]
year: Annotated[int, "电影上映时间(四位数)"]
director: Annotated[str, "电影导演"]
rating: Annotated[float, "电影评分(满分10分,可包含一位小数)"]
actors: Annotated[List[Actor], "演员列表"]
# 绑定结构到模型
structured_model = model.with_structured_output(MovieDict)
# 调用
response = structured_model.invoke("介绍一下星际穿越")
print(response) # dict 类型
print(type(response)) # <class 'dict'>
⚠️ 常见问题与避坑指南
- TypedDict 不是强校验器:运行时不会对字段类型做强制校验,不匹配时仅 IDE 给出警告,不会报错。
...的模型兼容性:不同模型供应商对 Ellipsis(必填)语义的实现不同,Claude 可能忽略,OpenRouter 会强制执行。需要针对目标模型做测试。- 实际开发中 TypedDict 优先于 JSON Schema:对于简单的 dict 结构,推荐使用 TypedDict 而非手动拼接 JSON Schema 字符串。
💡 个人总结与延伸
TypedDict 是 Pydantic 之外最实用的结构化输出方式,适合快速定义简单字典结构。结合 Annotated 可以提供字段描述,帮助大模型更准确地理解输出意图。需要注意的是,TypedDict 仅做类型标注不做运行时校验,实际生产中若需要严格校验,仍推荐 Pydantic。