MapleCheng

在浩瀚的網路世界中無限潛水欸少年郎!

0%

AI API 退場時,真正要搬的是狀態,不是端點

最近看到一套有狀態的 AI API 正式退場,官方提供了新舊物件的對照:原本的助理、對話串、執行與步驟,分別由新的提示詞、會話、回應與項目承接。表面上看起來很像一次 API 改版,把幾個資源名稱和呼叫方式換掉就好。

但其中有個訊號更值得技術主管注意:舊對話狀態不一定有自動遷移工具。這代表真正的工作不是把 endpoint 換掉,而是決定哪些歷史狀態值得搬、如何證明搬對,以及切換期間新舊世界要怎麼共存。

無狀態 API 可以改呼叫,有狀態服務必須搬語意

傳統的無狀態 API 遷移,相對容易想像。請求欄位改名、回傳格式調整、驗證方式更新,我們修改 client、補契約測試,再逐步切換流量。只要相同輸入仍能得到符合預期的輸出,事情大致可控。

有狀態的 AI API 不一樣。它保存的不只是幾筆聊天文字,還可能包含系統指令、工具定義、附件、執行順序、中途產物、錯誤、重試與使用者看到的對話脈絡。應用程式後續的判斷,往往依賴這些資料彼此的關係。

當新平台用另一組資源模型承接時,即使名稱可以一對一畫箭頭,語意也未必完全相同。舊系統的一次執行,在新系統裡可能被拆成多個項目;以前隱含保存的工具結果,現在可能需要應用端明確管理;原本綁在助理物件上的提示詞,也可能改由另一套版本化機制提供。

所以我不會把這類工作只交給「把 SDK 升級」的任務。它本質上是一次小型的狀態型服務遷移。

第一個決定不是怎麼搬,而是搬什麼

很多團隊聽到 API 即將關閉,第一反應是把所有歷史資料完整複製到新平台。這很直覺,卻未必合理。

有些對話只是短期問答,早已沒有產品價值;有些歷史狀態受到保存期限、刪除要求或資料區域限制約束;有些 Thread 雖然存在,應用程式其實從未再讀取。若不先分類,就可能花大量時間搬移沒人使用的資料,甚至把原本應該退場的敏感內容重新延長壽命。

我會先依用途把狀態分成幾類:仍在進行中的工作、使用者需要回看的歷史、系統為稽核而保留的證據,以及可以依法規或政策淘汰的暫存資料。每一類都要有不同策略。

進行中工作需要維持連續性;可回看歷史不一定要重新注入模型,也可以轉成唯讀封存;稽核資料重點是不可竄改與可查證,不代表必須留在供應商的對話物件裡;過期資料則應趁遷移清掉,而不是因為「搬家比較保險」就全部續命。

遷移不是備份競賽。保留愈多,不代表風險愈低。

不要把新舊資源名稱當成資料契約

官方 migration guide 會告訴我們物件如何對應,但企業真正需要的是自己的正規化狀態模型。

如果應用程式把供應商的 Thread ID 當成核心業務識別,把每個 Run 狀態直接寫進流程判斷,供應商一改抽象,整個產品就跟著重構。這次改完,下一次仍會再痛一次。

比較穩健的做法,是在應用層定義自己的 conversation、message、task、tool invocation 與 artifact。外部 API 的資源 ID 只是 adapter metadata,負責指出某筆內部狀態目前對應哪個供應商物件。產品規則依賴內部語意,不直接依賴外部命名。

這不是為了追求「隨時可換供應商」的漂亮口號。不同 AI 平台能力差異很大,完全抽象化通常不切實際。真正的目標,是把不能丟的業務狀態與可以替換的執行介面分開。模型與 API 可以有平台特色,但使用者的工作進度、權限、附件來源與稽核證據不能只活在某家 SDK 裡。

我會採取先截流,再回填

面對沒有完整自動搬遷工具的狀況,我偏好的順序不是先搬完全部歷史才上線,而是先阻止舊資料繼續增加。

第一階段讓新建立的對話直接走新 API,舊對話暫時維持原讀取路徑。這一步的價值,是先把遷移範圍固定下來。若新舊入口同時持續寫入,待搬資料每天增加,截止日只會愈來愈難控制。

第二階段處理活躍狀態。依最後使用時間、業務重要性與資料敏感度建立批次,先遷移近期仍會續談或執行中的工作。每批都保存來源 ID、目標 ID、轉換版本、筆數、雜湊或其他可核對證據,並確保重跑不會製造重複資料。

第三階段才處理長尾歷史。低頻內容可以在使用者打開時按需轉換,也可以保留成唯讀檢視,不必強迫所有舊紀錄重新成為新模型的上下文。

這種策略不是偷懶,而是把「產品不能中斷」和「歷史要完整處理」拆成兩條可管理的工作流。

驗證不能只看資料筆數

狀態遷移最容易出現的假成功,是來源與目標筆數一致,畫面也看得到對話,但行為已經不同。

我至少會驗證幾個層次:訊息角色與順序是否保留、附件是否仍可存取、工具呼叫與結果能否正確配對、取消與失敗狀態有沒有被誤轉成完成、時間與時區是否一致,以及權限與資料可見範圍是否維持原本限制。

還要用真實任務做行為回歸。選一組包含長對話、工具呼叫、錯誤重試、人工確認與附件的案例,分別跑在新舊路徑,比較最終結果與中間軌跡。AI 輸出不一定逐字相同,但不可破壞的契約必須清楚:該停下來時有沒有停、該要求確認時有沒有確認、同一位使用者能否繼續原本的工作,以及稽核人員能不能重建發生過什麼。

另外,回滾也不能只理解成把程式版本切回去。若新系統已經產生新狀態,舊 API 卻不認得,回滾後這些工作要去哪裡?比較安全的設計,是在切換期間讓應用層的正規化事件成為權威紀錄,外部 API 狀態則由 adapter 投影。至少在遷移窗口內,不要讓任何一邊成為唯一且無法匯出的真相。

API 退場,其實是在檢查架構主權

供應商淘汰 API 不一定是壞事。新介面可能更一致、更容易組合工具,也更適合長時間執行。但它會迫使團隊回答一個平常很容易迴避的問題:我們的產品狀態,到底掌握在自己手上,還是只存在供應商替我們管理的物件裡?

站在技術主管的位置,我不會要求所有 AI 能力都自己重做,也不會因為擔心綁定就拒絕使用託管狀態。真正務實的界線是:平台可以代管執行細節,但重要狀態要能盤點、匯出、驗證、淘汰,也要能在平台改變時重新投影。

一次成熟的 AI API 遷移,完成條件不該只是新版 SDK 成功回傳 200。它應該證明新對話已經截流、活躍工作沒有中斷、歷史資料依政策處理、權限與稽核仍然成立,而且舊入口關掉後,沒有任何關鍵狀態被留在門後。

端點可以改,物件名稱可以換,模型也會繼續更新。真正不能跟著供應商版本漂移的,是使用者正在做的事,以及我們對那段狀態負起的責任。