Agentic Reliability Engineering

第六章
代理式可靠性架構

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

大多數 AIOps 專案之所以失敗,是因為它們把智慧加裝到既有工具上,而不是設計出一套智慧能安全運作於其中的系統。這句話總結了十年來觀察到的模式。那些把聰明元件接到既有工具鏈上的團隊,會發現自己在十八個月後,還在解釋為什麼代理的行為不一致、為什麼信任在流失而不是在成長、為什麼同一類事故總是產出不同的回應。先設計系統的團隊不會有這些對話,他們有的是不同的、更困難的對話——但正是那些更困難的對話,才會帶你到達某個地方。

自主性不是一個你打開的功能,而是一種特質,當一個系統被建構成能清楚地觀察自己、在明確的限制內推理、並且不逾越被授予的權限時,這種特質才會浮現。沒有這樣的結構,聰明的元件只會放大既有的形狀——如果系統是破碎的,自主性也會跟著破碎;如果擁有權不清楚,代理就會做出自信卻方向錯誤的決策;如果治理存在於執行期之外,學習就會變得危險,而不是有用。這正是為什麼本書把架構放在工作流程之前,即使工作流程才是自主性最明顯發揮用處的地方。想直接跳到事故應變(第五章)的本能是對的,錯的是順序——這正是架構上的錯誤。本章存在的目的,就是在任何工作流程被疊加上去之前,先把這個結構講清楚。

讀者的第一反應,可能是質疑這個順序。事故應變很痛苦,變更管理很緩慢,混沌工程感覺很手動——這些自然而然是套用代理式行為的地方。但在定義架構之前就把自主性套用到工作流程上,就像在流沙上蓋房子:每個工作流程都會發明自己的模式,限制條件會彼此分歧,學習會變得破碎。久而久之,這個系統會變得更難理解,而不是更容易。第二部裡的每一章,都會回頭引用本章所安裝的這套架構。這些架構原語,在事故應變、交付、混沌、事前工作流程裡都同樣會出現。一旦你在這裡看見它們,你會在其他每個地方都認出它們——而正是這份「認出」,讓工作流程那幾章能作為參考來使用,而不只是獨立的教學。

本章具體要交付的,是一個參考形狀:四個把訊號、推理、執行、治理分開的平面;把「人在迴圈中」當成一個被設計出來的控制迴路、而不是備援機制的一套正規處理方式;一個透過單一情境展示這些平面如何互動的實作參考架構;以及一套告訴讀者「每個等級必須具備什麼,下一個等級才會安全」的成熟度模型。這些都不是廠商範本,而是讓代理式可靠性能夠安全運作所需要的最小架構形狀,以實務工作者能套用到自己環境、而不需要重新發明結構性決策的層次來表達。

附註 一套設計良好的代理式可靠性架構,提供三項保證。「決策是可解釋的」:訊號是結構化的,情境被保留下來,推理路徑是可見的。「行動是有邊界的」:每一條執行路徑,都受到明確政策與信心門檻的限制。「學習是安全的」:回饋迴圈能改善未來行為,而不會掩蓋問題或侵蝕當責。一套沒有提供這三者的架構,產出的自主性,感覺起來會是魯莽的,而不是被工程化出來的,而這兩者之間的差別,決定了這套系統能否在規模化之後依然被信任。

在傳統的可靠性工程裡,信任是社會性的:工程師之間基於經驗、共同的理解、既定的規範來互相信任,這份信任透過審查、事故流程與文化被強化。在代理式系統裡,信任也必須是技術性的:系統必須能夠證明自己為什麼行動、遵守了什麼限制,以及下次會如何表現。這份證明不能只仰賴事後分析,它必須在執行期就是可觀察的。架構,正是讓這一切成為可能的關鍵,也是本章其餘篇幅要展開的內容。

另一個值得先說明的觀察是:本章描述的是結構,而不是規範廠商。並不存在一套適用於代理式可靠性架構的唯一正確平台堆疊,每個平面都有好幾種有效的實作模式,我們會在它們有重要差異的地方為它們命名,但重要的是架構的形狀,不是工具的選擇。一支使用 OpenTelemetry、Prometheus、OPA,加上一套自建推理服務的團隊,可以產出一套乾淨的四平面架構;一支使用完全不同堆疊的團隊,也同樣可以。重要的是,本章所描述的結構性區隔,在團隊選擇的任何堆疊裡都存在且可被強制執行。結構是不變量,實作是在地的。

4.1 從工具到系統:重新框架可靠性堆疊

今天大多數的可靠性堆疊,是「組裝」出來的,不是「設計」出來的。隨著時間過去,團隊為了取得可見性而加入監控工具,為了偵測失敗而加入警報工具,為了協調應變而加入工單系統,為了減少 toil 而加入自動化,為了管理風險而加入治理流程。每一個元件都解決了一個真實的問題,合在一起,它們構成了看起來像是「可靠性系統」的東西。實務上,它們的表現更像是一條「工具鏈」,而工具鏈與系統之間的差別,正是本節要談的。

一條工具鏈,仰賴人類去連接情境、解讀訊號、判斷什麼重要、跨界協調行動。這套堆疊產出資料,但意義是在外部被建構出來的;自動化執行指令,卻不理解意圖;治理雖然存在,卻大多在執行期之外。這套模型之所以在過去二十年運作良好,是因為人類一直扮演著「整合層」的角色——我們刻意使用這個詞。整合層,是情境所在之處,是決策被做出之處,是工具之間的邊界變得有意義之處。在你曾經共事過的每一套可靠性堆疊裡,整合層一直都是待命的人類。他們做得夠好,好到這份整合的成本從未被真正看見。而這個成本如今變得可見了,因為整合層不再能夠擴展。

把這個具體化:想像今天一個中型工程組織裡的一起第一級事故。監控工具觸發了一個警報,呼叫了待命工程師。他們打開儀表板,掃描近期指標,注意到結帳服務上的延遲;跳到追蹤工具去找出哪個依賴變慢了;再跳到部署系統,確認過去一小時是否有東西上線;再跳到聊天頻道,問問有沒有人也注意到了;再跳到拓撲圖(大概是一份 wiki 頁面,大概已經過時),試圖弄清楚爆炸半徑;再跳回監控工具,驗證假設;再跳到操作手冊(同樣是一份 wiki 頁面),找出建議的緩解措施;再跳到雲端主控台去執行它;再跳回監控工具,看著它復原。六個工具,十分鐘,一個人類把所有情境都放在腦中。每個工具都盡了自己的本分,是人類做了把它們變成一套系統的那份工作。當同一起事故必須交給一個代理處理時,那些存在於腦中的情境,一個都不存在——代理繼承的是碎片化,不是整合。這正是代理式可靠性工程強迫每一支團隊必須面對的問題。

這裡的失效模式是可以預見的。沒有一個系統狀態機器可讀、意圖明確、擁有權可被發現、行動權限可被強制執行、結果被量測的一致執行期環境,自主性會以三種方式之一失敗:它會變成純諮詢性的,產出人類在壓力下會忽略的建議;它會變得過度自信,在沒有充分依據或限制的情況下採取行動;或者,它會變得不一致,在相似的條件下表現出不同的行為,因為它所仰賴的情境不完整或正在漂移。這些沒有一個是模型的問題,全部都是系統設計的問題——而這裡所說的系統,正是可靠性堆疊本身。

這個重新框架,說起來直接,做起來卻更難。可靠性不是一組工具,而是一套必須展現出某種行為的系統。與其問「你在用什麼工具」,更好的問題是:這套系統以什麼方式表達自己的狀態,讓機器能夠據以推理?它如何編碼意圖與取捨(效能、成本、風險)?它如何在執行期強制執行邊界?它如何證明自己為什麼行動?它如何在不隱藏擁有權的情況下安全地學習?這些是架構層級的問題,不是工具層級的問題,而今天大多數的可靠性堆疊,無法連貫地回答它們。這正是第 4.2 節的四個平面被設計來填補的落差。

這個重新框架還有第二個後果,值得明確點名,因為它是大多數團隊最容易低估的一點。當整合層是人類時,這份整合的成本是以工程師的時間、注意力與判斷力支付的——成本是真實的,卻是分散的,對預算流程而言不可見。當整合層變成系統本身時,成本轉移到了系統的設計裡:schema、契約、政策,以及系統對自身行為的可觀察性。總成本並沒有下降,它從一項營運費用(事故期間工程師的時間),轉移成了一項結構性費用(設計整合所需的工程工作)。那些以為代理式導入是免費的、因為「代理做了人類過去做的工作」的團隊,通常會感到失望。正確的框架是:代理式導入把成本「重新配置」到了架構投資裡,而架構投資會以營運工時永遠做不到的方式產生複利。

附註 當一個代理在一條破碎的工具鏈上運作時,它繼承的是破碎,不是整合。這是早期代理式導入裡,最常被低估的一項特質。團隊期望「加入代理」就能獲得整合,但只有在他們先把整合設計進系統裡時,他們才會獲得一致性。

