Response API的回應速度?
實驗場景
目標:確認在什麼樣的參數設定組合下可以用在即時客服對話的場景。
instructions
簡短的使用 You are a helpful assistant
。
input
一樣簡短的使用 Hello
。
以下每一種組合都跑 100次後取平均值。
model 使用 gpt-4.1
{
"model": "gpt-4.1",
"instructions": "You are a helpful assistant.",
"input": "Hello!",
"stream": false
}
實驗結果
Response Time: 776.11 ms
Response Time: 601.68 ms
Response Time: 729.11 ms
Response Time: 828.48 ms
Response Time: 788.19 ms
Response Time: 694.35 ms
Response Time: 512.29 ms
Response Time: 735.57 ms
Response Time: 2724.29 ms
Response Time: 788.22 ms
Average Response Time: 917.829 ms
model 使用 gpt-5 加上 reasoning=minimal
{
"model": "gpt-5",
"reasoning": {
"effort": "minimal",
"summary": "auto"
},
"text": {
"verbosity": "low"
},
"prompt_cache_key": "sean@deus.com.tw",
"instructions": "You are a helpful assistant.",
"input": "Hello!",
"stream": false
}
實驗結果:
Response Time: 785.53 ms
Response Time: 1036.23 ms
Response Time: 807.92 ms
Response Time: 953.96 ms
Response Time: 767.62 ms
Response Time: 931.57 ms
Response Time: 828.34 ms
Response Time: 936 ms
Response Time: 845.24 ms
Response Time: 1452.77 ms
Average Response Time: 934.518 ms
model 使用 gpt-5 加上 reasoning=low
{
"model": "gpt-5",
"reasoning": {
"effort": "low",
"summary": "auto"
},
"text": {
"verbosity": "low"
},
"prompt_cache_key": "sean@deus.com.tw",
"instructions": "You are a helpful assistant.",
"input": "Hello!",
"stream": false
}
實驗結果:
Response Time: 2411.65 ms
Response Time: 3013.74 ms
Response Time: 2503.46 ms
Response Time: 2710.34 ms
Response Time: 2365.91 ms
Response Time: 2385.66 ms
Response Time: 1994 ms
Response Time: 2806.7 ms
Response Time: 2486.08 ms
Response Time: 2692.6 ms
Average Response Time: 2537.014 ms
model 使用 gpt-5 加上 reasoning=medium
{
"model": "gpt-5",
"reasoning": {
"effort": "medium",
"summary": "auto"
},
"text": {
"verbosity": "low"
},
"prompt_cache_key": "sean@deus.com.tw",
"instructions": "You are a helpful assistant.",
"input": "Hello!",
"stream": false
}
實驗結果:
Response Time: 3284.84 ms
Response Time: 2612.2 ms
Response Time: 3135.54 ms
Response Time: 2899.31 ms
Response Time: 4515.12 ms
Response Time: 8193.02 ms
Response Time: 5961.67 ms
Response Time: 2736.92 ms
Response Time: 5467.37 ms
Response Time: 3801.95 ms
Average Response Time: 4260.794 ms
model 使用 gpt-5 加上 reasoning=high
{
"model": "gpt-5",
"reasoning": {
"effort": "high",
"summary": "auto"
},
"text": {
"verbosity": "low"
},
"prompt_cache_key": "sean@deus.com.tw",
"instructions": "You are a helpful assistant.",
"input": "Hello!",
"stream": false
}
實驗結果:
Response Time: 1524.27 ms
Response Time: 1514.5 ms
Response Time: 2060.71 ms
Response Time: 3853.27 ms
Response Time: 2523.61 ms
Response Time: 1826.42 ms
Response Time: 2757.69 ms
Response Time: 3476.06 ms
Response Time: 3497.13 ms
Response Time: 3181.17 ms
Average Response Time: 2621.483 ms
實驗小結論
- 單純就 API 回應速度來看,要讓 gpt-5 取得如同 gpt-4.1 模型的回應速度需要將
reasoning.effort
設定為minimal
。 - 基本上在
gpt-5
模型下reasoning.effort
的等級設置是影響 API 回應速度的關鍵之一。 - 注意:目前僅就 API 反應速度進行
eval
尚未對各個reasoning.effort
等級進行準確度之類的效能評估。
關於 previous_response_id
重點一句話:
previous_response_id
只是把對話狀態放在 OpenAI 基建端,不是「免計費的上下文」。模型每一輪實際讀到的內容,都會計入 token 使用量;差別在於其中一部分可能算作快取命中(cached_tokens
),費率較低。
會不會把整段歷史都算錢?
會.當你在新的 responses.create()
帶入 previous_response_id
時,伺服端會把該會話需要的上下文還原給模型.只要有被模型讀到,就會算 input tokens(其中重複的部分可能列為 cached_tokens
,費率折扣).如果歷史太長超過上下文上限,系統會修剪較舊的部分;沒有送進模型的內容自然不會計費。
到哪裡看實際用量?
回應物件內有 usage
欄位.常見重點如下︰
{
"id": "resp_68a1c758386c8199af418fd390a435e00d36ddfe068c7134",
"object": "response",
"created_at": 1755432792,
"status": "completed",
"background": false,
"error": null,
"incomplete_details": null,
"instructions": "You are a helpful assistant.",
"max_output_tokens": null,
"max_tool_calls": null,
"model": "gpt-4.1-2025-04-14",
"output": [
{
"id": "msg_68a1c75884448199995c89dbb53e37060d36ddfe068c7134",
"type": "message",
"status": "completed",
"content": [
{
"type": "output_text",
"annotations": [],
"logprobs": [],
"text": "Hello! How can I help you today? 😊"
}
],
"role": "assistant"
}
],
"parallel_tool_calls": true,
"previous_response_id": null,
"prompt_cache_key": null,
"reasoning": {
"effort": null,
"summary": null
},
"safety_identifier": null,
"service_tier": "default",
"store": true,
"temperature": 1.0,
"text": {
"format": {
"type": "text"
},
"verbosity": "medium"
},
"tool_choice": "auto",
"tools": [],
"top_logprobs": 0,
"top_p": 1.0,
"truncation": "disabled",
"usage": {
"input_tokens": 19,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 11,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 30
},
"user": null,
"metadata": {}
}
input_tokens
:本輪請求送進模型的輸入 token 總數(包含快取命中與未命中)。input_token_details.cached_tokens
:本輪被快取命中的輸入 token 數量(這些通常按「快取價」計費)。output_tokens
:模型本輪輸出 token。
控制成本的小撇步
- 定期重置+摘要:每隔幾輪,把對話濃縮成短摘要當作新的開場,舊訊息就不用一直跟著進上下文。
- 只帶必要事實:工具或檔案回傳的大量 JSON/原始資料,先在你這端壓縮成結論或表格。
- 善用快取:盡量固定不變的前置提示與規則文字,增加
cached_tokens
命中率。 - 限制輸出長度:設定
max_output_tokens
,避免輸出爆量。 - 避免把檔案內容「一路留著」:對檔案或檢索結果做「持續摘要」,別讓大量內容每輪都重複進上下文。
需要注意
- 「用了
previous_response_id
就不用算 token?」→ ✘.照算,只是可能有快取折扣。 - 「不用重傳歷史就比較省?」→ 成本與模型實際讀到的內容有關;省的是頻寬與程式碼管理,不等於省 token。
建議把每輪的
usage
萃取進你的遙測與計費流水,長期看得到哪一段上下文最吃錢,方便優化。
開發者要注意的幾件事
Session Registry
每輪呼叫存 response.id
、POST payload 與關鍵設定(如 store
),下一輪直接把「上一個 response.id
」放進 previous_response_id
即可串上下文。OpenAI 官方把這視為 Responses 的核心優勢之一,且預設會儲存 Session 狀態,可用 store: false
關閉。
Pinned Instructions
instructions
只在「本輪」生效,不會因為用了 previous_response_id
就自動沿用前幾輪的指令,所以你要在每一輪呼叫 Response API時都「重送」關鍵 prompt(或把 prompt 做成固定前綴)。
不一定要走 previous_response_id 的對話脈絡管理方式
對話脈絡管理不走 previous_response_id
也可以;若想完全自管,改為把歷史對話輪次手動整理後塞回 input
。
推薦的預設流程(每一輪)
- 取出上一輪
response.id
並將它設為新的previous_response_id
。 - 把「釘選指令」再次放到本輪
instructions
(因為不會自動延續)。 - 如果用戶設定
store: false
,就切到「手動附上下文」模式:把前一輪輸出的必要項(含工具結果、選段摘要)塞進input
。 - 送出
responses.create
,回寫response.id
與usage
指標。 - 定期做「滾動摘要」檢查點,縮短很久以前的訊息,保留關鍵事實,降低後續輪的輸入長度(命中快取也更穩)。
產品級功能清單(都圍繞 previous_response_id
)
- Session Linking UI:讓客戶在後台一鍵「接續會話」,你在後端自動帶上正確的
previous_response_id
;若找不到上一輪就自動回退到手動模式,避免 404 或鏈結斷裂。 - Policy Engine. 以租戶/應用為單位設定是否允許伺服端儲存、保存天數、以及模型切換策略(同一家對話盡量不跨大類模型).
- Pinned Instructions 管理. 提供「規則樣版」與版本控管,確保每輪都補上規則而不靠歷史沿用。
- Usage/快取儀表板. 顯示
input_tokens
、cached_tokens
、單輪成本、命中率趨勢與告警。 - 故障回退:若鏈接 ID 失效或跨模型導致不相容,就把上一輪「必要輸出項」直接塞回
input
再送一次;這是官方建議的另一條等價路徑。 - 工具鏈相容性:若你有用到「電腦操作/工具」或「推理項」,用
previous_response_id
最穩;若不用它,就要把前一輪的 reasoning/tool items手動帶回,不然會失敗。
實務注意
- 當你將 Context 的管理交由 OpenAI 的基建,也就是透過在 Response API 中帶入
previous_response_id
來讓 OpenAI 自動的幫你帶入先前所有輪次對話時,很大的程度上你是放棄了對 Context 的掌控主權(當然也就不用談什麼Context Engineering
了)。首先你無法(至少目前無法)明確的控制 OpenAI 要帶入多少先前的對話輪次,再來就是 OpenAI 也沒有詳細說明過去的對話脈絡他會以什麼樣的方式幫你帶入新一輪對話的 Context 中,意味著你無法透過更加精緻的自定義 prompt 去將歷史對話紀錄進行脈絡摘要與關鍵資訊提取、精煉,尤其是如果對話脈絡中有啟動到tool calls
或是MCP calls
,那你的對話中就會有大量的一坨又一坨的 JSON,如果這些資料沒有命中Prompt Cache
的話,這些資料都代表著 Token Fee 的消耗,當然如果 OpenAI 有幫你做更加細緻的處理的話那透過previous_response_id
來管理 Context 確實很方便,但我們目前無法一窺其實作方式,所以在便利與精確的掌控間,依舊是 trade-off 的拉扯。 - 跨模型切換要謹慎:某些情境下把先前「推理項」接到不同類型模型可能不相容;最穩做法是同會話盡量固定模型,或在回退路徑改為「手動附上下文」。
- 費用觀念:用了
previous_response_id
,模型仍會讀到需要的上下文而計入 token;但固定片段常會顯示在cached_tokens
,以快取價計費,差很多。