核心库:概念指南
图(Graphs)
Spring AI Alibaba Graph 将智能体工作流建模为图。您可以使用三个关键组件来定义智能体的行为:
-
State:共享的数据结构,表示应用程序的当前快照。它由
OverAllState对象表示。 -
Nodes:一个函数式接口 (
AsyncNodeAction),编码智能体的逻辑。它们接收当前 的State作为输入,执行一些计算或副作用,并返回更新后的State。 -
Edges:一个函数式接口 (
AsyncEdgeAction),根据当前的State确定接下来执行哪个Node。它们可以是条件分支或固定转换。
通过组合 Nodes 和 Edges,您可以创建复杂的循环工作流,随时间演化 State。真正的力量来自于 Spring AI Alibaba 如何管理 State。
需要强调的是:Nodes 和 Edges 就像函数一样 - 它们可以包含 LLM 调用或只是 Java 代码。
简而言之:节点完成工作,边决定下一步做什么。
StateGraph
StateGraph 类是使用的主要图类。它通过用户定义的状态策略进行参数化。
编译图
要构建您的图,首先定义 state,然后添加 nodes 和 edges,最后编译它。编译图是什么意思?为什么需要编译?
编译是一个非常简单的步骤。它提供了对图结构的一些基本检查(没有孤立节点等)。这也是您可以指定运行时参数(如检查点器和中断点)的地方。您只需调用 .compile() 方法来编译图:
import com.alibaba.cloud.ai.graph.StateGraph;
import com.alibaba.cloud.ai.graph.CompiledGraph;
// 编译您的图
CompiledGraph graph = stateGraph.compile();
在使用图之前,您必须编译它。
The first thing you do when you define a graph is define the State of the graph. The State consists of the schema of the graph as well as reducer functions which specify how to apply updates to the state. The schema of the State will be the input schema to all Nodes and Edges in the graph, and should be defined using a map of [Channel] object. All Nodes will emit updates to the State which are then applied using the specified reducer function.
Schema
State(状态)
The way to specify the schema of a graph is by defining map of [Channel] objects where each key is an item in the state.
定义图时首先要做的是定义图的 State。State 由图的 schema 以及 reducer 函数组成,reducer 函数指定如何将更新应用于状态。State 的 schema 将是图中所有 Nodes 和 Edges 的输入 schema,应使用 KeyStrategyFactory 定义。所有 Nodes 将发出对 State 的更新,然后使用指定的 reducer 函数应用这些更新。
Schema(模式)
在 Spring AI Alibaba 中,可以通过 KeyStrategyFactory 定义状态的更新策略。每个键都可以指定自己的更新策略(如替换或追加)。
如果没有为某个键指定策略,则默认假定该键的所有更新都应覆盖它。
Example A:
Reducers(归约器)
[Reducers][KeyStrategy] 是理解如何将节点的更新应用到 `State` 的关键。`State` 中的每个键都有自己独立的 reducer 函数。如果没有显式指定 reducer 函数,则假定该键的所有更新都应覆盖它。让我们看几个例子来更好地理解它们。
**示例 A:**
"messages", Channels.appender(ArrayList::new)
);
import com.alibaba.cloud.ai.graph.KeyStrategyFactory;
import com.alibaba.cloud.ai.graph.state.strategy.AppendStrategy;
private static KeyStrategyFactory createKeyStrategyFactory() {
return () -> {
Map<String, KeyStrategy> keyStrategyMap = new HashMap<>();
keyStrategyMap.put("messages", new AppendStrategy());
return keyStrategyMap;
};
### AppenderChannel
var graphBuilder = new StateGraph(createKeyStrategyFactory());
<a id="remove-messages"></a>
### AppendStrategy(追加策略)
#### 删除消息
[AppendStrategy] 支持通过 [RemoveByHash] 删除消息。
Langgraph4j provides a Built in [AppederChannel.RemoveIdentifier] named [RemoveByHash] that allow to remove messages comparing their `hashCode`, below an example of its usage:
Spring AI Alibaba 提供了内置的 [RemoveByHash],允许通过比较其 `hashCode` 来删除消息,下面是其用法示例:
var workflow = new StateGraph<>(MessagesState.SCHEMA, MessagesState::new)
.addNode("agent_1", node_async(state -> Map.of("messages", "message1")))
import static com.alibaba.cloud.ai.graph.StateGraph.END;
import static com.alibaba.cloud.ai.graph.StateGraph.START;
import static com.alibaba.cloud.ai.graph.action.AsyncNodeAction.node_async;
import com.alibaba.cloud.ai.graph.state.RemoveByHash;
var workflow = new StateGraph(createKeyStrategyFactory())
.addNode("agent_3", node_async(state ->
Map.of("messages", ReplaceAllWith.of( List.of("a1", "a2"))) // this replace current messages values with ["a1", "a2"]
))
Map.of("messages", RemoveByHash.of("message2.1")) // 从消息值中删除 "message2.1"
.addEdge("agent_2", "agent_3")
.addEdge(START, "agent_1")
.addEdge("agent_3", END);
Custom Reducer
You can also specify a custom reducer for a particular state property
Example B:
static class MyState extends AgentState {
static Map<String, Channel<?>> SCHEMA = Map.of(
"property", Channel.<String>of( ( oldValue, newValue ) -> newValue.toUpperCase() )
);
}
var graphBuilder = new StateGraph<>( MessagesState.SCHEMA, MyState::new)
### 自定义 Reducer
您也可以为特定的状态属性指定自定义的 reducer
Serializer
示例 B: During graph execution the state needs to be serialized (mostly for cloning purpose) also for providing ability to persist the state across different executions. To do this we have provided a new streighforward implementation based on [Serializer] interface.
import com.alibaba.cloud.ai.graph.KeyStrategy;
private static KeyStrategyFactory createCustomKeyStrategyFactory() {
return () -> {
Map<String, KeyStrategy> keyStrategyMap = new HashMap<>();
keyStrategyMap.put("property", (oldValue, newValue) ->
((String) newValue).toUpperCase()
);
return keyStrategyMap;
};
- Manage nullable value in serialization process
序列化器(Serializer)
- Allow to plug also different serialization techniques
在图执行期间,状态需要被序列化(主要用于克隆目的),同时也为跨不同执行持久化状态提供能力。Spring AI Alibaba 提供了基于 [PlainTextStateSerializer] 接口的直接实现。
Currently the main class for state's serialization using built-in java stream is [ObjectStreamStateSerializer]. It is also available an abstraction allowing to plug serialization techniques text based like
JSONand/orYAMLthat is [PlainTextStateSerializer].
为什么需要序列化框架?
There are several provided Serializers out-of-the-box:
- 不依赖不安全的标准序列化框架
- 允许为第三方(非可序列化)类实现序列化
- 尽可能避免类加载问题
- 在序列化过程中管理可空值 class | description
特性
MapSerializer | built-in Map<String,Object> serializer
- 允许使用 Java 内置标准二进制序列化技术进行序列化
- 允许插入不同的序列化技术
AiMessageSerializer| langchain4jAiMessageSerializer 当前,使用内置 Java 流进行状态序列化的主要类是 [PlainTextStateSerializer]。它支持基于文本的序列化技术,如JSON和YAML