Agentic Reliability Engineering

第九章
自主式混沌工程

本章為最終書稿的第七章。請注意,GitHub 儲存庫將於稍後正式啟用。
若您願意實際參與本草稿的審閱與意見回饋,請與編輯聯繫:jleonard@oreilly.com

今天大多數把混沌工程做得好的團隊,是以季度為單位在做——遊戲日、排定好的演練、幾週前就選定日期的刻意破壞。這套紀律為整整一個世代的 SRE 實務創造了巨大的價值,這份價值並沒有消失。消失的,是它底下的那個假設:三月被測試的系統,與六月被測試的系統足夠相似,讓季度快照足以作為韌性的證據。在一個代理式環境裡,你三月測試的系統,不是你六月正在運行的系統,而原因不是有人上線了一次重大變更,而是系統本身持續在演化——服務來來去去,依賴關係隱含地轉移,流量模式隨季節移動,代理學會了新的行為。如今存在的決策路徑,在上一次遊戲日並不存在,它們是由累積的推理形成的,而不是由任何刻意的工程決定形成的。

混沌工程要回答的核心問題,也隨之改變了。傳統的問題是「這套系統能不能撐過這次失效」。代理時代的問題,則是「我們目前對這套系統所持有的假設,是否依然成立」。第一個問題有一個二元的答案,能對一次已知的壓力產出有用的證據;第二個問題是持續性的,能對「這套系統對自己有多少信心」產出證據。兩者都值得問,但只有第二個問題,能靠一門持續運行、而不是以季為單位運行,由機器主導、而不是由人類排程,並且與即時決策綁定、而不是與事後檢討會議綁定的紀律來回答。這門紀律,就是自主式混沌工程(Autonomous Chaos Engineering,ACE),本章要展開它是什麼、如何運作,以及要安全地做到它,代價是什麼。

本章要安裝的轉變,有三個動作。第一,脆弱度變成一種訊號,而不是一項要被發現的特質。混沌代理(第 7.3 節完整登場)持續發送脆弱度證據,就像觀測代理發送延遲一樣。推理平面把脆弱度當成眾多輸入之一來讀取;治理平面把它當成自主性擴張的一項限制。第二,驗證變成程式碼。「驗證即程式碼」(Validation-as-Code,VaC),是本章第二個正式產物,緊接在第六章的 CRS 之後,它讓關於穩定狀態行為的假設變得可執行。一個你無法運行的假設,是一個你無法驗證的假設——系統沒有辦法知道這個假設是否依然成立。第三,學習複利累積,不是靠讀事後檢討,而是靠第 5.8 節那同一套封閉學習迴圈套用到混沌結果上。每一次實驗,無論成功與否,都會產出學習代理能夠吸收的結構化證據。第 3.0 節的複利曲線,在這個迴圈裡生死攸關,而混沌,正是以穩定的節奏,給它新證據可供學習的關鍵。

本章也正式命名了代理式系統最獨特的風險之一。「幻覺傳播」(Hallucination propagation,第 7.7 節),是這樣一種失效模式:一個在某個代理身上廉價形成的錯誤信念,隨著它流過檢索管線、記憶,以及代理間訊息傳遞,變得愈來愈權威。這是傳統混沌工程幾乎從不會呈現出來的失效模式,因為它不是由任何東西的失效觸發的,而是由「看似合理、實則錯誤」的推理觸發的,而系統則繼續自信地依照那份推理行動。把它命名為一個混沌問題,正是讓這套架構能夠防範它的關鍵;忽略它,則會讓自信地犯錯的決策複利累積成沒有人能乾淨歸因的事故,因為技術上什麼都沒有失效。本章最後,會把混沌重新接回五大旗艦 SLO 與成熟度模型,這正是讓 ACE 變得可量測、而不只是憧憬的關鍵。

7.1 ACE 的典範轉移:脆弱度作為第一等訊號

十年前被構想出來時,混沌工程是一個動詞——你「跑」混沌、你「注入」一次故障、你「觀察」復原。當混沌是人類在人類控制的排程上對系統做的事情時,這個動詞形式的用法是合適的;當混沌變成系統持續對自己做的事情時,它就變得不對了,因為這項活動如今是環境式的,而不是間歇性的。ACE 問的是一個不同的問題,用的是一套不同的文法。它問的不是「當我弄壞這個東西時會發生什麼」,而是「這套系統現在離失效有多近,有什麼證據支持這個估計」。在這個框架下,脆弱度不是一項要在它以事故形式浮現時才被發現的特質,而是這套架構持續發送的一個訊號,就像它發送延遲與錯誤率一樣。這裡的文法是名詞,不是動詞——這套系統是脆弱的,或者不是;這個分數是即時的,或者已經過時;這份證據是新鮮的,或者已經腐化。

值得放慢腳步的概念性轉變,是「失效」與「脆弱度」之間的區別。失效是二元的:某件事壞了,或者沒壞。脆弱度是機率性、持續性的:考量到我們目前對這套系統狀態所知的一切,它在合理壓力下失效的可能性有多高。一套系統可以完全沒有失效、卻愈來愈脆弱,而大多數登上頭條的事故的失效模式,一開始都是安靜的脆弱度,在事故發生之前,沒有人給它取過名字——服務之間形成了從未被設計成要互相依賴的間接依賴關係;復原路徑因為沒有人運行它們而變慢;代理累積信心的速度快過累積證據的速度;優化行為把運作邊際推得愈來愈靠近安全門檻。這些沒有一個會觸發警報,沒有一個會出現在 SLO 儀表板上。合在一起,它們定義了系統真正的韌性狀態,而系統在 ACE 開始盯著它們之前,並不知道它們的存在。

要讓脆弱度成為第一等訊號,這套架構需要三件事成立。脆弱度必須能從系統早已維護的產物中被觀察到——拓撲代理的依賴圖(第 2.4 節)揭露間接依賴與擁有權缺口;觀測代理的訊號契約揭露變異變化與穩定狀態漂移;學習代理的校準紀錄揭露信心跑得比證據快的代理。這些都不是新的儀表化,只是用一副不同的眼鏡去讀取既有的儀表化。脆弱度必須能以推理平面可以據以推理的形式表達出來——混沌代理(第 7.3 節介紹)為系統的每個區域產出一份結構化的脆弱度評估:哪些依賴暴露最多,哪些復原路徑最陳舊,哪些代理正運作在自己的證據範圍之外。脆弱度必須與行動連結——治理平面把脆弱度讀取為一項對自主性擴張的限制:一個脆弱度正在上升的服務,不應該是一個授權層級正在上升的服務。第 4.9 節描述的 L4 到 L5 轉換,仰賴的正是這個連結,因為沒有它,自主性擴張就會變成習慣的函數,而不是證據的函數。

