【Java AI Agent智能存库调拨+BI问答】第二章 Graph核心三要素深度解析
第2章 Graph核心三要素深度解析
章节目标:深入理解 Spring AI Alibaba Graph 的三大核心组件——State、Nodes 和 Edges,掌握它们各自的作用、接口定义以及协作方式,为后续构建智能体工作流打下坚实基础。
2.1 Graph概述
2.1.1 什么是 Spring AI Alibaba Graph
Spring AI Alibaba Graph 是一个用于构建智能体(Agent)工作流的框架,它将智能体的执行流程抽象为图(Graph)结构。在这个图中:
- 节点(Node)代表智能体执行的具体逻辑步骤,例如调用大模型、调用工具、数据处理等。
- 边(Edge)代表节点之间的流转关系,决定了执行流程的分支和顺序。
- 状态(State)是贯穿整个工作流的共享数据结构,记录着每个步骤的中间结果和上下文信息。
通过这种方式,开发者可以用图的方式来建模复杂的智能体行为,将一个大任务拆解为多个小步骤,并通过条件分支实现灵活的决策逻辑。
2.1.2 Graph 的核心设计理念
Spring AI Alibaba Graph 的设计遵循以下理念:
- 状态驱动(State-Driven):整个工作流的执行由
State驱动。每个节点读取当前状态,执行计算后更新状态,状态的变更推动流程向前推进。 - 函数式编程(Functional Programming):节点和边都使用函数式接口定义,代码简洁、易于测试和复用。
- 可组合性(Composability):节点可以自由组合,边可以灵活定义流转规则,支持条件分支和循环。
- 异步执行(Async Execution):所有节点和边默认支持异步操作,适合高并发的智能体场景。
2.2 State详解
2.2.1 OverAllState 的作用
OverAllState 是 Spring AI Alibaba Graph 中用于表示应用程序当前状态的核心数据结构。它扮演着共享状态容器的角色:
- 数据共享:所有节点都可以读取和修改
OverAllState中的数据,实现节点间的信息传递。 - 状态快照:在任何时刻,
OverAllState都代表着工作流的当前快照,包含了执行到当前步骤的所有中间结果。 - 类型安全:
OverAllState通过泛型机制支持自定义状态类型,确保类型安全。
2.2.2 OverAllState 的核心方法
OverAllState 提供了以下关键方法:
// 获取指定 key 的值
<T> T value(String key);
// 设置指定 key 的值
<T> void override(String key, T value);
// 向指定 key 追加值(如果 key 对应的值是列表)
<T> void append(String key, T value);
// 获取所有 key 的集合
Set<String> keySet();
// 获取状态的 Map 表示
Map<String, Object> data();
2.2.3 定义自定义 State
在实际开发中,通常需要定义自己的状态类型来承载业务数据。以下是一个自定义状态的示例:
import com.alibaba.cloud.ai.graph.state.OverAllState;
/**
* 自定义状态类,用于承载智能体工作流中的业务数据
*/
public class MyAgentState extends OverAllState {
// 定义状态中的 key 常量
public static final String KEY_USER_INPUT = "userInput";
public static final String KEY_LLM_RESPONSE = "llmResponse";
public static final String KEY_TOOL_RESULTS = "toolResults";
public static final String KEY_FINAL_ANSWER = "finalAnswer";
public MyAgentState() {
super();
}
public MyAgentState(Map<String, Object> initialData) {
super(initialData);
}
// 便捷方法:获取用户输入
public String getUserInput() {
return value(KEY_USER_INPUT);
}
// 便捷方法:设置 LLM 响应
public void setLlmResponse(String response) {
override(KEY_LLM_RESPONSE, response);
}
// 便捷方法:添加工具调用结果
public void addToolResult(Object result) {
append(KEY_TOOL_RESULTS, result);
}
}
2.2.4 State 的生命周期
在整个 Graph 执行过程中,OverAllState 的生命周期如下:
- 初始化:Graph 启动时,
OverAllState被初始化为空状态或传入初始数据。 - 节点读取:每个节点执行时,从
OverAllState中读取所需的数据。 - 节点更新:节点执行完成后,将计算结果写回到
OverAllState中。 - 状态传递:更新后的
OverAllState被传递给下一个节点或边。 - 最终状态:当 Graph 执行结束时,
OverAllState包含了整个工作流的完整执行结果。
重要提示:
OverAllState是工作流的唯一状态来源,节点之间不直接传递数据,所有数据交换都通过 State 完成。这种设计保证了数据流的清晰和可追溯。
2.3 Nodes详解
2.3.1 AsyncNodeAction 接口
AsyncNodeAction 是定义节点的核心函数式接口,它的作用是编码智能体的逻辑。
import com.alibaba.cloud.ai.graph.node.AsyncNodeAction;
import java.util.concurrent.CompletableFuture;
/**
* 节点函数式接口:接收当前 State,执行计算,返回更新后的 State
*/
@FunctionalInterface
public interface AsyncNodeAction {
/**
* 执行节点逻辑
*
* @param state 当前工作流状态
* @return CompletableFuture<OverAllState> 更新后的状态
*/
CompletableFuture<OverAllState> execute(OverAllState state);
}
2.3.2 创建节点的基本方式
以下展示几种创建节点的典型方式:
方式一:使用 Lambda 表达式
import com.alibaba.cloud.ai.graph.state.OverAllState;
// 创建一个简单的节点:调用大模型生成回复
AsyncNodeAction llmNode = (state) -> {
String userInput = state.value("userInput");
// 调用大模型 API
String response = chatModel.call(userInput);
// 将结果更新到状态中
state.override("llmResponse", response);
return CompletableFuture.completedFuture(state);
};
方式二:使用方法引用
/**
* 工具调用节点
*/
public class ToolNode {
public CompletableFuture<OverAllState> execute(OverAllState state) {
String query = state.value("query");
// 执行工具调用
ToolResult result = toolService.invoke(query);
// 将工具结果追加到状态
state.append("toolResults", result);
return CompletableFuture.completedFuture(state);
}
}
// 注册节点时使用方法引用
AsyncNodeAction toolNode = new ToolNode()::execute;
方式三:使用匿名内部类
AsyncNodeAction processNode = new AsyncNodeAction() {
@Override
public CompletableFuture<OverAllState> execute(OverAllState state) {
// 数据处理逻辑
String rawData = state.value("rawData");
String processedData = processRawData(rawData);
state.override("processedData", processedData);
return CompletableFuture.completedFuture(state);
}
};
2.3.3 AsyncNodeActionWithConfig 接口
当节点需要获取额外的上下文信息时(如超时配置、重试策略、自定义参数等),可以使用 AsyncNodeActionWithConfig 接口:
import com.alibaba.cloud.ai.graph.node.AsyncNodeActionWithConfig;
import com.alibaba.cloud.ai.graph.RunnableConfig;
/**
* 带配置参数的节点函数式接口
*/
@FunctionalInterface
public interface AsyncNodeActionWithConfig {
/**
* 执行节点逻辑,可接收 RunnableConfig 上下文
*
* @param state 当前工作流状态
* @param config 运行配置上下文
* @return CompletableFuture<OverAllState> 更新后的状态
*/
CompletableFuture<OverAllState> execute(OverAllState state, RunnableConfig config);
}
使用示例:
// 创建一个需要读取配置的节点
AsyncNodeActionWithConfig configAwareNode = (state, config) -> {
// 从配置中获取超时设置
long timeout = config.timeout();
// 从配置中获取自定义参数
Map<String, Object> customParams = config.metadata();
String modelName = (String) customParams.get("modelName");
String userInput = state.value("userInput");
// 使用配置参数调用大模型
String response = chatModel.call(userInput, modelName, timeout);
state.override("llmResponse", response);
return CompletableFuture.completedFuture(state);
};
AsyncNodeAction vs AsyncNodeActionWithConfig 对比
| 特性 | AsyncNodeAction | AsyncNodeActionWithConfig |
|---|---|---|
| 参数 | 仅接收 State | 接收 State + RunnableConfig |
| 适用场景 | 简单逻辑,无需外部配置 | 需要动态配置、上下文传递 |
| 灵活性 | 基础 | 更高 |
2.4 Edges详解
2.4.1 AsyncEdgeAction 接口
AsyncEdgeAction 是定义边的核心函数式接口,它的作用是根据当前 State 决定下一步执行哪个节点。
import com.alibaba.cloud.ai.graph.edge.AsyncEdgeAction;
/**
* 边函数式接口:根据当前 State 确定下一个节点
*/
@FunctionalInterface
public interface AsyncEdgeAction {
/**
* 决定下一步执行的节点
*
* @param state 当前工作流状态
* @return CompletableFuture<String> 下一个节点的名称
*/
CompletableFuture<String> route(OverAllState state);
}
2.4.2 固定转换(Fixed Transition)
固定转换是最简单的边,它总是指向同一个目标节点,不涉及条件判断:
import com.alibaba.cloud.ai.graph.CompiledGraph;
import com.alibaba.cloud.ai.graph.StateGraph;
// 创建图并添加固定转换
StateGraph graph = new StateGraph(MyAgentState::new)
// 添加节点
.addNode("nodeA", nodeAAction)
.addNode("nodeB", nodeBAction)
// 添加固定转换:从 nodeA 固定跳转到 nodeB
.addEdge("nodeA", "nodeB");
固定转换适用于顺序执行的场景,即前一个节点执行完后,无条件地进入下一个节点。
2.4.3 条件分支(Conditional Branching)
条件分支是边的重要特性,它允许根据当前状态的值动态决定下一步:
// 创建一个条件分支边
AsyncEdgeAction conditionalEdge = (state) -> {
String llmResponse = state.value("llmResponse");
// 根据 LLM 的响应内容决定下一步
if (llmResponse.contains("需要调用工具")) {
// 路由到工具调用节点
return CompletableFuture.completedFuture("toolNode");
} else if (llmResponse.contains("需要更多信息")) {
// 路由到信息收集节点
return CompletableFuture.completedFuture("infoCollectionNode");
} else {
// 直接返回答案
return CompletableFuture.completedFuture("outputNode");
}
};
// 在图中使用条件分支
StateGraph graph = new StateGraph(MyAgentState::new)
.addNode("llmNode", llmNodeAction)
.addNode("toolNode", toolNodeAction)
.addNode("infoCollectionNode", infoCollectionAction)
.addNode("outputNode", outputNodeAction)
// 条件分支边:从 llmNode 出发,根据条件路由到不同节点
.addConditionalEdge("llmNode", conditionalEdge);
2.4.4 AsyncEdgeActionWithConfig 接口
与节点类似,边也可以使用带配置的版本:
import com.alibaba.cloud.ai.graph.edge.AsyncEdgeActionWithConfig;
/**
* 带配置参数的边函数式接口
*/
@FunctionalInterface
public interface AsyncEdgeActionWithConfig {
/**
* 决定下一步执行的节点,可接收 RunnableConfig 上下文
*
* @param state 当前工作流状态
* @param config 运行配置上下文
* @return CompletableFuture<String> 下一个节点的名称
*/
CompletableFuture<String> route(OverAllState state, RunnableConfig config);
}
使用示例:
// 基于配置的条件分支边
AsyncEdgeActionWithConfig configAwareEdge = (state, config) -> {
Map<String, Object> metadata = config.metadata();
boolean enableToolCall = (Boolean) metadata.getOrDefault("enableToolCall", true);
String llmResponse = state.value("llmResponse");
if (enableToolCall && llmResponse.contains("工具调用")) {
return CompletableFuture.completedFuture("toolNode");
}
return CompletableFuture.completedFuture("outputNode");
};
2.4.5 边的类型总结
| 边的类型 | 说明 | 使用场景 |
|---|---|---|
| 固定转换(Fixed Edge) | 无条件地从一个节点跳转到另一个节点 | 顺序执行流程 |
| 条件分支(Conditional Edge) | 根据 State 的值动态决定下一个节点 | 需要决策的智能体流程 |
| 入口边(Entry Point) | 指定 Graph 的起始节点 | 定义工作流的入口 |
| 结束边(End Edge) | 标记 Graph 的终止节点 | 定义工作流的出口 |
2.5 KeyStrategy 策略
2.5.1 什么是 KeyStrategy
KeyStrategy 是 Spring AI Alibaba Graph 中用于控制状态更新方式的核心机制。它决定了当节点更新 State 中的某个键时,新的值如何与已有的值进行合并。
核心概念:
State中的每个键(Key)都有自己独立的 Strategy 策略。不同键可以使用不同的更新策略,从而实现灵活的状态管理。
2.5.2 默认策略:AppendStrategy
如果没有为某个键显式指定 KeyStrategy,则默认使用 AppendStrategy。这意味着:
- 该键的所有更新都会直接覆盖其原有值。
- 后一次写入会替换前一次的值。
// 默认行为:直接覆盖
state.override("key1", "value1"); // key1 = "value1"
state.override("key1", "value2"); // key1 = "value2"(覆盖了 value1)
2.5.3 常见的 KeyStrategy 类型
| 策略名称 | 行为描述 | 适用场景 |
|---|---|---|
AppendStrategy(默认) |
新值直接覆盖旧值 | 单值状态,如字符串、数字 |
ListAppendStrategy |
将新值追加到列表中 | 需要累积多个结果的场景 |
ReduceStrategy |
使用自定义的 reduce 函数合并新旧值 | 需要对值进行聚合计算 |
2.5.4 显式配置 KeyStrategy
在定义 State 时,可以为不同的键指定不同的策略:
import com.alibaba.cloud.ai.graph.state.strategy.ListAppendStrategy;
import com.alibaba.cloud.ai.graph.state.strategy.ReduceStrategy;
// 创建图时配置 KeyStrategy
StateGraph graph = new StateGraph(
// 定义状态工厂
() -> new MyAgentState(),
// 配置各键的更新策略
Map.of(
// "messages" 键使用列表追加策略
"messages", new ListAppendStrategy<>(),
// "tokenCount" 键使用累加策略
"tokenCount", new ReduceStrategy<>((oldVal, newVal) ->
(Integer) oldVal + (Integer) newVal)
)
);
ListAppendStrategy 示例:
// 使用 ListAppendStrategy 的消息列表
// 每次追加新消息时,消息会被添加到列表末尾,而不是覆盖
// 第一次更新
state.append("messages", new Message("user", "你好"));
// messages = [Message("user", "你好")]
// 第二次更新
state.append("messages", new Message("assistant", "你好!有什么可以帮助你的?"));
// messages = [
// Message("user", "你好"),
// Message("assistant", "你好!有什么可以帮助你的?")
// ]
// 第三次更新
state.append("messages", new Message("user", "我想了解 Graph"));
// messages = [
// Message("user", "你好"),
// Message("assistant", "你好!有什么可以帮助你的?"),
// Message("user", "我想了解 Graph")
// ]
2.5.5 KeyStrategy 的工作流程
节点A执行完成
|
v
节点A返回更新 Map(包含 key -> newValue)
|
v
Graph 根据 key 查找对应的 KeyStrategy
|
v
KeyStrategy 将 newValue 合并到 State 中
|
v
合并后的 State 传递给下一个节点
设计要点:
KeyStrategy的分离设计使得状态更新的行为可以独立配置,不同业务场景可以灵活选择最适合的合并策略,而不需要在节点逻辑中手动处理状态合并。
2.6 各组件之间的关系与协作流程
2.6.1 三要素协作模型
Spring AI Alibaba Graph 的三大核心组件通过以下方式协作:
+------------------+ +------------------+ +------------------+
| State |<----| Nodes | | Edges |
| (OverAllState) | | (AsyncNodeAction)| | (AsyncEdgeAction)|
| | | | | |
| - 数据共享 | | - 执行逻辑 | | - 路由决策 |
| - 状态快照 | | - 读取 State | | - 条件分支 |
| - 中间结果 | | - 更新 State | | - 确定下一节点 |
+------------------+ +------------------+ +------------------+
^ | |
| v v
| +------------------+ +------------------+
| | 节点执行逻辑 | | 判断下一节点 |
| | state -> newState| | -> "nodeName" |
| +------------------+ +------------------+
| |
+------------------------+
State 更新后回传
2.6.2 完整的执行流程
以下是一个完整的 Graph 执行流程示例:
1. 初始化
- 创建空的 OverAllState
- 注入初始数据(用户输入等)
2. 入口节点(Entry Point)
|
v
3. 执行 Node A(如:LLM调用)
- 读取 State 中的 userInput
- 调用大模型 API
- 将 llmResponse 写入 State
|
v
4. 执行 Edge A(条件分支)
- 读取 State 中的 llmResponse
- 判断是否需要工具调用
- 返回下一个节点名称:"toolNode" 或 "outputNode"
|
v
5. 根据 Edge 的决策,执行 Node B 或 Node C
|
v
6. 重复步骤 3-5,直到到达 END 节点
|
v
7. 返回最终的 State 作为执行结果
2.6.3 数据流示意图
// 数据流代码示意
public void executeFlow() {
// Step 1: 初始化 State
OverAllState state = new OverAllState();
state.override("userInput", "查询今天的天气");
// Step 2: 第一个节点读取 State 并更新
// Node: LLM 理解意图
String userInput = state.value("userInput"); // 读取: "查询今天的天气"
String intent = llmService.understand(userInput);
state.override("intent", intent); // 写入: intent = "weather_query"
// Step 3: 边根据 State 做路由决策
// Edge: 判断意图类型
String nextNode = intent.equals("weather_query") ? "weatherTool" : "generalLLM";
// Step 4: 第二个节点继续读取和更新
// Node: 调用天气工具
String city = state.value("userInput"); // 可读取之前的状态
WeatherResult result = weatherService.query(city);
state.override("weatherResult", result); // 写入工具结果
// Step 5: 最终结果
// Node: 生成回复
WeatherResult weather = state.value("weatherResult");
String answer = llmService.generateAnswer(weather);
state.override("finalAnswer", answer);
// 最终 State 包含了所有中间结果
String finalAnswer = state.value("finalAnswer");
}
2.7 完整代码示例
2.7.1 构建一个简单的智能体 Graph
以下是一个完整的智能体工作流示例,包含了状态定义、节点创建、边配置以及图的编译和执行:
package com.example.agent;
import com.alibaba.cloud.ai.graph.CompiledGraph;
import com.alibaba.cloud.ai.graph.StateGraph;
import com.alibaba.cloud.ai.graph.RunnableConfig;
import com.alibaba.cloud.ai.graph.state.OverAllState;
import com.alibaba.cloud.ai.graph.state.strategy.ListAppendStrategy;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* 简单的问答智能体 Graph 示例
*/
public class QaAgentGraph {
// ==================== 1. 定义状态键常量 ====================
public static final String KEY_INPUT = "input";
public static final String KEY_MESSAGES = "messages";
public static final String KEY_REQUIRES_TOOL = "requiresTool";
public static final String KEY_TOOL_RESULT = "toolResult";
public static final String KEY_OUTPUT = "output";
// ==================== 2. 节点定义 ====================
/**
* 输入处理节点:解析用户输入并初始化消息列表
*/
private CompletableFuture<OverAllState> inputNode(OverAllState state) {
String input = state.value(KEY_INPUT);
// 将用户输入添加到消息列表
state.append(KEY_MESSAGES, new Message("user", input));
return CompletableFuture.completedFuture(state);
}
/**
* LLM 推理节点:调用大模型生成回复
*/
private CompletableFuture<OverAllState> llmNode(OverAllState state) {
// 从状态中获取消息历史
List<Message> messages = state.value(KEY_MESSAGES);
// 调用大模型(此处为示例,实际使用 ChatModel)
String response = chatModel.call(messages);
// 判断是否需要工具调用
boolean requiresTool = response.contains("[TOOL_CALL]");
state.override(KEY_REQUIRES_TOOL, requiresTool);
state.override(KEY_LLM_RESPONSE, response);
return CompletableFuture.completedFuture(state);
}
/**
* 工具调用节点:执行外部工具
*/
private CompletableFuture<OverAllState> toolNode(OverAllState state) {
String response = state.value("llmResponse");
// 解析工具调用参数(简化示例)
String toolParams = extractToolParams(response);
// 调用工具
String toolResult = toolService.execute(toolParams);
// 将工具结果写入状态
state.override(KEY_TOOL_RESULT, toolResult);
state.append(KEY_MESSAGES, new Message("tool", toolResult));
return CompletableFuture.completedFuture(state);
}
/**
* 输出节点:生成最终回复
*/
private CompletableFuture<OverAllState> outputNode(OverAllState state) {
String llmResponse = state.value("llmResponse");
// 清理响应中的特殊标记,生成最终输出
String output = cleanResponse(llmResponse);
state.override(KEY_OUTPUT, output);
return CompletableFuture.completedFuture(state);
}
// ==================== 3. 边定义 ====================
/**
* 条件分支边:判断是否需要工具调用
*/
private CompletableFuture<String> routingEdge(OverAllState state) {
Boolean requiresTool = state.value(KEY_REQUIRES_TOOL);
if (Boolean.TRUE.equals(requiresTool)) {
// 需要工具调用,路由到工具节点
return CompletableFuture.completedFuture("toolNode");
}
// 不需要工具调用,直接输出
return CompletableFuture.completedFuture("outputNode");
}
// ==================== 4. 构建和编译 Graph ====================
public CompiledGraph buildGraph() {
StateGraph graph = new StateGraph(
// 状态工厂
OverAllState::new,
// KeyStrategy 配置
Map.of(
// messages 使用列表追加策略,保留完整的对话历史
KEY_MESSAGES, new ListAppendStrategy<>()
)
);
// 添加节点
graph.addNode("inputNode", this::inputNode)
.addNode("llmNode", this::llmNode)
.addNode("toolNode", this::toolNode)
.addNode("outputNode", this::outputNode);
// 设置入口点
graph.setEntryPoint("inputNode");
// 添加固定转换边
graph.addEdge("inputNode", "llmNode");
// 添加条件分支边:从 llmNode 出发,根据条件路由
graph.addConditionalEdge("llmNode", this::routingEdge);
// 工具执行后,再次回到 LLM 节点进行推理
graph.addEdge("toolNode", "llmNode");
// 编译图
return graph.compile();
}
// ==================== 5. 执行 Graph ====================
public String run(String userInput) {
// 编译图
CompiledGraph compiledGraph = buildGraph();
// 创建初始状态
OverAllState initialState = new OverAllState();
initialState.override(KEY_INPUT, userInput);
// 运行图
RunnableConfig config = RunnableConfig.builder()
.timeout(30000) // 30秒超时
.build();
OverAllState finalState = compiledGraph.invoke(initialState, config);
// 获取最终结果
return finalState.value(KEY_OUTPUT);
}
}
2.7.2 使用 RunnableConfig 传递上下文
import com.alibaba.cloud.ai.graph.RunnableConfig;
/**
* RunnableConfig 的使用示例
*/
public class ConfigExample {
public void demonstrateConfig() {
// 创建运行配置
RunnableConfig config = RunnableConfig.builder()
.timeout(60000) // 设置超时时间(毫秒)
.metadata(Map.of( // 设置自定义元数据
"modelName", "gpt-4",
"temperature", 0.7,
"maxTokens", 2000,
"enableRetry", true
))
.build();
// 节点中使用配置
AsyncNodeActionWithConfig configAwareNode = (state, runnableConfig) -> {
// 读取超时配置
long timeout = runnableConfig.timeout();
// 读取自定义参数
Map<String, Object> metadata = runnableConfig.metadata();
String modelName = (String) metadata.get("modelName");
Double temperature = (Double) metadata.get("temperature");
// 根据配置执行逻辑
String input = state.value("input");
String result = chatModel.call(input, modelName, temperature, timeout);
state.override("result", result);
return CompletableFuture.completedFuture(state);
};
// 边中使用配置
AsyncEdgeActionWithConfig configAwareEdge = (state, runnableConfig) -> {
Map<String, Object> metadata = runnableConfig.metadata();
boolean skipTool = (Boolean) metadata.getOrDefault("skipTool", false);
if (skipTool) {
return CompletableFuture.completedFuture("outputNode");
}
Boolean requiresTool = state.value("requiresTool");
return CompletableFuture.completedFuture(
Boolean.TRUE.equals(requiresTool) ? "toolNode" : "outputNode"
);
};
}
}
2.7.3 运行结果示例
public class Main {
public static void main(String[] args) {
QaAgentGraph agent = new QaAgentGraph();
// 场景1:直接问答
String result1 = agent.run("什么是 Spring AI Alibaba Graph?");
System.out.println(result1);
// 输出:Spring AI Alibaba Graph 是一个用于构建智能体工作流的框架...
// 场景2:需要工具调用
String result2 = agent.run("今天北京的天气怎么样?");
System.out.println(result2);
// 执行流程:inputNode -> llmNode -> toolNode -> llmNode -> outputNode
// 输出:今天北京的天气是晴天,气温 25°C...
}
}
2.8 本章小结
本章深入解析了 Spring AI Alibaba Graph 的三大核心要素:
核心知识点回顾
| 组件 | 接口 | 职责 |
|---|---|---|
| State | OverAllState |
共享数据结构,承载工作流的完整状态快照 |
| Nodes | AsyncNodeAction / AsyncNodeActionWithConfig |
执行智能体的业务逻辑,读取和更新 State |
| Edges | AsyncEdgeAction / AsyncEdgeActionWithConfig |
决定流程的流转方向,支持条件分支和固定转换 |
| KeyStrategy | AppendStrategy / ListAppendStrategy / ReduceStrategy |
控制 State 中各键的更新合并策略 |
关键设计原则
- State 是唯一的真相来源:所有节点间的数据交换都通过 State 完成。
- 函数式接口驱动:节点和边使用函数式接口定义,代码简洁且可测试。
- 策略分离:状态更新的策略与业务逻辑分离,通过
KeyStrategy独立配置。 - 全链路异步:所有操作基于
CompletableFuture,支持高并发场景。
下一步学习
在下一章中,我们将学习如何使用 StateGraph 来构建和编译完整的 Graph 工作流,包括如何添加节点和边、设置入口点、以及图的编译和执行流程。
更多推荐


所有评论(0)