在用LangGraph构建AI应用时,你可能会急于上手写代码,但别忽略一个关键基础:类型注解 (Type Annotations)。LangGraph大量使用类型注解来定义核心元素——状态 (State)。不理解它,就像没看蓝图就盖房子,迟早出问题。

这篇文章将带你快速了解类型注解的本质、在LangGraph中的作用,以及常见的类型注解用法,帮你为后续开发打下扎实基础。

为什么类型注解在LangGraph中重要?

类型注解是Python 3.5+引入的语法,用于标注变量、函数参数或返回值的预期类型。它不强制执行类型,而是通过类型检查工具帮助开发者在编码阶段发现错误。

age: int = 30
def greet(name: str) -> str:
    return f"你好,{name}!"

在LangGraph中,类型注解主要用于定义状态,即工作流中共享的数据结构。传统Python字典虽然灵活,但类型和结构不固定,容易在复杂项目中导致逻辑错误。LangGraph通过类型化字典 (TypedDict),明确状态的键值类型,确保代码的类型安全可读性易维护性

例如,一个简单的状态定义如下:

from typing import TypedDict

class AgentState(TypedDict):
    message: str
    count: int

这表明AgentState包含 message(字符串)和 count(整数),任何不符合类型的操作都会被类型检查工具捕获。

类型注解的核心价值

  1. 类型安全:提前发现类型错误,降低运行时Bug。
  2. 代码清晰:类型标注让变量用途一目了然。
  3. 调试高效:类型信息有助于快速定位问题。

LangGraph中常见的类型注解

以下是LangGraph中常用的类型注解及其应用场景,助你快速上手:

1. TypedDict:定义状态结构

TypedDict 用于声明状态的键值对及其类型,确保数据结构严谨。例如:

from typing import TypedDict, List # 导入 List

class ChatState(TypedDict):
    messages: List[str]
    user_id: int

这定义了一个包含字符串列表 messages 和整数 user_id 的状态。

2. Union:支持多种类型

Union 表示变量可以是多种类型之一,常用于处理多样的消息类型。

from typing import Union

def square(x: Union[int, float]) -> float:
    return x * x

x = 5           # 这是可以的,因为 x 是一个整数
x = 1.234       # 这也是可以的,因为 x 是一个浮点数
# x = "I am a string!" # X 这会失败(在类型检查时),因为它是一个字符串

在LangGraph的状态定义中,Union 也常用于消息列表,例如 List[Union[HumanMessage, AIMessage]],允许列表中包含不同类型的消息对象。

3. Optional:允许空值

Optional 表示变量可以是指定类型或 None,适合可选字段。

from typing import Optional

def nice_message(name: Optional[str]) -> None:
    if name is None:
        print("Hey random person!")
    else:
        print(f"Hi there, {name}!")

# 调用示例
# nice_message("Alice")
# nice_message(None)

在LangGraph的状态定义中,如果某个字段不是必须的,就可以用 Optional

4. Any:通用的“万能”类型

Any 表示任意类型,适合快速原型开发,但会降低类型安全性,建议谨慎使用。

from typing import Any

def print_value(x: Any):
    print(x)

print_value("I pretend to be Batman in the shower sometimes")
# print_value(123)
# print_value([1, 2, 3])

5. Lambda:简洁逻辑处理

lambda 函数用于定义小型匿名函数,常用于条件边或简单逻辑。

square = lambda x: x * x
print(square(10)) # 输出: 100

nums = [1, 2, 3, 4]
squares = list(map(lambda x: x * x, nums))
print(squares) # 输出: [1, 4, 9, 16]

在LangGraph中,lambda 经常用于定义条件边的判断逻辑,例如:
condition = lambda state: state.get("some_key") == "some_value"

实战示例:定义一个对话状态

假设你要构建一个简单的聊天Agent,状态需要记录消息列表和用户ID,可以这样定义:

from typing import Annotated, Sequence, Union, Optional
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
from langgraph.graph import add_messages

class ChatState(TypedDict):
    messages: Annotated[Sequence[Union[HumanMessage, AIMessage]], add_messages]
    user_id: int
    last_action: Optional[str]
  • messages:消息序列,支持人类或AI消息,追加更新。
  • user_id:整数,记录用户标识。
  • last_action:可选字符串,记录最近操作。

这样的定义既清晰又灵活,后续节点可以基于此状态进行处理。

总结

类型注解是LangGraph的“地基”,虽然看似枯燥,却是编写健壮代码的关键。掌握 TypedDictUnionOptionalAnyLambda 的用法,你就能轻松定义状态、构建节点和连接边,为复杂AI应用奠定基础。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