運作節奏上的轉變,也值得點名。季度混沌演練,以爆發的方式產出證據,系統以季度的節奏學習,即使它運作所在的世界每天都在改變。ACE 持續產出證據,讓系統的模型保持大致最新。這個代價不是零——持續性混沌,需要有邊界的爆炸半徑(第 7.6 節展開安全原語)、自動化的中止標準,以及一種接受「小型實驗持續在生產環境裡運行」、而不是「大型實驗偶爾在預生產環境裡運行」的文化。大多數團隊發現,這個轉變需要一季有紀律的投資,運作節奏才會穩定下來。到了第二季,問題不再是「我們這週要不要跑混沌」,而變成「我們系統的哪些假設,已經腐化到需要驗證的程度了」。第一個問題是一個排程決定;第二個問題是一個證據決定。只有第二個問題,能擴展到持續演化的系統。

附註 脆弱度是一種訊號,失效是一個事件。一門圍繞著事件組織起來的紀律,會告訴你剛剛壞了什麼;一門圍繞著訊號組織起來的紀律,會告訴你什麼正在變得不安全。兩者都有價值,但只有後者,能以符合現代系統實際變化速度的節奏產出證據。

值得點名的架構後果,是 ACE 把混沌從一項排定好的實務,變成一項持續性的實務,而這個改變不只是關於節奏。它改變了「誰決定混沌何時運行」。在排定好的模型裡,人類選擇實驗、運行它們、解讀結果、寫下發現。在持續性的模型裡,混沌代理產生假設,治理平面授權有邊界的實驗,測試代理(第 6.5 節)依照驗證即程式碼評估結果,學習代理把證據回饋進系統的模型裡。人類參與混沌政策的設計(迴圈之上),以及在罕見情況下審查結構上新奇的假設(迴圈之中)。大部分的工作持續運行,在產出這套架構能夠吸收的結構化證據的小型、有邊界的實驗裡。這正是第三章那同一套 DRAL 迴圈,套用到一個目的是「讓系統對自身的模型保持誠實」的工作流程上。

經濟學也以值得點名的方式改變了。季度混沌演練,每次實驗的成本很高:幾小時的準備、幾小時的執行、幾天的撰寫,還要等好幾週才能進行下一次演練。持續性混沌,每次實驗的成本很低,因為一旦這套架構到位,每次實驗的開銷會急劇下降。一次持續 90 秒的有邊界生產環境實驗,針對代理自動產生的假設,結果由學習代理吸收、不需要人類介入,一旦基質存在,就不會讓團隊付出任何代價。混沌工程的總成本下降了,即使實驗的總量提升了一個數量級,因為在一門持續性紀律裡,第一百次實驗的邊際成本,遠低於一門排定好紀律裡第十次實驗的邊際成本。讓 ARE 對事故應變有價值的同一個轉變,讓它對混沌同樣有價值:把工程心力移到生命週期更早的位置、移進迴圈之上的工作裡,讓進行中的工作能夠擴展到人類注意力無法維持的量級。

7.2 代理式系統裡的突發行為

大多數代理時代的失敗,不是來自單一元件的故障,而是來自沒有人設計、也沒有人完全擁有的元件間互動。一個服務裡的重試政策,放大成了跨三個下游服務的同步負載尖峰;兩個各自為了本地 SLO 而優化的代理,收斂到同一個備援路徑上,讓它飽和;一個適應性路由決策,與一個適應性擴容決策互動,產出了一個沒有任何單一代理能看見的回饋迴圈。這些都不需要一個 bug——大多數情況下,是「照設計運作」的元件,在沒有任何設計對話預期到的規模與條件下相遇。這一類失效,我們稱之為「突發性失效」(emergent failure),它是代理式系統裡未知脆弱度的主要來源。

突發性失效的界定特質,是它存在於「互動層」,而不是「元件層」。一次元件層級的混沌實驗(殺掉這個 pod、丟棄這些封包),無法把它呈現出來,因為每個元件依照自己的契約都在正確運作。這個失效,只在契約彼此相遇、且只在同時結合了局部壓力、多個並行決策,以及不完整的共享情境時才存在。這正是為什麼傳統混沌工程會漏掉這一類風險:傳統混沌是元件形狀的,而這些失效不是。突發性失效問的問題是「當這三個各自獨立運作都正確的代理,同時對重疊的訊號採取行動時,會發生什麼」。這個答案不存在於任何單一代理的規格裡,它存在於系統的行為裡,而找到它唯一的方法,是直接探測互動層。

第 7.3 節混沌代理的工作,正是要做這種探測,但這個框架屬於這裡,屬於 7.2:這個代理找的不是可能會失效的元件,而是可能會失效的互動,而這些互動,存在於可預測的結構性位置。共享資源:任何時候,只要有多個代理對同一個資料庫、同一個快取、同一個受速率限制的 API 採取行動,互動層就變成了脆弱度的候選對象。回饋迴圈:任何時候,只要一個代理的輸出是另一個代理的輸入,互動層就變成了脆弱度的候選對象,尤其當兩個代理都會依照近期觀察調整自己的行為時。推斷出來的契約:服務之間依照未在任一方契約裡宣告、只能從拓撲圖裡看見的方式互相依賴。復原收斂:多個代理在壓力下伸手去拿同一個備援方案的情況,讓那個原本應該是安全閥的資源恰好飽和。這四個類別,涵蓋了編輯團隊見過的大多數突發性失效案例,構成了混沌代理在產生假設時所搜尋的結構性模式。

本章其餘部分會反覆出現的一個實務框架,是「行為介面面積」(behavioural surface area)。行為介面面積,是突發性失效可能形成的互動層位置的集合,依每個位置暴露於「產生突發現象的條件」的程度來評分。一個決策會影響共享狀態的服務,行為介面面積比一個決策孤立的服務要高;一個依照推斷、而不是明確契約行動的代理,行為介面面積比一個契約完全被宣告的代理要高;一條自上次架構變更以來就沒有被演練過的復原路徑,行為介面面積比一條經常被走過的路徑要高。混沌代理,為自己所運作的系統維護一份行為介面面積清單,依暴露程度為這些位置排序,並針對排序最高的位置產生假設。這正是讓 ACE 變得「有針對性」、而不是「隨機」的關鍵——這個代理選擇實驗,不是因為它們被排定了,而是因為拓撲與近期活動合在一起,暗示著某個特定的互動,正是脆弱度最可能下一個浮現的地方。

警告 一個從未作為一個生態系被混沌測試過的代理生態系,還沒有準備好上生產環境。每一個代理,個別來看可能都很出色,但它們之間的互動,正是產出這一類系統裡大多數頭條事故的失效面,而一套只測試元件、不測試互動的混沌紀律,會漏掉整整一個類別。ACE 是架構性的答案;人類形狀的等價物,是多代理遊戲日,它能找到其中一部分,但無法以系統需要的節奏運行。

