← 部落格
靈感閱讀約 13 分鐘

當 AI 能決定下一步做什麼,軟體還有什麼用?

軟體正從指令轉向制度——我從打造一套複雜 AI 系統中帶走的原則

Translated by AI

長久以來,我一直在打造一套複雜的 AI 系統。

它起初是一個相當具體的產品。隨著時間推移,它逐漸涵蓋執行、工具、記憶、權限、長時間執行的任務、外部能力,以及多種產品形態。隨著它日益龐大,我花在思考「如何再加一個功能」的時間變少了,花在另一類問題上的時間變多了:一項能力應該歸屬於哪裡?誰擁有詮釋它的最終權威?哪些決策該交給模型,哪些保證必須來自軟體?今天幫助我們出貨的機制,明天會不會變成我們無法逃脫的邊界?

這些問題看起來像架構問題。但實際上,它們改變了我對軟體本身的思考方式。

傳統軟體是圍繞指令建構的。程式設計師事先定義路徑,機器精確遵循:若發生 A,就做 B;若輸入是 C,就回傳 D。軟體的大部分價值,來自將人類的判斷轉化為穩定、可重複的步驟。

AI 改變了這個安排。機器首次能在有意義的各種情境範圍內決定下一步做什麼。我們不再需要列舉每一條路徑。我們可以描述一個目標,提供環境與回饋,讓模型形成計畫、選擇工具、觀察結果並進行調整。

這可能給人一種印象:隨著模型能力越來越強,軟體變得越來越不重要。

我的經驗讓我得出相反的結論。軟體並沒有消失。它肩負責任的對象正在改變。

過去,軟體告訴機器下一步做什麼。現在,模型可以選擇下一步,但軟體仍然必須回答另一組問題:什麼是真的?什麼是被允許的?什麼才算完成?出錯時誰負責?一個智慧行動如何成為人們可以信賴的結果?

我逐漸相信這一點:

模型生成可能性。軟體將可能性轉化為秩序。

軟體不再只是圍繞 AI 的指令集。它正成為 AI 所棲身之世界的制度層。

以下原則是在我建構、捨棄、重建並驗證這套系統不同部分的過程中逐漸浮現的。它們不是針對某個特定產品的架構指南,也不是一套放諸四海皆準的方法論。它們只是我現在認為值得帶進下一件作品的幾個想法。

1. 在今天的介面定義目的地之前,先定義你在打造什麼

長期專案中最危險的漂移,不是把某個功能做錯。而是逐漸忘記自己當初要打造什麼。

產品總是從一個具體的切入點開始。它可能是一個聊天介面、一個桌面工具、一個編輯器、一個瀏覽器,或一個工作台。因為這些東西看得見、用得到,它們很容易開始反向定義整個專案:專案變成今天存在的那些畫面,而它的未來則變成當前最成熟那個功能的擴張。

但當前的產品往往只是驗證目的地的載體,而不是目的地本身。

我學會刻意區分三件事:我最終想打造什麼、支撐那個目標所需的共同基礎,以及使用者今天真正能用的東西。

這三者必須相互連結,但絕不能彼此冒充。

如果你只談目的地,專案就變成一個沒有交付物的願景。如果你只談現在,專案就會被當前介面與臨時實作困住。如果沒有共同基礎,每一種新產品形態都得重新發明執行、狀態、權限與記憶。

這個區分改變了我的許多決策。我不再只憑「哪裡實作最快」來決定一個功能該歸屬於何處。我開始問:它是當前產品獨有的體驗,還是未來產品也會需要的系統能力。臨時實作可以不完美,但不應被允許重新定義長期目標。

一個長壽的系統首先需要的不是路線圖。而是一種層次感:什麼是方向、什麼是基礎、什麼只是系統今天觸及使用者的方式。

2. 先問「這歸誰管?」,再問「我們怎麼打造它?」

軟體中的許多複雜性,並非來自程式碼太多。而是來自無處安放的責任。

當一個概念沒有明確的擁有者,它自然會開始複製。介面保留一份狀態,後端保留另一份,設定檔再保留第三份。沒有哪一份明顯是錯的,但當它們不一致時,也沒有哪一份能給出最終答案。

