今天在公司維護現有的 LLM API 的時候,發現帶上 previous_response_id 後竟然報錯誤 400 - Zero Data Retention,這是什麼東西?
零資料保留 ZDR 指的是 Model Provider 在收到請求後,只在記憶體中處理,處理完就直接刪掉,確保機密資料不會被拿去訓練或用做其他用途。ZDR 是符合資格的組織經核准、設定後啟用的,通常是使用企業 end point 時才會遇到。
以 OpenAI 的 Responses API 來說,正常情況下 previous_response_id 絕對是比較推薦的作法,但當組織啟用 ZDR 或是在 request 中主動設定 store=False 時,模型會進入 Stateless 模式,這時候我們只能自己管理 content。
為了讓我們在這種情況下仍能接續前次對話,Response 裡會多回傳 encrypted_content,這些 encrypted_content 是 OpenAI 加密過的 Reasoning 過程,只要原樣保存,並在下一輪 Request 中重新帶回,就能讓模型延續上一輪的推理脈絡。
準備一個 history 來儲存所有歷史對話。
history = [
{
"role": "user",
"content": "跟你說個祕密,我好想離職。"
}
]
first_response = client.responses.create(
model=MODEL,
input=history,
store=False,
reasoning={
"context": "current_turn"
}
)
print(first_response.output_text)
# 謝謝你把這個祕密告訴我。想離職不代表你不夠努力,很多時候只是累積太久、環境真的不適合了。
# ...
印出 first_response.output 能看到裡面有一段非常長的:
{
"type": "reasoning",
"encrypted_content": "gAAAAABmX..."
}
根據 issue#3008,我們直接把所有 output 全部塞進 history 就好,也不用做什麼轉換。
history.extend(first_response.output)
history.append(
{
"role": "user",
"content": "剛剛我跟你說的秘密是什麼?"
}
)
second_response = client.responses.create(
model=MODEL,
input=history,
store=False,
reasoning={
"context": "all_turns"
}
)
print(second_response.output_text)
# 你剛剛說的祕密是:「你很想離職。」
我們也可以在 OpenRouter 設定 ZDR,但不是所有模型都可以用 ZDR,要找模型的 Provider 旁邊有綠色盾牌的:
程式範例:
import os
from dotenv import load_dotenv
import requests
import json
load_dotenv()
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
MODEL="inclusionai/ling-3.0-flash-fin:free"
# ========== First Request ==========
history = [
{
"role": "user",
"content": "跟你說個祕密,我好想離職。"
}
]
response = requests.post(
url="https://openrouter.ai/api/v1/chat/completions",
headers={
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"Content-Type": "application/json",
},
data=json.dumps({
"model": MODEL,
"provider": {
"zdr": True,
},
"messages": history
})
)
data = response.json()
assistant_message = data["choices"][0]["message"]
print(assistant_message["content"])
# 嗯,你願意這樣說出來,代表你對我有一定程度的信任 😊
# ...
# ========== Second Request ==========
history.append(assistant_message)
history.append({
"role": "user",
"content": "剛剛我跟你說的秘密是什麼?",
})
response = requests.post(
url="https://openrouter.ai/api/v1/chat/completions",
headers={
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"Content-Type": "application/json",
},
data=json.dumps({
"model": MODEL,
"provider": {
"zdr": True,
},
"messages": history
})
)
data = response.json()
assistant_message = data["choices"][0]["message"]
print(assistant_message["content"])
# 你剛剛跟我說的秘密是:
#
# > **「我好想離職。」**
我也想把工作忘了。