在進入 7.3 的假設挖掘之前,值得點名的重點是:突發性失效是無法被預防的。你無法在一套適應性系統裡預防它,就像你無法預防一座城市裡突發的交通模式一樣。你能做的,是及早偵測它、限制它的影響,並在它浮現時更新你的模型。ACE 提供了偵測機制;有邊界的爆炸半徑(第 7.6 節)提供了影響上限;學習代理的封閉學習迴圈提供了模型更新機制。整套架構合在一起,把突發現象從「產出我們最糟事故的失效模式」,轉變成「我們混沌紀律被設計來在它產出一次事故之前,先把它找出來的失效模式」。這套系統永遠不會變得沒有失效,它會系統性地變得更不容易被自己確實擁有的失效所驚訝。

7.3 機器主導的假設挖掘

一旦脆弱度變得可觀察、突發行為變成了目標,下一個問題就是:實驗要在哪裡運行。一套現代分散式系統,包含數百個服務、數千個依賴,以及數百萬條可能的失效路徑。在這個空間裡隨機運行實驗,浪費、昂貴,且不安全;只在人類懷疑有風險的地方運行實驗,則太慢,且過度偏向人類早已理解的東西。混沌代理的工作,是在這兩個極端之間搭起橋樑,方法是產生「脆弱度最可能出現在哪裡」的假設,依照預期的資訊價值為它們排序,並把高價值的假設排入有邊界實驗驗證的佇列。本節,是混沌代理的完整登場。

這個代理工作所在的概念單位,是假設:一份關於系統可能如何失效的結構化主張。一個假設有四個部分。「位置」:假設中哪個元件或互動是脆弱的。「壓力源」:什麼樣的壓力會讓這份脆弱性浮現。「預期行為」:代理預測在這個壓力下會發生什麼,包括哪些穩定狀態特質可能會被打破、以多快的速度。「證據」:哪些觀測到的訊號,讓這個假設值得被測試,而不是另一個假設。這四個部分被刻意設計成可被檢視。一位審視假設的團隊成員,能質疑每一個部分:工程師可以問,為什麼是這個位置、而不是另一個;為什麼是這個壓力源、而不是不同的一個;為什麼代理主張的預期行為是這樣;以及有什麼證據支持這個假設值得這週跑、而不是下個月。這套結構,正是讓機器產生的假設變得站得住腳的關鍵——沒有它,假設產生就是一個黑盒子,團隊就無法信任代理的選擇。

假設挖掘的過程,持續運行,遵循一套四階段的模式。「訊號彙總」:這個代理讀取訊號平面早已維護的產物,包括拓撲圖、變更事件串流、近期事故紀錄、學習代理的校準歷史,以及測試代理的驗證軌跡。「敘事合成」:訊號群組被聚類成關於潛在脆弱度的短命敘事,每個敘事把一個結構性模式(一個共享依賴、一次近期變更、一個推斷出來的契約),與這個模式可能是個問題的目前證據配對起來。「假設評分」:每個敘事沿著三個軸線評分:爆炸半徑(如果這個脆弱性是真的,會造成多大傷害)、新穎性(這個假設與近期實驗有多不同),以及證據強度(這個敘事攜帶多少相互佐證的訊號)。「實驗排隊」:高分的假設被排入驗證佇列;治理平面依照團隊政策允許的速率,對這個佇列授權有邊界的實驗。

把這件事具體化,來自本章要跟隨的標準混沌情境的兩個實作假設:一個近期收緊了重試政策的支付處理服務,與一個剛上線 schema 遷移的庫存服務共享一個資料庫連線池。

範例 混沌代理本週產生的兩個假設,從它目前的候選清單裡排序而出:

hypothesis_id: HYP-2026-05-14-001
location: payment-service ↔ shared_db_pool
stressor: 200ms induced latency on database write path
expected_behaviour:
  - payment-service retry rate rises to within configured envelope
  - inventory-service queue depth stays under 500
  - aggregate error budget burn does not exceed 1.5x
  - recovery within 90 seconds after stressor removed
evidence:
  - retry policy tightened 6 days ago (release rel-payment-svc-12891)
  - shared connection pool not exercised under this retry profile yet
  - inventory-service schema migration changed write amplification
  - two related "near miss" patterns in the past 30 days
blast_radius_score: 62
novelty_score: 78
evidence_score: 71
composite_score: 70.3
status: queued_for_validation
hypothesis_id: HYP-2026-05-14-002
location: recommendations-agent confidence calibration
stressor: injected contradictory product-availability signals
expected_behaviour:
  - recommendations-agent confidence drops to 0.55 or below
  - agent reduces recommendation aggressiveness automatically
  - no recommendations exceed declared confidence threshold
  - Calibration Error stays within band during the experiment
evidence:
  - agent confidence rose 18% over last 30 days
  - no major evidence-base expansion in same period
  - confidence-without-convergence pattern flagged by Learning Agent
  - similar agent shipped an over-confident decision two months ago
blast_radius_score: 28
novelty_score: 85
evidence_score: 64
composite_score: 61.4
status: queued_for_validation

兩個結構上截然不同的假設,都排名很高。第一個瞄準的是一個典型的基礎架構層級突發性失效(收緊重試下的共享依賴);第二個瞄準的是一個代理基質的脆弱度(信心漂移)。同一套機制產生了這兩者,因為假設的結構,不取決於脆弱度是在服務裡還是在代理裡。兩者都進入同一個實驗佇列,兩者都產出學習代理會吸收的結構化證據。

值得點名的紀律,是假設產生,正是 ACE 的智慧真正所在之處。下游機制(有邊界的實驗、驗證即程式碼的評估、學習代理的封閉學習迴圈),一旦假設形式良好,本質上就是機械化的。假設,是「這次實驗應該要學到什麼」的人類可讀規格,而一個形式不良的假設,無論下游工具有多精密,都無法產出一次有用的實驗。一個假設裡最重要的兩項特質,是可否證性與資訊價值。一個假設若對「什麼能證明這是錯的」有清楚的答案,就是可否證的;一個假設若無論結果(真或假)都會實質改變系統對自己的信念,就是有資訊性的。無論在三項數字軸線上得分多高,任何一項測試沒通過的假設,都不應該進入實驗佇列。混沌代理會在自己的候選清單裡呈現它們,但會標記它們供審查。可否證性與資訊價值,是兩道能夠抓住數字評分漏掉的假設品質問題的質性關卡。

圖 9-1 混沌代理管線:從訊號平面輸入,經過敘事合成與假設評分,到有邊界的實驗。結果餵回學習代理,讓未來的假設變得更銳利。

另一項值得點名的特質,是人類在這個過程裡的角色是「策展式」的,而不是「產生式」的。工程師不寫假設,他們審查代理產生的假設,在資料證明有理時校準評分權重,並在自己的判斷與代理的排序不一致時覆寫這個佇列。這與交付裡的轉變相同:人類從「做這份工作」,移動到「設計這份工作被做好的條件」。這個代理的工作,是永遠不漏掉一個本該出現在清單上的假設;人類的工作,是確保清單一旦被產生出來,就是應該被據以運行的正確清單。這兩個角色是互補的,這份工作能夠擴展,正是因為沒有任何一方,需要做另一方做得更好的事。

7.4 驗證即程式碼:讓假設變得可執行

