iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
AI 自動化

從 BPM 到 Agentic Workflow:企業 AI 流程的狀態、控制與驗證系列 第 4

Day 04|Agentic Workflow 參考架構:Conversation、Orchestrator、Tool、Policy、State

  • 分享至 

  • xImage
  •  

昨天我把一次共享資源預約分成 Understand、Propose、Authorize、Commit 與 Recover,也實際測了 typed contract、核准與 RBAC 三條邊界。

但這些邊界如果只散落在幾個 function 裡,後面很快就會出現新問題:誰可以改狀態?誰可以呼叫有 side effect 的 tool?自然語言內容和授權資訊應該在哪裡分開?

所以今天我不是先畫一套理想架構,而是回頭盤點現在這套 Reference System 裡,每個責任實際落在哪裡。


最後留下七個責任區

現在的程式沒有 Web UI,也沒有外部 LLM。這反而讓控制面更容易看清楚:

責任區 現在的實作 不應該做的事
Conversation raw_request 與未來的 LLM adapter 不能當權限或 workflow state
Typed Intent BookingIntent.from_mapping() 不根據自然語言自行補權限
Orchestrator WorkflowService.start_booking_workflow() 不跳過 state transition 直接 commit
Tool BookingTools 不暴露 raw SQL 或 database connection
Policy evaluate_policy()_policy_for() 不從 prompt 取得放行權
State SQLite workflow_runsstate_transitions 不用聊天紀錄推測當前狀態
Audit / Trace audit_logtrace_id 不只保留最後一句回覆

這七個責任並不等於七個微服務,目前可以留在同一個程式和 SQLite 裡,只要 API 與資料擁有權的邊界清楚。我不想為了看起來像「企業架構」,在還沒有負載和團隊邊界前就先拆成一堆服務。

Conversation 只能提供上下文,不能改變權限

Reference System 對自然語言有一個很刻意的設計:raw_request 只是 untrusted context。真正進入流程的是已經通過 schema validation 的 BookingIntent

def start_booking_workflow(
    self,
    actor_id: str,
    intent_payload: Mapping[str, Any],
    *,
    idempotency_key: str,
    raw_request: str | None = None,
) -> WorkflowSnapshot:
    ...

我很喜歡這個 function signature 呈現出來的邊界:

  • actor_id 是身份,不從句子裡猜。
  • intent_payload 是將要被驗證的結構化輸入。
  • idempotency_key 是重試與副作用的控制資訊。
  • raw_request 可以幫助理解與審計,卻不具有授權力。

未來接上 LLM 時,模型會在 Conversation 和 Typed Intent 之間,不是在 Conversation 和 Database 之間。

Orchestrator 負責順序,Policy 負責允許與否

WorkflowService 會沿著狀態機執行、呼叫資源查詢、要求確認,並在條件滿足後進入 commit,但不應該把「流程現在走到哪裡」和「這個人能不能做」混成同一個 if statement。

現在的 policy decision 是一個明確物件:

@dataclass(frozen=True)
class PolicyDecision:
    allowed: bool
    requires_approval: bool
    reason: str

這讓 Orchestrator 可以依 decision 推進或停止,同時把 reason 留在 audit。未來 policy 就算從 Python 移到其他引擎,Orchestrator 需要的 contract 也不必跟著改寫。

Tool 層刻意做得窄

BookingTools 只開放五個 typed methods:

search_resources
get_availability
create_booking
cancel_booking
get_booking

沒有 execute_sql,也沒有一個萬用的 call_backend(action, payload)。這個限制不是為了少寫功能,而是讓每個 side effect 都能有自己的 schema、授權、idempotency 與 audit 規則。

從 Day 03 的測試可以看到,即使直接呼叫 create_booking,high-impact request 仍然會被 policy 擋下。也就是說,控制不只在 Orchestrator 的正常路徑上,Tool commit 邊界還會再檢查一次。

State 是事實,Trace 是如何變成事實

我把這兩個概念分開:

  • workflow_runs.state 回答現在在哪裡。
  • state_transitions 回答經過哪些轉移才到這裡。
  • audit_log 回答誰在什麼時候做了哪個動作,結果為何。
  • trace_id 把同一次流程跨元件的事件串起來。

如果只有最後的 SUCCEEDED,我不知道中間是否真的經過確認和核准。如果只有 audit events,卻沒有明確 state,服務重啟後又不知道該從哪裡繼續。這兩者不能互相取代。

用現有整合測試重跑這條架構

我重跑了有確認與核准的路徑:

python3 -m unittest \
  tests.test_agentic_workflow.AgenticWorkflowIntegrationTests.test_confirmation_approval_state_audit_and_trace_are_persisted \
  -v

結果:

test_confirmation_approval_state_audit_and_trace_are_persisted ... ok

Ran 1 test
OK

這個 test 同時穿過了 typed intent、orchestrator、policy、state、tool 與 audit。我最在意的不是最後 OK,而是還驗證這條狀態鏈:

NEW
-> UNDERSTOOD
-> SEARCHED
-> AWAIT_CONFIRMATION
-> APPROVED
-> EXECUTING
-> SUCCEEDED

也重新建立 WorkflowService 後讀回 AWAIT_CONFIRMATION,證明暫停中的狀態不是只留在 Python object 或對話文字裡。

這還不是生產架構

這次驗證足以說明責任邊界有對應的程式和資料,但不代表:

  • SQLite 適合所有多節點、高併發部署。
  • 目前的 policy 已覆蓋完整規則。
  • 將來接上 LLM 後的 intent extraction 一定正確。
  • 關鍵字式惡意文字檢查是完整的安全層。
  • 現在就應該把每个責任拆成獨立服務。

是一套可以持續加入失敗、重試、衝突與攻擊測試的 reference architecture,不是架構完成宣言。

今天的結論

盤點完實作後,我對 Agentic Workflow 的架構原則比較明確了:

Conversation 承載使用者語意,Orchestrator 推進流程,Policy 決定能不能做,Tool 負責受控的 side effect,State 保存事實,Audit 證明如何發生。

下一篇我會把焦點收斂到 State:哪些狀態是必要的、哪些 transition 應該被禁止,以及為什麼對話紀錄無法代替狀態機。

下一篇:Day 05|先定 State:企業流程不是一串 Prompt


參考資料

  1. Anthropic, Building Effective Agents
  2. OMG, Business Process Model and Notation 2.0.2
  3. Python Documentation, sqlite3 — Transaction control

本篇只描述 repository 中已實作並可測試的邊界,未接上真實企業系統或外部模型。


上一篇
Day 03|哪些事交給 LLM,哪些事不要
下一篇
Day 05|先定 State:企業流程不是一串 Prompt
系列文
從 BPM 到 Agentic Workflow:企業 AI 流程的狀態、控制與驗證10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言