由這個重新框架推導出的架構原則是:同一套原語必須橫跨所有工作流程共用。驅動事故應變的訊號,就是驅動變更管理的訊號;規範復原的行動契約,就是規範交付回滾的行動契約;在事故期間限制自主性的治理政策,就是在混沌實驗期間限制自主性的政策。如果每個工作流程都發明自己版本的這些原語,這套系統就會沿著工作流程的界線碎片化,學習也就無法複利累積。如果原語是共享的,每個工作流程都能從其他任何工作流程的改善中受益。這正是架構要排在最前面的結構性理由——第二部的每一章,都運行在本章所安裝的這套架構之上。

最後一點,關於遷移路徑。大多數團隊無法從零重建自己的可靠性堆疊,而本章提出的架構,也不要求他們這麼做。這四個平面可以漸進式地安裝到既有堆疊之上。訊號平面,通常從套用在既有遙測資料上的「結構化發送」紀律開始,用訊號契約包裹團隊已經在產出的串流。推理平面,通常從一個與既有儀表板並行運行的諮詢層開始,在取得執行權限之前先建立起信譽。治理平面,通常從團隊為了合規已經做過的「政策即程式碼」工作中浮現。執行平面,通常從一小份高信心行動的目錄開始,再逐漸成長。這場遷移是真實的工程工作,但它是建立在既有堆疊之上的工程,而不是一場空地重建。這種漸進式的採用,正是第 4.9 節的成熟度模型要逐級講清楚的內容。

4.2 代理式可靠性的四個核心平面

這套架構建立在四個平面之上:訊號平面(Signal Plane)、推理平面(Reasoning Plane)、執行平面(Execution Plane)、治理平面(Governance Plane)。這四個平面,是代理式可靠性系統的結構語法,本書其餘展開的每一項能力,都能被對應到其中一個或多個平面。如果你無法把某項能力乾淨地放進某個平面裡,這就是一個訊號,代表這個設計不完整或不安全。本書其餘部分會如此頻繁地回到這一組概念,值得在這裡放慢腳步,把框架講對。

「平面」(planes)這個詞是刻意選用的。傳統架構描述的是「層」(layers),而層意味著層級——上層消費下層,失效向上傳播,心智模型是一疊層層相依的關係。代理式可靠性需要一個不同的心智模型:平面意味著正交性。每個平面各自獨立運作,卻透過定義明確的介面相交。一個平面的失效,不應該自動波及其他平面,因為每個平面都有自己的職責、自己的契約、自己的失效圍堵。一個壞訊號不應該直接觸發執行;一次推理錯誤不應該繞過治理;一次執行失敗不應該腐化意圖;一條治理規則不應該要求重寫自動化。平面,讓這些邊界變得明確,並且能以程式碼、而不只是政策文件的形式被強制執行。

在我們各自用一節(4.3 到 4.6)展開每個平面之前,值得先快速理解每個平面各自負責什麼、以及各自絕對不能做什麼。

「訊號平面」負責呈現現實。它蒐集、正規化、豐富化,並發布機器能據以推理的遙測資料形式。指標、日誌、追蹤、事件、拓撲、擁有權中繼資料,以及變更情境,都依照第二章的決策級紀律,結構化地存在於這裡。訊號平面不決定什麼重要,不推斷因果關係,也不觸發行動——它的工作是讓真相變得可觀察。一個為儀表板、而不是為機器消費而優化的訊號平面,無論上層其他平面變得多麼精密,都會限制住它們。

「推理平面」負責理解訊號的意義。它從訊號平面消費訊號,依照意圖與政策評估它們,產生假設,比較選項,產出帶有相應信心的「候選行動」。推理平面的輸出永遠不是一個指令,而永遠是一個提案。推理如何運作的內部細節(演算法、提示模式、信心評分),屬於第九章與第十章。在架構這個層級,重要的是那道邊界:推理平面只推理,僅止於推理。如果它能直接行動,這套架構在設計上就是不安全的。

「執行平面」負責改變系統。它執行會修改執行期行為的行動:擴容、路由、節流、重啟、容錯移轉、功能降級。執行是確定性的、有邊界的、可逆的。它不決定該做什麼,只執行已經被核准的事。這個平面圍繞著「行動契約」建構起來,行動契約宣告每個行動做什麼、必須滿足什麼前置條件、成功長什麼樣子,以及若不奏效該如何逆轉。我們會在第 4.5 節正式介紹行動契約;這裡要內化的特質是:執行平面的權限,在結構上被限定在其契約所允許的範圍之內。

「治理平面」負責在執行期強制執行信任與當責。它評估提議的行動,是否符合意圖、政策、風險容忍度與擁有權邊界,並決定目前條件下允許什麼程度的自主性。關鍵在於,治理平面推理的是「權限」,不是「狀態」。推理平面決定什麼行動是合適的;治理平面決定代理是否被允許採取這個行動。對來自傳統 SRE 背景的工程師而言,這是四個平面裡最違反直覺的一個,因為它把治理放進了執行期內部,而不是放在外部、作為一道審查流程。治理平面的工作,是讓「這個行動現在是否被允許」這個問題的答案,變成系統在毫秒之間計算出來的東西,而不是被路由給人類、等上數小時的東西。

這幾個平面,是在一個持續不斷的迴圈裡互動,而不是一條線性的流程。訊號平面持續產出訊號,推理平面消費它們並產出提案,治理平面評估提案並核准或駁回,執行平面執行已核准的行動,並把結果訊號發送回訊號平面。這個迴圈不斷重複。這正是第三章的 DRAL 迴圈被對應到一個架構結構上的樣子:偵測是訊號平面的工作,推理屬於推理平面,行動透過執行平面運行,而學習則透過把結果回饋給訊號平面來閉合這個迴圈。治理平面坐落在推理與行動之間,強制執行讓行動變得安全的限制。第二部的每一個工作流程,都是這個迴圈套用在某個具體營運議題上的一個實例。

這套平面模型也是一種診斷工具。如果你的監控系統直接觸發腳本,你就把訊號與執行合併了,架構就沒有機會進行推理。如果你的自動化內嵌了政策邏輯,你就把執行與治理合併了,政策會在自動化改變時變得不可見、不可強制執行。如果你的 AI 系統既決定又行動、卻沒有限制,你就把推理與執行合併了——這是最危險的合併,因為它移除了讓自主性有邊界的安全檢查。每一次合併,都會提升速度、降低安全性;每一次區隔,都會降低風險、提升信任。剛接觸這套架構的團隊,可以把四個平面當成一份結構性稽核清單來用:我們目前的堆疊裡,每個平面各自存在於哪裡?哪個平面是缺失的?哪兩個平面被合併成了一個?這份稽核,通常會浮現出本來就需要做的工作。

圖 6-1 代理式可靠性的四個核心平面。每個平面各自只有一項職責,邊界是明確的介面。

關於這幾個平面,有一個值得及早點出的細微之處:這些平面是概念上的區隔,不一定是各自獨立的服務或各自獨立的團隊。如果一個平台尊重這些平面之間的結構性邊界,一支團隊完全可以透過單一平台運行全部四個平面;一支團隊也可以把它們拆成四個由不同子團隊擁有的獨立服務——這是在較大型組織裡擴展性最好的模式。重要的是「職責的區隔」,不是「流程的區隔」。一個同時產出訊號、進行推理、評估治理、執行行動的單一流程,只有在這四項職責在其內部是結構上可區分的情況下,才算是實作了四個平面;如果它們被混在一起,這個流程實作的就只是一個做了四件事的平面,而這套架構所承諾的安全特質也就無法成立。

接下來四節會詳細展開每個平面。已經內化上述結構的讀者,可以用任何順序閱讀這幾節,每個平面都是一份獨立站得住腳的架構工作。第一次接觸這套框架的讀者,會發現順序很重要:這幾個平面彼此建立在對方之上,每一節都假設前一節的結論已經成立。

4.3 訊號平面:為機器消費而設計

訊號平面是整套架構的基礎。如果它設計得不好,上層的每一個平面要嘛遲疑,要嘛不安全地行動——再精密的推理,再嚴謹的治理,都無法補償模糊、不完整,或針對人類優化的遙測資料。第二章展開了這個平面運行所在的基質(決策級遙測、拓撲圖、拓撲代理、五種被具名的可觀測性失效模式)。本節談的是這套基質如何坐落在架構裡,以及它與系統其餘部分的邊界長什麼樣子。

訊號平面的職責是有邊界的,值得精確陳述:它橫跨基礎架構、平台與服務蒐集遙測資料;它把訊號正規化成一致的 schema;它用擁有權、拓撲與變更情境豐富化訊號;它發布一個目前的、可查詢的系統狀態視圖;它維護量測自身品質的代理式 SLI(涵蓋率、新鮮度、語意完整性、schema 一致性),好讓上層平面知道自己讀到的訊號是否可信。這就是它的全部工作——它不決定什麼重要,不推斷因果關係,也不觸發行動。它的工作,是讓真相以機器能據以行動的形式變得可觀察。