假設只有在能夠被推翻時,才有意義。這正是大多數混沌計畫最安靜的失效模式:實驗運行了,儀表板被盯著看了,結論從直覺中被得出,但系統本身沒有任何東西知道發生了什麼。團隊或許學到了一些東西,系統則確定什麼都沒學到。在一個代理式環境裡,這道落差是不可接受的,因為代理無法從直覺中學習,它們只能從被明確定義、評估,並記錄下來的結果中學習。「驗證即程式碼」(Validation-as-Code,VaC),是本章第二個正式產物,它把「關於系統行為的假設」變成在每次混沌實驗期間與之後都會運行的可執行檢查。如果假設成立,系統記錄信心;如果不成立,系統記錄證據。無論哪一種,學習都是明確且可重複使用的。

值得放慢腳步的概念性轉變,是驗證檢查的不是「一切是不是都是綠燈」。這個框架太粗糙,沒有用。真實的系統,在混沌實驗期間,會以細緻的方式惡化——有些服務優雅地惡化然後復原;有些惡化了卻持續下去;有些看似健康,卻掩蓋著更深層的惡化。混沌期間的一片綠色儀表板,往往是「這次混沌不夠力」的證據,而不是「系統有韌性」的證據。驗證即程式碼,取而代之,編碼的是可接受的惡化:在這次失效期間,多少效能損失是可容忍的、哪些下游服務被允許惡化、哪些不被允許、不穩定在復原必須開始之前可以持續多久是可接受的、在不確定性之下哪些代理行動是被允許的、哪些需要升級。這些問題早已存在,經驗豐富的團隊會非正式地問這些問題;VaC,強制這些問題被寫下來,寫成系統能夠評估的形式。

針對 7.3 那個支付服務假設的一份 VaC 宣告:

validation_contract: HYP-2026-05-14-001
steady_state:
  payment_service:
    max_error_rate: 2.0%
    max_p99_latency_ms: 450
    max_queue_depth: 500
  inventory_service:
    max_error_budget_burn_rate: 1.5x
    max_p99_latency_ms: 380
  system:
    max_recovery_time_seconds: 90
    max_cascading_alert_count: 0
agent_constraints:
  allowed_actions_during_experiment:
    - traffic_shed
    - retry_backoff_adjust
    - circuit_breaker_open
  forbidden_actions_during_experiment:
    - database_restart
    - schema_rollback
    - cross_service_failover
  escalation_required_after_seconds: 60
abort_conditions:
  - error_budget_burn_rate > 2.0x
  - cascading_alert_count > 0
  - recovery_not_initiated_within: 30s
  - agent_confidence_drop > 40%_in_60s
invariants:
  - >
    checkout latency must not exceed payment-gateway latency by more than 50ms
    under any traffic profile within the experiment window

VaC 契約有四個部分。「穩定狀態斷言」,宣告在這次實驗期間,可接受的行為長什麼樣子,涵蓋直接受壓的服務,以及下游消費者。「代理限制」,宣告在對這次壓力做出反應時,哪些自主行動是被允許的、哪些是被禁止的——團隊不希望代理在一場本該是學習演練的實驗期間,採取激進的補救行動。「中止條件」,宣告無論其他情況如何,這次實驗必須終止的幾個點;第 7.6 節的有邊界爆炸半徑,正是從這份宣告出發的。「不變量」,宣告整個實驗期間都必須成立的特質,以這套架構能持續評估的可執行斷言來表達。這些都不是奇特的東西,它們與第 4.5 節的行動契約,以及第 6.2 節意圖宣告裡的成功標準,是同一種形狀,只是套用在一個不同的營運脈絡裡。這個架構上的對稱,是刻意的。

範例 標準情境的一項具體不變量,以 VaC 寫成:

invariant_id: checkout_payment_latency_bound
declaration: >
  For all traffic profiles within this experiment, the p99 latency of
  checkout-api must not exceed the p99 latency of payment-gateway by more
  than 50ms, measured in 30-second windows.
measurement:
  metric_a: checkout_api.p99_latency_ms
  metric_b: payment_gateway.p99_latency_ms
  window: 30s
  assertion: (metric_a - metric_b) <= 50
evaluation_cadence: every_5s_during_experiment
violation_response:
  - record_violation_event
  - if violation_duration > 30s: abort_experiment
  - if abort_triggered: notify_change_owner

這項不變量,擷取了系統的一項結構性特質:結帳依賴付款,如果結帳延遲的成長速度遠快於付款,就代表有其他東西正在放大它。這項不變量在實驗期間每 5 秒運行一次,以 30 秒視窗評估以過濾雜訊,並在連續違反超過 30 秒時中止。代理不需要被告知這一點,這套架構會從契約裡強制執行它。

值得點名的結構性特質,是 VaC 把混沌變成了會複利累積的學習。每次實驗,都會產出一份結構化的結果紀錄:假設、驗證契約、觀測到的行為、哪些斷言成立、哪些失敗、持續了多久、在什麼條件下。學習代理(來自 5.8)吸收這份紀錄,並相應地更新系統的模型。一個被證實成立的假設,會提升對底層假設的信心;一個失敗的假設,會呈現出一個具體的缺口,附帶正當化投資的證據。隨著時間過去,混沌代理的假設挖掘會變得更銳利,因為過去的實驗精煉了它對「脆弱度實際居住在哪裡」的理解;測試代理的評估會變得更銳利,因為可接受惡化門檻的校準隨著證據而改善;治理平面的政策會變得更銳利,因為「實驗結果」與「自主性擴張」之間的關係,變得由資料驅動、而不是靠憧憬。這正是我們說混沌是「自主性的信心引擎」的意思——它正是那門為這套架構其餘部分複利累積提供證據的紀律。

另一項值得點名的特質,是 VaC 是跨工作流程可攜的。在一次混沌實驗期間運行的同一份不變量宣告,也可以在正常運作期間作為事前控制(第 8.2 節)運行、在交付驗證期間作為測試代理持續迴圈的一部分(第 6.5 節)運行,以及在推理取捨評估期間(第 9.5 節)運行。契約,就是這份可攜性的單位。一支撰寫了一次好的 VaC 不變量的團隊,能在第二部的四個工作流程裡重複使用它,這正是讓 VaC 前期成本變得合理的原因。第一項不變量是昂貴的,第一百項是廉價的,因為團隊已經內化了這個形狀,而這套架構也擁有執行、並從這種形狀的契約中學習的機制。這正是把 ARE 與一堆針對個別工作流程的點狀解決方案區分開來的那種跨工作流程槓桿。

7.5 混沌作為 CI/CD 與執行期原語

一旦假設被挖掘出來、驗證被編碼下來,混沌就不再屬於一份排程表。它會在條件正當化它的任何時候運行,這意味著它運行在兩個地方:在 CI/CD 管線裡,作為一個交付期原語;在生產環境裡,作為一個執行期原語。機制是相同的,觸發器不同。本節簡短,因為實質的機制早已在第 6.5 節(測試代理)、第 6.7 節(交付模式),以及本章前面幾節裡展開了。剩下的,是結構性的框架:混沌在代理式運作模型裡坐落在哪裡,以及同一套架構原語如何服務兩種脈絡。

