状态图 #
本文档引用的文件
- graph/state_graph.go
- graph/schema.go
- graph/messages_graph.go
- examples/state_schema/main.go
- examples/state_schema/README.md
- examples/memory_basic/main.go
- examples/memory_chatbot/main.go
- examples/human_in_the_loop/main.go
- examples/human_in_the_loop/README.md
- examples/time_travel/main.go
- examples/time_travel/README.md
- graph/checkpointing.go
- graph/update_state_test.go
- prebuilt/rag.go
- prebuilt/react_agent.go
目录 #
简介 #
LangGraphGo 的状态图(StateGraph)是一个强大的状态管理系统,相较于基础的消息图(MessageGraph),提供了更丰富的状态管理模式和更灵活的数据处理能力。状态图通过结构化的状态模式、智能的状态合并机制和持久化能力,为复杂的多步骤工作流和人机交互场景提供了坚实的基础。
状态图的核心优势在于:
- 结构化状态管理:通过 StateSchema 定义明确的状态结构和更新规则
- 智能状态合并:支持多种合并策略,满足不同业务场景的需求
- 持久化能力:完整的检查点机制确保状态的可恢复性
- 人机交互支持:内置中断和恢复机制,支持人工干预
- 预构建组件集成:与 RAG、Agent 等预构建组件无缝协作
核心架构 #
StateGraph 的核心架构围绕状态管理和流程控制展开,其设计体现了现代状态机的最佳实践。
classDiagram
class StateGraph {
+map~string,Node~ nodes
+[]Edge edges
+map~string,func~ conditionalEdges
+string entryPoint
+RetryPolicy retryPolicy
+StateMerger stateMerger
+StateSchema Schema
+AddNode(name, fn)
+AddEdge(from, to)
+AddConditionalEdge(from, condition)
+SetEntryPoint(name)
+SetRetryPolicy(policy)
+SetStateMerger(merger)
+SetSchema(schema)
}
class StateSchema {
<<interface>>
+Init() interface
+Update(current, new) (interface, error)
}
class MapSchema {
+map~string,Reducer~ Reducers
+map~string,bool~ EphemeralKeys
+RegisterReducer(key, reducer)
+RegisterChannel(key, reducer, isEphemeral)
+Init() interface
+Update(current, new) (interface, error)
+Cleanup(state) interface
}
class StateRunnable {
+*StateGraph graph
+Invoke(ctx, initialState) (interface, error)
+InvokeWithConfig(ctx, initialState, config) (interface, error)
}
class ListenableStateGraph {
+*StateGraph StateGraph
+*EventEmitter eventEmitter
+AddListener(listener)
}
StateGraph --> StateSchema : "uses"
StateGraph --> StateRunnable : "compiles to"
StateGraph <|-- ListenableStateGraph : "extends"
MapSchema ..|> StateSchema : "implements"
图表来源
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L10-L32)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L12-L19)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L29-L42)
章节来源
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L10-L32)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L12-L19)
状态模式与 Schema 定义 #
状态图的核心在于其状态模式的设计,通过 StateSchema 接口定义了状态的结构和更新行为。这种设计使得状态管理既灵活又类型安全。
StateSchema 接口设计 #
StateSchema 接口定义了状态的基本契约:
classDiagram
class StateSchema {
<<interface>>
+Init() interface
+Update(current, new) (interface, error)
}
class CleaningStateSchema {
<<interface>>
+Cleanup(state) interface
}
class MapSchema {
+map~string,Reducer~ Reducers
+map~string,bool~ EphemeralKeys
+Init() interface
+Update(current, new) (interface, error)
+Cleanup(state) interface
}
StateSchema <|-- CleaningStateSchema : "extends"
MapSchema ..|> StateSchema : "implements"
MapSchema ..|> CleaningStateSchema : "implements"
图表来源
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L12-L19)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L21-L27)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L29-L42)
MapSchema 实现详解 #
MapSchema 是最常用的状态模式实现,它基于键值对结构,支持为每个键注册特定的更新逻辑:
| 特性 | 描述 | 默认行为 |
|---|---|---|
| 键值映射 | 将状态组织为字符串键到任意值的映射 | 支持任意 Go 类型 |
| Reducer 注册 | 为特定键注册自定义更新逻辑 | 可覆盖默认行为 |
| 临时键 | 支持标记某些键为临时,执行后自动清理 | 默认不过滤任何键 |
| 初始化 | 提供空状态的初始化方法 | 返回空 map |
章节来源
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L29-L100)
状态合并器与自定义逻辑 #
状态合并器(StateMerger)提供了比 Schema 更高级的状态合并能力,适用于复杂的状态聚合场景。
自定义状态合并器 #
flowchart TD
A["输入状态列表"] --> B["遍历每个状态"]
B --> C{"是否有自定义合并器?"}
C --> |是| D["调用自定义合并器"]
C --> |否| E["使用 Schema 更新"]
D --> F["合并结果"]
E --> F
F --> G["返回合并后状态"]
图表来源
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L200-L220)
Reducer 函数体系 #
LangGraphGo 提供了完整的 Reducer 函数体系,支持常见的状态更新模式:
| Reducer 类型 | 用途 | 实现特点 |
|---|---|---|
| OverwriteReducer | 覆盖旧值 | 直接替换,不保留历史 |
| AppendReducer | 追加元素 | 支持切片追加和单元素添加 |
| SumReducer | 数值累加 | 适用于计数器和统计场景 |
| 自定义 Reducer | 业务特定逻辑 | 完全可定制的更新规则 |
章节来源
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L140-L186)
- [examples/state_schema/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/state_schema/main.go#L11-L22)
状态清理机制 #
状态清理机制是状态图的重要特性,特别是对于临时数据和中间状态的管理。
清理状态 Schema #
sequenceDiagram
participant SG as StateGraph
participant CS as CleaningStateSchema
participant SC as StateCleaner
SG->>CS : 检查是否为 CleaningStateSchema
CS->>SC : 调用 Cleanup(state)
SC->>SC : 检查临时键集合
SC->>SC : 创建新状态副本
SC->>SC : 过滤临时键
SC-->>SG : 返回清理后状态
图表来源
- [graph/state_graph.go](https://github.com/smallnest/langgraphgo/blob/main/graph/state_graph.go#L277-L280)
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L102-L137)
临时通道(Ephemeral Channels) #
临时通道是一种特殊的状态管理机制,用于处理只在单个执行周期内有效的数据:
| 特性 | 描述 | 应用场景 |
|---|---|---|
| 生命周期 | 仅在当前执行周期内有效 | 中间计算结果、临时标志 |
| 自动清理 | 执行完成后自动移除 | 避免状态污染 |
| 性能优化 | 减少不必要的状态存储 | 提高内存效率 |
| 类型安全 | 编译时检查临时键定义 | 防止运行时错误 |
章节来源
- [graph/schema.go](https://github.com/smallnest/langgraphgo/blob/main/graph/schema.go#L30-L55)
SetSchema 方法详解 #
SetSchema 方法是状态图配置的核心入口,它决定了整个状态管理的行为模式。
Schema 配置流程 #
flowchart TD
A["创建 StateGraph"] --> B["定义初始状态"]
B --> C["创建 MapSchema"]
C --> D["注册 Reducers"]
D --> E["配置临时键"]
E --> F["调用 SetSchema"]
F --> G["编译 StateRunnable"]
G --> H["执行状态图"]
图表来源
- [examples/state_schema/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/state_schema/main.go#L28-L41)
Schema 配置最佳实践 #
| 配置项 | 推荐做法 | 注意事项 |
|---|---|---|
| Reducer 选择 | 根据业务需求选择合适的合并策略 | 避免意外的状态覆盖 |
| 临时键设置 | 明确标识不需要持久化的数据 | 平衡性能和功能需求 |
| 初始化逻辑 | 提供有意义的默认状态 | 确保状态图的健壮性 |
| 类型安全 | 使用强类型状态结构 | 减少运行时错误 |
章节来源
- [examples/state_schema/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/state_schema/main.go#L28-L41)
- [examples/state_schema/README.md](https://github.com/smallnest/langgraphgo/blob/main/examples/state_schema/README.md#L14-L28)
持久化检查点 #
持久化检查点是状态图可靠性的基石,它确保了长时间运行的工作流能够从中断处恢复。
检查点存储架构 #
classDiagram
class CheckpointStore {
<<interface>>
+Save(ctx, checkpoint) error
+Load(ctx, checkpointID) (*Checkpoint, error)
+List(ctx, executionID) ([]*Checkpoint, error)
+Delete(ctx, checkpointID) error
+Clear(ctx, executionID) error
}
class Checkpoint {
+string ID
+string NodeName
+interface State
+map~string,interface~ Metadata
+time.Time Timestamp
+int Version
}
class MemoryCheckpointStore {
+map~string,*Checkpoint~ checkpoints
+sync.RWMutex mutex
+Save(ctx, checkpoint) error
+Load(ctx, checkpointID) (*Checkpoint, error)
+List(ctx, executionID) ([]*Checkpoint, error)
+Delete(ctx, checkpointID) error
+Clear(ctx, executionID) error
}
class SqliteCheckpointStore {
+*sql.DB db
+string tableName
+Save(ctx, checkpoint) error
+Load(ctx, checkpointID) (*Checkpoint, error)
+List(ctx, executionID) ([]*Checkpoint, error)
+Delete(ctx, checkpointID) error
+Clear(ctx, executionID) error
}
CheckpointStore <|.. MemoryCheckpointStore : "implements"
CheckpointStore <|.. SqliteCheckpointStore : "implements"
CheckpointStore --> Checkpoint : "manages"
图表来源
- [graph/checkpointing.go](https://github.com/smallnest/langgraphgo/blob/main/graph/checkpointing.go#L12-L38)
- [graph/checkpointing.go](https://github.com/smallnest/langgraphgo/blob/main/graph/checkpointing.go#L40-L50)
检查点生命周期 #
stateDiagram-v2
[*] --> 初始化
初始化 --> 执行中 : 开始执行
执行中 --> 检查点保存 : 达到检查点
检查点保存 --> 执行中 : 继续执行
执行中 --> 中断 : 发生错误
中断 --> 恢复 : 修复问题
恢复 --> 执行中 : 从检查点继续
执行中 --> 完成 : 正常结束
完成 --> [*]
章节来源
- [graph/checkpointing.go](https://github.com/smallnest/langgraphgo/blob/main/graph/checkpointing.go#L1-L485)
人机交互场景 #
人机交互(Human-in-the-Loop, HITL)是状态图的重要应用场景,它允许人类在自动化流程中进行干预和决策。
中断机制 #
sequenceDiagram
participant App as 应用程序
participant SG as StateGraph
participant Int as 中断处理器
participant Human as 人工干预
App->>SG : 设置 InterruptBefore
SG->>SG : 执行到目标节点前暂停
SG->>Int : 触发中断事件
Int->>Human : 展示当前状态
Human->>Int : 提供修改后的状态
Int->>SG : 恢复执行ResumeFrom
SG->>App : 返回最终结果
图表来源
- [examples/human_in_the_loop/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/human_in_the_loop/main.go#L68-L100)
状态编辑与时间旅行 #
时间旅行功能允许开发者探索不同的执行路径:
| 功能 | 描述 | 应用场景 |
|---|---|---|
| 状态快照 | 保存特定执行点的状态 | 调试和测试 |
| 状态编辑 | 修改暂停时的状态 | 人工校正 |
| 分叉执行 | 从修改后的状态继续 | A/B 测试 |
| 历史追踪 | 记录所有状态变更 | 审计和分析 |
章节来源
- [examples/human_in_the_loop/README.md](https://github.com/smallnest/langgraphgo/blob/main/examples/human_in_the_loop/README.md#L1-L85)
- [examples/time_travel/README.md](https://github.com/smallnest/langgraphgo/blob/main/examples/time_travel/README.md#L1-L55)
预构建组件集成 #
状态图与 LangGraphGo 的预构建组件紧密集成,形成了完整的应用开发框架。
RAG 系统集成 #
classDiagram
class RAGState {
+string Query
+[]Document Documents
+[]Document RetrievedDocuments
+[]DocumentWithScore RankedDocuments
+string Context
+string Answer
+[]string Citations
+map~string,interface~ Metadata
}
class RAGPipeline {
+*RAGConfig config
+*graph.MessageGraph graph
+BuildBasicRAG() error
+BuildAdvancedRAG() error
+BuildConditionalRAG() error
}
class StateGraph {
+StateSchema Schema
+SetSchema(schema)
}
RAGPipeline --> RAGState : "manages"
StateGraph --> RAGState : "integrates"
图表来源
- [prebuilt/rag.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/rag.go#L57-L67)
- [prebuilt/rag.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/rag.go#L107-L123)
React Agent 集成 #
React Agent 展示了状态图在多轮对话和工具调用场景中的应用:
| 组件 | 功能 | 状态管理 |
|---|---|---|
| Agent 节点 | 处理用户查询和工具调用 | 管理消息历史 |
| Tools 节点 | 执行外部工具 | 处理工具响应 |
| 条件路由 | 根据响应决定流向 | 控制执行流程 |
| 状态 Schema | 结构化消息存储 | 使用 AppendReducer |
章节来源
- [prebuilt/react_agent.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/react_agent.go#L18-L182)
- [prebuilt/rag.go](https://github.com/smallnest/langgraphgo/blob/main/prebuilt/rag.go#L1-L200)
最佳实践与示例 #
状态设计原则 #
- 单一职责:每个状态字段应该有明确的职责
- 不可变性:避免直接修改状态,使用更新函数
- 类型安全:使用强类型结构体而非 map
- 向后兼容:设计时考虑状态结构的演进
常见模式 #
flowchart LR
A["简单计数器"] --> B["累加 Reducer"]
C["消息历史"] --> D["追加 Reducer"]
E["配置状态"] --> F["覆盖 Reducer"]
G["临时标志"] --> H["临时键"]
I["复杂对象"] --> J["自定义 Reducer"]
性能优化建议 #
| 优化策略 | 适用场景 | 效果 |
|---|---|---|
| 状态压缩 | 大型消息历史 | 减少存储空间 |
| 增量更新 | 频繁的状态变更 | 提高更新效率 |
| 异步处理 | 耗时的状态操作 | 改善响应性 |
| 缓存机制 | 重复的状态查询 | 减少计算开销 |
章节来源
- [examples/state_schema/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/state_schema/main.go#L1-L105)
- [examples/memory_basic/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/memory_basic/main.go#L1-L266)
- [examples/memory_chatbot/main.go](https://github.com/smallnest/langgraphgo/blob/main/examples/memory_chatbot/main.go#L1-L186)
总结 #
LangGraphGo 的状态图功能代表了现代状态管理系统的发展方向,它通过以下核心特性为复杂应用提供了强大的支撑:
核心优势 #
- 结构化状态管理:通过 StateSchema 提供类型安全的状态定义
- 灵活的合并策略:支持多种 Reducer 和自定义合并逻辑
- 可靠的持久化:完整的检查点机制确保状态的可恢复性
- 强大的人机交互:内置中断和恢复机制支持人工干预
- 生态集成能力:与预构建组件无缝协作
应用场景 #
- 复杂工作流管理:多步骤、条件分支的业务流程
- 人机协作系统:需要人工审核和决策的应用
- 长时任务处理:需要从中断处恢复的长时间运行任务
- 调试和测试:时间旅行功能支持开发和调试
- 多轮对话系统:维护对话历史和上下文状态
发展方向 #
状态图功能将继续朝着更高的性能、更好的易用性和更强的扩展性发展,为构建下一代 AI 应用提供坚实的技术基础。