訊號平面與推理平面之間的邊界,正是大多數團隊出錯的地方。誘惑,是把解讀推進訊號平面,因為這樣做感覺起來很有效率。一個說「系統正在惡化」的訊號,比一個說「p99 延遲在一個第一級端點上是 412 毫秒,相對於 38 毫秒的基準線」的訊號更精簡。這個精簡的訊號感覺很有用,但它也是一個範疇上的錯誤。訊號平面一旦開始解讀,它做的就是推理,而它上層的推理平面,此刻推理的對象,就變成了「別人的推理」,卻無從檢視原始的證據。這裡的紀律,是把解讀完全排除在訊號平面之外——訊號描述狀態,推理解讀狀態,把這兩者混在一起,會讓讓這套架構得以安全的那道邊界崩解。

讓這道邊界可被強制執行的產物,是「訊號契約」。訊號契約,是一份機器可讀的宣告,說明一個訊號代表什麼、訊號平面提供什麼保證,以及這個訊號被設計來支援哪些決策。一份延遲訊號契約,可能會宣告它的名稱、版本、擁有者、它意圖支援的決策(流量塑形、擴容、回滾、升級)、它的新鮮度保證(低於 30 秒)、它的最短觀測視窗(5 分鐘)、它所需要的信心(≥ 0.75)、不應被信任的排除條件(維護窗口、已確認的依賴中斷),以及它所攜帶欄位的 schema。這份契約就是介面——推理平面讀取的是這份契約,而不是原始串流。如果契約版本改變了,推理平面會知道;如果契約的保證無法成立,這個訊號會被標記,推理平面也會相應地調降自己的信心。

這正是「把訊號設計成一份契約、而不是廢氣」的意思。大多數可觀測性堆疊把遙測資料當成廢氣來對待:蒐集流過的一切、儲存它、查詢它,然後祈禱在你需要的時候,正確的訊號恰好存在。代理式架構裡的訊號平面,把遙測資料當成一份契約來對待:每一個決策級訊號,都被宣告、被擁有、被版本控管,並被綁定到一個具體的推理使用案例。如果一個訊號不支援任何決策,它就不屬於訊號平面(它或許依然為了鑑識目的而存在,但它坐落在訊號平面的契約範圍之外)。這正是從「把涵蓋率當成目標」轉向「把涵蓋率當成系統一項被精選、被刻意設計出來的特質」的關鍵一步。

這裡值得點名的實作細節是:訊號契約會演進,而這份演進,必須以和生產程式碼相同的紀律來管理——語意化版本適用,不向下相容的變更需要與消費端協調,schema 驗證在發送時就執行,而不是在查詢時才執行。把這件事做對的團隊,會把自己的訊號契約當成一個有版本控管的 API 來對待,把自己的推理平面代理當成這個 API 的消費者。做不對的團隊,會在六個月後才發現,自己的代理正在對著意義早已漂移的訊號進行推理,而且沒有辦法在這個漂移顯現為糟糕的決策之前偵測到它。第二章把這種失效模式命名為「靜默腐化」,而訊號平面,正是它被預防的地方。

警告 一個為儀表板優化的訊號平面,會限制住它上層的一切。把訊號設計給人類消費的誘惑始終存在,因為通常是同一支工程團隊在維護儀表板與代理。這裡的紀律,是認清這兩種消費者想要的東西不同,並把訊號平面設計給要求較高的那一個。儀表板可以從決策級訊號中生成,反過來則不行。

訊號平面另一項值得點名的特質,是它把拓撲圖當成第一等產物,而不是附掛在其他訊號上的中繼資料。這張圖(在第 2.4 節展開)擁有自己可查詢的介面,由拓撲代理維護,有版本控管、有擁有者,並持續地與觀測到的遙測資料進行驗證。當推理平面需要知道某個服務依賴什麼、或誰擁有它時,拓撲代理就是它會呼叫的 API。把拓撲當成一個第一等訊號、而不是一份 wiki 頁面來對待,是一支團隊從代理式可靠性投資中能獲得的最大單一回報之一,也正是一個能對爆炸半徑進行推理的代理、與一個只是在猜測的代理之間,結構上的分野。

4.4 推理平面:從訊號到決策

推理平面,是代理式可靠性變得可見的地方。單靠訊號,無法改善可靠性;單靠行動,也無法改善可靠性。真正重要的,是在不確定性、時間壓力與資訊不完整的情況下,所做決策的品質。推理平面存在的目的,是把結構化的真相,轉化成有邊界、具意圖感知的決策,而讓這個平面安全的架構邊界,是它只推理,不行動。

這個平面有四項職責,後續章節會反覆遇到它們。第一,它透過持續評估橫跨時間、拓撲、變更情境的系統狀態,來維持情境覺知。第二,它產生關於「正在發生什麼、為什麼」的假設,包括可能的原因、受影響的元件,以及擴散路徑。第三,它透過將候選行動與意圖、風險,以及 DRAL「學習」這一拍所擷取的歷史結果做比較,來評估選項。第四,它產出的是決策提案,不是指令——每一個提案都包含理由、預期影響、信心,以及執行它所需要的授權層級。提案是這個平面的輸出,而治理平面,則決定這個提案是否會變成行動。

這個輸出產物值得擁有自己的名字與結構,因為本書其餘部分會不斷引用它。我們把它稱為「候選行動」(candidate action)。候選行動,是一份結構化的建議,包含觸發訊號、領先假設、依適合度排序的候選行動、意圖對齊情形、風險估計、信心分數,以及執行所需要的治理層級。一個候選行動,可能會像這樣被表示:

proposal_id: "rp-48291"
triggering_signal: "latency_anomaly:v1.2"
leading_hypothesis: "dependency_saturation"
candidate_actions:
  - "throttle_non_critical_traffic"
  - "scale_read_replicas"
intent_alignment:
  primary_slo: "checkout_latency"
  allowed_degradation: true
risk_estimate: "low"
confidence: 0.82
requires_human_approval: false

候選行動,正是從推理跨越到治理的邊界所在。治理平面依照政策評估這個提案,而不需要重跑一次推理,因為這次推理已經被擷取成了一個結構化的產物。候選行動,也正是讓這套系統能對人類保持可解釋的關鍵——當人類問代理為什麼做了那件事時,候選行動就是稽核紀錄。這正是第一章所說的「代理式系統必須把自己的推理攤開來,而不是藏起來」的意思,候選行動,正是這件事發生的地方。

推理平面另一項刻意設計的特質,是它推理的對象是契約,而不是原始資料。這個平面透過訊號平面的契約來消費訊號,它不會直接查詢底層的遙測資料。這一點很重要,因為推理的好壞,取決於它所能仰賴的假設,而契約提供了這個平面可以當作輸入來使用的保證(新鮮度、統計顯著性、排除條件)。沒有這些保證,每一個決策都會變成一場賭博;有了它們,這個平面就能以校準過的信心進行推理,準確地知道自己的輸入被保證代表什麼意思。這正是訊號與推理之間的邊界必須清晰的結構性理由——推理如果越界伸手去碰原始遙測資料,會破壞讓它的輸出值得信賴的那份校準。

信心,是值得放慢腳步細談的一項特質,因為它是代理式推理裡最常被誤解的一面。一個有信心的決策,不等於一個正確的決策,而是一個假設有充分證據支撐的決策。推理平面計算信心,是根據訊號契約本身宣告的信心、跨多個訊號的一致性、類似推理模式的歷史成功率、彼此競爭的假設之間的區分度,以及證據的完整性。它的輸出,是一個經過校準的數字,會隨著 DRAL「學習」這一拍隨時間被精煉。第 3.6 節的校準誤差 SLO,量測的正是這個數字是否真的值得信賴——如果推理平面產出的是校準良好的信心,CE 會維持在低點;如果這個平面過度自信,CE 會上升,下游的治理平面應該以收緊自主邊界來回應,直到校準恢復。

低信心不是一種失效模式,而是一種資訊。一個設計良好的推理平面,會在信心低的時候,在提案中降低它要求的自主程度、觸發降級模式,或透過第 4.7 節的模式把決策路由給人類。真正的失效模式,是「未被承認的不確定性」:一個在證據並不支撐這份信心的情況下,依然產出看起來很有信心的提案的平面。這正是第三章「自信地錯誤的訊號」,在此變成一項結構性議題的地方。推理平面,正是「自信地犯錯」被預防(透過誠實的校準)或被製造出來(透過過度自信的推論)的地方。從架構上來說,能防止自信地犯錯的,是把「信心」當成證據的一項被計算出來的特質、而不是一種感覺來對待的紀律。