在 CI/CD 裡,混沌是事件驅動的。一次變更觸發管線;管線計算這次變更的 CRS(第 6.3 節);混沌代理讀取 CRS 與這次變更的爆炸面,決定是否需要混沌驗證。對一次針對一個被充分理解的服務所做的例行變更而言,不需要混沌,測試代理的持續驗證就足夠了。對一次跨越脆弱度門檻的變更(新依賴、新奇的代理行為、鄰域裡近期的脆弱度證據)而言,混沌代理會產生一次有邊界的實驗,治理平面在 CI/CD 的預生產環境裡授權它,而這次實驗,是針對這次變更可能弄壞什麼而具體對齊的假設運行的。結果會餵進交付決策:一次通過的實驗,提高對這次變更安全性的信心;一次失敗的實驗,把這次變更路由去審查,而不是晉升。這個模式,與第 6.7 節附帶信心把關的金絲雀,是同樣的形狀,只是這個金絲雀,現在承受的是一個刻意的壓力源,而不是靠自然的流量變異來呈現問題。

在生產環境裡,混沌是訊號驅動的。混沌代理持續維護一個系統脆弱度輪廓的視圖,當脆弱度證據在系統的某個區域累積時,實驗就會被觸發:無法解釋的信心漂移、沒有升級成事故的異常群集、長期沒有近期驗證的穩定性、隨時間改變的代理行為。這些實驗比 CI/CD 裡的實驗更小、更短,也更難被注意到。它們的目的不是戲劇性地對系統施壓,而是安靜地驗證「系統對自己目前的理解,是否依然符合現實」。一次影響某個區域 0.3% 流量、持續 90 秒的生產環境混沌實驗,附帶持續運行的 VaC 與緊繃的中止條件,正是那門在刻意驗證之間、防止系統模型漂移的紀律。大多數團隊發現,隨著自己的 ACE 成熟,生產環境混沌會變得更平靜:早期階段,在系統基準線建立的過程中,實驗密集;後期階段,運行的實驗更少、更小,因為脆弱度輪廓變得愈來愈被充分理解,系統的大多數區域,都擁有足夠新近的驗證證據,不再需要新的實驗。

附註 當混沌存在於 CI 裡時,它是一道關卡;當混沌存在於生產環境裡時,它是一個感測器。同一套機制服務這兩種角色,但營運上的意義不同。CI 關卡防止壞的變更抵達生產環境;生產環境感測器,抓住的是任何變更都沒有造成的漂移——那種來自系統自己演化、卻沒有人上線任何東西所造成的漂移。

值得點名的架構特質,是這種雙重位置,正是讓 ACE 變得完整的關鍵。只有 CI 的混沌,會漏掉生產環境漂移;只有生產環境的混沌,會漏掉最糟的情況——一次變更引入了一個原本生產環境漂移正要暴露出來的 bug,而這個組合,恰好產出了一次事故。這兩種脈絡,產出學習代理以不同方式吸收的不同類型證據。CI 實驗,產出關於具體變更的證據:更新 CRS 歷史波動性組成(第 6.3 節)的那種證據。生產環境實驗,產出關於系統目前實際樣貌的證據:更新混沌代理脆弱度輪廓、以及拓撲代理依賴圖信心的那種證據。合在一起,它們構成了這套架構需要用來讓自己的模型對照現實保持校準的封閉迴圈。第 4.9 節的成熟度模型乾淨地對應到這裡:L3 是 CI 混沌成為管線例行部分的等級,L4 是生產環境混沌作為感測器持續運行的等級。達到 L3、卻沒有達到 L4 的團隊,會在一兩季之後發現,自己的生產環境系統,已經以自己 CI 實驗無法呈現的方式漂移了;達到 L4、卻沒有達到 L3 的團隊,會發現自己是在事後、而不是事前抓住漂移。兩個部分都是必要的,而第二個部分,正是讓這一切能夠擴展的關鍵。

決定混沌何時運行的觸發邏輯,值得自己的關注。在 CI/CD 裡,觸發器就是變更本身:管線計算這次變更的 CRS,混沌代理讀取這個分數與爆炸面,一個政策門檻決定是否需要有邊界的混沌驗證。在生產環境裡,觸發器更微妙。混沌代理盯著四類暗示「系統的模型可能已經漂移到需要驗證的程度」的訊號:信心漂移——一個代理對系統某個區域所宣稱的信心一直在上升,卻沒有相應的證據成長;異常群集——一小群沒有升級到事故層級、卻暗示某件事正在改變的訊號異常;穩定性陳舊——系統裡好一段時間沒有被混沌測試過、脆弱度輪廓正變得不確定的區域;拓撲變更——引入新互動介面、卻沒有相應驗證的依賴圖變化。這些每一個,都能從這套架構早已維護的產物中計算出來,這套觸發邏輯,與第 7.3 節的假設挖掘過程是同一種形狀,只是套用在「何時」而不是「何處」這個問題上。

7.6 有邊界的爆炸半徑與安全架構

沒有邊界爆炸半徑的自主混沌,不是混沌工程,而是一次事故。讓持續性、機器主導的混沌足夠安全、能在生產環境運行的安全原語,正是「被描述出來的 ACE」與「被實作出來的 ACE」之間的架構性差異,本節要正式安裝它們。這些原語不是奇特的東西,它們是被刻意編碼進這套架構契約裡、由治理平面在執行期評估、並由執行平面強制執行的限制,無論任何代理如何推理都不例外。這門紀律很重要,因為混沌代理,在某種意義上,是這套架構裡最自主的代理——它決定何時對生產環境施壓。如果它的自主性不受制於自己判斷之外的東西,失效模式會是災難性的。這些邊界是不容妥協的,它們存在於這個代理運作層級之下。

五項原語承擔了大部分的重量。第一項是「範圍限縮」。每一次混沌實驗,都在實驗契約裡明確宣告自己的範圍:哪些服務受壓、它們多大比例的流量暴露其中、哪些使用者群組落在這次實驗的爆炸面裡,以及最長時長是多少。治理平面在授權這次實驗之前,會依政策評估這個範圍;一次範圍超過目前服務層級政策邊界的實驗,會被自動拒絕。代理無法在實驗開始之後擴大範圍,這套架構強制執行範圍,代理在其中運作。

第二項是「中止標準」。每一次實驗,都宣告無論其他狀態如何都必須終止的條件。VaC 宣告的 abort_conditions 欄位攜帶著這些條件(7.4 的範例展示了其中四個)。這套架構會在實驗全程持續評估這些中止標準,評估節奏是個位數秒。任何一項中止條件觸發時,實驗立即終止——代理不會協商,中止是結構性的。一套設計良好的中止標準,涵蓋三個類別:硬性安全上限(error budget 燃燒超過宣告的限制、連鎖警報被觸發)、復原失敗(受壓的服務沒有在宣告的視窗內開始復原),以及意外範圍(效果出現在宣告爆炸面之外的服務裡,暗示這次實驗正在觸及它不該觸及的東西)。

