內容概述
前一篇(spring-ai-alibaba 1.0.0.2 學習(十七)——初識graph-CSDN博客)初步介紹了graph:
概念:圖、邊、節點、狀態等,及其核心類和衍生類
使用流程:
1)定義流程圖:添加節點,添加邊
2)使用流程圖:編譯圖,執行圖
但是在定義流程圖時,省略了圖初始化的過程;
在使用流程圖時,省略了參數設置的過程
本篇會補充對應的內容
簡單樣例
圖初始化
KeyStrategyFactory keyStrategyFactory = () -> {HashMap<String, KeyStrategy> keyStrategyHashMap = new HashMap<>();// 用戶輸入keyStrategyHashMap.put("query", new ReplaceStrategy());keyStrategyHashMap.put("documents", new AppendStrategy());return keyStrategyHashMap;};StateGraph stateGraph = new StateGraph(keyStrategyFactory)...
在新版本1.0.0.3中,狀態圖StateGraph的初始化不再建議使用OverAllStateFactory,而是改用KeyStrategyFactory
KeyStrategyFactory實際就是一個 Supplier<Map<String, KeyStrategy>>,一個Map<String, KeyStrategy>的提供者
而其提供的Map<String, KeyStrategy>,key是參數名,value是該參數的更新策略,用來指定全局狀態類OverAllState的某個參數的更新策略
提到KeyStrategy,就需要先了解OverAllState,全局狀態類OverAllState,內部維護了一個Map<String, Object> data 用來保存各種狀態參數,如果將該類提煉為一個接口,那對外提供的最主要的方法其實就是一個:
OverAllState updateState(Map<String, Object> nodeOutput);
也就是用節點的輸出來更新全局狀態的data,并返回一個新的全局狀態
而 KeyStrategy 就是在這個環節中生效,用來指定 OverAllState 中某個參數,是如何與節點輸出進行合并的
比如常見的ReplaceStrategy,就是直接用nodeOutput中的值替換掉data中的值,例如樣例中的query參數
另一個 KeyStrategy 的子類 AppendStrategy,主要用于參數的類型是List的時候,是將nodeOutput和data的某個參數的元素進行去重生成新 List,例如樣例中的documents參數
子類MergeStrategy,主要用于參數的類型是Map的時候,用節點輸出結果nodeOutput覆蓋全局狀態中data的值(如果存在的話)
所以KeyStrategyFactory最終就是負責提供狀態參數的更新策略
在并行節點中,若某個結果的key不設置更新策略,那即使節點輸出中包含該key,也不會被更新進入全局狀態OverAllState中(普通節點不存在這個問題,會默認使用覆蓋策略,不知道是不是bug)
ps:graph默認會為“input”添加一個ReplaceStrategy的更新策略
參數設置(可選參數)
編譯圖的參數
SaverConfig saverConfig = SaverConfig.builder().register(SaverConstant.MEMORY, new MemorySaver()).build();
CompileConfig complieConfig = CompileConfig.builder().saverConfig(saverConfig).interruptBefore("humanfeedback").build(); //CompileConfig 參數可省略
//CompiledGraph compiledGraph = stateGraph.compile();
CompiledGraph compiledGraph = stateGraph.compile(compileConfig);
...
編譯圖時,有一個可選參數 CompileConfig,編譯參數,主要是用來生成 CompiledGraph,內部包含如下屬性:
SaverConfig:保存各種類型的檢查點保存器,缺省狀態下,CompileConfig會創建一個MemorySaver放到SaverConfig中
????????Map<String, BaseCheckpointSaver>:key 為保存器的類型,如Memory
????????String type:默認類型,調用無參的 get 方法時,從Map中獲取該默認類型對應的BaseCheckpointSaver
lifecycleListeners:圖生命周期監聽器的隊列,處理時先進后出,目前支持開始節點、結束節點、報錯、節點前、節點后等幾種觸發情景。
interruptsBefore:Set<String> 類型,值為nodeId,表示在該 node 之前加入中斷
interruptsAfter:Set<String> 類型,值為nodeId,表示在該 node 之后加入中斷
ps:除了這些,CompiledGraph 還有個設置,即最大執行步驟數,代表圖中節點總共的可執行次數,每執行一個節點算一次,需要調用 CompiledGraph.setMaxIterations 方法設置,不在 CompileConfig 中
執行圖的參數
RunnableConfig runnableConfig = RunnableConfig.builder().threadId(threadId).build();Map<String, Object> objectMap = new HashMap<>();objectMap.put("query", query);objectMap.put("documents", List.of(document));//RunnableConfig 參數可以省略//AsyncGenerator<NodeOutput> resultFuture = compiledGraph.invoke(objectMap);AsyncGenerator<NodeOutput> resultFuture = compiledGraph.invoke(objectMap, runnableConfig);...
CompiledGraph執行時,需要兩個參數
Map<String, Object>:對應全局狀態中的data,是執行圖時傳入的初始參數
該Map的 key 需要對應前面的 KeyStrategyFactory 中 返回Map的 key,否則該參數無法更新
RunnableConfig:運行時配置,是一個可選參數,主要存放線程id threadId、檢查點id checkPointId,下一節點id nextNode,metaData 等信息。
????????threadId: 主要是用來區分會話的,在前端另開一個會話,就會新建一個 threadId,不同會話之間狀態(OverAllState)不共享
? ? ? ? checkPointId:猜測是用于時間旅行,即重新回到某個節點,錯誤恢復和人工介入目前不需要傳遞該參數,會自動獲取最新存檔
? ? ? ? metaData:運行時的其他配置,比如llm中實際使用的大模型型號,不想污染OverAllState時可以在這里設置