首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Agent开发:StateGraph vs CompiledGraph

Agent开发:StateGraph vs CompiledGraph

作者头像
码农戏码
发布2026-06-25 20:04:51
发布2026-06-25 20:04:51
1140
举报

Spring AI Alibaba 项目从架构上包含如下三层:

Agent Framework

是一个以 ReactAgent 设计理念为核心的 Agent 开发框架,使开发者能够构建具备自动上下文工程和人机交互等核心能力的Agent。

Graph

graph 是一个低级别的工作流和多代理协调框架,能够帮助开发者实现复杂的应用程序编排,它具备丰富的预置节点和简化的图状态定义,Graph 是 Agent Framework 的底层运行时基座。

Augmented LLM

以 Spring AI 框架底层原子抽象为基础,为构建大型语言模型(LLM)应用提供基础抽象,例如模型(Model)、工具(Tool)、多模态组件(MCP)、消息(Message)、向量存储(Vector Store)等。

1. Graph概述

spring-ai-alibaba-graph-core 是一个基于响应式编程的图执行引擎,用于构建和执行复杂的 AI 工作流。它采用类似 LangGraph 的设计理念,支持节点、边、条件分支、并行执行、中断恢复等特性。


2. StateGraph vs CompiledGraph 深度对比

2.1 核心区别总结

特性

StateGraph

CompiledGraph

职责

图的定义与构建

图的执行与运行

阶段

设计时 (Design-time)

运行时 (Runtime)

可变性

可变 (可添加节点/边)

不可变 (编译后固定)

验证

延迟验证

编译时验证完成

优化

包含预处理优化

执行能力

无执行方法

提供 stream()/invoke()

状态管理

仅定义 KeyStrategy

管理运行时状态

检查点

不支持

支持检查点保存/恢复

2.2 StateGraph 详解 - 图定义器

核心职责: 定义图的结构(节点和边),类似"蓝图"

代码语言:javascript
复制
// StateGraph 的核心属性
public class StateGraph {
    final Nodes nodes = new Nodes();              // 节点集合
    final Edges edges = new Edges();              // 边集合
    private final KeyStrategyFactory keyStrategyFactory;  // 状态更新策略
    private final String name;                    // 图名称
    private final StateSerializer stateSerializer; // 状态序列化器
}

主要方法:

addNode(id, action) - 添加节点•addEdge(sourceId, targetId) - 添加普通边•addConditionalEdges(sourceId, condition, mappings) - 添加条件边•validateGraph() - 验证图结构•compile() - 编译为 CompiledGraph

2.3 CompiledGraph 详解 - 可执行图

核心职责: 执行图的逻辑,类似"可运行的程序"

代码语言:javascript
复制
// CompiledGraph 的核心属性
public class CompiledGraph {
    public final StateGraph stateGraph;           // 原始图定义
    public final CompileConfig compileConfig;     // 编译配置
    final Map<String, Node.ActionFactory> nodeFactories;  // 节点工厂(线程安全)
    final Map<String, EdgeValue> edges;           // 优化后的边
    private final Map<String, KeyStrategy> keyStrategyMap; // 状态策略
    private final ProcessedNodesEdgesAndConfig processedData; // 预处理数据
    private int maxIterations = 25;               // 最大迭代次数
}

主要方法:

stream(inputs, config) - 流式执行(返回 Flux)•invoke(inputs, config) - 同步执行•getState(config) / updateState(config, values) - 状态管理•getStateHistory(config) - 获取历史状态

2.4 为什么需要拆分?设计原因分析

原因 1: 关注点分离 (Separation of Concerns)

代码语言:javascript
复制
┌──────────────────────────────────────────────────────────────────────┐
│                        关注点分离                                     │
├──────────────────────────────────────────────────────────────────────┤
│                                                                       │
│   StateGraph (定义阶段)              CompiledGraph (执行阶段)          │
│   ┌─────────────────────┐           ┌─────────────────────────┐      │
│   │ • 定义节点          │           │ • 执行节点 Action        │      │
│   │ • 定义边关系        │  compile  │ • 管理运行时状态         │      │
│   │ • 配置状态策略      │ ────────► │ • 处理中断/恢复          │      │
│   │ • 验证图结构        │           │ • 检查点管理             │      │
│   │                     │           │ • 流式/同步执行          │      │
│   └─────────────────────┘           └─────────────────────────┘      │
│                                                                       │
└──────────────────────────────────────────────────────────────────────┘