於是系統開始長出同步邏輯。一處變更必須通知另外兩處。通知偶爾會遺失,於是加上復原。復原順序被證明不穩定,於是加上補償。補償又產生另一個狀態,於是加上對帳。程式碼越來越賣力,系統卻越來越難以解釋。

我以前會立刻被「如何把一切串起來」這個問題吸引。現在我會先問不同的問題:

  • 這個概念真正屬於誰?
  • 誰負責建立它、詮釋它、結束它?
  • 如果它被停用、遷移或刪除,系統的哪一部分理解這項變更的完整意義?
  • 其他元件接收到的是真相,還是只是從真相投射出來的視圖?

只有在這些問題有了答案之後,連接策略才重要。

「歸屬」聽起來像程式碼組織的術語,但我認為它表達了一個更廣泛的原則:任何會持續存在的東西,都需要有一個對其完整生命週期負責的對象。否則,每個人都能改變它,卻沒有人真正理解它。

這也讓我強烈偏好為每一項事實保留單一的最終詮釋者。其他元件可以觀察、快取、呈現並使用那項事實,但不應發明同樣具有權威性的版本。

複雜系統不怕擁有大量狀態。它們怕的是擁有太多權威。

3. 整合機制,而非使用者體驗

隨著系統成長,為每個新需求建立新機制,既是最自然的選擇,也是最危險的選擇。

某項能力略有不同,於是有了新的註冊路徑。某個使用情境有點特殊,於是有了新模式。某份狀態還沒有明顯的歸屬,於是有了獨立的儲存。新的執行路徑不方便整合,於是繞過既有路徑、另起一套。

每個決定單獨看都合理。合在一起,它們就產生了用於探索、權限、載入、更新、停用與復原的平行系統。真正的成本不是多出幾個類別。而是未來每一項能力都必須在這些平行機制之間,把同樣的問題再回答一遍。

我逐漸學會區分兩種多樣性:使用者體驗到的多樣性,以及系統內部必須維護的多樣性。

使用者可以也應該遇到非常不同的產品、切入點與互動方式。不同的情境值得擁有自己的語言與心智模型。但在這些體驗之下,能力可以透過少數穩定的機制進入系統、取得權限並獲得生命週期。

整合機制,而非體驗。

這項原則困難的地方,在於抗拒「因為接起來比較容易就另創新東西」的誘惑。在引入另一個機制之前,我現在會問:是現有機制真的無法表達這個需求,還是新機制只是在短期內比較方便?

「它看起來有點不一樣」通常不足以成為在系統中開闢新軸線的理由。

穩定的機制不是為了讓架構圖看起來更乾淨。它們降低未來的認知成本:模型、開發者與產品不再需要在幾種幾乎等效的做事方式之間猜測。

4. 軟體應約束後果,而非規定模型的思考過程

這是我想法改變最大的地方。

當模型行為不一致時,自然的衝動是把理想工作流程寫進軟體。要求先研究再規劃、先規劃再執行、完成一個階段才能開始下一個。每次變更後都執行驗證。每當模型似乎可能走錯路,就再加一道執行期關卡。

這些系統通常出於善意而設計。但它們往往會變成僵化的流程管線。一個原本能依任務大小與形狀調整做法的模型,卻被迫連簡單的請求也要走完每個階段。多重防護機制也可能互相作用,造成模型無從逃脫的死結。

我開始用一個更簡單的測試來判斷什麼該屬於軟體、什麼該留在模型裡:這條規則約束的是一方法,還是一後果?

「編輯前先閱讀」、「實作前先提出方案」和「記得在最後驗證」都是方法。它們屬於提示詞、技能與脈絡,模型可以在那裡理解並靈活運用它們。

「未經授權不得存取資料」、「未經確認不得造成不可逆的損失」和「不得繞過使用者明確停用的權限」都是對後果的界線。它們不能依賴模型記得。軟體必須強制執行。

針對重複、空轉與迴圈的機械式防護也應節制使用。第一次嘗試應該被允許。當系統阻擋某個動作時,應該說明原因。而且它必須提供清楚的復原路徑,而不是把模型困在防護機制後面。

