iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
顯示名稱 分支
node_type Branch
一句話用途 依規則比對流程變數或表單欄位目前的值,決定接下來要走哪一條、哪幾條出線,或完全不走任何出線。
會讓流程等待 否。比對是同步進行的,評估完規則立刻決定去向,不會進入等待狀態,也不佔用任何人的待辦。
出線 不限制條數。每條規則可以同時勾選多條出線(代表命中後同時並行走這幾條);也可以完全不勾(該分支安靜結束)。命中多條規則時,這些規則各自勾選的出線會全部一起被推進。
可用範圍 所有企業,不需要平台管理者另外授權。

1. 這個節點做什麼

分支(Branch)是流程裡負責「路由」的節點:它讀取目前的表單欄位或流程變數,依你設定的一組規則逐條比對, 命中某條規則就把流程往那條規則指定的出線推進。它本身不呼叫任何外部服務、不寫回表單、也不會停下來等任何人, 純粹是「看一眼目前的值、決定往哪走」的判斷點。

適合用在:依金額分段走不同的簽核路徑、依事件嚴重度決定要不要交給人處理、檢查某個流程變數是否已經被填過(例如 是否已經有人簽核、是否已經有處置結果)。不適合用在:需要等待某個條件「之後才成立」的情境——分支只評估「當下」的值, 不會反覆檢查,要做這種等待要靠暫停(Delay)配合分支輪流檢查;也不適合直接拿來做需要 人判斷的決策,那是簽核(FormAdapter)的工作,分支通常接在簽核之後,依簽核結果 再往下分流。

2. 設定欄位

設計器面板把設定分成兩個區塊:「分支規則」與「無匹配時(Fallback)」。

2.1 分支規則