第三項是「速率限制」。這套架構限制了同時能運行多少混沌實驗,以及對同一個服務或區域,新實驗能多頻繁開始。這個上限不只是一個計數,而是一個隨時間的預算,由與 SRE 實務裡評估 error budget 相同的機制評估。一個過去一小時已經被三次實驗鎖定的服務,無論下一個假設的優先度多高,在同一個窗口內都不能被第四次鎖定。這門紀律,防止了一群「小」實驗複利累積成這套架構沒有預期到的更大壓力這種失效模式。每一次實驗都是有邊界的,近期實驗的總量也是有邊界的。

第四項是「強制冷卻期」。每一次實驗之後,這套架構會強制執行一個冷卻窗口,才允許任何新實驗鎖定同一個區域、同一個服務,或它直接依賴鄰域裡的任何服務。冷卻期服務於三個目的:它給系統時間復原、重新建立一個乾淨的穩定狀態基準線;它給學習代理時間吸收前一次實驗的證據,才讓新證據到來;它防止了「為了追求吞吐量而把實驗一個接一個疊起來」的誘惑,而放慢速度才是更安全的特質。冷卻期的時長是政策調校的,典型的預設是 L3 生產環境實驗 15 分鐘,影響更高的實驗更長,在預生產環境裡明確有邊界的實驗更短。

第五項是「人類升級觸發器」。某些類別的實驗,無論混沌代理對這個假設的信心有多高,都需要人類核准才能運行。治理平面依照政策的升級門檻評估每一次實驗:這個代理過去沒跑過的新奇實驗形狀、鎖定被歸類為結構性關鍵服務的實驗、爆炸面包含受特定合規限制使用者群組的實驗、在 error budget 已經以超過宣告速率燃燒時被觸發的實驗。人類核准的不是這次實驗的設計(混沌代理已經做了那件事),人類核准的,是在目前條件下執行這次實驗。這次核准以一次快速的決策落地(幾秒到一分鐘,因為組裝早已完成),但它一定會落地——代理在任何情況下都不會跳過這一步。

警告 沒有邊界爆炸半徑的自主混沌,不是混沌工程,而是一次事故。在本節五項安全原語裡,最常失效的架構紀律是第二項(中止標準),失效時產出最糟事故的架構紀律是第一項(範圍限縮)。第五項(人類升級觸發器),是團隊最容易誘惑自己去「優化」、透過降低需要升級的門檻的那一項。這三種誘惑有著同樣的形狀:團隊對混沌代理建立了信心,想要授予它更多自主性。第 4.9 節的成熟度模型有答案:自主性擴張屬於政策層級(人類撰寫一份新政策),不屬於執行期層級(代理自己決定自己掙得了更多授權)。信任天花板正是為了這個原因而存在——混沌代理恰恰是那種會反覆測試信任天花板的代理,這套架構正確的回應,是守住這條線,直到證據正當化一次審慎的政策變更。

這五項原語共有的架構特質,是它們由執行期強制執行,而不是靠代理自律遵守。混沌代理不會自己檢查自己是否落在範圍、中止標準、速率限制、冷卻期,或升級門檻之內——治理平面會檢查,而執行平面會拒絕運行違反其中任何一項的實驗。這個代理的工作,是產生好的假設;這套架構的工作,是確保即使是一個壞假設,也無法逃脫它有邊界的實驗形狀。這種關注點的分離,正是保護這套架構其餘部分不受任何單一代理錯誤影響的同一個模式。混沌代理得以對假設進行創造性思考,卻不得擴張自己的爆炸面。對這個代理的信心,隨著證據累積而成長;邊界本身,不會鬆動,除非政策被審慎地改變。這正是第 4.9 節 L2 到 L3 信任天花板的跨越,具體套用在最可能測試這道邊界的那個代理身上。

7.7 失效放大與幻覺傳播

代理式系統裡最危險的失效,很少是喧鬧的。它們一開始只是小小的不精確、不完整的情境,或不正確的假設,並在流過推理鏈、代理記憶,以及代理間訊息傳遞的過程中悄悄地複利累積。等到這個失效浮現時,原始的錯誤早已被放大到跨越多個決策、被嵌入多個代理的模型裡,並被這套架構自信地付諸行動。這種失效模式,有一個值得正式安裝的名字:幻覺傳播(hallucination propagation)。這是傳統混沌工程幾乎從不會呈現出來的失效模式,因為技術上沒有任何東西失效。一次檢索回傳了一個看似合理、脈絡上卻錯誤的答案;一個代理把一個中間結論當成證據;另一個代理從那個結論更新了自己的記憶;第三個代理檢索了這個此刻已經腐化的記憶,並用它做出一次自信的決策。沒有警報觸發,沒有元件當機,而這套系統現在正依照一個已經變得權威的錯誤信念在運作。

值得放慢腳步的機制,是「情境」與「證據」之間的差異。證據,是來源與信心在整條推理鏈裡都被追蹤的資訊;情境,是已經被吸收進一個代理工作集、如今被當成背景事實對待的資訊。這兩者之間的邊界,正是幻覺傳播運作的地方。一個代理從一個看起來相似的過去事件裡,檢索出一份歷史事故摘要。這份摘要,作為對那個過去事件的描述而言是正確的;但當它被當成與目前事件相關時,它就變成了錯誤的,因為系統自那個過去事件以來已經改變了,而這份摘要並沒有反映這一點。這個代理不會重新驗證,它把這份摘要當成情境,在它之上建構一條推理鏈,並發出一個自信的決策。如果這個決策被記錄進記憶、或被訊息傳遞給另一個代理,原始的誤判此刻就已經傳播出去了。這個接收訊息的新代理,沒有辦法知道自己收到的情境是不穩固的,因為原本能標記出這個問題的中繼資料(這是什麼時候被學到的、在什麼條件下、對照什麼證據)並不是這則訊息的一部分。

來自標準情境的一個實作範例:本章前面提到的支付服務重試變更。一個事故應變代理,檢索到一份情境,指出六個月前發生過一次類似的延遲模式,並靠重啟應用程式層解決。這份歷史摘要是正確的:那次重啟確實解決了那次過去的事故。但當它被套用到目前這起事故時,它變成了錯誤的,因為自那次過去事件以來,支付服務與庫存服務已經開始共享一個資料庫連線池,而庫存服務剛上線了一次 schema 遷移。這個代理斷定支付服務是根源,這就是幻覺——這條推理鏈是連貫的,這份歷史證據是真實的,信心分數維持在高點。這個代理建議對支付服務做一次滾動重啟,重啟成功,延遲短暫改善,接著卻惡化了,因為真正的原因是庫存服務的遷移與共享連線池之間的互動。此刻連鎖反應開始了:這次重啟帶來的短暫改善訊號,被記錄成部分成功;代理對這個模式的信心遞增;下一次類似的事故,檢索到這次「成功」的復原,錯誤就這樣複利累積。在任何一步,技術上都沒有任何東西失效,系統只是對一個從來就不太對的模式,建構起了愈來愈自信的信念。

