← Archive
lm-002074 · 2026-08

03_工作流如何成為函數_邊界端口契約狀態與副作用_v0.1

下載 MD 檔 ⬇

工作流如何成為函數:邊界、端口、契約、狀態與副作用

How a Workflow Becomes a Function: Boundaries, Ports, Contracts, State, and Side Effects

系列名稱: 遞歸自適應積木組合語言(Recursive Adaptive Block Composition Language, RABCL)
系列編號: EML-RABCL-2026-03
作者: Neo.K(許筌崴)with Aletheia(GPT)
機構: EveMissLab/一言諾科技有限公司
版本: v0.1 基礎形式化稿
日期: 2026 年 7 月 30 日
文件定位: 工作流函數化、封裝邊界、端口推斷、功能契約、狀態模型、副作用模型與 AI 輔助介面生成


摘要

RABCL 系列前兩篇分別提出「連線即封裝」總命題與封裝靜止屏障:一組已形成相對完整功能的工作流,可以在局部靜止、一致快照、隔離分析、驗證與原子提交後,被升格為新的高階積木。然而,從「一張可執行的工作流圖」到「一個可再次組合的函數積木」之間,仍存在一個不能被視覺折疊取代的語義轉換問題。

工作流內部可能包含資料流、控制流、模型呼叫、持續狀態、外部檔案、網路服務、資料庫、人工核准、非同步事件與不可逆操作。若系統只根據圖上的入邊與出邊產生幾個輸入輸出孔位,便會把隱藏依賴、狀態生命週期、錯誤語義、權限與副作用留在封裝之外,形成表面可呼叫、實際不可理解的黑盒。

本文提出 RABCL 的工作流函數化模型。本文所稱的函數,不限於無副作用的數學純函數,而是具有顯式輸入、輸出、環境能力、持續狀態、效果集合、錯誤通道與可觀測證據的契約呼叫單元:

FB:(X,S,Γ)(Y,S,E,T).F_B: (X,S,\Gamma) \rightarrow (Y,S',\mathcal E,\mathcal T).

其中 XX 是顯式輸入, SS 是呼叫前狀態, Γ\Gamma 是外部能力與環境依賴, YY 是輸出, SS' 是呼叫後狀態, E\mathcal E 是已發生或承諾發生的效果, T\mathcal T 是追蹤、驗證與來源證據。

本文將函數化拆成五個不可省略的部分:

  1. 邊界:哪些節點、資源、狀態與效果屬於積木內部;
  2. 端口:哪些資料、事件、能力與錯誤可以跨越邊界;
  3. 契約:積木承諾做什麼、要求什麼、可能如何失敗;
  4. 狀態:哪些資訊跨呼叫持續存在,如何初始化、遷移、重設與並行存取;
  5. 副作用:積木會讀寫哪些外部世界,效果是否冪等、可補償或不可逆。

本文進一步提出邊界完備性、端口充分性、契約可執行性、狀態顯式性與效果封閉性五項基本條件,並設計 AI 輔助推斷流程:從一致快照抽取候選邊界,建立切邊與資源清單,合併端口型別,合成契約草案,辨識狀態與效果,再依信心分數、測試與人工審查決定是否提交。AI 可以提出函數化候選,但不能在隱藏效果、權限或不可逆操作尚未釐清時,將推測直接提升為權威契約。

本文最後給出一份可供後續 MVP 使用的最小積木描述結構。它不要求第一版完成形式證明或通用程式分析,只要求每個大格子具有可機器讀取的端口、狀態、效果、錯誤、權限與版本描述,使工作流封裝不再只是視覺群組,而成為可以安全調用、再次組合與後續演化的計算單元。

關鍵詞: 工作流函數化、封裝邊界、端口、契約、狀態、副作用、效果系統、能力導入、RABCL、AI 編譯


0. 問題:工作流可執行,不代表它已經是函數

設一個工作流為:

W=(V,E),\mathcal W=(V,E),

其中 VV 是節點集合, EE 是節點間的連線。若工作流可以從起點執行到終點,常會被直覺地寫成:

W(x)=y.\mathcal W(x)=y.

但這個表示可能隱藏大量未被列出的條件。例如,一個「產生並發布圖片」工作流可能實際依賴:

  • 一組模型 API 金鑰;
  • 某個目前可用的模型版本;
  • 本地素材資料夾;
  • 雲端儲存空間;
  • 內容安全政策;
  • 使用者的發布權限;
  • 上一次執行留下的快取;
  • 失敗重試計數;
  • 人工核准結果;
  • 外部服務的速率限制。

因此,它真正的形態不是:

xy,x\mapsto y,

而更接近:

(x,s,γ,p,t)(y,s,e,r),(x,s,\gamma,p,t) \mapsto (y,s',e,r),

其中 ss 是狀態, γ\gamma 是環境能力, pp 是權限與政策, tt 是時間或事件條件, ee 是外部效果, rr 是執行證據與錯誤結果。

若封裝只保留 xxyy ,其餘依賴仍然存在,只是變成隱藏依賴。這種積木具有三種風險:

  1. 在原畫布中可以運行,換到其他環境便失敗;
  2. 使用者看不到它會讀寫什麼,也無法判斷權限;
  3. AEREC 未來改寫內部實現時,無法判斷外部行為是否仍等價。

所以,工作流函數化不是把一張圖命名,而是把原本分散在節點、連線、執行環境與操作歷史中的外部可觀測語義,提升成一份明確契約。


1. RABCL 中「函數」的廣義定義

1.1 純函數只是特例

數學純函數通常表示為:

f:XY,f:X\rightarrow Y,

並要求相同輸入得到相同輸出,且不改變外部世界。

但實際工作流常是:

  • 非同步的;
  • 有狀態的;
  • 會失敗的;
  • 會呼叫外部服務的;
  • 會產生檔案或通知的;
  • 需要人工或 Agent 回覆的;
  • 會在不同 Runtime 上被派發的。

因此,本文將 RABCL 積木的呼叫語義定義為:

FB:(X,S,Γ,P)R(Y,S,E,T),F_B: (X,S,\Gamma,P) \rightarrow \mathcal R(Y,S',\mathcal E,\mathcal T),

其中:

  • XX :顯式資料或事件輸入;
  • SS :呼叫前的持續狀態;
  • Γ\Gamma :外部能力與環境依賴;
  • PP :權限、政策與治理條件;
  • YY :正常輸出;
  • SS' :更新後狀態;
  • E\mathcal E :效果集合;
  • T\mathcal T :追蹤、來源、測試與證書;
  • R\mathcal R :成功、失敗、取消、逾時或待外部事件的結果型別。

純函數是下列條件成立時的特例:

S=S=,Γ=,E=,S=S'=\varnothing, \quad \Gamma=\varnothing, \quad \mathcal E=\varnothing,

且:

x,FB(x)=y\forall x, \quad F_B(x)=y

具有確定性。

1.2 可呼叫單元而非語法假象

一個積木若要被視為函數,至少必須使外部呼叫者知道:

  • 如何提供輸入;
  • 何時會產生輸出;
  • 需要哪些外部能力;
  • 會改變哪些狀態;
  • 可能發生哪些效果;
  • 失敗時會返回什麼;
  • 是否可以重試、取消或補償。

因此:

Functionization=Boundary Extraction+Interface Construction+Contract Publication\boxed{ \text{Functionization} = \text{Boundary Extraction} + \text{Interface Construction} + \text{Contract Publication} }

2. 候選工作流的擴充模型

為了推斷函數介面,不能只保存節點與邊。本文將候選工作流表示為:

W=(V,E,D,C,S,X,A,L,H),\mathcal W = (V,E,D,C,S,X,A,L,H),

其中:

  • VV :節點;
  • EE :資料流、控制流與事件流;
  • DD :資料與型別描述;
  • CC :控制條件與排程關係;
  • SS :內部與外部狀態;
  • XX :副作用與外部資源交互;
  • AA :能力、權限、機密與環境依賴;
  • LL :生命週期、重試、取消與逾時規則;
  • HH :來源、版本、執行與修改歷史。

候選封裝區域為:

WCW.\mathcal W_C \subseteq \mathcal W.

函數化程序不是只對 VCV_CECE_C 做圖切割,而是對上述所有維度建立封裝邊界。


3. 第一條件:邊界

3.1 圖邊界

設候選節點集合為 VCV_C 。其內部邊為:

Eint={(u,v)EuVC, vVC}.E_{\mathrm{int}} = \{(u,v)\in E\mid u\in V_C,\ v\in V_C\}.

輸入切邊為:

Ein={(u,v)EuVC, vVC}.E_{\mathrm{in}} = \{(u,v)\in E\mid u\notin V_C,\ v\in V_C\}.

輸出切邊為:

Eout={(u,v)EuVC, vVC}.E_{\mathrm{out}} = \{(u,v)\in E\mid u\in V_C,\ v\notin V_C\}.

若工作流只含顯式資料流,則 EinE_{\mathrm{in}}EoutE_{\mathrm{out}} 可以初步生成資料端口。然而,真實工作流還存在不畫在線上的關係。

3.2 非圖形邊界

候選積木的完整邊界應寫成:

B=DBEBSBXBABTB.\partial B = \partial_D B \cup \partial_E B \cup \partial_S B \cup \partial_X B \cup \partial_A B \cup \partial_T B.

其中:

  • DB\partial_D B :資料輸入輸出;
  • EB\partial_E B :事件與控制信號;
  • SB\partial_S B :外部可見或持續狀態;
  • XB\partial_X B :外部副作用與資源;
  • AB\partial_A B :能力、權限與機密;
  • TB\partial_T B :時間、排程、逾時與生命週期。

例如,一個節點雖然沒有畫出「網路」連線,卻可能透過模型 SDK 呼叫外部 API。這個網路能力必須被納入 AB\partial_A BXB\partial_X B ,不能因畫布上沒有線而被視為內部純計算。

3.3 邊界完備性

本文定義:若所有跨越封裝內外的可觀測交互,都被端口、能力導入、狀態宣告或效果宣告表示,則邊界完備:

BoundaryComplete(B)    zCross(B),zDeclared(B).\operatorname{BoundaryComplete}(B) \iff \forall z\in\operatorname{Cross}(B), \quad z\in\operatorname{Declared}(B).

其中 Cross(B)\operatorname{Cross}(B) 是所有跨界交互集合。

實際系統無法保證完全找出所有隱藏依賴,因此 MVP 應將此條件實作成:

KnownCross(B)Declared(B),\operatorname{KnownCross}(B) \subseteq \operatorname{Declared}(B),

並對未知部分保留:

  • 未解析標記;
  • 沙盒限制;
  • 執行期監測;
  • 人工確認;
  • 拒絕封裝。

4. 第二條件:端口

4.1 端口不只是名稱與型別

每個端口定義為:

p=(ι,δ,τ,κ,μ,ω,ρ,α,π,ε),p = ( \iota, \delta, \tau, \kappa, \mu, \omega, \rho, \alpha, \pi, \varepsilon ),

其中:

  • ι\iota :端口識別與名稱;
  • δ\delta :方向,輸入、輸出或雙向;
  • τ\tau :資料或事件型別;
  • κ\kappa :基數,一筆、可選、多筆、串流;
  • μ\mu :呼叫模式,同步、非同步、事件、future 或 stream;
  • ω\omega :所有權、借用與生命週期;
  • ρ\rho :可靠性與順序語義;
  • α\alpha :權限、信任域與敏感度;
  • π\pi :來源與資料血緣;
  • ε\varepsilon :錯誤通道。

這與現代元件介面設計中的核心原則一致:介面描述的是元件可提供與需要的功能契約,而不是內部實作;輸入與輸出若具有型別,組合時便可以先做相容性檢查。

4.2 端口種類

RABCL 至少區分六類端口。

資料端口

接收或產生結構化資料:

pD:x:τx.p_D:x:\tau_x.

事件端口

表示事件到達、觸發或通知:

pE:eventτe.p_E:\operatorname{event}\langle\tau_e\rangle.

控制端口

表示啟動、取消、暫停、核准、拒絕或重試。

能力端口

宣告積木需要的外部能力,例如:

  • 檔案讀寫;
  • 網路;
  • 模型呼叫;
  • GPU;
  • 機密儲存;
  • 人工核准;
  • 資料庫交易。

能力端口不是普通資料值,而是對外部世界操作的授權入口:

pA:capabilityc.p_A:\operatorname{capability}\langle c\rangle.

狀態端口

用於顯式載入、保存、檢查點或遷移狀態。

錯誤端口

將失敗視為正式結果,而不是只在日誌中拋出文字:

perr:resultY,E.p_{\mathrm{err}}: \operatorname{result}\langle Y,E\rangle.

4.3 端口合併

候選子圖常有多條相似輸入邊。AI 可以提出端口合併:

{p1,p2,,pn}Unifyp.\{p_1,p_2,\ldots,p_n\} \xrightarrow{\mathsf{Unify}} p^\ast.

但只有在以下條件成立時才能自動合併:

  • 型別可以安全統一;
  • 語義角色相同;
  • 權限與敏感度相容;
  • 時序與基數相容;
  • 合併不會消除重要來源資訊。

「兩條線都傳字串」不表示它們是同一端口。提示詞、API 金鑰、使用者姓名與檔案路徑都可能是字串,但具有完全不同的語義與安全要求。

4.4 端口充分性

端口集合 PBP_B 充分,若外部呼叫者只依賴公開端口與契約,就能合法地使用積木,而不必直接存取其內部節點:

PortSufficient(B)    Use(B) 不需要 Access(VBinternal).\operatorname{PortSufficient}(B) \iff \operatorname{Use}(B) \text{ 不需要 } \operatorname{Access}(V_B^{\mathrm{internal}}).

這不表示呼叫者不可以展開積木除錯,而是表示正常組合不依賴內部結構。


5. 第三條件:契約

5.1 契約結構

積木契約定義為:

CB=(I,O,Pre,Post,Inv,Eff,Err,QoS,Sec,Ver).C_B = ( I, O, \operatorname{Pre}, \operatorname{Post}, \operatorname{Inv}, \operatorname{Eff}, \operatorname{Err}, \operatorname{QoS}, \operatorname{Sec}, \operatorname{Ver} ).

其中:

  • II :輸入規格;
  • OO :輸出規格;
  • Pre\operatorname{Pre} :前置條件;
  • Post\operatorname{Post} :後置條件;
  • Inv\operatorname{Inv} :執行期間必須維持的不變量;
  • Eff\operatorname{Eff} :允許的效果集合;
  • Err\operatorname{Err} :錯誤、取消、逾時與部分成功語義;
  • QoS\operatorname{QoS} :品質、延遲、成本與資源限制;
  • Sec\operatorname{Sec} :權限、機密與資料治理;
  • Ver\operatorname{Ver} :版本與相容性政策。

5.2 功能契約與實現分離

契約描述「積木對外承諾什麼」,不規定所有內部細節。令內部實現為 RiR_i ,則多個實現可以滿足同一契約:

R1CB,R2CB,,RnCB.R_1\models C_B, \quad R_2\models C_B, \quad \ldots, \quad R_n\models C_B.

這是 AEREC 能夠在不破壞積木身分的前提下持續演化內部實現的基礎。

若新實現改變了輸出語義、允許的效果或權限需求,則不能只增加 patch 版本並聲稱是最佳化,而應:

  • 擴充契約;
  • 建立新主版本;
  • 或建立新的積木身分。

5.3 三級契約

描述契約

自然語言摘要與端口說明。它可供人類理解,但不能單獨作為安全依據。

可執行契約

包含可由系統檢查的:

  • Schema;
  • 型別;
  • 前後條件;
  • 效果白名單;
  • 權限;
  • 測試;
  • 逾時與重試政策。

證書契約

在可執行契約上附加:

  • 測試結果;
  • benchmark;
  • 靜態分析;
  • 形式證明;
  • 人工批准;
  • 執行歷史統計。

MVP 不必要求所有積木達到證書契約,但至少要有可執行契約。

5.4 錯誤不是例外附註

工作流函數化必須顯式表示:

Outcome=Success(Y)Failure(E)CancelledTimeoutPending(K).\operatorname{Outcome} = \operatorname{Success}(Y) \mid \operatorname{Failure}(E) \mid \operatorname{Cancelled} \mid \operatorname{Timeout} \mid \operatorname{Pending}(K).

其中 KK 可以表示等待人工核准、外部事件或長時間工作。

若一個工作流只描述成功輸出,卻把失敗藏在 Runtime 日誌中,它尚未形成充分契約。


6. 第四條件:狀態

6.1 狀態分類

候選工作流的狀態集合為:

SB=SephemeralSpersistentSexternalSderivedSsecret.S_B = S_{\mathrm{ephemeral}} \cup S_{\mathrm{persistent}} \cup S_{\mathrm{external}} \cup S_{\mathrm{derived}} \cup S_{\mathrm{secret}}.

暫時狀態

只存在於單次呼叫,例如中間張量、局部變數與暫存結果。

持續狀態

跨呼叫保存,例如對話記憶、重試計數、使用者偏好與任務進度。

外部權威狀態

真正的權威資料位於資料庫、檔案系統或外部服務,積木只保存引用或快照。

衍生狀態

可以從其他資料重建,例如快取、索引、嵌入與預計算結果。

機密狀態

金鑰、Token、敏感個資或內部政策。此類狀態不能直接寫入可分享工作流檔案,只能保存安全引用。

6.2 狀態契約

每種持續狀態應具有:

CS=(Init,Read,Write,Checkpoint,Restore,Migrate,Reset,Concurrency,Retention).C_S = ( \operatorname{Init}, \operatorname{Read}, \operatorname{Write}, \operatorname{Checkpoint}, \operatorname{Restore}, \operatorname{Migrate}, \operatorname{Reset}, \operatorname{Concurrency}, \operatorname{Retention} ).

即:

  • 如何初始化;
  • 誰可以讀寫;
  • 何時建立檢查點;
  • 如何復原;
  • 版本變更時如何遷移;
  • 如何重設;
  • 並行衝突如何處理;
  • 保存多久與何時刪除。

6.3 狀態顯式性

若積木的輸出受到先前執行歷史影響,卻未在契約中宣告狀態,則外部呼叫者會誤以為它是無狀態函數。

本文定義:

StateExplicit(B)    sSBobservable,sCBsPB.\operatorname{StateExplicit}(B) \iff \forall s\in S_B^{\mathrm{observable}}, \quad s\in C_B \lor s\in P_B.

其中 SBobservableS_B^{\mathrm{observable}} 是會影響外部可觀測行為的狀態。

6.4 狀態不是都要變成輸入端口

顯式狀態不等於每次呼叫都要傳入完整狀態。RABCL 可以支援:

  • 外部傳入狀態;
  • 積木內部持久化狀態;
  • Runtime 管理的狀態句柄;
  • 內容定址的不可變狀態;
  • 事件溯源重建狀態。

關鍵不是狀態放在哪裡,而是其權威位置與生命週期必須可被查詢。


7. 第五條件:副作用

7.1 效果集合

積木的效果集合表示為:

EB={Read,Write,Send,Invoke,Allocate,Publish,Approve,Delete,}.\mathcal E_B = \{ \operatorname{Read}, \operatorname{Write}, \operatorname{Send}, \operatorname{Invoke}, \operatorname{Allocate}, \operatorname{Publish}, \operatorname{Approve}, \operatorname{Delete}, \ldots \}.

每個效果記錄:

e=(kind,target,scope,authority,idempotency,compensation,observability).e = ( \operatorname{kind}, \operatorname{target}, \operatorname{scope}, \operatorname{authority}, \operatorname{idempotency}, \operatorname{compensation}, \operatorname{observability} ).

7.2 四級效果風險

純讀取或局部效果

例如讀取不可變設定、產生記憶體內中間值。

冪等效果

重複執行不改變最終結果,例如以相同內容位址寫入同一不可變物件。

可補償效果

無法真正回滾,但可以執行相反操作,例如建立預約後取消預約。

不可逆效果

例如公開發布、永久刪除、對外寄信、付款或觸發實體設備。

其風險順序可寫成:

LocalIdempotentCompensatableIrreversible.\operatorname{Local} \prec \operatorname{Idempotent} \prec \operatorname{Compensatable} \prec \operatorname{Irreversible}.

風險越高,封裝提交前需要越強的確認、權限與觀測。

7.3 能力導入

外部效果最好透過顯式能力導入,而不是讓積木任意取得整個主機權限:

ΓB={filesystem.read,storage.write,model.invoke,network.send,publish.approve}.\Gamma_B = \{ \operatorname{filesystem.read}, \operatorname{storage.write}, \operatorname{model.invoke}, \operatorname{network.send}, \operatorname{publish.approve} \}.

若積木沒有導入某項能力,Runtime 原則上就不應允許其執行該效果。

這使權限從文件中的道德聲明,轉變成可由執行層強制的邊界。

7.4 效果封閉性

本文定義:所有可觀測副作用都被宣告、追蹤或由能力系統限制時,積木具有效果封閉性:

EffectClosed(B)    ObservedEffects(B)DeclaredEffects(B).\operatorname{EffectClosed}(B) \iff \operatorname{ObservedEffects}(B) \subseteq \operatorname{DeclaredEffects}(B).

MVP 可在測試執行與沙盒執行中比較:

ΔE=ObservedEffects(B)DeclaredEffects(B).\Delta_E = \operatorname{ObservedEffects}(B) - \operatorname{DeclaredEffects}(B).

若:

ΔE,\Delta_E\neq\varnothing,

則不得自動提升為已驗證積木。


8. 從工作流到函數積木的推斷程序

8.1 輸入

函數化程序接收:

Functionize(ΣC,M,P,H),\mathsf{Functionize} ( \Sigma_C, M, P, H ),

其中:

  • ΣC\Sigma_C :EQB 產生的一致候選快照;
  • MM :節點、模型、工具與 Runtime 元資料;
  • PP :治理與安全政策;
  • HH :執行與修改歷史。

8.2 十步流程

第一步:抽取候選子圖

建立內部節點、邊、控制條件與巢狀積木清單。

第二步:建立跨界清單

找出資料切邊、事件切邊、外部資源、狀態儲存、能力與權限。

第三步:產生端口候選

依每個跨界交互建立端口,保留原始來源與信心分數。

第四步:型別與語義統一

合併相容端口,但不因底層型別相同而忽略語義差異。

第五步:狀態辨識

根據節點宣告、歷史執行與讀寫行為,區分暫時、持續、外部、衍生與機密狀態。

第六步:效果掃描

結合靜態元資料、沙盒追蹤與 Runtime 日誌,建立效果與能力清單。

第七步:合成契約草案

產生輸入、輸出、前後條件、錯誤、品質、權限與版本描述。

第八步:產生驗證案例

至少生成:

  • 正常案例;
  • 邊界案例;
  • 失敗案例;
  • 重試案例;
  • 權限拒絕案例;
  • 狀態恢復案例。

第九步:信心與歧義評估

對每個推斷項目記錄:

qi[0,1],q_i\in[0,1],

並列出候選解釋,而不是只輸出單一答案。

第十步:提交或退回

只有當最低門檻成立時,才由 EQB 的原子提交程序寫入權威表示並註冊至 RDR。

8.3 AI 的角色

AI 適合:

  • 命名端口;
  • 解釋節點用途;
  • 合併相似介面;
  • 推斷自然語言契約;
  • 產生測試;
  • 找出可能隱藏依賴;
  • 提出函數化候選。

AI 不應單獨決定:

  • 是否具有付款、發布、刪除等高風險權限;
  • 未知外部效果是否可以忽略;
  • 機密資料是否可被包入積木;
  • 不可逆操作是否可自動重試;
  • 高不確定契約是否可直接成為權威。

因此:

AI proposes+validators constrain+governance commits\boxed{ \text{AI proposes} \quad+ \text{validators constrain} \quad+ \text{governance commits} }

9. 函數化品質與信心

9.1 五維品質向量

令函數化品質為:

QF(B)=(qb,qp,qc,qs,qe),Q_F(B) = (q_b,q_p,q_c,q_s,q_e),

其中:

  • qbq_b :邊界完備度;
  • qpq_p :端口充分度;
  • qcq_c :契約可執行度;
  • qsq_s :狀態顯式度;
  • qeq_e :效果封閉度。

總分可以作為產品顯示,但不能以單一平均值掩蓋高風險缺陷。最低門檻應採用:

Qmin(B)=min{qb,qp,qc,qs,qe}.Q_{\min}(B) = \min \{q_b,q_p,q_c,q_s,q_e\}.

若效果封閉度極低,即使其他四項很好,也不應自動提交。

9.2 函數化狀態

積木可具有以下狀態:

DRAFT
  → INFERRED
  → REVIEWED
  → EXECUTABLE
  → VERIFIED
  → CERTIFIED

其中:

  • DRAFT:只有工作流與初步名稱;
  • INFERRED:AI 已產生端口與契約候選;
  • REVIEWED:人類或政策已確認主要歧義;
  • EXECUTABLE:可以由 Runtime 正常調用;
  • VERIFIED:通過最低測試與效果核對;
  • CERTIFIED:具有更強證據或正式批准。

這避免系統把「可呼叫」與「已可信」混為同一狀態。


10. 觀測等價與內部替換

10.1 積木對外身分

兩個內部實現 RiR_iRjR_j 若要被視為同一積木的可替換版本,至少必須在契約允許的觀測域內等價:

RiCBRj.R_i \equiv_{C_B} R_j.

其含義是:對所有符合前置條件的輸入、允許狀態與環境,兩者的外部可觀測輸出、狀態變化、效果、錯誤與品質皆落在契約允許範圍內。

可形式化為:

x,s,γ,p,\forall x,s,\gamma,p,

若:

PreCB(x,s,γ,p),\operatorname{Pre}_{C_B}(x,s,\gamma,p),

則:

Obs(Ri(x,s,γ,p))CBObs(Rj(x,s,γ,p)).\operatorname{Obs} (R_i(x,s,\gamma,p)) \sim_{C_B} \operatorname{Obs} (R_j(x,s,\gamma,p)).

10.2 效果也是等價的一部分

只比較最終輸出 YY 不足以判定等價。例如:

  • 兩個版本都輸出相同圖片;
  • 其中一個未經允許把提示詞傳送到第三方服務;
  • 另一個完全本地執行。

雖然 Yi=YjY_i=Y_j ,但效果與安全語義不同,因此:

Ri̸CBRj.R_i \not\equiv_{C_B} R_j.

這也是 AEREC 演化必須依賴完整契約,而不能只比較輸出樣本的原因。


11. 與既有介面與工作流思想的關係

11.1 介面描述與內部實現分離

WebAssembly Component Model 的 WIT 將介面與 world 用來描述元件提供與需要的功能,並明確區分外部契約與內部行為。這提供一個重要工程參照:RABCL 大格子也應以 imports/exports 或等價結構描述它對外提供與依賴的能力,而不是讓呼叫者理解內部節點。

11.2 語言無關的機器可讀契約

OpenAPI 的核心價值之一,是讓人類與機器在不查看服務原始碼時,也能理解其操作、參數、回應、錯誤與安全要求。RABCL 的契約層可以借鑑這種語言無關描述,但對象不只限於 HTTP API,而包含本地函數、模型、檔案操作、事件流與 Agent 工作流。

11.3 流程圖不是完整執行語義

BPMN 等流程規格證明,流程節點、事件、訊息與控制結構可以被標準化與機器表示;但 RABCL 進一步要求流程在封裝後形成可再次組合的一級積木,並把狀態、權限、效果與演化證據納入同一權威描述。

11.4 持久執行與狀態恢復

耐久工作流系統顯示,長時間執行的函數可以在故障後恢復到先前位置,而不必被迫表現成一次性無狀態呼叫。RABCL 因此不把「函數」限制為瞬時執行,而允許 Pending、檢查點、外部事件與可恢復狀態。


12. 最小積木描述格式

後續 MVP 可以先使用如下概念結構:

block:
  id: evemiss.asset.generate-validated
  version: 0.1.0
  name: GenerateValidatedAsset
  status: executable

  inputs:
    - name: source
      type: asset-ref
      required: true
    - name: requirements
      type: generation-spec
      required: true

  outputs:
    - name: approved_asset
      type: asset-ref

  errors:
    - validation_failed
    - model_unavailable
    - permission_denied
    - timeout

  state:
    - name: retry_count
      kind: persistent
      authority: runtime
      reset: per-job

  capabilities:
    - model.invoke
    - storage.read
    - storage.write

  effects:
    - kind: write
      target: asset-store
      idempotency: content-addressed
    - kind: invoke
      target: selected-model
      compensation: none

  lifecycle:
    timeout: PT10M
    retry:
      max_attempts: 3
      only_for:
        - model_unavailable

  security:
    secrets:
      - model-credential-ref
    approval_required_for:
      - publish

  provenance:
    source_workflow: workflow-hash
    snapshot: snapshot-hash
    contract_inference: inference-report-hash

這份格式不是最終標準,只用來確認 MVP 最低需要保存哪些語義。


13. 基本命題

命題一:圖切邊不足命題

只根據節點圖的入邊與出邊,不能完整推斷函數邊界,因為狀態、外部資源、權限、時間與副作用可能不表現在顯式連線上。

命題二:純函數非必要命題

一個工作流可以成為合法函數積木,而不必是純函數;但其狀態與效果必須顯式化。

命題三:端口語義命題

端口相容不只取決於底層資料型別,也取決於語義、基數、時序、所有權、權限與錯誤通道。

命題四:契約先於演化命題

若沒有穩定外部契約,AEREC 無法判斷新實現是合法最佳化、語義擴充或功能破壞。

命題五:狀態權威命題

任何會影響外部行為的持續狀態,都必須具有可查詢的權威位置、生命週期與遷移規則。

命題六:效果等價命題

輸出相同不足以證明兩個積木實現等價;外部效果、權限與錯誤行為亦屬觀測語義。

命題七:AI 候選命題

AI 可以推斷並合成函數介面,但推斷結果在通過驗證與治理提交前,只是候選契約。

命題八:拒絕函數化命題

若邊界不明、隱藏效果無法限制、狀態無法一致保存或契約無法測試,系統應保留原工作流,不強制將其封裝為函數積木。


14. MVP 邊界

第一版 MVP 不需要解決通用程式分析。可以限制為:

  • 節點必須提供基本元資料;
  • 外部工具呼叫必須經統一 Adapter;
  • 檔案、網路、模型與資料庫能力經 Runtime 代理;
  • 僅支援有限型別集合;
  • 只推斷顯式連線與代理可觀測效果;
  • AI 生成契約草案;
  • 使用者確認高風險項目;
  • 沙盒執行一次正常案例與一次失敗案例;
  • 通過後才建立大格子;
  • 大格子可展開回原工作流。

最低驗收條件可以寫成:

MVPReady(B)    TypedPorts(B)ExecutableContract(B)StateDeclared(B)EffectsDeclared(B)Rollbackable(B).\operatorname{MVPReady}(B) \iff \operatorname{TypedPorts}(B) \land \operatorname{ExecutableContract}(B) \land \operatorname{StateDeclared}(B) \land \operatorname{EffectsDeclared}(B) \land \operatorname{Rollbackable}(B).

15. 限制與風險

本文仍有以下限制。

第一,AI 對自然語言節點與第三方工具的意圖理解可能錯誤,不能取代實際 Runtime 觀測。

第二,反射、動態載入、任意程式碼、原生外掛與未經代理的網路操作,可能繞過效果追蹤。

第三,工作流的功能契約可能依賴統計性品質,而非單一確定輸出。生成式模型積木需要分布、品質門檻與評估器,而不能只以精確相等判斷。

第四,長時間工作流的狀態、外部事件與人工核准會使函數介面更接近協議或狀態機,而非一次呼叫。

第五,過度暴露所有內部狀態與效果會使介面難以使用;過度隱藏則會破壞安全與可替換性。RABCL 必須在最小介面與充分契約之間取得平衡。

第六,契約本身也會演化,因此必須在第五、六篇進一步處理權威版本、相容性、證書與回滾。


結論

工作流成為函數,不是因為它被畫上一個外框,也不是因為系統替它產生一個名稱。真正的函數化,是將原本散落在工作流內外的可觀測語義,收斂成一個具有清楚邊界、端口、契約、狀態與效果的可呼叫單元。

其核心轉換為:

WCBoundaryBPortsPBContractCBState+EffectsFB\boxed{ \mathcal W_C \xrightarrow{\mathsf{Boundary}} \partial B \xrightarrow{\mathsf{Ports}} P_B \xrightarrow{\mathsf{Contract}} C_B \xrightarrow{\mathsf{State+Effects}} F_B }

最終得到:

FB:(X,S,Γ,P)R(Y,S,E,T)\boxed{ F_B: (X,S,\Gamma,P) \rightarrow \mathcal R(Y,S',\mathcal E,\mathcal T) }

這個表示承認現代 AI 工作流可能有狀態、可能非同步、可能失敗、可能呼叫外部世界,也可能需要人工或 Agent 參與。它不把這些現實藏起來,而是將它們提升為正式介面的一部分。

因此,RABCL 中的大格子不是黑盒,而是可受約束地隱藏內部細節、同時公開足夠外部語義的契約膠囊

只有完成這一步,工作流才能真正從「一張可執行的圖」升格為「一個可以再次組合的語言基元」。


參考基礎

  1. WebAssembly Component Model:WIT、Interfaces、Worlds 與 Components 相關官方規格與設計文件。
  2. OpenAPI Initiative:OpenAPI Specification v3.2.0。
  3. Object Management Group:Business Process Model and Notation(BPMN)Version 2.0.2。
  4. Temporal Technologies:Durable Execution 與 Workflow 官方文件。
  5. EveMissLab:RABCL 第 01 篇〈連線即封裝〉。
  6. EveMissLab:RABCL 第 02 篇〈封裝靜止屏障〉。
  7. EveMissLab:MSSP × RDR 整合規格與 AEREC 系列。