這改變了我對模型與軟體之間分工的理解:

把目標與方法交給模型。把不可協商的界線交給軟體。

如果軟體規定了推理過程的每一個步驟,我們只是用 AI 在裡面重建了一個工作流程引擎。如果每一條界線都只存在於提示詞中,我們就是把真正的責任交給了機率。

好的系統會避開這兩種極端。

5. 讓現實保持明確,而不是讓模型聽起來很確定

模型的推理可以保持開放。它的語言可以多變。它的計畫可以修訂。但一旦它開始對現實世界採取行動,有些事實就不能模糊。

任務是否真的開始了?變更是否真的發生了?某項權限是否已啟用?哪個工作階段擁有某個結果?這些問題的答案不應該因為是哪個畫面在看它們而改變。

我越來越把軟體視為 AI 系統的現實層。模型可以提供對世界的詮釋,但軟體記錄的是世界裡實際發生了什麼。

這意味著介面可以表達狀態,但不能成為狀態本身。附加在請求上的參數可以表達意圖,但不能暫時凌駕於持久授權之上。快取可以提升效能,但不能取得與其來源相同的地位。當系統無法確立某項事實時,它應該誠實地停下來,而不是為了維持順暢的感覺而猜測最方便的答案。

傳統軟體也需要一致性,但 AI 讓這件事更加重要。模型極擅長從不完整的資訊繼續推演,並產出聽起來合理的解釋。當底層事實早已分歧,頂層的智慧反而能讓矛盾感覺更連貫,讓問題隱藏得更久。

因此我的原則很簡單:允許模型不確定,但不允許系統事實變得模糊。

當系統不知道時,它應該說它不知道。當權威資料受損時,它應該拒絕行動。當兩個來源衝突時,它應該要求解決衝突,而不是默默選擇較容易的那一個。

智慧可以與模糊共處。制度必須守住現實。

6. 可逆性是自主的前提

我們常把 AI 自主定義為向使用者少問幾個問題。但決定使用者是否願意放手的,不是確認對話框的數量。而是系統是否讓他們能看見、能停止、能修正、能復原。

如果每一步都需要確認,AI 就變成一個要求不斷點擊的半自動工具。如果沒有任何步驟需要確認,也沒有紀錄或回頭的路,自主就變成失去控制。

我開始更關注另一組特質:過程是否可見?動作能否中斷?變更能否審閱?歷程能否追溯?失敗之後,系統能否復原到意義明確的狀態?

可逆性不是出錯時額外的一層保險。它是一開始授予權限的前提條件。

當某個動作容易復原時,系統可以給模型更多嘗試的空間。當某個動作不可逆時,系統應該收緊權限,把決定交還給使用者。自主的程度不應該由我們對模型有多樂觀來決定。它應該由後果能否復原來決定。

這也改變了我對「完成」的定義。完成不是介面上的一個綠色狀態。它意味著系統已把結果、剩餘風險與復原路徑都說清楚。當長時間執行的任務被中斷時,動畫不能就這樣消失。當變更被拒絕時,不能留下一半的執行狀態。當某項能力被停用時,復原邏輯不能在下次應用程式啟動時悄悄把它帶回來。

我們越想讓 AI 獨立行動,就越必須仔細設計它停下來與返回的方式。

7. 不要只修 bug。讓每次失敗都留下一條原則

任何長期專案都會遇到許多失敗。區分專案的不是失敗是否發生,而是失敗之後以什麼形式留存下來。

最弱的回應是讓眼前的症狀消失。更好的回應是找出並修正根本原因。最有價值的回應則更進一步:這是哪一類失敗?同樣的失敗還能透過哪些其他路徑回來?系統是否缺少一條規則、一個單一擁有者,或一個能防止問題再度滋長的結構?

我養成了一個習慣,不只記錄症狀與修正。我也記錄根本原因、擁有者,以及能防止回歸的證據。一個只用症狀描述、沒有責任界線、沒有證據的問題,還不算成為知識。

補丁修好一次失敗。原則減少一整類失敗。