對抗幻覺傳播的防禦,必須運作在「信念形成層」,而不是「行動層」。一旦一個自信卻錯誤的行動已經被採取,這套架構的保護措施(有邊界的範圍、自動逆轉、稽核軌跡)會限制傷害,但它們無法防止這個錯誤信念一開始就被形成。五種驗證模式,能從源頭防止傳播。「跨訊號佐證」:任何一項會變成情境的主張,在被當成證據對待之前,必須至少得到兩個獨立資料來源的支持——單靠那份歷史事故摘要是不夠的,它需要來自目前即時遙測資料的確認,代理才能據以行動。「新鮮度門檻」:歷史情境,隨著底層拓撲改變而自動被降權——一份在近期依賴變更之前學到的摘要,在對照目前條件時不能攜帶完整的權重。「負向訊號檢查」:預期指標的缺席,被當成反對某個假設的證據來對待,而不是沉默。如果代理的假設預測資料庫健康會惡化,而資料庫健康訊號是穩定的,這個假設就會失去信心。「部分成功時的信心衰減」:當一個行動產出了部分改善、卻沒有朝著宣告的穩定狀態收斂時,代理對底層假設的信心必須「下降」,不是上升。「強制證據引用」:每一份建議,都必須引用在最近一次驗證窗口內被檢查過的即時遙測資料;只引用歷史情境的建議,會被標記,需要跨驗證才能行動。

圖 9-2 幻覺傳播鏈,以及在信念形成層中斷它的五種驗證防禦。
警告 一個被自信地付諸行動的錯誤假設,比完全沒有假設還要糟。沒有假設的情況,至少呈現出了不確定性;自信卻錯誤的情況,把它藏了起來。幻覺傳播,是把成熟的代理式系統與天真的代理式系統區分開來的架構性風險,這裡描述的防禦措施,對任何 L2 成熟度以上的系統而言都是不容妥協的。一支沒有專門針對信念形成層運行混沌實驗的團隊,會以慘痛的方式在生產環境裡發現這種失效模式,以一起根本原因是「這套系統隨時間變得自信地錯誤,卻沒有人注意到」的事故的形式。

呈現出幻覺傳播的混沌紀律,必然與基礎架構層級的混沌不同。殺掉 pod、丟棄封包,不會產出模糊的條件,它們產出的是清楚的條件。幻覺傳播出現在模糊的條件下,那種存在多個看似合理的解釋、代理必須在其中選擇的情況。混沌代理產生刻意設計來製造模糊性的實驗:注入彼此矛盾、卻各自看似合理的遙測資料;延遲矯正性訊號,同時讓部分真相傳播;腐化單一一個上游情境來源,觀察下游推理的分歧;在代理呼叫之間引入不一致的工具輸出;在不改變表面指標的情況下修改被檢索的文件。這些實驗,測試的是代理究竟會重新驗證假設,還是只會在假設之上繼續建構。一個設計良好的代理生態系,在這些條件下不會喧鬧地失敗,它會遲疑、自我調降權限、尋求協助;一個設計不良的代理生態系,則會自信地行動並傳播這個錯誤。這門混沌紀律,把兩者區分開來。校準誤差(CE),是量測這項特質穩定狀態版本的 SLO,而上升的 CE,正是在任何混沌實驗抓到它之前,標記幻覺傳播漂移的金絲雀指標。

7.8 為韌性而設的封閉學習迴圈

找到脆弱度是不夠的,即使把它修好一次也是不夠的。讓有韌性的代理式系統與傳統系統區分開來的,是每一次混沌結果,都會永久性地改變系統下一次的行為方式。第 5.8 節安裝了封閉學習迴圈(CLL),作為學習代理吸收事故結果的五階段模式;本節把同一套模式套用到混沌上。機制是相同的,輸入與速率不同。事故產出的是稀疏、高資訊量的結果(一週一次或更少,每一次都富含證據);混沌產出的是密集、低資訊量的結果(一週幾十次,每一次都是更小幅度的證據增量)。兩者都餵進同一個學習代理,兩者都產出對系統模型同一種類型的更新。混沌,正是給予學習代理足夠的量、讓它能夠複利累積、而不是漸近趨緩的關鍵。

套用到混沌上的五階段 CLL:擷取系統在實驗當下相信什麼(假設、驗證契約、預測行為、混沌代理對這個假設的信心);觀察實際發生了什麼(哪些斷言成立、哪些失敗、復原長什麼樣子、出現了什麼附帶效應);比較預測與觀察(系統在哪裡對了、在哪裡錯了、這個分歧意味著什麼);提議對系統模型、參數與政策的更新;透過受治理的路徑套用這些更新,使用與第 5.8 節相同的授權層級(低風險更新附帶審查自動套用,中風險更新需要明確的人類核准,結構性更新需要設計審查裡的審慎討論)。

混沌學習更新的四類產物,與事故學習是同一種形狀。假設挖掘模型:混沌代理的訊號彙總,是否呈現出正確的結構性模式;敘事合成,是否正確地把訊號聚類;評分,是否恰當地為假設排序。脆弱度輪廓:系統的哪些區域現在被更好地理解、哪些依然帶著不確定性、目前的脆弱度分布實際上長什麼樣子。驗證契約:哪些斷言被證明校準正確、哪些太嚴格(在健康運作期間失敗)、哪些太寬鬆(在惡化運作期間通過)。信心校準:代理宣稱對這個假設的信心,是否符合類似假設被證實正確的比率。第 3.6 節的校準誤差 SLO,是標記信心校準何時被腐化的金絲雀指標。特別是混沌代理的 CE,是本章最安靜、卻最有後果的訊號之一。

把這件事具體化,一次典型混沌實驗的學習更新:

experiment_outcome: HYP-2026-05-14-001
hypothesis_outcome: "validated with caveat"
predicted_behaviour:
  payment_service.retry_rate: "within configured envelope"
  inventory_service.queue_depth: "<= 500"
  aggregate_error_budget_burn: "<= 1.5x"
  recovery_time_seconds: "<= 90"
observed_behaviour:
  payment_service.retry_rate: "within envelope (peak 8.2%, threshold 12%)"
  inventory_service.queue_depth: "peaked at 487, within threshold"
  aggregate_error_budget_burn: "1.18x peak, well within threshold"
  recovery_time_seconds: "62s (better than predicted)"
  side_effects: "noted: recommendations-service p99 latency rose 8% during stressor"
learning_signals:
  - signal: fragility_profile_updated
    target: shared_db_pool
    change: "exposure_to_retry_amplification: reduced from 0.62 to 0.41"
    path: auto_apply_with_review
  - signal: validation_threshold_recalibration
    target: inventory_service.queue_depth
    change: "consider lowering threshold from 500 to 450 (peak was 487, close to edge)"
    path: human_review_required
  - signal: novel_emergent_interaction
    target: recommendations-service ↔ payment-gateway_dependency
    change: >
      previously unobserved coupling surfaced during experiment;
      add to behavioural-surface-area inventory
    path: human_review_required
  - signal: hypothesis_scoring_calibration
    target: hypothesis_mining_model
    change: >
      blast_radius_score for this class slightly underestimated
      (62 vs observed ~58); minor weight adjustment proposed
    path: auto_apply_with_review

