Earendil 官方授權中文譯文 · 01
無法隨身帶走的工作階段
繁體轉換版說明
本頁為簡中授權譯文之繁體轉換版。英文原文版權歸 Earendil 所有,中文譯文及轉換部分按 CC BY 4.0 發布。如有歧義,請以英文原文為準。
- 原文標題 The 工作階段(Session) You Cannot Take With You
- 作者 Earendil Engineering
<rfc@earendil.com>- 釋出日期 2026-07-30
- 原文地址 earendil.com/posts/session-portability
- 授權說明 經 Earendil 授權改編與翻譯(Adapted and translated with permission from Earendil.)
- 譯文許可 CC BY 4.0
推理 API 最初的承諾簡單得令人愉快:傳送一些輸入,接收一些輸出。如果你同時儲存了兩者,就儲存了這段對話。你可以檢查、歸檔或重放它,也可以把它交給另一個模型。
這種抽象從來沒有完全成立。例如,提示快取位於別人的 GPU 上;不同模型的 token 化方式不同;取樣也無法復現——而且這是有意如此。不過,以轉錄記錄形式存在的工作階段語義記錄仍然可以屬於使用者。一份轉錄記錄應當包含指令、訊息、工具呼叫和工具結果。另一個能力足夠強的模型或許無法以完全相同的方式繼續,但它可以理解發生過什麼,並接手後續工作。
令人沮喪的是,推理 API 正在逐漸偏離這一特性——至少在一定程度上如此。它們越來越多地返回文字與提供商綁定狀態的混合物,而這種狀態被刻意設計成不可移植。
- 向使用者計費,卻最多隻返回無用摘要的推理 token;真正內容只是不可讀的加密資料塊。
- 模型能看到源材料、客戶端卻看不到的網頁搜尋。
- 只有原提供商才能解密的壓縮上下文。
- 以加密載荷形式隱藏,不讓執行 Agent 的應用看到的子代理(Subagent)指令和訊息。
- 無法在其他地方解析的檔案、向量儲存、容器和快取引用。
- 完全依賴 ID 的響應和對話狀態,而這些 ID 所指向的資料全部存放在提供商伺服器上。
提供商很容易為每項功能給出一個基本理由,也能提出這些設計為什麼有利於使用者的好論據。但它們合在一起,改變了 AI 工作階段在現實中的歸屬:你電腦上的轉錄記錄不再等同於你的工作階段,而只是某個工作階段的區域性檢視;這個工作階段的執行狀態屬於推理提供商,而不屬於你。
我們不喜歡這個方向。下面想談談它對作為使用者的你意味著什麼,也談談它對我們這些開發相關工具的人意味著什麼。
檢驗工作階段歸屬的實用方法
我們所說的可移植工作階段,並不是指從一個模型切換到另一個模型後,必須生成完全相同的下一個 token。這顯然不可能,因為模型的能力、訓練出的性格、上下文視窗和工具使用方式都不同,更不用說整個過程本來就有很強的非確定性。
可移植性指的是一件更樸素的事:
const transcript = session.export();
revokeCredentials(oldProvider);
session = newProvider.continueFrom(transcript);這份歸檔應當包含足夠多且能夠理解的資訊,讓另一個模型接手工作。它不應該要求舊提供商解析某個 ID、解密某段資料、記住某次搜尋結果,或重新構造某份摘要。
由此可以得到五項有用的檢驗標準:
- 檢查: 使用者能否看到模型看到了什麼、執行了哪些工具呼叫,以及各個 Agent 之間說了什麼?
- 匯出: 除了同樣可以下載的普通產物之外,工作階段本身是否自包含?
- 重放: 另一個實現能否重建語義等價的上下文?
- 審計: 事後能否由人解釋系統為什麼執行了某個操作?
- 刪除: 使用者能否找出並刪除工作階段所依賴的每一份伺服器端副本?
響應 ID 不是轉錄記錄,因為資料存放在伺服器上;密文不是由使用者控制的狀態,因為使用者無法解密它;引用清單也不是搜尋結果放進模型上下文裡的證據,因為你通常無法取得模型當時看到的同一份資料。
為誰而加密?
這些功能的名稱和宣傳方式可能會誤導使用者。encrypted_content 聽起來像是一項由使用者控制的隱私功能。實際上,它通常是一個客戶端無法讀取、只有提供商能夠開啟的封裝。提供商選擇金鑰,為自己的模型解密內容,並規定這些資料可以在哪裡重放。
一個更準確的名稱是提供商封存狀態(provider-sealed state)。
提供商封存確實可能帶來隱私收益。例如,OpenAI 可以在客戶端設定 store: false 時返回加密的推理內容,然後在下一次請求中只把它解密到記憶體裡,而不持久儲存中間狀態。對於零資料保留(Zero Data Retention)客戶來說,這優於強制使用伺服器端對話儲存。但是別忘了:其實一開始並沒有什麼東西是非加密不可的!
這種加密不會對推理提供商隱藏資料,它隱藏的是你自己的資料。
儲存式對話把轉錄記錄變成了指標
OpenAI 的 Responses API 預設會儲存響應。文件說明,預設情況下響應物件至少保留 30 天。你可以使用 store: false,而且應該這樣做,因為它會讓介面的工作方式更接近 Completions:資料不會儲存在 OpenAI 的伺服器上。
新的 Gemini Interactions API 做出了類似選擇。它預設設定 store: true。付費層的 interaction 會保留 55 天,免費層則保留一天。
顯然,在伺服器上儲存狀態這個想法很有吸引力:
const first = responses.create({
model: "frontier-model",
input: "Investigate this production failure",
store: true,
});
const second = responses.create({
model: "frontier-model",
previousResponseId: first.id,
input: "Now implement the fix",
store: true,
});應用需要傳送的資料更少;提供商可以保留隱藏的推理和工具狀態;快取路由也會更容易。但是,如果本地應用只記錄使用者訊息和最終文字,那麼 first.id 就成了指向一個不受本地應用控制的資料庫的外來鍵。
不會給你看的推理過程
所有主要實驗室都聲稱,有正當理由不公開原始思維鏈。因此,在非開放權重模型上,我們通常看不到這些 token。
透過 API 無法看到原始推理。使用已儲存響應時,可以透過 previous_response_id 恢復先前推理。使用 store: false 時,API 會返回 encrypted_content,客戶端必須儲存並在後續請求中重放它。即使 reasoning.context: "all_turns" 允許後續取樣使用已儲存的推理,它仍然是不透明的。
Anthropic 會在 signature 欄位中返回加密的完整 thinking。啟用可讀 thinking 文字時,使用者看到的是另一個模型生成的摘要,而不是原始思維鏈。在使用工具的輪次中,thinking 塊必須原樣回傳。Anthropic 的文件還說明,這些 thinking 塊與生成它們的模型綁定,切換模型時應將其移除。因此,這些推理軌跡即使在 Anthropic 內部也並不試圖做到可移植。
所有閉源權重模型上都在重複同一種情況。
這些加密機制允許工作階段在一個生態系統內部延續,卻不會產生一份能夠交給另一家提供商模型使用的可移植轉錄記錄。工作階段歸檔可以包含加密資料塊,但其他模型無法利用其中的含義:
{"type": "reasoning", "encrypted_content": "gAAAAAB..."}
{"type": "thinking", "thinking": "", "signature": "EqQBCg..."}
{"type": "thought", "summary": [], "signature": "EpoGCp..."}隱藏的搜尋過程
以網頁搜尋為例。伺服器端網頁搜尋是轉錄記錄中出現“隱藏空洞”的最清晰案例之一。客戶端搜尋工具與普通工具的行為相同:
const result = search(query);
record({
query,
retrievedAt: now(),
results: result.map((item) => ({
url: item.url,
title: item.title,
passages: item.passages,
})),
});
model.send({ toolResult: result });使用者可以檢查結果排序和文字片段,重新抓取頁面,儲存一份副本,或把相同證據交給另一個模型。
使用託管搜尋時,提供商會執行一段私有工具迴圈。OpenAI、Google 和 Anthropic 會公開搜尋動作、引用,有時還會公開來源 URL 清單,卻不會公開生成答案時使用的完整文字上下文。URL 無法帶來穩定重放,因為頁面內容可能變化,也可能在當時就已經被縮減為模型所見的短得多的片段。
最終答案可能完全正確。問題會在下一輪顯現:
比較第三個來源和第一個來源,重新核對有爭議的數字,然後換一個模型繼續這項研究。
新模型會收到答案和幾個 URL,卻收不到結果排序、摘取的段落、被過濾掉的材料,也收不到第一個模型使用過的確切證據。即使下一次請求發往別處,舊提供商仍是這段工作階段的一部分。即使你保留了引用並重新抓取網頁,也無法重現當時的精確資料。
託管搜尋應當提供全保真匯出模式,包含查詢、結果後設資料、取回的段落、時間戳和保留的內容。使用者介面仍可以只顯示簡潔引用,但這不應成為唯一記錄。
不透明的壓縮
很長的 Agent 工作階段最終都需要壓縮。可見且由客戶端控制的摘要雖然有損,但至少可以檢查和轉移。使用者可以審閱、編輯它,也可以讓另一個模型再生成一版。
與之相反,OpenAI 的伺服器端壓縮會生成一條加密的壓縮項。文件稱它“不透明,且無意讓人類理解”。獨立的 /responses/compact 端點返回一個“規範的下一上下文視窗”,並指示客戶端原樣傳回。
從概念上看,這一轉換如下:
// 之前:成本高,但可以移植
let history = [
userMessage,
assistantMessage,
toolCall,
fullToolResult,
// ……另外 200,000 個可理解的歷史 token
];
// 之後:只有原提供商才能低成本地繼續
history = [
{
type: "compaction",
encryptedContent: "enc_provider_only_state...",
},
...recentItems,
];OpenAI 可以從壓縮後的含義繼續,但另一家提供商只能看到一段不可讀字串和最近的一小段字尾——更準確地說,它本可以看到這些內容,只是 Pi 從來不會把這類資訊傳給另一家提供商。
這並不是技術上的必然。Anthropic 的伺服器端壓縮會返回一個帶有可讀 content 欄位的 compaction 塊。它允許客戶端提供自定義摘要指令,生成的摘要可以檢查,也可以傳給另一個模型。使用任意提供商時,同樣可以在客戶端執行壓縮。
OpenAI 的封存產物可能比純文字摘要保留更多與模型相關的狀態,並在原模型上有更好的表現。把它作為可選最佳化是合理的,但同時應該提供可讀的交接摘要,而不是用它取代摘要。不過還是那句話,這一切還附帶了把你進一步鎖進單一生態系統的好處。
子代理帶著隱藏指令而來
多代理系統讓問題更加複雜,因為此時不再只有一份轉錄記錄,而是一棵工作階段樹和一系列 Agent 間訊息。這些訊息通常就是像人類寫出的一樣的提示,只不過現在由一臺機器寫給另一臺機器。
OpenAI 託管的 Responses Multi-agent beta 會返回三種新的專案型別:multi_agent_call、multi_agent_call_output 和 agent_message。spawn_agent 的示例裡,message 引數是加密的;Agent 間訊息也只包含 encrypted_content。一旦啟用 Multi-agent,每個 Agent 都會隱式啟用自動伺服器端壓縮,即使客戶端沒有提出要求。它不支援推理摘要,API 還會注入開發者無法編輯或移除的 root 和子代理指令。
這是一整套無法轉移的狀態:封存的任務委派、封存的 Agent 訊息、各自被自動壓縮的上下文、隱藏推理,以及提供商託管的編排過程。
2026 年 6 月,開源 Codex 客戶端也合入了一項相關改動。這個提交名為 “Encrypt multi-agent v2 message payloads”,其中直接說明了這一流程:
// 父模型發出的工具呼叫,Codex 會這樣儲存它
{
"name": "spawn_agent",
"arguments": {
"task_name": "worker",
"message": "<ciphertext>"
}
}
// 子模型收到的輸入
{
"type": "agent_message",
"author": "/root",
"recipient": "/root/worker",
"content": [{
"type": "encrypted_content",
"encrypted_content": "<ciphertext>"
}]
}Responses API 會加密父 Agent 發出的工具引數,Codex 負責轉發,API 再在內部為子代理解密。Codex 自己的 InterAgentCommunication.content 是空的。實際任務不會出現在它的可讀 rollout 和歷史記錄中。
這大概不只是一個抽象的模型切換問題。可以想象,如果子代理改錯了檔案、洩露了秘密、重複了另一個 Agent 的工作,或沿用了錯誤假設,使用者甚至無法回答一個簡單問題:那個 Agent 當時到底被要求做什麼?
一個尚未關閉的 Codex issue要求加密傳輸同時保留一份單獨的可讀審計副本。這是最低限度可以接受的設計。更好的做法是讓明文 Agent 間訊息繼續成為常態。
“大多數人不會在工作階段中途切換模型”
也許確實如此。大多數人也不會每週更換作業系統或手機電信業者。但即使你沒有行使這種自由,它仍然很重要,因為它會改變你與提供商之間的關係,也會改變提供商對待你的方式。
作為使用者,你還可能因為模型退役、服務宕機、價格變化、策略阻止下一次請求(你好,Fable)、某個機密階段必須在本地執行,或審計人員需要重建事件經過,而不得不遷移工作階段。Agent 也讓工作階段變得越來越長:一次程式設計或研究工作階段可能積累好幾天的決定和證據;個人助手甚至可能積累跨越多年的工作階段記錄——大概如此,畢竟我們還沒有真正使用它們那麼多年。
離開的選項本身也會形成約束。如果提供商知道使用者可以去別處繼續,它就必須在模型品質、價格、可靠性和信賴上競爭。如果使用者積累的上下文只能由一家提供商解釋,產生的激勵就會非常糟糕。
可移植推理 API 應當承諾什麼
我們希望推理提供商和 Agent 開發者採用一小組規則。
- 本地事件日誌是規範記錄。 伺服器儲存可以映象或加速它,但客戶端無需解析伺服器 ID,也能重建工作階段。
- 儲存必須明確。
store: false應當易用、有清楚文件,最好成為預設設定。需要保留資料的功能,應在使用時明確說明。 - 任何不透明專案都不能成為意義的唯一載體。 為了在同一提供商內部獲得更好效果,可以包含加密推理、壓縮和工具簽名,但每一項都應有可讀、與提供商無關的交接表示。
- 託管工具必須保留全保真日誌。 記錄確切的輸入、輸出、證據、篩選、來源、時間戳和內容雜湊,而不只是潤色後的答案和引用。
- 子代理通訊必須可審計。 為每個 Agent 儲存確切且可讀的任務、訊息、結果、繼承關係、模型和工具權限。
- 壓縮必須可檢查。 返回可讀摘要、建立摘要時使用的指令,以及足以理解哪些內容被丟棄的來源資訊。
- 產物必須可匯出。 檔案、容器輸出、搜尋快照和生成媒體,都應能下載到一個按內容定址的本地歸檔中。
蒸餾其實很棒
在模型層面,還存在一種相關的鎖定。
美國一些最大的閉源權重實驗室,對外部蒸餾表現得越來越敵對。Anthropic 在 2026 年 2 月的一篇文章中指控 DeepSeek、Moonshot 和 MiniMax 開展相關行動,並稱其為“蒸餾攻擊”。Anthropic 的商業條款規定客戶擁有輸出,卻禁止使用其服務訓練競爭性 AI 模型。與此同時,Anthropic 自己的文章也承認,當前沿實驗室對自己的模型使用蒸餾時,“蒸餾是一種被廣泛使用且合理的訓練方法”。
Anthropic 使用機器人從公共網路收集資料用於模型開發,還以切開紙質書並掃描而聞名。OpenAI 同樣表示會使用公開網際網路內容訓練模型,並主張用公開可存取的網際網路材料訓練屬於合理使用。兩家公司都把內部用於生產較小模型的蒸餾描述成正常方法。OpenAI 還提供過明確的第一方 API 蒸餾工作流,允許使用更強 OpenAI 模型的輸出微調較小的 OpenAI 模型。
其中的道德不對稱顯而易見。這些實驗室要求社會接受機器可以學習人類放在網際網路上的海量作品——往往沒有事先取得個人許可——卻堅持其他機器不能學習這些實驗室生成的輸出。這個原則最寬泛的版本,恰好允許知識流入封閉模型,卻不允許再從中流出。
我們認為,對蒸餾的預設態度應該從敵視轉向支援。蒸餾可以把昂貴的前沿能力轉化為更小、更便宜、更快的模型,讓它們能夠在本地、離線、受限硬體或使用者自己的控制下執行。它可以增加競爭,在 API 消失後保留能力,並減少常見任務所需的算力和能源。
最低限度的自由
使用者應該能夠關閉一個帳戶、保留一段工作階段,再把它交給另一個模型。新模型可能不同意此前的結論,可能追問問題,也可能表現更差,但它不應在舊模型能夠看到使用者歷史、證據、計劃和委派工作的位置,只看到一段密文。
我們不反對提供商構建更好的有狀態 API。我們反對的是把更好的效能與更少的使用者控制綁在一起。狀態儲存應當可選,託管工具應當可觀察,壓縮應當可讀,Agent 通訊應當可審計;理想情況下,不透明推理應該不再不透明,或者至少要有可移植的交接表示。蒸餾應該成為一條讓能力更普及的路徑,而不是用來築起更高圍牆的禁忌。
譯者說明
本文為 Earendil Engineering 原文的完整中文譯文。中文譯文及適配部分經授權按 CC BY 4.0 釋出;英文原文版權歸 Earendil 所有。如中文表述與原文存在歧義,請以英文原文為準。