Annotated vs TypedDict 区别和使用
·
1️⃣ TypedDict - 定义字典结构
| 特性 | TypedDict | Annotated |
|---|---|---|
| 作用 | 定义字典的结构(有哪些键、值的类型) | 为类型添加元数据描述 |
| 返回值 | 一个类(用于创建字典) | 一个带注释的类型 |
| 运行时校验 | ❌ 无(仅静态检查) | ❌ 无(仅静态检查) |
| 典型用途 | 结构化数据定义 | 字段说明、文档化 |
from typing import TypedDict
class Person(TypedDict):
name: str
age: int
email: str
# 创建符合结构的字典
p = Person(name="张三", age=25, email="zhang@example.com")
print(p) # {'name': '张三', 'age': 25, 'email': 'zhang@example.com'}
# ❌ 类型检查器会警告(但运行时报错)
p2 = Person(name="李四", age="不是数字", email="test@test.com")
作用:告诉类型检查器"这个字典必须有 name/age/email 这三个键,且值类型分别是 str/int/str"
2️⃣ Annotated - 为类型添加说明
from typing import Annotated
# 给 int 类型添加描述
Age = Annotated[int, "年龄,范围0-150"]
Email = Annotated[str, "邮箱地址,必须符合邮箱格式"]
def create_user(age: Age, email: Email):
pass
作用:不改变类型本身,只是附加人类可读的描述信息(供文档、工具使用)
3️⃣ 组合使用(LangChain 常见)
from typing import Annotated, TypedDict
class PersonInfo(TypedDict):
"""人员信息结构"""
name: str # 普通字符串
age: Annotated[int, "年龄,范围0-150"] # ← 带描述的整数
email: Annotated[str, "邮箱地址"] # ← 带描述的字符串
# LangChain 大模型会自动理解这些描述
parser = PydanticOutputParser(pydantic_object=PersonInfo)
效果:
TypedDict 定义结构:必须有 name/age/email
Annotated 提供语义:告诉大模型 age 的含义和约束
实际对比示例:
场景:定义用户数据结构
# ❌ 只用 TypedDict(缺少字段说明)
class User1(TypedDict):
name: str
age: int
phone: str
# ✅ 组合使用(有结构 + 有说明)
class User2(TypedDict):
name: Annotated[str, "用户真实姓名"]
age: Annotated[int, "年龄,范围0-150"]
phone: Annotated[str, "手机号,11位数字"]
对大模型的影响:
User1:模型只知道类型,不知道字段含义
User2:模型能理解每个字段的语义和约束,返回更准确的数据
总结:
| 需求 | 选择 |
|---|---|
| 定义字典有哪些键值对 | TypedDict |
| 为类型添加说明文档 | Annotated |
| 既要结构又要说明 | TypedDict + Annotated ⭐ |
核心记忆:
TypedDict = 骨架(有什么字段)
Annotated = 注释(字段是什么意思)
Annotated 非常像数据库的字段描述(COMMENT)。
类比理解:
数据库表定义:
CREATE TABLE person (
name VARCHAR(50) COMMENT '用户真实姓名', -- ← 字段描述
age INT COMMENT '年龄,范围0-150', -- ← 字段描述
phone VARCHAR(11) COMMENT '手机号,11位数字' -- ← 字段描述
);
from typing import Annotated, TypedDict
class Person(TypedDict):
name: Annotated[str, "用户真实姓名"] # ← 等价于 COMMENT
age: Annotated[int, "年龄,范围0-150"] # ← 等价于 COMMENT
phone: Annotated[str, "手机号,11位数字"] # ← 等价于 COMMENT
| 概念 | 数据库 | Python (Annotated) |
|---|---|---|
| 作用 | COMMENT 说明字段含义 | 字符串描述说明字段含义 |
| 谁来看 | DBA、开发人员阅读 | 大模型、静态分析工具阅读 |
| 影响运行 | ❌ 不影响 SQL 执行 | ❌ 不影响 Python 运行 |
| 典型用途 | 文档化、团队协作 | 指导大模型生成正确数据 |
在 LangChain 中的实际价值:
没有描述(大模型可能乱填):
class Person(TypedDict):
name: str
age: int
⚠️ 模型不知道 age 的含义,可能返回负数或超大值
有描述(大模型更准确):
class Person(TypedDict):
name: Annotated[str, "用户真实姓名,中文"]
age: Annotated[int, "年龄,范围0-150"]
✅ 模型理解约束,返回合规数据
总结:
Annotated = 给大模型看的"数据库字段注释" 📝
数据库用 COMMENT 告诉人字段含义
Annotated 用描述告诉大模型字段含义和约束
两者都是元数据(metadata),不改变数据结构本身,只提供额外说明!
更多推荐




所有评论(0)