幾種失效模式,在早期推理平面的實作裡很常見。「過度擬合」,發生在這個平面過度倚賴近期事故、忽略新奇模式的時候。「規格不足」,發生在推理缺乏足夠情境、產出治理平面無法評估的模糊提案的時候。「行動偏誤」,發生在這個平面偏好「做點什麼」勝過「什麼都不做」、即使觀察才是更安全的選擇的時候。這些失效模式,無法透過調校來消除,必須透過架構來管理:明確的假設、綁定契約的訊號、被計算出來的信心,以及下游的治理平面。第九章展開了如何設計推理平面來管理這些風險的內部細節;第十章展開推理模式本身。在架構這個層級,重要的是這個平面所維持的邊界:它只推理,僅止於推理,而它產出的提案,永遠在變成行動之前,先接受治理的檢驗。

警告 如果推理平面能直接行動,這套架構就是不安全的。為了速度而跳過治理平面的誘惑始終存在,尤其是對於例行行動而言。要抵抗它。治理平面的評估運行在毫秒之間,速度上的代價微不足道;而移除它的結構性代價,是這套架構失去了強制執行「自主性維持在當責邊界之內」的能力。這道邊界一旦消失,不重建系統就無法找回。

4.5 執行平面:在不失去控制的情況下行動

執行平面,是自主性變得真實的地方。到目前為止,架構裡的一切都關乎「理解」——訊號平面呈現現實,推理平面提議決策,治理平面核准或駁回它們,這些都不會改變系統。執行平面,是意圖變成行動的地方,也是大多數自主性專案在失敗時所失敗的地方。常見的錯誤,是把執行當成推理的簡單延續——如果一個系統能夠決定,它應該也就能夠行動。實務上,沒有邊界的執行,是可靠性被摧毀的速度比任何一次中斷都還要快的原因。

這個平面的工作恰好只有一項:精準地執行已核准的決策,不多做任何事。它把決策提案轉譯成具體的行動,強制執行範圍、權限與護欄,安全且可預測地執行,並把結果訊號發送回訊號平面以閉合迴圈。它不決定該做什麼,不對替代方案進行推理,也不會凌駕治理。正是這個區隔,讓自主性在規模化之後依然能夠存活。

讓這個平面的行為變得可預測的產物,是「行動契約」。就像訊號契約讓訊號平面的輸出值得信賴一樣,行動契約讓執行平面的行為有邊界。行動契約,是一個行動的機器可讀描述:它做什麼、它需要什麼、它如何逆轉,以及什麼算是成功。執行平面圍繞著一份行動契約目錄建構起來,這個平面不能執行任何不在這份目錄裡的東西——自由形式的行動生成,被明確排除在這個平面的範圍之外。這聽起來很限制,確實也是。這份限制,正是安全特質所在。可靠性的失敗,很少是因為「缺乏行動」,而是因為「不安全的行動」,而「缺乏行動」的問題,遠比「不安全的行動」的問題更容易解決。

第三章介紹的「節流非關鍵路徑」這個行動,一份具體的行動契約可能長這樣:

action_contract:
  name: throttle_non_critical_paths
  version: "1.2"
  owner: team-platform
  intent: >
    Reduce load on a degrading service by limiting non-critical request paths,
    preserving capacity for high-criticality user journeys.
  preconditions:
    triggering_signal: latency_anomaly:v1.2 or saturation_warning:v1.0
    confidence_threshold: ">= 0.75"
    service_criticality: tier-1
    error_budget_remaining: "> 30%"
    not_in_change_window: true
  action:
    method: traffic_classifier_update
    scope:
      service: <from_signal>
      path_classes: ["background", "secondary"]
      throttle_percent: 40
    duration_max: "10m"
  reversal:
    method: traffic_classifier_restore
    timeout_max: "30s"
    automatic: true
    trigger_conditions:
      - signal: latency_anomaly cleared
      - signal: error_budget_recovered
      - manual: operator_request
  success_criteria:
    primary: latency_p99_returned_to_baseline within 5m
    secondary: error_rate_remained_below 1.0
  outcome_signals:
    - latency_change
    - error_rate_change
    - throttled_request_count
    - revenue_impact_estimate

這份契約有幾項特質值得留意。intent 欄位是一段散文陳述,說明這個行動是為了什麼,寫給維護這份契約的人類看。前置條件是機器可評估的,只要有任何一項不成立,這個行動就不會執行。行動以機械化的方式宣告自己的範圍(哪些路徑、多少百分比、持續多久)。逆轉是強制性的——一個無法自動逆轉的行動,很少應該出現在這份目錄裡。成功標準是明確且可量測的,讓執行平面能評估這個行動是否達成了預期結果。結果訊號,宣告了這個平面將會把什麼回饋給訊號平面,這正是閉合 DRAL 迴圈、讓學習成為可能的關鍵。

這份契約,讓執行平面的行為變得可預測,這是自由形式的行動生成永遠做不到的。推理平面裡的一個代理,可以提議這個行動;治理平面,可以評估這個提案是否符合政策;執行平面,可以在嚴格定義的邊界內執行它,並在不奏效時自動回滾。關於這個行動行為的一切,都被宣告在這份契約裡,由特定團隊擁有,有版本控管,可被檢視。當有人類問,為什麼系統在凌晨三點對流量做了節流時,答案可以從觸發它的候選行動、以及限制它執行的行動契約中被重建出來。

範例 上面「節流非關鍵路徑」這份行動契約,是標準的形式。執行平面目錄裡的每一個行動,都遵循這個形狀:意圖、前置條件、行動、逆轉、成功標準、結果訊號。採用這套紀律的團隊,往往會發現,書寫契約這個動作本身,就釐清了他們真正希望這個行動做什麼、他們真正認定的成功是什麼,以及他們真正認定的「可逆」是什麼。這份契約會變成一場設計對話,而不只是一種執行機制。許多團隊最終的行動目錄,會比他們原本預期的還要短,因為書寫契約會浮現出那些沒有人能完整描述、以至於無法自動化的行動。

爆炸半徑,是執行平面在結構上強制執行、而不是仰賴推理平面去限制的一項特質。每一份行動契約,都宣告自己的範圍、時長、影響幅度,以及可逆性限制,執行平面會機械化地強制執行這些限制。把一個服務擴容三個副本、為期兩分鐘,與無限期地擴容五十個副本,本質上是兩個不同的行動,這個平面會把它們當成帶有不同契約的不同行動來對待。這不是一個政策層面的議題,而是架構層面的議題。推理平面提議一個行動,這個行動攜帶著自己的爆炸半徑,執行平面強制執行它——這一切都不仰賴良好的意圖,或營運人員審慎的判斷。

有兩種實作模式值得在此簡短點名,因為本書其餘部分會遇到它們兩者。第一種是「集中協調式執行」,由單一執行服務接收已核准的提案、驗證契約,並透過受控的整合(雲端 API、部署系統、設定管理)執行行動。這種模式提供強一致性與集中式可稽核性,是擁有強大中央平台團隊的組織的預設選擇。第二種是「分散式執行代理」,由運行在它們所管理系統附近的輕量級執行器,接收已核准的行動,並在嚴格的契約邊界內就地執行。這種模式降低延遲、改善韌性,但需要更強的加密控制與契約強制執行。這兩種模式都是有效的,架構上的要求是:無論執行器身處何地,執行的權限都在結構上保持有邊界。

結果回報,是閉合這個迴圈的特質。執行不算完成,直到結果被觀察到為止。執行平面會把結果訊號發送回訊號平面:延遲變化、error budget 恢復、回滾觸發、行動逾時、部分失敗。沒有這些訊號,自主性無法改善,只能重複自己。這些訊號餵進 DRAL 的「學習」這一拍,正是系統對「在這些條件下採取這個行動」的信心,為下一次被精煉的地方。一個不發送結果訊號的執行平面,只是在產出行動,而不是在學習——一個會行動卻不會學習的系統,是自動化,不是代理式可靠性。

4.6 治理平面:編碼信任與當責

治理平面,是讓自主性變得可被接受的關鍵。沒有治理,代理式系統雖然強大,卻很危險。當治理被放錯位置(放在執行期之外、放在核准流程裡、放在變更諮詢委員會的會議裡)時,代理式系統會變得緩慢、脆弱,且與人工作業無異。解決這個問題的架構性做法,是把治理變成一項執行期的關注點——政策存在於系統裡,在毫秒之間,由治理平面自動地對每一個候選行動進行評估。

對 SRE 讀者而言,這是最違反直覺的一個平面,因為傳統維運把治理放在執行期之外——變更諮詢委員會審查變更,核准流程把請求路由給人類簽核,操作手冊把政策編碼成程序。這些機制,在行動稀少、時間壓力低的時候是有效的;在行動持續發生、時間壓力高的時候——也就是代理式系統運作所在的體制——它們會徹底失效。治理平面,正是對此的架構性回應:它把政策從一套系統之外的流程,移動到系統之內一個執行期的評估器裡,而且不會移除賦予政策意義的人類監督。