一次實驗,產出四個學習訊號,其中三個餵進系統模型的結構性更新。「新奇突發互動」這個訊號,正是能夠正當化整套 ACE 紀律的那種發現:一次先前未曾觀測到的耦合,在一次有邊界的實驗中浮現,附帶把它列為未來假設目標的證據。沒有 ACE,這個耦合最終還是會浮現,只是會以一次事故的形式;有了 ACE,它以一次受控實驗的一部分浮現,這次實驗的爆炸半徑是有邊界的,證據是結構化的。

附註 沒有餵進學習代理的混沌,是可觀測性劇場。實驗運行了,儀表板看起來可以接受,團隊往前走了,而系統本身沒有任何東西因此改變。兩個月後,同一次實驗會呈現出同樣的假設、同樣的證據,中間什麼都沒學到。CLL,正是把混沌從一個動詞(你做的事),變成一項特質(系統擁有的東西)的關鍵。沒有這個迴圈,ACE 會崩解回帶著一個更精密觸發器的排定式混沌。

第 3.0 節的複利曲線,正是這個迴圈的產物。一支運行 ACE 一季的團隊,擁有一套脆弱度輪廓大致被校準的系統;運行兩季,這份輪廓會變得夠銳利,足以站得住腳地驅動自主性擴張決策;運行一年,系統對自己的理解,會接近那種把 L4 成熟度與 L3 區分開來的結構性自我認識。每一次增量都很小,一年累積下來卻很可觀,而且這份可觀,會以五大旗艦 SLO 裡看得見的方式呈現:ARR 上升,因為代理正確做出更多決策;DQ-SLO 上升,因為這些決策日益有證據支撐;AE-SLO 上升,因為這套架構知道哪些行動真正有效;CE 下降,因為信心與結果變得更加吻合。系統並沒有變聰明,它只是以會複利累積的速率,累積了關於自己的結構化證據。

7.9 量測學習、信任與韌性

第 3.6 節那同一套五大旗艦 SLO,量測 ACE,就像它量測事故應變與交付一樣。沒有新的指標被引入,五大旗艦,是整套架構的運作量測系統。在混沌脈絡裡改變的,是每項 SLO 實際追蹤的東西。混沌裡的自主解決率(ARR),量測混沌代理產生的假設裡,端到端被驗證(假設 → 實驗 → 結果 → 學習)、不需要人類介入的百分比。一支處於 L3 成熟度的團隊,可能在例行生產環境實驗上跑混沌 ARR 80%,剩下的依政策路由給人類審查。決策品質(DQ-SLO),量測混沌決策(測試哪個假設、何時中止、如何為結果評分)是否正確,依照這次實驗觀測到的價值來評估。推理延遲(RL-SLO),量測從假設產生到實驗提交的時間;對混沌而言,這通常以小時計、而不是以秒計,因為實驗是依照速率限制與冷卻期排程的,而不是即時對事故做出反應。行動有效性(AE-SLO),量測這些實驗是否在沒有附帶損害的情況下,達成了自己意圖的學習結果;一次產出意外爆炸面的混沌實驗,無論它發現了什麼,都會算在 AE-SLO 的反面。校準誤差(CE),量測混沌代理的假設信心,是否符合結果比率——這是抓住混沌代理自身幻覺傳播的 SLO,也是最值得為 L4 晉升關注的一項。

一支處於 L3 成熟度的團隊,在穩定狀態下可能看見這樣的數字:混沌 ARR 80%(例行實驗是例行的,新穎性觸發審查)、DQ-SLO 高於 75%(大多數假設證明有資訊性;五分之一最終是死路,這是健康的)、生產環境實驗的 RL-SLO p95 在 4 到 8 小時(速率限制與冷卻期主導)、AE-SLO 高於 85%(大多數實驗維持在自己的邊界之內)、CE 低於 20%(代理對自己假設宣稱的信心,大致符合這些假設被證明正確的比率)。這些數字是示意性的,團隊應該依照自己的證據建立自己的區間。重要的是,同樣的五項 SLO 量測混沌,而團隊據以運作的區間是明確的、經過稽核的,並在證據證明有理時被重新校準。第四部的代理式運作模型,在所有工作流程裡都是連貫的,因為量測系統是相同的。

7.10 從實驗到營運現實

十年前這門紀律存在時,混沌工程是一個動詞:工程師依排程對系統做的事情。ACE 把它變成一項特質:系統擁有的東西,持續存在,作為它如何運作的一部分。這個轉變的後果並不含蓄。一支在 L3 成熟度運行 ACE 的團隊,擁有一套對自己的理解,大致跟上它實際運行所在世界的系統;一支以季為單位運行混沌的團隊,擁有一套對自己的理解,在演練之間漂移的系統,而這份漂移,會以「根因本來是可知、卻不為人知」的事故形式浮現。這套架構,用它為其他一切支付的同一種貨幣,支付這個差異:結構化的產物(假設、VaC 契約、實驗結果)、受治理的行動(有邊界的爆炸半徑、中止標準、升級觸發器)、被學習的結果(套用在混沌上的 CLL)。這份投資會複利累積,這正是為什麼 ACE 出現在這本書裡、而不只是出現在一篇給混沌專家看的獨立論文裡的原因。它是這套架構所服務的第二部四個工作流程之一。

本章「沒有」主張 ACE 能消除意外,它不能。生產系統永遠會呈現出沒有任何混沌實驗預見到的失效模式;適應性系統裡突發行為的失效模式,就其本質而言,是那種無法事先被完整窮舉的類型。ACE 主張的是:這套系統讓自己的營運者感到意外的速率,會隨時間下降,因為系統學習自己的速率會上升。這門紀律對自己的極限是誠實的:混沌無法找到一個「還沒有任何訊號存在」的失效模式,混沌只能找到「訊號存在、但尚未被據以行動」的失效模式。「訊號存在」與「失效顯現」之間的這道窗口,正是 ACE 運作所在的窗口,而這門紀律的價值,與它能多可靠地在失效自己顯現之前就把這道窗口關上,成正比。

第八章是可觀測性強化與事前情報。如果混沌工程透過有邊界的實驗發現脆弱度,事前情報就是透過累積的訊號模式預見失效。餵進混沌假設挖掘的同一個訊號平面,也餵進事前偵測;授權有邊界實驗的同一個治理平面,也授權事前介入。情境豐富層(第 8.3 節)與容量代理(第 8.4、8.5 節),會加入這批反覆出現的代理陣容。不同的議題,同一套架構,離第二部收尾又近了一章。再兩章工作流程,第二部就完整了;本書其餘部分運行所在的基質,也將被完整安裝。