從台灣打 AI API 慢在哪?連線只佔首字延遲的一成
從台北量三家 API 的八個模型,DNS 加 TCP 加 TLS 三家都落在 104 到 109 毫秒,只佔首字延遲的 7% 到 15%。慢的地方不是距離。這篇拆開首字延遲、吐字速度與尾巴延遲,並記下量測時翻掉的兩個假設。
目錄(12 節)
從台北的家用網路打 Anthropic、OpenAI 與 Google 的 API,DNS 加 TCP 加 TLS 合計是 104、109、104 毫秒。三家幾乎一樣。
這段是純粹的地理成本,跟你選哪個模型無關。而它只佔首字延遲的 7% 到 15%。
所以如果你覺得從台灣打 API 很慢,把機器搬到東京或美西並不會解決。剩下的 85% 到 93% 發生在對方的機房裡,是模型在想事情。
這篇是 146 次直連呼叫的結果,涵蓋 8 個模型、3 家廠商,時間落在 2026 年 8 月 16 日到 18 日的晚間與深夜。
連線層:三家都有亞洲節點,差距在誤差內
握手拆成三段量:DNS 查詢、TCP 三次握手、TLS 協商。用原生 socket 不用 SDK,因為 SDK 會重用連線,第二次呼叫之後握手就消失了,地理成本會被藏起來。
| 廠商 | DNS ms | TCP ms | TLS ms | 合計 p50 ms | p95 ms | n |
|---|---|---|---|---|---|---|
| Anthropic | 0.8 | 29.6 | 72.4 | 103.7 | 223.0 | 57 |
| OpenAI | 0.9 | 28.9 | 69.0 | 109.1 | 196.0 | 57 |
| 0.9 | 31.2 | 70.3 | 103.9 | 309.0 | 32 |
TCP 握手只有 29 到 31 毫秒。台北到東京的來回大約就是這個數字,到美西則要 120 毫秒以上。三家都在亞洲有節點,這件事沒有懸念。
TLS 那 70 毫秒看起來多,但它本來就要多跑一到兩趟來回。真正值得記的是三家的差距只有 5 毫秒,在你的體感裡不存在。
首字延遲:跟模型等級沒有關係
首字延遲是按下送出到螢幕出現第一個字。這是體感的來源,也是唯一要開 streaming 才量得到的數字。
| 廠商 | 層級 | 模型 | 首字 p50 ms | p95 ms | 連線佔比 | n |
|---|---|---|---|---|---|---|
| Anthropic | 輕量 | Claude Haiku 4.5 | 733 | 1,292 | 15% | 19 |
| Anthropic | 中階 | Claude Sonnet 5 | 1,350 | 2,555 | 7% | 19 |
| Anthropic | 旗艦 | Claude Opus 5 | 891 | 3,785 | 11% | 19 |
| OpenAI | 輕量 | GPT-5.6 Luna | 976 | 2,676 | 11% | 19 |
| OpenAI | 中階 | GPT-5.6 Terra | 787 | 1,360 | 13% | 19 |
| OpenAI | 旗艦 | GPT-5.6 Sol | 1,297 | 3,586 | 9% | 19 |
| 輕量 | Gemini 3.5 Flash-Lite | 737 | 898 | 15% | 20 | |
| 中階 | Gemini 3.6 Flash | 1,160 | 11,788 | 9% | 12 |
反直覺的地方在這裡:旗艦的 Opus 5 首字 891 毫秒,比中階的 Sonnet 5 的 1,350 還快。OpenAI 也一樣,中階的 Terra 787 毫秒贏過輕量的 Luna 的 976。
模型大小決定的是算完一個 token 要多久,不是排隊要多久。首字延遲裡混了排程、批次組裝與當下的負載,這些跟參數量沒有固定關係。
所以拿首字延遲當「這個模型比較小所以比較快」的證據會錯。 它量的是那一刻的服務狀況。
吐字速度才照等級排
第一個字出現之後的速度是另一回事。這裡的順序就乾淨得多。
報字元不報 token,因為 token 跨廠商不可比,這正是前一篇量 tokenizer 的結論。同一句話在不同家會被切成不同數量的 token,用 token/秒 比較等於用不同的尺量長度。
| 廠商 | 層級 | 模型 | 字元/秒 p50 | 最慢 5% | token/秒 p50 | n |
|---|---|---|---|---|---|---|
| Anthropic | 輕量 | Claude Haiku 4.5 | 412 | 232 | 311 | 19 |
| Anthropic | 中階 | Claude Sonnet 5 | 158 | 96 | 130 | 19 |
| Anthropic | 旗艦 | Claude Opus 5 | 93 | 73 | 68 | 19 |
| OpenAI | 輕量 | GPT-5.6 Luna | 334 | 235 | 249 | 19 |
| OpenAI | 中階 | GPT-5.6 Terra | 270 | 171 | 202 | 19 |
| OpenAI | 旗艦 | GPT-5.6 Sol | 176 | 70 | 131 | 19 |
| 輕量 | Gemini 3.5 Flash-Lite | 292 | 234 | 292 | 20 | |
| 中階 | Gemini 3.6 Flash | 265 | 25 | 265 | 12 |
Anthropic 三個層級是 412、158、93,一路往下。OpenAI 是 334、270、176。等級愈高吐得愈慢,這符合直覺。
Opus 5 每秒 93 個字元,是 Haiku 的四分之一。一段 500 字的回答,Haiku 一秒多吐完,Opus 要五秒半。
要估等待時間,用吐字速度乘上你預期的輸出長度,再加首字延遲。 只看首字會低估長回答的體感。
p50 好看,p95 才是你會抱怨的那一次
百分位用 nearest-rank 不做內插,所以印出來的每個數字都真的有某一次呼叫等過那麼久。
Opus 5 的首字 p50 是 891 毫秒,p95 是 3,785,差 4.2 倍。Sol 是 1,297 對 3,586。Gemini 3.6 Flash 更極端,p50 1,160 但 p95 11,788。
| 模型 | 首字 p50 ms | 首字 p95 ms | 倍數 |
|---|---|---|---|
| Gemini 3.5 Flash-Lite | 737 | 898 | 1.2 |
| Claude Haiku 4.5 | 733 | 1,292 | 1.8 |
| GPT-5.6 Terra | 787 | 1,360 | 1.7 |
| Claude Sonnet 5 | 1,350 | 2,555 | 1.9 |
| GPT-5.6 Sol | 1,297 | 3,586 | 2.8 |
| Claude Opus 5 | 891 | 3,785 | 4.2 |
| Gemini 3.6 Flash | 1,160 | 11,788 | 10.2 |
平均值在這種分布上沒有意義。延遲右偏,平均會落在一個沒人經歷過的位置。
如果你要做的是面向使用者的即時介面,該看的是 p95 那一欄。Flash-Lite 的 1.2 倍代表它很少爆走,Opus 5 的 4.2 倍代表二十次裡有一次要等快四秒。
三家連「不要想」都不是同一件事
要比延遲,前提是讓三家做同樣的事。這件事比想像中難,因為思考時間會整包算進首字延遲。
第一版腳本送 OpenAI 的 minimal 被退 400,程式默默改用預設思考強度,跑完一切正常。那批數字的首字含思考時間,跟另外兩家不可比。現在 fallback 會印警告。
靜默降級是錯誤數字上線的標準路徑。 量測腳本的每個 fallback 都要出聲。
三家的最低檔
- Anthropic:本次沒有送任何思考參數。4.5 世代預設不思考;5 世代改成 adaptive,由模型自己決定要不要想,而舊的
thinking.type: enabled在 4.7 之後直接回 400。這題它們選擇不想,輸出的 token 數可以確認。 - OpenAI:
reasoning_effort的可用值依模型而定,5.6 上可用的地板是none。 - Google:thinking_level 沒有 off 這個檔。3.5 Flash 的最低是
minimal,而 3.7 Flash 連minimal都不支援,只剩 low、medium、high。
所以本篇的三家是在「未送參數」「地板 none」「地板 minimal」三種狀態下被量的,不是同一條起跑線。這是這類跨家比較的天花板,不是本次的疏漏。
同一顆模型走 gateway 多等多久
gateway 不是第四家廠商,是同一顆模型的第二條路徑。所以做成配對:同一輪裡把直連與 gateway 兩通交錯送出,相隔數秒,共用當下的網路狀況。
全部分開跑完再跑另一批的話,量到的是時間差不是 gateway。
| 模型 | 直連首字 ms | gateway 首字 ms | 差 | 差 % | n 直/gw |
|---|---|---|---|---|---|
| Claude Haiku 4.5 | 733 | 1,078 | 345 | +47% | 19/6 |
| Claude Sonnet 5 | 1,350 | 2,228 | 878 | +65% | 19/6 |
| Claude Opus 5 | 891 | 1,440 | 550 | +62% | 19/6 |
| GPT-5.6 Luna | 976 | 1,001 | 25 | +3% | 19/6 |
| GPT-5.6 Terra | 787 | 1,083 | 295 | +37% | 19/6 |
| GPT-5.6 Sol | 1,297 | 2,122 | 824 | +64% | 19/6 |
| Gemini 3.5 Flash-Lite | 737 | 760 | 23 | +3% | 20/7 |
gateway 那側每個模型只有 6 到 7 次呼叫,這個樣本量還撐不起「多幾成」的定論。但有一件事樣本已經夠說:加價不是固定的。Luna 與 Flash-Lite 只多 3%,另外幾個多 37% 到 65%。
值得注意的是連線層在 gateway 這側反而更短,多數落在 77 到 99 毫秒之間。慢的不是那一跳,是後面那一段。
有一列被剔除了,原因比數字有用
Gemini 3.6 Flash 走 gateway 的首字是 3,065 毫秒,比直連的 1,160 多出 164%。這個數字不能用。
| 路徑 | 輸出字元 | 輸出 token | 首字 ms |
|---|---|---|---|
| 直連(thinking_level=minimal) | 110 | 110 | 1,160 |
| gateway(未帶思考參數) | 11 | 296 | 3,065 |
同一個 prompt,直連吐 110 個字元用掉 110 個 token。走 gateway 吐 11 個字元卻用掉 296 個 token。
原因是 gateway 講 OpenAI 的格式,而那個格式裡沒有 Gemini 的 thinking_level 欄位。一個關不掉思考的模型收不到指示,就用預設檔去想。296 個 token 撞到 300 的輸出上限,答案在數到第三個數字時就被截斷。
多出來的 1,905 毫秒是思考時間,不是路由成本。 把它寫成 gateway 慢會是一個錯誤的結論。
這條對你的實際意義比延遲數字大:走 gateway 時,你送的參數不保證原樣到達,而且沒有回報。這裡的代價是一次貴 2.7 倍而且被截斷的呼叫。
產表腳本現在會自動比對兩側的輸出長度,差超過兩成就把該列移出配對表並印出原因。
這次量不到的東西
- 時段:樣本只落在台北時間 21、23、0 這三個小時,沒有早上與下午。時段對照表在工具裡但沒有放進這篇,因為 4 個時段只覆蓋了 2 個。
- Google 旗艦:個人 key 是免費層,Pro 模型零配額,直連一律回 429。gateway 打得到,但那是取用差異,沒有直連對照就不能拿來比延遲。
- 中國廠商:DeepSeek、GLM、Qwen 這批還沒進量測名單,價格表上有它們但延遲沒有。
- 樣本量:直連每個模型 12 到 20 次,gateway 6 到 7 次。夠看出量級,不夠看出小差距。
另外 Gemini 3.6 Flash 直連出現過 3 次超過 90 秒的讀取逾時,同一輪的 gateway 那通正常。次數還太少,先記著不下結論。
方法
量的是三件互相獨立的事,混在一起講就會得到「某家比較快」這種沒有用的結論。
用原生 socket 不用 SDK。 SDK 會 pool 連線,第二次呼叫就沒有握手,地理成本會消失。
nonce 放在句首不放句尾。 prompt 遠低於各家的最小快取長度,本來就不會命中快取,但把隨機字串放在最前面讓這件事在結構上不可能發生,而不是靠推論。
報 p50 與 p95,不報平均。 延遲的分布右偏,平均落在沒人經歷過的位置。
測試 prompt 是請模型從 1 數到 40 用半形逗號分隔。輸出長度可預期、不需要推理、而且是純 ASCII,字元速率因此不會被各家怎麼切中文干擾。
今天可以做的一件事
打開你手上那支正式環境的服務,找出它呼叫模型那一段有沒有重用 HTTP 連線。
如果每次呼叫都重新握手,你在每一次請求上白付 104 毫秒。這是這篇量到的所有數字裡,唯一一個你自己改得掉的。