如果一個同步 bug 是靠多加一個通知來修復,它日後可能在不同的觸發順序下回來。如果這次失敗反而確立了「每一份狀態都只有一個擁有者」的原則,未來的設計自然會少掉許多同步鏈。如果一個舊的進入點造成權限模糊,再加一個特例只會多出一個分支。確立「一個意圖只有一個標準進入點」,就能給系統一條持久的決策規則。

我認為在 AI 參與軟體開發的現在,這件事更加重要。程式碼產出的速度更快,局部修補也變得更便宜。沒有原則,系統可能以前所未有的速度累積看似合理的重複實作。

AI 可以幫我們更快寫出補丁。但每次失敗該教會系統什麼,仍然必須由人來決定。

一個專案真正累積的價值,不是程式碼的量,也不是它關掉了多少張票。而是過去失敗的代價,是否已轉化為能防止同樣代價再次付出的原則。

8. 不要把完成的表象誤當成證據

AI 非常擅長製造完整感。它會產出結構良好的解釋、語法正確的程式碼,以及令人安心的摘要。但工程最困難的部分,往往存在於那層表面之外。

介面沒有顯示錯誤,不能證明背景沒有東西繼續在跑。某項能力在開發環境中可用,不能證明它存在於交付給使用者的成品中。在一個平台上驗證過,不能證明在另一個平台上行為相同。程式碼通過型別檢查,不能證明舊的權威路徑已從系統其餘部分消失。

久而久之,我越來越少問「完成了嗎?」,而更常問「什麼證據才足以證明它完成了?」

證據不是一個通用的綠色指示燈。不同層次回答不同問題。程式碼檢查確立局部結構。執行時驗證確立真正的執行路徑。成品檢視確立使用者實際會收到什麼。復原測試確立系統在非理想條件下是否仍保有原意。

在 AI 時代,驗證不只是防止模型寫出不正確的程式碼。它還要對抗一個更隱微的風險:一個結果可能在邏輯上如此有說服力,以至於每個人都願意相信它已經存在於現實中。

我最重要的規則之一,是不從表面狀態推斷底層事實,不從局部通過推斷全系統正確,也不把未經驗證的未來當成今天已交付的能力來呈現。

尊重現實,有時意味著承認:「這還沒完成。」這種誠實不會削弱產品。它給系統一個可靠的立足點,讓它能繼續演進。

軟體正從指令轉變為制度

回顧起來,我從這項工作中帶走的並不是某個特定的架構,而是一種對 AI 軟體截然不同的看法。

過去,軟體試圖列舉出各種路徑。未來,這些路徑中將有更多是由模型在當下生成的。軟體不再需要為智慧規定每一個動作,但它確實需要提供一個穩定的世界:清楚的身分與歸屬、無法被繞過的邊界、能保存現實的狀態、退出與復原的方式,以及能確立某個結果是否為真的證據。

這類似於制度與個人之間的關係。

機構不會替每個人思考,也不應把每個行動都變成固定的程序。它們界定共享的現實、權利、責任,以及出錯時會發生什麼事。好的機構在保留行動空間的同時,也防止自由以犧牲秩序為代價。

在人工智慧時代,軟體正開始扮演類似的角色。

它不是模型的大腦,也不該與模型爭奪工作。它是模型所處世界的法律、帳本、邊界與記憶。它把當下即興的聰明舉動,轉化為穩定的能力。它把偶然的成功,轉化為可重複的產品。它讓使用者能將更重要的工作託付給 AI,而不必以盲目信任換取便利。

我不認為 AI 會讓軟體變得不那麼重要。恰恰相反,模型能力越強,軟體就越必須回答那些模型不該自行決定的問題。

什麼是真實的?

什麼是被允許的?

誰擁有它?

失敗之後我們如何返回?

什麼證據能證明完成?

模型探索答案。軟體守護問題。

我們正從人們為機器寫下每一個步驟的時代,邁向人們建立原則、機器探索路徑的時代。軟體的角色也隨之轉變:從描述動作,轉為建立秩序。

模型生成可能性。

軟體讓這些可能性值得信任。