1 依賴
<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>1.0.0.2</version>
</dependency><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-graph-core</artifactId><version>1.0.0.2</version>
</dependency><!--接入兼容OpenAI api的大模型--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai</artifactId></dependency>
2 實戰
以實現一個簡單的模型調用工作流為例,闡述工作流實現步驟。
2.1 實現業務節點 (NodeAction)
通用模型調用節點。
@Slf4j
public class CommonModelCallNode implements NodeAction {private ChatClient chatClient;public CommonModelCallNode(ChatClient chatClient) {this.chatClient = chatClient;}@Overridepublic Map<String, Object> apply(OverAllState state) {// 調用AI模型,生成查詢String result = null;try {result = chatClient.prompt().user(u -> u.text(state.value("query", ""))).call().content();} catch (Exception e) {log.error("CommonModelCallNode error", e);HashMap<String, Object> resultMap = new HashMap<>();resultMap.put("errorMsg", e.getMessage());return resultMap;}// 將結果放入Map,該Map會根據狀態策略合并到OverAllState中HashMap<String, Object> resultMap = new HashMap<>();resultMap.put("commonModelCallResult", result);return resultMap;}
}
2.2 創建工作流 (StateGraph)
創建工作流時,需要定義狀態策略。
@Configuration
public class GraphConfig {@Resourceprivate ChatClient chatClient4VolcesDoubaoV1;/*** 定義狀態策略* ps:定義在全局狀態 OverAllState 中,各個字段的更新策略。*/@Bean("overAllStateFactory4Demo1")public OverAllStateFactory overAllStateFactory4Demo1() {return () -> {OverAllState state = new OverAllState();// 入參必須在OverAllState中注冊,否則無法傳遞給NodeActionstate.registerKeyAndStrategy("query", new ReplaceStrategy()); // 新值替換舊值state.registerKeyAndStrategy("commonModelCallResult", new ReplaceStrategy());state.registerKeyAndStrategy("errorMsg", new ReplaceStrategy());return state;};}/*** 創建工作流*/@Bean("stateGraph4Demo1")public StateGraph stateGraph4Demo1(@Qualifier("overAllStateFactory4Demo1") OverAllStateFactory factory) throws GraphStateException {return new StateGraph("stateGraph4Demo1", factory).addNode("commonModelCallNode", node_async(new CommonModelCallNode(chatClient4VolcesDoubaoV1))) // 添加業務節點.addEdge(StateGraph.START, "commonModelCallNode") // 從開始節點連接到業務節點.addEdge("commonModelCallNode", StateGraph.END); // 從業務節點連接到結束節點}}
2.3 編譯工作流并執行
創建一個 http 接口,執行工作流。
@Slf4j
@RestController
@RequestMapping("/graph")
public class SimpleGraphController {@Resourceprivate StateGraph stateGraph4Demo1;@GetMapping("/demo1")@ResponseBodypublic BaseResponse<Map<String, Object>> demo1(@RequestParam(name = "query") String query,@RequestParam(name = "threadId", defaultValue = "test-thread") String threadId) {long startTime = System.currentTimeMillis();log.info("======>>> SimpleGraphController demo1 start. query: {}", query);if (StringUtils.isBlank(query)) {return BaseResponse.error("query 不能為空");}// 準備初始輸入參數Map<String, Object> inputMap = new HashMap<>();inputMap.put("query", query);// 配置執行參數,如線程ID(用于會話追蹤)RunnableConfig config = RunnableConfig.builder().threadId(threadId).build();// 執行Graph并獲取最終狀態CompiledGraph compiledGraph;try {compiledGraph = stateGraph4Demo1.compile();} catch (GraphStateException e) {log.error("Graph compile error: {}", e.getMessage());return BaseResponse.error("Graph compile error");}Optional<OverAllState> resultState = compiledGraph.invoke(inputMap, config);Map<String, Object> resultMap = resultState.map(OverAllState::data).orElse(new HashMap<>());log.info("======>>> SimpleGraphController demo1 end. cost:{}ms, query:{}", System.currentTimeMillis() - startTime, query);return BaseResponse.success(resultMap);}
}
2.5 打印工作流
可以打印工作流流程圖。包括?PLANTUML 和?MERMAID 兩種格式的語言。
public class GraphPrintTest extends BaseTest{@Resourceprivate StateGraph stateGraph4Demo1;@Testpublic void testGraphPrint() {System.out.println(stateGraph4Demo1.getGraph(GraphRepresentation.Type.PLANTUML, "Demo1工作流", true).content());System.out.println("=========================");System.out.println(stateGraph4Demo1.getGraph(GraphRepresentation.Type.MERMAID, "Demo1工作流", true).content());Assert.assertTrue(true);}}@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringAiDemoApplication.class)
public class BaseTest {
}
打印的流程圖如下所示: