import com.alibaba.cloud.ai.graph.CompileConfig;
import com.alibaba.cloud.ai.graph.CompiledGraph;
import com.alibaba.cloud.ai.graph.KeyStrategy;
import com.alibaba.cloud.ai.graph.KeyStrategyFactory;
import com.alibaba.cloud.ai.graph.RunnableConfig;
import com.alibaba.cloud.ai.graph.StateGraph;
import com.alibaba.cloud.ai.graph.checkpoint.config.SaverConfig;
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
import com.alibaba.cloud.ai.graph.exception.GraphStateException;
import com.alibaba.cloud.ai.graph.state.StateSnapshot;
import com.alibaba.cloud.ai.graph.state.strategy.AppendStrategy;
import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
/**
* 完整示例
*/
public static void completeExample() throws GraphStateException {
// 构建 Graph
KeyStrategyFactory keyStrategyFactory = () -> {
HashMap<String, KeyStrategy> strategies = new HashMap<>();
strategies.put("messages", new AppendStrategy());
strategies.put("step", new ReplaceStrategy());
return strategies;
};
StateGraph builder = new StateGraph(keyStrategyFactory)
.addNode("step1", node_async(state ->
Map.of("messages", "Step 1", "step", 1)))
.addNode("step2", node_async(state ->
Map.of("messages", "Step 2", "step", 2)))
.addNode("step3", node_async(state ->
Map.of("messages", "Step 3", "step", 3)))
.addEdge(START, "step1")
.addEdge("step1", "step2")
.addEdge("step2", "step3")
.addEdge("step3", END);
// 配置持久化
var checkpointer = new MemorySaver();
var compileConfig = CompileConfig.builder()
.saverConfig(SaverConfig.builder()
.register(checkpointer)
.build())
.build();
CompiledGraph graph = builder.compile(compileConfig);
// 执行
var config = RunnableConfig.builder()
.threadId("demo")
.build();
graph.invoke(Map.of(), config);
// 查看历史
List<StateSnapshot> history = (List<StateSnapshot>) graph.getStateHistory(config);
history.forEach(snapshot -> {
System.out.println("State: " + snapshot.state());
System.out.println("Node: " + snapshot.node());
System.out.println("---");
});
// 回溯到 step1
StateSnapshot step1Snapshot = history.stream()
.filter(s -> "step1".equals(s.node()))
.findFirst()
.orElseThrow();
var replayConfig = RunnableConfig.builder()
.threadId("demo")
.checkPointId(step1Snapshot.config().checkPointId().orElse(null))
.build();
// 从 step1 重新执行
graph.invoke(Map.of(), replayConfig);
}
- 性能考虑: 历史记录会占用内存,生产环境建议使用持久化存储
- 数据一致性: 确保状态数据可序列化
- 版本兼容: Graph 结构改变时历史状态可能不兼容
- 清理策略: 定期清理旧的历史记录
- 持久化 – 状态持久化
- 等待用户输入 – 中断和恢复
- Checkpoint 机制 – 检查点详解
- 快速入门 – Graph 基础使用
本文整理自 Spring AI Alibaba 官方文档《时光旅行与状态回溯》:https://java2ai.com/docs/frameworks/graph-core/examples/time-travel

AI项目博客