治理不對「狀態」進行推理,推理平面早已做過這件事;治理平面對「權限」進行推理。給定這個被提議的行動、這些輸入、這個信心,在這些目前的條件下、在這個團隊的擁有權與這些合規限制之下,這個行動是否被允許?在簡單的情況下,輸出是二元的(核准、駁回);在真實的情況下,輸出是分級的(以完整範圍核准、以縮減範圍核准、附帶強制人類通知的核准、附帶升級的駁回)。這個平面消費三項輸入:來自推理平面的候選行動、來自執行平面目錄的行動契約,以及同時限制兩者的組織政策。只有這三者都對齊時,這個行動才會繼續進行。

一個簡單的政策範例,能釐清執行期治理長什麼樣子。以一條規範自主擴容行動的政策為例:

policy:
  name: autonomous_scaling_policy
  version: "2.0"
  applies_to: scale_service
  allow_when:
    confidence: ">= 0.80"
    service_criticality: ["tier-2", "tier-3"]
    time_window: "any"
    error_budget_remaining: "> 20%"
  constraints:
    max_instances_added: 3
    max_duration: "10m"
    max_cost_increase_percent: 5
  require_human_approval_when:
    confidence: "< 0.80"
    service_criticality: "tier-1"
    affects_regional_failover: true
  escalation:
    on_constraint_violation: require_human_approval
    on_repeated_failure: tighten_autonomy

這份政策,明確地編碼了信任。它在風險低的地方(第二級/第三級服務、高 error budget、保守範圍)允許自主性,並在後果較高的地方(第一級服務、區域性影響、低信心)路由給人類。不需要開會,不需要開工單,系統會在執行期,對每一個符合其範圍的提案評估這份政策,答案在毫秒之間就被計算出來。治理的人力成本,從「核准行動」轉移到了「設計政策」,而政策設計是以一種比核准流程曾經允許的更緩慢、更審慎的節奏在進行的。

這正是我們說「當責不會被委派」時的意思。第 3.7 節介紹了包圍著自主邊界的當責邊界這一層;治理平面,正是這道邊界變得可操作的地方。擁有這項服務的團隊撰寫政策,治理平面在執行期強制執行它。當系統行動時,是團隊的政策讓這個行動變得被允許;而當這個行動受到質疑時,團隊的政策,正是系統所指向的東西。政策的當責永遠不會移動,被政策允許的行動的執行權,則移轉給了系統。正是這個區隔,讓代理式營運變得可持續——沒有它,團隊要嘛保留所有執行權(緩慢、手動),要嘛放棄當責(快速、危險)。

「授權層級」,是治理平面用來讓政策變得分級、而不是二元的結構性概念。這個平面問的不是「這個行動是被允許還是被禁止」,而是「多少程度的授權才是合適的」。常見的層級包括:唯讀觀察(代理觀察,但不提議)、僅提議(代理提議,但不能執行)、執行可逆行動(代理在嚴格範圍內行動,並自動逆轉)、執行有邊界的不可逆行動(代理在逆轉不可能、但爆炸半徑受控的地方行動),以及要求人類核准(任何超出自主門檻的行動都路由給人類)。隨著信心上升、成熟度改善,服務可以往這些層級的上方移動;隨著信心下降(依照第 3.6 節的校準誤差 SLO)或條件變得異常,服務則往下方移動。這正是自主性能在不打破信任的情況下擴展的方式:它是分級的、可觀察的,並且在授權層級這個層面本身就是可逆的。

這裡值得點名兩種實作模式。「中央政策引擎」模式,把單一政策服務放在執行期裡,對每一個提案評估共享的規則,提供一致性與強稽核性,適合有標準化治理要求的組織。「分散式政策評估」模式,對政策包進行加密簽署,並在執行代理端就地評估,降低延遲、改善韌性,但需要謹慎的版本控管。這兩種模式並不互斥,許多成熟的組織兩者兼用:中央引擎用於跨切面的合規限制,分散式評估用於團隊專屬的營運政策。兩種形狀的工具都存在(中央模式的 OPA,分散式模式的已簽署政策包)。在架構上重要的是,無論由哪種模式承載評估,政策都是自動地、確定性地、在執行期被評估的。

可稽核性,是讓治理平面能隨時間保持值得信賴的特質。每一次核准、駁回、升級,都會產出一個稽核事件,擷取被評估的提案、被套用的政策、做出的決策、當時的信心,以及當責的擁有者。可稽核性不是為了追究責任,而是為了信任——當人類能夠審查系統做了什麼、為什麼這麼做時,自主性才會擴大;當稽核軌跡不完整或是事後才補上的,信任就會流失,團隊就會退回到更緩慢的機制。這個平面的稽核輸出,也正是讓監管互動變得具建設性、而不是對抗性的關鍵。一支能對任何過去的行動,展示觸發它的候選行動、核准它的政策,以及最終結果的團隊,和一支對「系統為什麼做了 X」的回答只有「代理決定的」的團隊,是處於根本不同的對話之中。

警告 如果治理存在於執行期之外,自主性最終會違反信任。核准流程與變更諮詢委員會的流程,適用於低頻率、人類步調的作業,它們跟不上持續的自主決策。試圖在擴大自主性的同時,保留外部治理的團隊,會發現代理要嘛無限期地等待核准(崩解回人工作業),要嘛在壓力下繞過它們(違反政策原本要編碼的信任)。治理平面,正是這個問題的架構性解方——政策移入執行期,由系統評估,每一次都在毫秒之間完成。

動態護欄,是第 11.2 節將展開的、執行期治理的延伸。治理平面裡的政策不必是靜態的,它們可以依照目前的條件自我調整:在高流量期間收緊限制,在低風險窗口放寬限制,在校準誤差上升時自動收窄授權,在下降時自動放寬。正是這一點,讓這套架構能運作在 L4 成熟度(適應性,在第 4.9 節定義),而不只是 L3(有邊界)。治理平面,是動態政策存在的介面,而設計動態政策的紀律,正是第十一章的工作。現階段,架構上的重點是:這個平面在結構上有能力支援它——政策是程式碼,在執行期被評估,可透過稽核被觀察,處理靜態規則的同一個評估器,也能處理動態規則。

4.7 人在迴圈中,作為一個控制迴路

「人在迴圈中」不代表「人工核准」。這句話就是本節的整個論點,本節其餘篇幅,都是這句話所隱含的工程工作。在代理式可靠性架構裡,人類的定位不是每一個行動的決策者,而是隨時間讓系統穩定、校準、演進的控制迴路。把人類當成核准關卡,會讓自主性崩解;把人類當成不存在,會移除當責;把人類當成控制迴路,則能同時保住這兩者——本節,正是本書其餘部分會回頭引用的正規處理方式。

核准式模型在代理式系統下會崩潰,有三個值得明確點名的原因。第一是速度:代理以機器的時間尺度進行推理與行動,人類核准會引入延遲,抵銷自主性的意義。第二是量:代理產生的決策量,遠超過人類能在即時狀態下合理審查的量,佇列的成長速度會快過人類清空它的速度。第三是品質:在時間壓力下審查局部情境的人類,做出的決策,往往比在明確邊界內運作、有良好限制的代理還要糟。這三者的組合,正是讓核准流程在結構上與持續性自主運作不相容的原因。修正的方式,不是去精煉核准流程,而是重新配置人類的角色。

行得通的心智模型,是古典控制理論裡的控制迴路。一個控制迴路不會決定每一個行動,它觀察系統行為,把它與期望結果做比較,並調整參數以維持系統穩定。代理持續在這個迴圈內部運作,人類則在特定的插入點上偶發性地介入——那些人類判斷力能增添最多價值的地方——而代理則在介入之間持續運作。這把對話從「人類有沒有核准這個行動」,轉變為「人類有沒有設計出這種行動會被核准的條件」。第一個問題,隨著行動數量而擴展;第二個問題,隨著行動「類型」的數量而擴展,而後者要小得多。

這套架構辨識出三種人類參與的模式,本書其餘部分會一致地使用這幾個詞:「迴圈之上」(above the loop)、「迴圈之中」(in the loop)、「迴圈之上監看」(on the loop)。每一種都有自己的工作、自己合適的節奏,以及自己的量測方式。

「迴圈之上」,是人類定義意圖的地方——服務目標、可接受的風險、爆炸半徑容忍度、成本限制、法規邊界、當責邊界本身。這些被編碼為政策與意圖宣告,而不是操作手冊。迴圈之上的工作,以緩慢的節奏(數週到數月)、審慎的注意力、在平靜的條件下,由擁有這項服務的團隊進行。代理在決策當下讀取這份意圖,並在其中運作;人類不在執行現場,人類的設計選擇存在於治理執行的那份政策裡。這是代理式系統裡最有價值的一種人類參與模式,也是那些把問題框架為「我們如何核准代理的行動」的團隊投資最不足的一種。正確的框架是「我們如何設計代理運作所在的條件」。

