每個 Asana 部署都有一個系統管理主控台。 IT 系統管理員可以在此處設定公司使用 Asana 的方式,例如調整密碼要求、角色和權限、是否可以從 Dropbox 附加檔案,以及在預設情況下誰可以看見新專案。
隨著 Asana 的發展,系統管理主控台累積了多年的自訂邏輯和臨時拼湊的解決方案,導致建立和維護管理控制項的成本越來越高。 以其中一項管理設定為例:新專案的預設隱私設定。 系統管理員可選擇新專案一開始是否對整個組織可見、對其團隊可見,或僅對受邀成員可見。 描述起來很簡單,但其中隱藏著許多複雜性:
此功能是否包含在客戶的方案中?
他們是否曾經付費使用此功能,後來停止付費,並因此受限於無法再變更的設定?
他們是 HIPAA 或 FedRAMP 客戶嗎?只有擁有較高權限的角色才能進行編輯?
是否有某個選項因其他設定而無法使用?
是否應顯示資訊橫幅,以描述目前的限制?
任何想要新增系統管理控制項的團隊都必須正確處理所有這些問題。 大多數人認為這不值得,隨著時間的推移,Asana 的功能與系統管理員能夠管理的內容之間的差距越來越大。 這可以從以下事實看出:有些控制項只能在全公司層級進行設定,因此 IT 系統管理員很難只將控制項套用至其使用者子集。
以下是專案隱私設定對話方塊的程式碼片段,用於確定是否應停用該功能,以及是否應顯示橫幅:
其中有許多邏輯需要解析 - 功能授權、管控、因部署結構而產生的覆寫,以及使用者角色,特別是針對審查人員。 為了謹慎起見,您必須在腦海中重建測試矩陣,以確定其是否正確。
這只是對話方塊而已。 該列是否顯示在設定頁面上,是在其他地方決定的,而且也不一致:
三列、三種機制,且閘控並不一定在同一份檔案中。 因此,若要回答「此客戶實際上會看到哪些設定?」 您不僅必須閱讀每一列,還必須掃描每個元件。 這個問題經常出現:客戶支援人員試圖解釋為什麼某個設定對客戶來說消失了;產品經理希望直接瞭解新控制項是快速變更還是需要兩週時間;新進員工試圖找到決定特定使用者能看到什麼內容的那個地方。
從大方向來看,有四件事讓在系統管理主控台中工作變得成本高昂:
審查成本高昂。 邏輯存在於作者放置它們的任何地方,因此 PR 可能會引入特殊行為,但審查者卻不會察覺,且正確性並非您僅憑閱讀就能輕鬆驗證的內容。
缺乏標準化導致錯誤被掩蓋。 我們存在一些長期難以發現的錯誤。 許多錯誤是由於產品規格與實作之間存在差異所致,這是因為大量採用了客製化實作。 團隊做出任意的決策,導致每個控制項都有其自身的特點。
變更的成本高昂。 若要為終端使用者進行一項變更,您必須找到規則被編碼的所有位置,而且很少有一個單一的定義點。
測試成本高昂。 設定測試需要對後端狀態有深入的瞭解,而由於互動維度的數量眾多,對最終部署進行全面的手動測試並不可行。
我們為管理控制項建立了一個宣告式架構,作為程式碼庫中的事實來源。 現在,控制項會說明其內容:
此處的每個欄位都對應到上方對話方塊中的一個分支: requiredAdminRole 是 HIPAA/超級管理員檢查, upsellBehavior 是兩個追加銷售分支,而 churnBehavior 是流失客戶的案例,讓他們還原為預設值,除此之外別無其他。
作為此過程的一部分,架構會公開 Hook,工程師可使用這些 Hook 來導出控制項的計算狀態。 一起來看看同一個專案的隱私對話框現在是什麼樣子:
橫幅的 if 鏈合併為一個由集中式 Hook 驅動的共用元件。 架構處理所有不同情境的組合邏輯,而負責維護架構的專業人員深入瞭解管理產品,因此可以有信心地進行大規模變更。 現在,我們使用嚴格的類型檢查來引導實作人員填寫必要資訊,以便在所有可能的情境中正確呈現他們的設定。 最重要的是,他們不需要瞭解這些情境的複雜性,或它們是如何互動的。
這些設定可透過系統管理主控台 UI 中的列進行存取。 這些列的可視度也經過相同的處理,這就是第二個架構的用武之地。 設定登錄檔中的列並未描述其自身的顯示規則,而是將其與代表該列的控制項連結起來:
控制項陣列是附加價值。 它包含與對話方塊傳遞給 useAdminConsoleControl 的 ProjectDefaultPrivacy 物件相同的物件,而登錄檔則透過相同的單一事實來源來執行該物件,因此頁面和對話方塊不會有不一致的情況。 過去,這是分開計算的,因此差異可能會導致兩種失敗模式:一個可見但開啟您無法使用的對話方塊的列,以及一個客戶付費但沒有列可存取的設定。 集中化消除了這一類錯誤。
採用集中式架構的測試大大改善了提取請求審查者的體驗。 例如,以列可見性測試為例,它回答了「此客戶實際上會看到哪些設定?」 之前提到的問題。 情境並非測試程式碼,而只是資料:角色、網域狀態以及其呈現的頁面。
而一行只列出它必須出現在哪些已命名的情境中:
不需要撰寫任何渲染呼叫或斷言。 動態測試套件會讀取目錄,並針對其命名的每個情境檢查每一列。 現在,目錄是唯一能說明客戶所見內容的地方,並由機器進行檢查。 不再需要仰賴勤奮的程式碼審查人員或作者來正確識別並撰寫自己的測試案例。
我們在 2025 年底開始這項工作,因為我們預期需要讓非主題專家 (SME) 的工程師能夠在系統管理主控台中充滿信心地進行建置。 當時的目標並非為了最佳化 LLM 的效能,但事實證明,為工程師標準化和簡化體驗,對 AI 代理程式來說也有同樣的效果。
在建立這些架構之前,我們確實曾嘗試使用 AI 來解決此遷移問題,從技術上來說,這確實可行。 問題在於,代理程式和審查人員都無法判斷測試是否真的正確,這意味著存在虛假信心和隱性差距。 AI 無法解決缺乏結構的問題,它只是在現有結構的基礎上更快地產生更多程式碼。 Google 在 AI 輔助開發中為 Go 的類型系統提出了類似的論點:靜態類型可作為自動化安全網,因為 LLM 容易產生幻覺屬性,並在不同檔案之間出現類型不符的情況。 TypeScript 的靜態嚴格性不如 Go,但架構可以在其基礎上提供相同的保證:在架構層級定義一次控制項的類型,且每個實作都必須在使用點符合該類型。
架構準備就緒後,我們開始準備委派和平行化。 我使用我們新的規格導向開發工具 [連結預留位置:關於規格導向開發的工程部落格文章: Asana 工程部落格 - 規格導向開發:優點] 來建立一種從頭到尾都能完成工作的技能。 它對整個轉換過程進行編碼:定義控制項、呼叫 Hook、替換橫幅、更新片段、新增新的宣告式測試,以及一個自動更新的核對清單和先前轉換中邊緣案例的日誌。 在所有大約 150 次遷移中,91% 的遷移在審查後無需修改。
啟動代理程式來撰寫 PR 不需要太多的投入量,審核該 PR 也不需要太多的投入量。 由於所有內容都是以可預測的方式宣告,因此審查人員無需成為管理方面的專業人士,即可檢查實作是否符合產品規格。 至關重要的是,這將合適的審查人員群組擴大到更廣泛的工程師群體,這不僅僅是在頂端建立 PR 的漏斗更寬,還能進一步加快速度。 我們並非唯一一個針對這個時代重新思考審查流程的組織: GitHub 根據結構化的 PR 證據重建了 Copilot 自己的審查代理程式,以幫助人類審查人員更快找到正確的問題,從而將審查成本降低約 20%。
最初,涵蓋多個架構的約 150 個項目的遷移被視為從頭到尾的手動、一次性工程工作。 先建立架構,然後再將遷移工作委託給負責監控代理程式的工程師,這讓我們比原先計畫提前一個多月完成整個工作。
建立這些架構本身從來就不是一個專案。 這是出於必要性,源自於一個需要平行化和擴展的藍圖,在過程中人員配置有限且不斷變動,且不要求每位貢獻者都必須先成為領域專家。 我們已經看到它在建立它的團隊之外發揮作用:目前架構中的 66 個控制項中有 18 個是由 8 個不同團隊的工程師撰寫的。
現在,我們正在尋找下一個可以進行此類投資的地方。 如果說有什麼值得一提的話,那就是現在的情況比我們剛開始時更有說服力:精心設計的宣告式架構不僅能讓審查變得更輕鬆,還能決定代理程式是產生可靠的成果,還是只是快速的成果。 這也是讓自主審查成為可能的原因: Cloudflare 建置了一個系統,讓 AI 審查員自行核准乾淨的程式碼並攔截實際問題,而這之所以可行,是因為他們的輸入資料結構化程度足以讓審查員信任。 我們的架構是否足夠完善,可以嘗試同樣的做法,這是下一個值得探討的問題。
Leo Zhang 是系統管理基礎團隊的軟體工程師,負責協助 IT 系統管理員管理其組織。 目前,他正透過投資支援我們產品的技術架構,來改善系統管理主控台中其他產品工程師的開發體驗。
設計、實施、測試和推廣這些變更需要團隊投入大量心力。 這要歸功於系統管理基礎團隊的其他工程師的貢獻: Yunus Rahbar、Maryam Booshehrian、Saverio Castelli、Bronwyn Damm、Cindy Yu、Calvin Norton 和 Jaxsun McCarthy Huggan。 來自代理程式成功虎隊的 Walter Li 為這些遷移設定合適的 AI 工具提供了莫大幫助。
Lan Cheng、Emerson Murphy-Hill、Mark Canning、Ciera Jaspan、Collin Green、Andrea Knight、Nan Zhang 和 Elizabeth Kammer,《什麼能提升 Google 開發人員的生產力? 程式碼品質」,ESEC/FSE '22,2022 年 11 月。https://doi.org/10.1145/3540250.3558940
「大規模協調 AI 程式碼審查」,Cloudflare 部落格,2026 年 4 月。https://blog.cloudflare.com/ai-code-review/
Napalys Klicius,「更好的工具讓 Copilot 的程式碼審查變得更糟。 以下是我們實際改善的方式。」GitHub 部落格,2026 年 7 月。https://github.blog/ai-and-ml/github-copilot/better-tools-made-copilot-code-review-worse-heres-how-we-actually-improved-it/
「為什麼 Go 是適合 AI 輔助軟體工程的理想語言」,Google 開發人員部落格,2026 年 8 月。https://developers.googleblog.com/why-go-is-an-ideal-language-for-ai-assisted-software-engineering/