面板欄位 config key 必填 預設值 說明
(規則清單,按「新增規則」新增) rules 選填 空陣列 規則陣列,逐條獨立評估。完全沒有規則時,等於每次都直接走 fallback。
規則名稱 rules[].name 選填 「規則 N」 純顯示用,只影響畫面與節點日誌上看到的名稱,不影響比對邏輯。
條件(一條規則內可加多個,按「+條件」新增) rules[].conditions 必填 — 至少要有一個條件;沒有條件的規則視為驗證失敗,無法儲存。
條件的變數(輸入框,placeholder 為 ${v.name}) conditions[].variable 必填 — 要拿來比較的值,見下方「3. 可用的變數與輸出」。務必整段包在 ${...} 內,例如 ${f.amount};沒有包起來的文字會被當成常數字串,不會被解析成變數。
運算符(下拉選單) conditions[].operator 必填 == 15 種,見下方「運算符一覽」。
值(empty/not_empty 時面板會隱藏此欄) conditions[].value 依運算符而定 — 可以是固定文字,也可以包含 ${...} 變數表達式(例如拿另一個流程變數當比較基準); 字串裡只要出現 ${ 就會先做一次變數替換再比較。
條件之間的關係(每個條件後面的下拉選單,最後一個條件不顯示) conditions[].logic 選填 AND 不是「這個條件」的標記,而是分組的切分符,見下方「規則內條件怎麼組合」。
目標路徑(可多選的核取方塊,列出此節點目前的出線) rules[].target_edges 必填(或 target_nodes) 空陣列 這條規則成立時要推進的出線,可多選;多選代表同時並行推進多條路徑。

handler 的驗證邏輯同時接受 rules[].target_nodes(陣列,直接指定目標節點 ID 而非出線 ID)作為 target_edges 的替代寫法,但設計器面板完全沒有提供設定它的介面。不建議使用 target_nodes——原因見下方「6. 注意事項」,它並不會如字面意思限定路徑。

運算符一覽

運算符 面板顯示 語意 需要「值」欄位
== == 相等(一律轉成字串比較,不是數值比較) 是
!= != 不相等(同上,字串比較) 是

|>|數值大於|是
=|>=|數值大於等於|是
<|<|數值小於|是
<=|<=|數值小於等於|是
contains|包含|變數值是否包含指定子字串|是
not_contains|不含|變數值是否不包含指定子字串|是
startswith|開頭|變數值是否以指定字串開頭|是
endswith|結尾|變數值是否以指定字串結尾|是
in|在|變數值是否等於清單中的某一項|是
not_in|不在|變數值是否不等於清單中任何一項|是
empty|空|變數值是否為空|否
not_empty|非空|變數值是否非空|否
matches|正則|變數值是否符合正則表達式(「值」欄位放正則本身)|是

in/not_in 的「值」欄位如果不是陣列(面板輸入的一定是文字),會以逗號切開、 去除頭尾空白後再逐一比對——例如填 approved, confirmed 等同 ['approved','confirmed']。

規則內條件怎麼組合

logic 不是「這個條件是 AND 還是 OR」,而是「這個條件與下一個條件之間」的分組切分符: 依序掃描條件,遇到標 OR 的條件、或掃到最後一個條件時,就把目前累積的條件收成一組;組內全部 成立(AND)才算這組成立,只要有任一組成立,整條規則就成立(組間是 OR)。例如三個條件依序標 AND、OR、AND,會被拆成「條件1 且 條件2」與「條件3」兩組,整條規則 等於「(條件1 且 條件2)或 條件3」。

2.2 無匹配時(Fallback)

面板欄位 config key 必填 預設值 說明
下拉選單:不走任何出線(終止此分支)/路由至節點 fallback.action 選填 log log=這個分支到此為止,不推進任何出邊(安靜結束,不算錯誤);route=依 target_edge 導向指定的單一出線。
Log 訊息(action=log 時顯示) fallback.log_message 選填 「無匹配規則」 只寫進節點日誌,方便事後追查為什麼落到 fallback,不影響流程走向。
選擇目標出線(action=route 時顯示的下拉選單) fallback.target_edge route 時必填 — 只能從這個 Branch 節點目前已有的出線中挑一條,不能指向不相連的節點。

3. 可用的變數與輸出

「變數」與「值」兩個欄位都吃同一套解析規則,支援的前綴:

前綴 意義 範例
${f.欄位} 表單欄位(目前這次流程實例送出的表單資料) ${f.amount}
${v.變數} 流程變數(NODE > FLOW > TREE 優先序) ${v.soc_decision}
${fi.xxx} 表單實例資訊:applicant/applicant_dept/applicant_email/applicant_code/serial/name/subject/code/status ${fi.applicant}
${wi.xxx} 流程實例資訊,只有五個:code/exec_code/name/status/depth ${wi.status}
${n.xxx} 節點上下文:name/id/type ${n.type}
${t.xxx} 時間:now/date/time(皆為 UTC) ${t.date}

不加 ${}、只寫裸名稱(例如直接填 status)會被當成流程變數名稱查詢(等同 ${v.status}),但這是過渡期相容寫法,一律用完整的 ${...} 前綴寫法比較不會混淆。

分支本身不會寫出任何流程變數,也不會動表單資料——它純粹決定出線。如果想留下「這次走了 哪一段」的紀錄,慣例是在每條出線後面各接一個設定變數(OpSet)節點,寫入一個 記錄用的流程變數。

4. 出線行為

執行順序:

  1. 依陣列順序逐條評估 rules,每一條都會評估,不是比對到第一條命中的規則就停止。
  2. 命中(即整條規則依「規則內條件怎麼組合」判定為真)的規則會被收進「命中清單」。
  3. 如果命中清單不是空的:把所有命中規則的 target_edges 取聯集(去重),逐條推進——也就是說, 只要有一條規則命中,就會沿著那條規則勾選的出線往下建立節點;如果同時有多條規則命中,它們的出線會 全部一起被推進,等同並行分支。
  4. 如果命中清單是空的:走 fallback。action=route 且確實填了目標時,只推進那一條指定的出線; 其餘情況(action=log,或 action=route 卻沒有選目標)一律不推進任何出線, 這個分支到此安靜結束——不算錯誤,流程實例不會因此卡住或失敗,只是這條路徑沒有後續。

單一條件的比較如果因為缺值或型別不符而拋出例外(例如用數值運算符比較一個非數字字串),該條件視為不成立, 只記一條警告日誌,不會讓整個節點失敗。

分支本身是同步節點,不會進入等待狀態;它產生的下游節點(例如各出線接的簽核、暫停)才各自可能等待。

5. 常見設計方式

5.1 互斥條件:金額分段

最常見、也是設計時該優先追求的用法:把規則設計成彼此互斥的區間,讓每次評估只會有一條規則命中, 流程只走一條路徑。
https://ithelp.ithome.com.tw/upload/images/20260928/20184261wFDU26b4CG.png

5.2 一條規則勾兩條出線:並行雙軌(取自 SOC 團隊版)

一條規則的 target_edges 不是只能填一個。資安事件處置流程(SOC 團隊版)的「嚴重度分流」用 這個特性讓高危事件同時走兩條路:一條交給值班人員簽核,另一條純粹計時,用來在遲遲沒人處理時自動催辦—— 計時分支只負責提醒,不會代替人做出封鎖或放行的決定。
https://ithelp.ithome.com.tw/upload/images/20260928/20184261Z2xPRBVaup.png

5.3 fallback 的兩種寫法

下面兩段 config 效果不同,容易搞混:

// 寫法 A:真的有指定路由目標
"fallback": {
  "action": "route",
  "target_edge": "edge-med",
  "log_message": "嚴重度缺值,走中危標準簽核"
}
// 效果:無匹配時只推進 edge-med 這一條出線

// 寫法 B:選了「路由至節點」但沒有選目標(面板下拉維持空白)
"fallback": {
  "action": "route"
}
// 效果:等同 action=log——不推進任何出線,分支安靜結束
// 因為 handler 只有在 target_edge 或 target_node 真的有值時才會路由,
// 否則會落到與 action=log 完全相同的「不推進任何出線」處理路徑

6. 注意事項

規則條件重疊,案件會同時走多條路
症狀:設計時以為每次只會命中一條規則,結果同一批案件裡,落在某個金額或某個值域的案件,兩條規則 下游的節點都真的被執行了(例如兩個 OpSet 都各自寫入了自己的流程變數)。
原因:分支對「同時命中多條 規則」的處理方式是全部展開、取聯集推進,不是先到先贏,也不會因為某條規則已命中就跳過其餘規則不評估。 兩條規則的判斷區間只要有重疊(例如一條是「>=50000」、另一條是「<=200000」),中間的區間就會同時 命中兩條。
正確做法:設計規則時明確畫出彼此互斥的邊界(例如用 < 而非 <= 錯開兩段的分界),或者本來就是要並行(像圖 2 的高危雙軌),那就不是問題,但要在規則 名稱與節點描述裡寫清楚這是刻意設計。

用 target_nodes 指定目標,不會真的限定路徑
症狀:直接編輯流程 graph(例如用腳本產生流程),用 rules[].target_nodes 取代 target_edges 指定某條規則命中後要去的節點,結果命中時流程不是只往那個節點走, 而是把這個分支節點所有的出線全部一起推進了。
原因:handler 確實會把 target_nodes 的內容整理進執行結果的 data.selected_nodes,但實際負責推進流程的 程式只讀取 data.selected_edges(陣列)或 data.selected_edge(單一字串),完全不會 讀 selected_nodes。當一條規則只填了 target_nodes、沒有填 target_edges 時,selected_edges 會是空陣列,於是被判定成「沒有指定出線」, 依通用規則退回「取所有出邊」——不會有任何錯誤或警告訊息。
正確做法:一律使用 target_edges(也就是面板上「目標路徑」的核取方塊),不要使用 target_nodes;設計器面板本身也沒有提供設定 target_nodes 的介面,只有直接編輯 流程 graph 才會踩到這個坑。

fallback 選了「路由至節點」卻忘了選目標
症狀:面板上把 fallback 動作切成「路由至節點」,但下拉選單裡沒有選任何出線就直接按套用並發行, 結果無匹配時的行為跟原本「不走任何出線」一模一樣。
原因:只有在確實選了目標出線、 fallback.target_edge 真的有值時,才會產生路由效果;action 設成 route 但目標是空的, 會落到與 action=log 完全相同的處理路徑。
正確做法:選了「路由至節點」之後,務必確認下拉 選單裡已經選到一條出線;這個節點至少要先拉出你想要的那條出線,下拉選單才選得到。

AND/OR 分組容易拆錯
症狀:同一條規則裡有兩個條件,本來想表達「兩個都要成立」,結果只要其中一個條件成立,規則就命中了。
原因:logic 是「這個條件跟下一個條件之間」的分組切分符,不是「這個條件本身」的性質。 只要中間有任何一個條件被誤標成 OR,就會被拆成兩個獨立的群組(組間是 OR 關係)。
正確做法:要表達「全部條件都要成立」,每個條件(除了最後一個)都要標 AND(或留預設值); 只有真正想要「任一群組成立即可」時才用 OR 斷開分組。

== 是字串比較,empty 把數字 0 也當成空
==/!= 一律把兩邊轉成字串再比較,所以字串 "100" 與 "100.0" 不相等;金額類比較建議一律用 >/>=/</ <= 等數值運算符。另外,empty 運算子的判定是 Python 的真假值判定,數字 0、空字串、未設定的變數(預設回傳空字串)都會被視為「空」——如果拿它去判斷一個合法值可能是 0 的欄位(例如某個計數),要注意 0 會被誤判成空。

比較失敗一律視為不成立,不會報錯
缺值、型別不符(例如拿一個文字字串做數值比較)都會讓該條件判定為不成立,只記一條警告到節點日誌, 不會讓節點失敗、也不會中斷流程。這個特性可以刻意拿來當安全閥(缺資料時自動落到 fallback),但也代表 「變數欄位打錯字」這種設定錯誤不會有任何提示——案件會一路落到 fallback,畫面上看不出原因,要靠節點日誌 才查得到。

7. 在 node展覽館 實際操作

node展覽館裡有兩支分支的示範流程,都在同一個批次(B2):

  • NT-05 Branch 示範(互斥條件):對應圖 1。填不同金額(例如 5000/50000/500000)各送一次單, 查流程變數應該只看到對應那一段的 bracket_result,另外兩段的 OpSet 節點完全不會有執行紀錄。
  • NT-05 Branch 示範(多條命中會全部展開):兩條規則刻意重疊(金額>=50000 與金額<=200000)。送 amount=100000(同時滿足兩條)後,應該同時看到兩個流程變數 path_a_triggered 與 path_b_triggered 都是 true,證明兩條路徑都真的 執行了;此範圍外只會命中一條,完全不在任一規則範圍內則走 fallback(route 到第三條路徑,避免 流程卡住)。

在平台安裝目錄下執行(需要系統管理權限):

venv/bin/python scripts/seed_node_showcase.py --apply --only B2

寫入後到表單中心(例如 http://192.168.0.112:8000/beakplatform/forms/center)的「填寫表單」 分類「node展覽館」下找到對應表單送出;兩個示範表單送出後都會產生一張待簽核任務(示範用設計成發起人自己簽核), 簽核完流程才會走到結束。

8. 相關節點

  • 簽核(FormAdapter):分支常常接在簽核之後,依簽核的決策結果再分流; 也常常在分支之前用來判斷要不要交給人簽核。
  • 設定變數(OpSet):分支本身不寫任何變數,通常在每條出線後面各接一個 OpSet,把「走了哪一段」記下來;沒有出線的 OpSet 也是讓某條分支安靜結束的標準做法。
  • 暫停(Delay):分支只看「當下」的值,要做「等一段時間後再檢查」的 SLA 邏輯,要靠暫停配合分支輪流檢查(見圖 2 對應的 SOC 團隊版流程)。
  • 緊急廣播(AlertBroadcast):分支判定出「需要提醒」的路徑時, 常見的下一步就是發一則緊急廣播。

上一篇
簽核(FormAdapter)下
下一篇
SOC團隊版Node說明--防禦決策(DecisionWriter)
系列文
企業管理自動化與執行框架-以SOC運作為實例 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言