「迴圈之中」,是人類即時參與特定決策的地方——按設計,不是每一個決策;這套架構的紀律在於,迴圈中的參與是罕見的、且在結構上受政策限制的。當治理平面把一個提案路由給人類時(因為信心低、條件異常,或政策明確要求),人類進入這個迴圈,審查附帶著完整情境的候選行動,並核准、修改,或駁回。人類在這個模式裡的體驗,與傳統核准流程有根本上的不同:代理已經完成了調查,把情境結構化,命名了領先假設,為各個替代方案評分,並把這份提案呈現為一個連貫的產物。人類的工作,是為一個已經準備妥當的問題帶來判斷力,而不是從原始材料中組裝出這個問題——這正是讓「迴圈之中」的參與變得高價值、而不是耗損人心的關鍵。

「迴圈之上監看」,是人類觀察持續運作中的自主行動、只在有事需要介入時才介入的地方。他們盯著各項 SLO(第 3.6 節的五大旗艦,尤其是校準誤差),審查自主決策的樣本以驗證它們形式良好,在校準漂移時調整門檻,並依照趨勢證據所顯示的內容,擴大或收緊自主性。這是能夠擴展的模式:一名迴圈之上監看的工程師,可以監督每天數千個自主決策,因為這名工程師不是在核准它們,而是在觀察核准它們的那套系統。SLO 是這名工程師的儀器,稽核軌跡是這名工程師的證據,政策是這名工程師的槓桿。

附註 三種模式:迴圈之上、迴圈之中、迴圈之上監看。迴圈之上的人類,設計意圖與政策;迴圈之中的人類,參與特定的決策;迴圈之上監看的人類,監督運作並調整校準。每一支運行代理式系統的團隊,都會把自己的人力時間分配到這三者之間。在「迴圈之上」工作投資不足的團隊,會發現自己被「迴圈之中」的決策淹沒;在「迴圈之上監看」工作投資不足的團隊,會發現自己的校準悄悄漂移、校準誤差悄悄上升。正確的平衡因成熟度等級而異,第 4.9 節的成熟度模型會把這一點講清楚。

為了讓這些模式變得具體,設想一個在疑似過載期間自動節流流量的代理。這個代理偵測到延遲上升,評估風險,以 85% 的信心提議節流。政策允許在信心高於 80% 時自主執行,於是這個行動被執行了。稍後,這位「迴圈之上監看」的人類審查了這次結果,注意到使用者影響很小,但營收損失卻比預期高(因為被節流的路徑,恰好承載了比政策所預期更多的營收流量)。這位人類沒有停用這個代理,而是在迴圈之上更新意圖,把尖峰時段的營收敏感度納入考量,相應地調整政策,下次同樣的條件出現時,這個代理就會以不同的方式進行推理。這位人類的介入,小、慢、審慎,而且是架構層面的,代理則在整個過程中持續運作。這正是正確做法的「人在迴圈中」,它能以核准流程永遠做不到的方式擴展。

圖 6-2 人在迴圈中的三種模式:迴圈之上、迴圈之中、迴圈之上監看,各有自己的節奏與工作。

另一項值得點名的特質是:人類的控制,行為應該像斷路器,而不是總開關。斷路器在偵測到不穩定時跳脫,保護系統,並在條件恢復正常時重置;總開關則停止一切,需要手動重啟,並在例行作業中引入恐懼與遲疑。代理式系統需要的是斷路器。人類設計斷路器何時跳脫(特定的校準誤差門檻、特定的失敗率、特定的異常條件),以及復原如何發生(當 SLO 恢復時自動重新接入,當跳脫是由一個未被辨識的條件造成時手動重新接入)。總開關依然為極端情況而存在,它是最後手段,不是預設的安全機制。

這個框架,正是在不崩解自主性的情況下保住當責的關鍵。擁有服務的團隊,依然對意圖定義、政策設計、門檻校準、以及覆寫決策負責。系統代表團隊行動,在團隊定義的限制之內,由團隊「迴圈之上監看」的工程師觀察。這支團隊,並不比在傳統作業下承擔更少的責任,他們只是對不同的事情負責。這個轉變,是從「核准行動」轉向「設計行動被允許的條件」,而正是這個轉變,讓可靠性工作能夠擴展到代理式系統所帶來的速度。

4.8 參考架構:把一切組合起來

目前為止所描述的一切(訊號、推理、執行、治理,以及作為控制迴路的人類),構成了代理式可靠性系統的結構語法。本節把這些部分組裝成一套單一的、可操作的參考架構,讓實務工作者能據以推理、調整,並漸進式地實作。這不是一份廠商範本,而是一張概念性的建構清單,設計來被畫在白板上,並套用到團隊實際工作所在的任何環境裡。我們會透過一個單一的實作情境走一遍:結帳服務上的一起第一級延遲惡化,由這套架構端到端地處理。

在 t=0 時,結帳服務開始惡化。/api/v2/cart/submit 端點上的 p99 延遲開始向上漂移。訊號平面早已透過第 4.3 節介紹的 latency_anomaly 訊號契約在觀察這項服務。在 t=15 秒時,這個訊號突破了契約的顯著性門檻,這份契約發送出一個結構化訊號:服務身分、端點、旅程分類、關鍵性層級(第一級)、百分位數值(p50/p99/p999)、上游依賴狀態(拓撲代理回報,付款依賴在過去三分鐘一直處於降級狀態)、近期變更情境(四分鐘前 inventory-api 上有一次部署上線),以及新鮮度/信心保證。這個訊號是決策級的——推理平面接下來需要的每一項特質,都已經在這個訊號本身裡了。

在 t=18 秒時,推理平面收到這個訊號,開始建構候選行動。它產生假設:依賴飽和(考量到付款降級訊號,機率高)、近期變更(考量到四分鐘前 inventory-api 的部署,機率中等)、流量轉移(考量到目前流量模式,機率低)、容量耗盡(考量到目前資源指標,機率低)。它依照可用證據為每個假設評分,領先假設是「依賴飽和」,信心 0.82。它依照這個領先假設評估候選行動:throttle_non_critical_paths(對依賴飽和適合度高、爆炸半徑低、完全可逆)、scale_read_replicas(適合度中等、爆炸半徑較高)、rollback_inventory_deploy(對這個領先假設適合度低,但被標記為若第二個假設被證實為真時的應變方案)。它產出一個候選行動,推薦 throttle_non_critical_paths,意圖對齊確認在事故期間第一級端點上允許降級,風險估計為低,信心 0.82,requires_human_approval 為否(因為信心超過了政策的自主執行門檻)。這個候選行動,跨越進入治理平面。

在 t=22 秒時,治理平面進行評估。它載入 autonomous_throttling_policy(規範第一級服務上 throttle_non_critical_paths 類型行動的執行期政策),檢查政策的條件:信心 ≥ 0.80(通過,0.82)、服務關鍵性為第一級(政策已明確處理,允許在依賴降級的條件下對第一級服務進行節流,只要節流保住了高關鍵性路徑)、剩餘 error budget > 30%(通過,目前為 67%)、不在變更窗口內(通過)、行動契約的 max_duration 上限為 10 分鐘(在政策限制內)、行動契約的逆轉是自動的(政策要求)。這份政策以完整的自主權限核准了這個行動,不需要人類核准。系統發出一個稽核事件:提案 ID、政策 ID、決策、評估當下的信心、當責擁有者(team-platform)。這個候選行動,轉移到執行平面。

在 t=23 秒時,執行平面載入 throttle_non_critical_paths 行動契約,最後一次驗證前置條件(訊號依然有效、信心依然超過門檻、error budget 依然健康),然後執行這個行動:結帳服務上的流量分類器,被更新為把次要與背景路徑分類節流 40%。這個行動把一個 action_started 結果訊號發送回訊號平面,訊號平面開始觀察這個行動的效果。執行平面為這個行動的成功標準設置了一個監視器:p99 延遲必須在 5 分鐘內回到基準線,錯誤率必須維持在 1.0% 以下。

在 t=180 秒時,監視器回報:p99 延遲已回到基準線,錯誤率全程維持在 0.4% 以下,被節流的請求數為 1,247(佔總量的一小部分),營收影響估計在政策容忍範圍之內。這個行動成功了。執行平面發送結果訊號(latency_change:已恢復;error_rate_change:穩定;action_outcome:成功),並在滿十分鐘時,除非底層條件發生變化,開始自動逆轉。DRAL 迴圈的「學習」這一拍,接手這個結果:針對這類失效(付款降級期間結帳服務上的依賴飽和)的 throttle_non_critical_paths 策略,被以一次成功的結果更新。推理平面對這類失效使用這項策略的信心,會稍微上升。下一次類似訊號到來時,推理平面會以稍高的信心,採用這個行動。