原因 2: 编译时优化

CompiledGraph 在编译时进行多项优化:

代码语言:javascript
复制
// 1. 子图展开 - 将嵌套的 StateGraph 展开为扁平结构
ProcessedNodesEdgesAndConfig.process(stateGraph, compileConfig);

// 2. 并行节点处理 - 将多个并行边合并为 ParallelNode
var parallelNode = new ParallelNode(e.sourceId(), actions, actionNodeIds,
                                    keyStrategyMap, compileConfig);

// 3. 节点工厂预创建 - 使用工厂模式确保线程安全
for (var n : processedData.nodes().elements) {
    nodeFactories.put(n.id(), n.actionFactory());
}

// 4. 边优化 - 将边列表转换为 Map 加速查找
for (var e : processedData.edges().elements) {
    edges.put(e.sourceId(), targets.get(0));
}

原因 3: 不可变性保证

代码语言:javascript
复制
编译前 (StateGraph - 可变):
┌─────────────────────────────────────┐
│  可以随时添加/修改节点和边            │
│  graph.addNode("newNode", action);  │
│  graph.addEdge("A", "B");           │
└─────────────────────────────────────┘
                    │
                    │ compile()
                    ▼
编译后 (CompiledGraph - 不可变):
┌─────────────────────────────────────┐
│  结构固定,无法修改                   │
│  只能执行,保证运行时稳定性           │
│  支持并发执行同一个 CompiledGraph    │
└─────────────────────────────────────┘

原因 4: 验证与错误提前发现

代码语言:javascript
复制
// StateGraph.compile() 中的验证
public CompiledGraph compile(CompileConfig config) {
    Objects.requireNonNull(config, "config cannot be null");

    validateGraph();  // 验证图结构

    return new CompiledGraph(this, config);
}

// validateGraph() 的验证内容
void validateGraph() {
    // 1. 验证所有节点
    for (var node : nodes.elements) {
        node.validate();
    }

    // 2. 验证必须有入口点 (START 边)
    var edgeStart = edges.edgeBySourceId(START)
        .orElseThrow(Errors.missingEntryPoint::exception);

    // 3. 验证所有边的目标节点存在
    for (Edge edge : edges.elements) {
        edge.validate(nodes);
    }
}

原因 5: 复用与效率

代码语言:javascript
复制
场景: 同一个图需要执行多次

❌ 如果不分离:
┌────────────────────────────────────────────────────────┐
│ 每次执行都需要:                                         │
│   • 重新验证图结构                                      │
│   • 重新处理子图                                        │
│   • 重新创建节点工厂                                    │
│   • 重新优化边结构                                      │
└────────────────────────────────────────────────────────┘

✅ 分离后:
┌────────────────────────────────────────────────────────┐
│ StateGraph ──► CompiledGraph (编译一次)                 │
│                      │                                  │
│         ┌────────────┼────────────┐                    │
│         ▼            ▼            ▼                    │
│    执行1次       执行2次       执行N次                  │
│  (复用已优化的结构,无需重复编译)                         │
└────────────────────────────────────────────────────────┘

2.5 类比说明

概念

类比

说明

StateGraph

Java 源代码 (.java)

人类可读、可修改的定义

compile()

javac 编译器

验证、优化、转换

CompiledGraph

字节码 (.class)

机器可执行、不可修改

stream()/invoke()

JVM 执行

运行编译后的代码


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农戏码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Agent Framework
  • Graph
  • Augmented LLM
  • 1. Graph概述
  • 2. StateGraph vs CompiledGraph 深度对比
    • 2.1 核心区别总结
    • 2.2 StateGraph 详解 - 图定义器
    • 2.3 CompiledGraph 详解 - 可执行图
    • 2.4 为什么需要拆分?设计原因分析
    • 原因 1: 关注点分离 (Separation of Concerns)
    • 原因 2: 编译时优化
    • 原因 3: 不可变性保证
    • 原因 4: 验证与错误提前发现
    • 原因 5: 复用与效率
    • 2.5 类比说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档