1.State概述State是langgraph的核心数据结构是一个贯穿整个工作流执行过程的共享数据的结构存储了工作流从开始到结束的所有必要信息历史对话检索到的文档工具执行结果等在节点之间传递并且被持久化保存。State既可以是TypedDict类型也可以是BaseModel类型对比项TypedDictBaseModel来源标准库pydantic定位类型提示轻量字典强类型数据类型含验证逻辑运行时检查无运行时校验自动校验字段类型默认值继承自dictBaseModel性能快稍慢需要解析和验证序列化/反序列化手动处理自动.dict().json()用途场景简单的数据结构定义需要验证解析和约束的模型langgraph支持官方推荐不推荐除非自己控制模型转换定义图的第一件事就是定义图的StateState在各个节点中共享而且每个节点都能进行修改包含两部分模式SchemaState的模式将作为图中所有边和节点的输入模式可以是一个TypedDict或Pydanic模型规约函数Reducer function指明如何把更新应用到状态上所有Node都可对State的更新然后用指定的reducer function函数应用这些更新2.模式SchemaSchema主要使用三种state_schema完整内部状态包含所有的节点可能读写的字段必须指定不能为空input_schema定义state接受什么调用时只允许传入固定的键值对多余的key会被直接过滤可实现参数校验和隔离是state_schema的一个子集可选指定不指定默认等于state_schemaoutput_schema出参规范指定输出结果里面只包含哪些key大量中间和私有的状态属性不会暴露实现输出收紧隐私隔离可选指定不指定默认等于state_schema三者搭配可以实现外部只传必要参数内部自由拓展中间状态外部只拿目标结果。例以往的StateGraph(MsgState)写法默认指定state_schema是MsgStategraph StateGraph(MsgState)现在的graph StateGraph()明确的指定schema多传入的phone: 13099987654被忽略流转到最后只输出resplanggraph建议使用字段覆盖级更新只把更新了的字段返回没有指定合并策略默认会覆盖合并只更新返回的key未返回的key保留原值return {resp: sin(a)}只会覆盖resp对应的值未返回的key保留原值。from typing import TypedDict from langgraph.graph import StateGraph from langgraph.constants import START from langgraph.constants import END class DemoState(TypedDict): user_input: str resp: str count: int process_data: dict phone: str class InputState(TypedDict): user_input: str class OutputState(TypedDict): resp: str def node1(state: DemoState) - dict: print(node1 ) print(state) return {resp: sin(a)} def node2(state: DemoState) - dict: print(node2 ) print(state) return state if __name__ __main__: graph StateGraph( input_schemaInputState, output_schemaOutputState, state_schemaDemoState ) graph.add_node(node1, node1) graph.add_node(node2, node2) graph.add_edge(START, node1) graph.add_edge(node1, node2) graph.add_edge(node2, END) app graph.compile() app.get_graph().print_ascii() print(* * 30) res app.invoke({ user_input: 什么是正弦函数, phone: 13099987654 }) print(res) print(res)----------- | __start__ | ----------- * * * ------- | node1 | ------- * * * ------- | node2 | ------- * * * --------- | __end__ | --------- ****************************** node1 {user_input: 什么是正弦函数} node2 {user_input: 什么是正弦函数, resp: sin(a)} res {resp: sin(a)}3.规约函数Reducer functionReducer是理解节点更新如何应用于State的关键节点更新的方式可能有很多种不仅仅是覆盖还有追加和合并。State中每个键都有自己独立的reducer函数如果未显式指定reducer函数则默认的更新行为是覆盖。例nameage会被新的值覆盖掉from typing import TypedDict from langgraph.constants import START from langgraph.constants import END from langgraph.graph import StateGraph # 状态类 class DemoState(TypedDict): name: str age: int # 节点 def name(state: DemoState) - dict: new_name fqiangqiang, { state[name] } print(new_name) return {name: new_name} # 节点 def age(state: DemoState) - dict: new_age state[age] 10 print(new_age) return {age: new_age} if __name__ __main__: graph StateGraph(DemoState) graph.add_node(name, name) graph.add_node(age, age) graph.add_edge(START, name) graph.add_edge(name, age) graph.add_edge(age, END) app graph.compile() res app.invoke({name:lzj, age:15}) print(res)qiangqiang, lzj 25 {name: qiangqiang, lzj, age: 25}除了默认规约函数外langgraph还提供了几个常见规约函数1.add_messages消息追加专用于和大模型对话声明messages: Annotated[List, add_messages]表明messages是一个消息追加规约变化的状态变量from typing import Annotated, TypedDict, List from langgraph.constants import START, END from langgraph.graph import add_messages, StateGraph class MsgState(TypedDict): messages: Annotated[List, add_messages] messages2: str def node1(state: MsgState): return {messages: 在吗, messages2: 在吗} def node2(state: MsgState): return {messages: 你好啊, messages2: 你好啊} if __name__ __main__: graph StateGraph(MsgState) graph.add_node(node1, node1) graph.add_node(node2, node2) graph.add_edge(START, node1) graph.add_edge(node1, node2) graph.add_edge(node2, END) app graph.compile() res app.invoke({messages: hi, messages2: hi}) print(res[messages]) print(**50) print(res[messages2])[HumanMessage(contenthi, additional_kwargs{}, response_metadata{}, id5e8e65ed-d333-43db-b36b-898c3a996686), HumanMessage(content在吗, additional_kwargs{}, response_metadata{}, id0c8cc7b2-e7fd-4efe-9288-0ed770ba267b), HumanMessage(content你好啊, additional_kwargs{}, response_metadata{}, ida38a474a-361e-4edf-828f-530e58b6991d)] ************************************************** 你好啊2.add追加add可以实现列表追加import operator from typing import Annotated, TypedDict, List from langgraph.constants import START, END from langgraph.graph import add_messages, StateGraph class MsgState(TypedDict): msg: Annotated[List[int], operator.add] def node1(state: MsgState): return {msg: [1, 2]} def node2(state: MsgState): return {msg: [3, 4]} if __name__ __main__: graph StateGraph(MsgState) graph.add_node(node1, node1) graph.add_node(node2, node2) graph.add_edge(START, node1) graph.add_edge(node1, node2) graph.add_edge(node2, END) app graph.compile() res app.invoke({msg: [0]}) print(res[msg])[0, 1, 2, 3, 4]除此之外还能实现字符串拼接和数值累加比较简单原理相同不再赘述字符串拼接msg: Annotated[str, operator.add]数值累加msg: Annotated[int, operator.add]