這就是整套架構的運作。從初始訊號到確認復原,不到四分鐘,例行執行過程中沒有人類介入迴圈,「迴圈之上監看」的工程師透過稽核軌跡得到通知,卻沒有被呼叫。每一步都是可觀察的,每一步都是可逆的,每一步都被契約與政策限制住。稽核軌跡擷取了完整的推理鏈——如果有任何地方出錯,團隊都能重建出發生了什麼、為什麼發生,一路追溯到決策當下的那個信心分數。

圖 6-3 代理式可靠性參考架構。四個平面,一個持續運作的迴圈,人類在三個位置參與。

現在,思考一下這個情境沒有按計畫進行時會發生什麼。假設在 t=22 秒時,推理平面的信心是 0.74,而不是 0.82。治理平面的政策要求第一級服務上的自主執行需要信心 ≥ 0.80,於是政策把這個提案路由給人類。待命工程師的介面,收到附帶完整情境的候選行動:領先假設、替代方案、證據、建議的行動、建議的逆轉方式,以及展示「為什麼這個決策被路由給他們、而不是被執行」的稽核情境。工程師進行審查——代理已經完成的組裝工作全都攤在眼前,工程師不是從零開始。他們一鍵核准這個行動,從那一刻起,這套架構的行為完全一致:執行平面運行契約,監視器觀察,結果回流,學習發生。人類的參與只花了 30 秒,這位工程師從未需要從六個不同的工具中組裝情境。

現在,思考一個更糟的情況。假設在 t=22 秒時,信心是 0.82,但政策偵測到,這將是過去一小時內,這項服務上的第三次節流行動。政策的升級規則被觸發:repeated_action_threshold_exceeded。治理平面沒有執行,而是調降自主性,並把它路由給人類,稽核軌跡明確顯示出這個重複行動的模式。工程師審查後看見,系統一直在反覆節流、卻沒有底層的復原——這正是第 3.8 節的「過度矯正與隱藏的損害」失效模式。他們沒有核准另一次節流,而是把它升級為一次調查。這套架構的行為是正確的:它透過政策辨識出了這個失效模式,把它呈現給人類,並且沒有讓自主行動掩蓋底層問題。這正是架構在自己的失效模式演變成營運災難之前,先把它們抓住的樣子。

範例 一張圖看懂參考架構:左邊是訊號平面,產出決策級訊號;推理平面消費它們,產出候選行動;治理平面依政策評估,產出核准/駁回/路由給人類的決策;執行平面透過行動契約執行已核准的行動;結果回流到訊號平面以閉合這個迴圈。「迴圈之上監看」的人類,透過稽核軌跡與 SLO 觀察這套系統;「迴圈之中」的人類,處理由政策路由過來的例外;「迴圈之上」的人類,演進規範其他一切的意圖與政策。這張圖,正是本書其餘部分會反覆回頭引用的畫面。

關於團隊實際如何採用這套架構,有幾點實務上的觀察值得一提。第一,你不會一次採用全部四個平面。大多數團隊從強化訊號平面開始,因為其他每個平面都依賴它。有了決策級訊號,推理平面就能漸進式地被引入,通常先從諮詢模式開始(代理提議,但不執行)。一旦推理平面產出的提案值得被治理,治理平面就開始變得有意義——這通常也是自主執行開始的時候。執行平面的行動目錄會隨時間成長,先從爆炸半徑最小的行動開始(流量塑形、功能降級),再隨著信心與政策成熟度而擴展。這種漸進式的採用,正是第 4.9 節的成熟度模型要講清楚的內容。

第二個觀察,是大部分的工程工作,存在於平面之間的邊界上:訊號—推理邊界上的訊號契約,推理—治理邊界上的候選行動格式,推理/治理—執行邊界上的行動契約,執行—訊號邊界上的結果訊號。每一道邊界,都是一個明確、有版本控管、有擁有者的介面。一支代理式可靠性團隊的工作,很大程度上就是設計並演進這些介面的工作;而一支代理式可靠性平台團隊的工作,很大程度上就是維護承載這些介面的基礎架構的工作。

第三個觀察,是這套架構是可以被畫出來的。一位讀完本章的實務工作者,應該能在五分鐘內,不查閱本書,就在白板上畫出四個平面、它們之間的邊界,以及它們形成的那個迴圈。這種「可畫性」,正是這套架構是否已被內化的測試。如果你畫不出來,你就還沒有真正掌握它;如果你畫得出來,你就能把它套用到自己的環境裡,本書其餘部分,就會變成對一個你已經理解的形狀所做的一系列精煉。

4.9 代理式可靠性成熟度模型

大多數成熟度模型,都以同樣的理由讓實務工作者失望:它們描述你身在何處,卻不告訴你要讓自己安全地往前走,必須具備什麼。在代理式系統裡,這道落差是危險的。自主性不是靠野心或工具就能解鎖的,它是在可觀測性、推理、授權這三個維度上都具備特定能力、且治理在執行期被強制執行時,才會被解鎖。這三個維度中的任何一個薄弱,都會製造出一道「信任天花板」(trust ceiling):一個系統無法安全運作的臨界點,無論其他維度看起來多麼先進。本節安裝的成熟度模型,是本書其餘部分會回頭引用的架構。它是本書除了「四個平面」之外,被引用次數第二多的一節,也是「我們怎麼知道自己準備好邁向下一個等級了」這個問題的結構性答案。

這套模型有五個等級、三個維度。五個等級是「反應式」(Reactive)、「輔助式」(Augmented)、「有邊界」(Bounded)、「適應式」(Adaptive)、「系統性」(Systemic)。三個維度是「可觀測性」(系統能感知並賦予情境的能力)、「推理」(決策如何被形成與驗證)、「授權」(代理被允許採取哪些行動)。治理在這套模型裡不是第四個維度,因為治理是強制執行「授權」的執行期機制;治理成熟度的「等級」,隱含在授權這個維度裡。每個等級的定義,是這三個維度必須各自具備什麼,這個等級才能被安全地運作。跳過等級並不會加速導入,只會產出第三章所點名的失效模式,尤其是「信心崩潰」(當授權跑得比推理快時)與「靜默學習腐化」(當推理跑得比可觀測性快時)。

L1,反應式(人類主導)。可觀測性是孤島式的:指標、日誌、事件、追蹤存在於各自獨立的工具裡,在事故期間由人類專業知識手動關聯。推理是靜態的:if-then 邏輯內嵌在腳本或操作手冊裡,橫跨元件沒有情境覺知。授權完全屬於人類:人類確認警報、執行所有變更。這是大多數組織的起點,作為起點,這沒有什麼不對。在這個等級導入代理,不會產出回報,只會產出意外,因為它們所需要的基質尚未存在。第三章的代理式 SLO,在這個等級並不適用,傳統的 MTTR 與可用性指標,依然是正確的量測方式。

L2,輔助式(決策就緒)。可觀測性被標準化:遙測資料被一致地標記,訊號與服務、依賴關聯起來,有相當一部分遙測資料是結構化的。推理以諮詢模式運作:代理提議行動,有時透過 ReAct 風格的模式,但不會自主執行。授權僅止於建議:人類在每一次寫入觸及系統之前都要核准。治理是有文件記載的政策,加上初步的提示詞層級護欄。這個等級的主要指標,是「建議採納率」(Suggestion Acceptance Rate,SAR):人類實際採納的代理建議所佔的百分比。80% 或更高的目標,代表代理的推理夠好、值得被聽取;低於 60%,代表這個代理正在產出雜訊;高於 95%,代表這個代理過度保守,只是在提供人類本來就會做的事。SAR 是 L2 的指標,也是判斷是否準備好邁向 L3 的關卡。

L3,有邊界(政策鎖定)。可觀測性加上了橫跨服務的情境敘事與因果關聯覺知,拓撲圖是可查詢且經過驗證的。推理變成多步驟的:代理能夠拆解一個問題,在步驟之間保持短期的工作階段記憶,並產出結構化的候選行動。授權允許對低風險、預先核准的行動進行自主執行,由執行平面契約上的政策即程式碼把關。治理平面正式運作,在執行期依政策評估提案。這是第一個真正的自主性門檻。這個等級的主要指標,是「自主解決率」(ARR)落在 20-40% 的範圍內(大多數決策依然升級處理,但有相當一部分自主執行),以及「校準誤差」(CE)低於 25%(代理宣稱的信心,與它觀測到的成功率有良好的對齊)。行動契約有版本控管,自主行動的逆轉是自動的。「迴圈之上監看」的角色,成為人類參與的主導模式。

L4,適應式(目標導向)。可觀測性支援橫跨服務的環境式漂移感知,通常透過組合了拓撲、擁有權與歷史模式的知識圖來實現。推理變得具反思性:代理會自我批判自己的提案,跨事故(而不僅是事故內)學習,並依照 DRAL「學習」這一拍調整自己的假設產生方式。授權變得動態:代理依照意圖與政策的目前狀態選擇戰術,而不是依照一份固定的操作手冊。治理變得風險適應性:治理平面的政策本身,被目前的 SLO 狀態參數化,讓自主性在校準良好時擴大、在校準不良時收縮。ARR 上升到 40-70% 的範圍,推理延遲(RL-SLO)變得可強制執行且可見。系統此時是在適應,而不是在重複,人類的角色進一步移往「迴圈之上」的意圖設計。

