Langgraph State TypedDict 类型和dict类型
目录
状态类型 dict vs TypedDict
builder = StateGraph( xx ) 是 LangGraph 中初始化状态图的代码,其核心作用是 定义一个动态状态(State)的结构。以下是详细解析:
1. 如state_schema 为 dict 的含义
- 状态类型:
dict表示状态(State)是一个 普通的 Python 字典,而非严格类型定义的TypedDict。 - 动态性:状态可以包含任意字段(如
x、y等),无需预定义结构,字段在运行时动态添加。
2. 对比 TypedDict 方案
之前的代码(使用 TypedDict)
class OverallState(TypedDict):
question: str
answer: str
builder = StateGraph(OverallState)
- 严格类型:状态字段需提前声明(如
question、answer)。 - 类型安全:节点函数返回值必须匹配
TypedDict的字段定义,否则会触发类型检查错误。
当前代码(使用 dict)
builder = StateGraph(dict)
- 完全动态:状态可以是任意字典,字段无需提前声明。
- 灵活性:节点函数可以返回任意字段(如
x、y),LangGraph 会自动合并到状态中。
3. 何时选择 dict vs TypedDict
| 场景 | dict |
TypedDict |
|---|---|---|
| 开发阶段 | 快速原型 | 正式项目 |
| 状态复杂度 | 简单(字段少且动态) | 复杂(字段多且固定) |
| 团队协作 | 个人开发 | 多人协作(需明确接口) |
| 错误检查 | 运行时可能报错(如 KeyError) |
编码时类型检查(提前发现问题) |
总结
- 核心作用:
StateGraph(dict)表示状态是一个动态字典,字段无需预定义。 - 优势:灵活快速,适合简单或动态场景。
- 劣势:缺乏类型安全和文档支持,需谨慎处理字段访问。
建议在复杂项目中使用 TypedDict,而在快速验证逻辑时使用 dict。
例子1 : node1 输入的结果通过node2翻译。 使用TypedDict 作为类型
设计要点: 在节点里面操作的变量必须在模式里面定义。
FAQ
1 llm_node 函数,return llm_answer 属于InputState还是OuputState ?
在用户的代码中,InputState被扩展为包含llm_answer,这是一个Optional字段。这意味着在初始输入时,llm_answer可能不存在,但llm_node执行后会添加它。因此,llm_answer实际上是中间状态的一部分,属于OverallState,而不是单纯的InputState或OutputState。
可能用户混淆了TypedDict的继承与实际状态流转。OverallState合并了Input和Output,所以所有可能的字段都应该在其中定义。但用户可能认为InputState和OutputState是独立的,而实际上在状态流转中,所有的中间变量都存储在OverallState里。
from langgraph.graph import StateGraph
from typing_extensions import TypedDict
from langgraph.graph import START, END
from typing_extensions import TypedDict, Optional
# 定义输入的模式
class InputState(TypedDict):
question: str
llm_answer: Optional[str] # 表示 answer 可以是 str 类型,也可以是 None
# 定义输出的模式
class OutputState(TypedDict):
answer: str
# 将 InputState 和 OutputState 这两个 TypedDict 类型合并成一个更全面的字典类型。
class OverallState(InputState, OutputState):
pass
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
import getpass
import os
def create_llm() -> ChatOpenAI:
"""创建并返回配置好的大模型实例"""
return ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY") or "your_api_key_here",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen2.5-math-72b-instruct",
)
def llm_node(state: InputState):
messages = [
("system", "你是一位乐于助人的智能小助理",),
("human", state["question"])
]
llm = create_llm()
response = llm.invoke(messages)
# 自定义变量 llm_answer, 该变量需要在 模式里面定义
return {"llm_answer": response.content}
def action_node(state: InputState):
messages = [
("system", "无论你接收到什么语言的文本,请翻译成英语",),
("human", state["llm_answer"])
]
llm = create_llm()
response = llm.invoke(messages)
return {"answer": response.content}
# 明确指定它的输入和输出数据的结构或模式
builder = StateGraph(OverallState, input=InputState, output=OutputState)
# 添加节点
builder.add_node("llm_node", llm_node)
builder.add_node("action_node", action_node)
# 添加边
builder.add_edge(START, "llm_node")
builder.add_edge("llm_node", "action_node")
builder.add_edge("action_node", END)
# 编译图
graph = builder.compile()
final_answer = graph.invoke({"question":"你好,请你详细的介绍一下你自己"})
print(final_answer["answer"])
例子2 : 使用dict作为state类型
from langgraph.graph import StateGraph
# 构建图
builder = StateGraph(dict)
print("builder.schema",builder.schema)
def addition(state):
print(state)
return {"x": state["x"] + 1}
def subtraction(state):
print(state)
return {"y": state["x"] - 2}
from langgraph.graph import START, END
# 向图中添加两个节点
builder.add_node("addition", addition)
builder.add_node("subtraction", subtraction)
# 构建节点之间的边
builder.add_edge(START, "addition")
builder.add_edge("addition", "subtraction")
builder.add_edge("subtraction", END)
print("builder.edges=",builder.edges)
graph = builder.compile()
# 定义一个初始化的状态
initial_state = {"x":10}
graph.invoke(initial_state)
from IPython.display import Image, display
display(Image(graph.get_graph(xray=True).draw_mermaid_png()))

浙公网安备 33010602011771号