L5,系統性(自主生態系)。可觀測性涵蓋系統的完整語意情境,包括跨租戶覺知,以及代理彼此之間的關係。推理發生在彼此協作的代理之間:拓撲代理、發布代理、商業影響代理、資源配置代理等,透過結構化的移交進行協調(第十四章展開這些協調模式)。授權延伸到全端優化,包括在當責邊界限制內,對服務與政策進行自主重新設定。治理包含不可否認的稽核帳本,通常經過加密簽署,讓稽核軌跡本身在結構上就能防止竄改被察覺。ARR 超過 70%。L5 的關卡指標,是「溯源率」(Grounding Rate,GR)高於 99%:能夠端到端重建其證據鏈(訊號、假設、政策、契約)的自主行動所佔的百分比。在這個等級,可靠性不再是反應式的,而是在團隊宣告的限制內自我維護的。實務上,極少組織運作在這個等級——這套模型之所以包含這個等級,是為了描述如果它們真的達到了,會是什麼樣子。

第 3.6 節的五大旗艦 SLO,對應到這些成熟度等級,是作為「關卡」,而不是「目標」。ARR 隨成熟度等級上升而上升;DQ-SLO 隨成熟度上升(一個更成熟的系統,出手時做出更好的決策);RL-SLO 只有在 L3 才變得可強制執行,在 L4 才變得有意義;AE-SLO 隨行動目錄與政策的品質而上升;CE 是唯一一項必須在每個等級都維持低點的 SLO——過度自信的推理,在任何成熟度下都是危險的。建議採納率是 L2 專屬的關卡,溯源率是 L5 專屬的關卡。在某個特定等級上,一整套代理式 SLO 的表現,就是「這個等級可量測的就緒度長什麼樣子」這個問題的答案。

附註 信任天花板:L2 → L3 的轉換,才是成熟度模型裡最困難的轉換,而不是 L4 → L5。這是系統從「代理作為顧問」轉變為「代理作為執行者」的時刻,也是大多數導入專案失敗的地方。失效模式是一致的:團隊試圖用更強的提示詞來補償治理平面投資的不足,而提示詞層級的安全,在負載下撐不住。跨越信任天花板唯一可持續的路徑,是結構性的:在授予任何自主寫入權限之前,治理平面必須是真實的、在執行期被評估的、由政策驅動的。這個洞見會在第二部與第四部再出現三次,現在就把它內化。

信任天花板值得一段更深入的說明,因為它會塑造團隊該如何規劃自己的導入計畫。L2 → L3 的轉換,不是一個隨著代理推理能力自然改善而水到渠成的技術步驟,而是一項離散的組織決定:第一次授予代理自主的寫入權限。這個決定,要求結構性的安全機制(治理平面、行動契約、自動逆轉、校準過的信心)在同一時刻全部就緒。許多團隊在四項機制中只具備三項的情況下嘗試這個轉換,然後發現,缺失的那一項,正是第一次自主失敗降落的地方。這種對稱性毫不留情——一個產出校準良好提案的推理平面,無法彌補一個缺失的治理平面;一個擁有健全行動契約的執行平面,無法彌補從目錄中溜出的不可逆行動;一個擁有強大代理式 SLI 的訊號平面,無法彌補尚未依照結果驗證過的信心模型。這四項機制,在 L3 都是必要的,且必須同時具備——這正是這個轉換之所以困難的原因。

關於團隊該如何使用這套模型,有幾點實務上的觀察。第一,成熟度在一個組織裡不會是均勻的。一支運行第一級服務的團隊,可能在那項服務上處於 L3,同時在第二級服務上處於 L2,在其他一切上處於 L1。這是健康的——這套模型是要依服務、依工作流程來套用,而不是作為一張組織記分卡。第二,進展不是單調遞增的。一項服務可能運作在 L3,然後因為 CE 上升超過了 L3 的門檻,而暫時退回到 L2——這也是健康的。這套架構優雅地降級自主性的能力,正是讓更高的等級能夠被安全運作的關鍵。第三,這套模型描述的是就緒度,而不是規範步調。一支真正處於 L2 的團隊,不會單靠野心就在一季內變得「L3 就緒」——那些基質工作(訊號契約、行動契約、政策即程式碼、代理式 SLI 儀表化)需要花它該花的時間。一支試圖跳過步驟的團隊,會發現自己陷入第 3.8 節的那些失效模式。

圖 6-4 代理式可靠性成熟度模型。三個維度、五個等級,信任天花板位於 L2 → L3 的轉換。

等級之間的邊界,往往也是這套架構最大投資的落腳處。L1 → L2 的轉換,大多是可觀測性工作:標準化標籤、訊號 schema、擁有權中繼資料。L2 → L3 的轉換,是架構性的轉換:治理平面投資、行動契約、政策即程式碼,把推理平面從諮詢模式升級為有邊界的自主模式。L3 → L4 的轉換,是學習性的轉換:DRAL「學習」這一拍跨服務正式運作,校準變得具適應性,推理變得具反思性。L4 → L5 的轉換,是協調性的轉換:多個代理協同工作、加密稽核、全端優化。每一次轉換,都有自己典型的工作,明確地為這次轉換命名,正是團隊把正確資源分配到正確階段的方式。

這套成熟度模型,也是本書其餘部分安排自身期望的方式。第五章談事故應變,為它的標準情境假設了 L3 或更高;第十一章談有邊界的自主性,為它對動態護欄的討論假設了 L4;第十四章談多代理協調,為它最具野心的模式假設了 L5。讀者可以用這套模型來定位自己的系統,辨識哪些章節描述的是自己目前的運作模式,哪些章節描述的是自己正試圖成長進去的模式。正是這一點,讓這套模型對實務工作者真正可用,而不只是描述性的。它是一個羅盤,不是一張記分卡。

4.10 本章總結

架構,是代理式可靠性裡決定其他一切能否被真正部署的那部分。沒有它,第二部裡的工作流程只是憧憬;有了它,它們才變成工程工作。四個平面、人在迴圈中的控制迴路、成熟度模型,是第二部每一章都會取用的結構性遺產。第五章談事故應變,會透過這些平面追溯 DRAL 迴圈在一個標準情境裡的路徑。第六章談交付,會把部署當成一連串由治理平面評估的行動契約。第七章談混沌,會把 BFI 當成一門透過有邊界行動契約執行的推理平面紀律。第八章談事前工作,會讓訊號平面以預測模式、而不是反應模式運作。每一章工作流程,都假設這套架構已經存在;而這套架構,也只有在一支團隊能把它畫出來、建構它、並在符合自身情境的成熟度等級上運作它時,才真正重要。

本章「沒有」主張的是:這套架構是一件已經完成的工作。四個平面是結構語法,為某個特定環境設計具體契約、政策與代理的工作,才是團隊會花掉大部分時間的地方。成熟度模型說明每個等級何時可以安全運作,從一個等級走到下一個等級的工作,大多是不起眼的基礎架構:schema、契約、政策即程式碼、校準儀表化。人在迴圈中的控制迴路是正確的框架;為某個特定團隊設計具體的意圖宣告與政策包的工作,是持續進行的。這一切都不是「隨插即用」,全部都是工程工作,做得好會複利累積,被忽略則會腐蝕。

第一部在此收尾。三章下來:第一章命名了為什麼以人類為中心的可靠性,無法擴展到這個產業如今所到達的地方;第二章命名了未來十年可靠性工作運行所在的可觀測性基質;第三章命名了把觀察轉化為學習的韌性迴圈,以及讓這個迴圈可量測的五大旗艦 SLO;本章命名了承載這個迴圈的架構,以及為它的導入定速的成熟度模型。這四章合在一起,是代理式可靠性工程的概念核心。第二、三、四部裡的一切,都會回頭引用其中之一。內化了這四章的讀者,能在自己的環境裡建構、運作、演進代理式可靠性;沒有內化的讀者,會發現接下來的工作流程那幾章,比它們原本需要的還要難——不是因為這些工作流程本身困難,而是因為它們假設了一個原本應該在這裡被打下的基礎。

下一章,是這套架構第一次遇上一個熟悉的 SRE 工作流程的地方。事故應變,是這個產業裡被最切身理解的可靠性實務,也是代理式可靠性工程最明顯能證明自己價值的地方。檢驗這套架構是否已被內化的方式,是看那一章工作流程讀起來,是不是像是在一個你已經理解的形狀上做精煉,而不是要吸收一套全新的框架。如果你不查閱本書,就能畫出四個平面、DRAL 迴圈與五項 SLO,接下來的工作流程那幾章會彼此複利累積;如果你還做不到,現在正是翻回去、把它們鞏固起來的時候。