多模態輸入
多模態輸入讓模型不僅能處理文字,還能理解圖像、音訊等其他形式的內容。RouteAPI 支援在 /v1/chat/completions(OpenAI 格式)和 /v1/messages(Claude 格式)上傳遞多模態內容,並會自動完成不同上游協定之間的格式轉換。
1. 多模態概述
Section titled “1. 多模態概述”支援的模態類型
Section titled “支援的模態類型”| 模態類型 | 說明 |
|---|---|
| 圖像(Vision) | PNG、JPEG、WebP、GIF 等格式,用於圖像理解、OCR、圖表分析 |
| 音訊(Audio) | 部分模型支援音訊輸入,用於語音理解、轉錄等場景 |
| 視訊(Video) | 部分模型支援視訊幀輸入,將視訊拆分為關鍵幀序列 |
目前圖像輸入支援最為廣泛,幾乎所有主流視覺模型都支援。音訊和視訊輸入取決於具體模型能力。
支援的視覺模型
Section titled “支援的視覺模型”以下模型支援圖像輸入(非完整列表):
| 模型系列 | 典型模型 ID |
|---|---|
| OpenAI GPT-4 Vision | gpt-4o, gpt-4-turbo, gpt-5.5 |
| Claude Vision | claude-sonnet-4-5, claude-opus-4-5 |
| Gemini Vision | gemini-2.0-flash, gemini-2.5-pro |
| Azure OpenAI | azure-gpt-4o |
先用模型列表介面確認模型在你帳戶下可用:
curl https://api.routeapi.ai/v1/models \ -H "Authorization: Bearer $ROUTEAPI_KEY"該介面不返回圖像輸入能力欄位。是否支援視覺輸入請以供應商文件或一次實際帶圖請求為準。
2. 圖像輸入基礎
Section titled “2. 圖像輸入基礎”支援的圖像格式
Section titled “支援的圖像格式”| 格式 | MIME Type | 說明 |
|---|---|---|
| PNG | image/png | 無損格式,適合截圖、圖表 |
| JPEG | image/jpeg | 有損壓縮,適合照片 |
| WebP | image/webp | 現代格式,體積小品質高 |
| GIF | image/gif | 非動圖格式(只取首幀) |
圖像大小限制
Section titled “圖像大小限制”不同模型對圖像大小的限制不同,通用建議:
| 限制項 | 建議值 | 說明 |
|---|---|---|
| 單張圖像大小 | < 20 MB | 超大圖像會增加處理時間和成本 |
| 圖像解析度 | 長邊 ≤ 2048px | 高解析度會被自動縮放或分塊處理 |
| Base64 編碼後 | < 32 MB | 總請求大小受上游服務限制 |
建議在上傳前壓縮圖像,在保證可讀性的前提下降低解析度,這樣既能減少傳輸時間,也能降低 token 成本。
解析度和成本考量
Section titled “解析度和成本考量”圖像會被轉換為 token 計費。高解析度圖像消耗的 token 數遠高於文字:
- 低解析度模式(如 OpenAI 的
detail: "low"):固定約 85 tokens/圖。 - 高解析度模式(如
detail: "high"):根據圖像尺寸分塊,一張 2048×2048 的圖可能消耗 800-1500 tokens。
生產環境建議根據實際需求選擇解析度模式,不需要精細識別時優先用 low 模式。
3. 圖像傳遞方式
Section titled “3. 圖像傳遞方式”圖像有兩種傳遞方式:URL 和 Base64 編碼。
URL 方式
Section titled “URL 方式”傳遞一個公開可存取的圖像 URL,由上游模型服務抓取:
優點:
- 請求體積小,不占用你的上傳頻寬。
- 適合已有 CDN 託管的圖像。
缺點:
- 圖像必須公開可存取,上游服務的 IP 必須能存取到。
- 如果圖像載入失敗(網路問題、鑑權、過期連結),請求會報錯。
適用場景:已有公開圖床、CDN 託管的圖像,不需要臨時上傳。
Base64 編碼方式
Section titled “Base64 編碼方式”把圖像讀取為二進位資料,用 Base64 編碼後直接嵌入請求:
優點:
- 無需公開可存取的 URL,適合私有圖像。
- 請求自包含,不依賴外部服務可用性。
缺點:
- Base64 編碼會讓資料體積增大約 33%。
- 請求體積大,上傳耗時長。
適用場景:使用者上傳的私有圖像、本機檔案、臨時截圖等無公開 URL 的場景。
兩種方式對比
Section titled “兩種方式對比”| 對比項 | URL 方式 | Base64 方式 |
|---|---|---|
| 請求體積 | 小(僅 URL 字串) | 大(Base64 編碼後約為原檔案 1.33 倍) |
| 上傳速度 | 快 | 慢 |
| 圖像可存取性 | 必須公開可存取 | 無要求,私有圖像可用 |
| 外部依賴 | 依賴圖像伺服器和上游抓取 | 無外部依賴 |
| 適用場景 | 公開圖床、CDN | 使用者上傳、本機檔案 |
4. OpenAI 格式圖像輸入
Section titled “4. OpenAI 格式圖像輸入”在 /v1/chat/completions 中,圖像透過 content 陣列傳遞,每個元素是一個內容區塊,用 type 區分文字和圖像。
content 陣列結構
Section titled “content 陣列結構”content 可以是字串(純文字),也可以是陣列(多模態):
{ "role": "user", "content": [ { "type": "text", "text": "這張圖片裡有什麼?" }, { "type": "image_url", "image_url": { "url": "https://example.com/image.jpg" } } ]}image_url 結構
Section titled “image_url 結構”image_url 內容區塊的欄位:
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
type | string | 是 | 固定為 "image_url" |
image_url.url | string | 是 | 圖像 URL 或 Base64 Data URI |
image_url.detail | string | 否 | 解析度模式: "low", "high", "auto"(預設) |
detail 參數
Section titled “detail 參數”detail 控制圖像處理的解析度和成本:
| 值 | 行為 | Token 消耗 |
|---|---|---|
"low" | 低解析度模式,圖像縮小到固定尺寸(如 512×512) | 固定約 85 tokens |
"high" | 高解析度模式,圖像分塊處理,保留細節 | 按分塊數量,通常幾百到上千 tokens |
"auto" | 模型自動選擇(預設) | 取決於模型策略 |
成本差異範例:
- 一張簡單截圖用
"low"可能只需 85 tokens(約 ¥0.0001)。 - 同一張圖用
"high"可能消耗 800 tokens(約 ¥0.001)。
對於不需要識別小字、細節的場景(如「這是什麼動物」「介面主題色是什麼」),用 "low" 即可滿足需求。需要 OCR、讀取圖表數值、識別小物體時才需要 "high"。
URL 方式完整範例
Section titled “URL 方式完整範例”{ "model": "gpt-4o", "messages": [ { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/320px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg", "detail": "high" } }, { "type": "text", "text": "描述這張圖片的內容" } ] } ]}Base64 方式完整範例
Section titled “Base64 方式完整範例”Base64 需要使用 Data URI 格式:data:<mime_type>;base64,<encoded_data>。
{ "model": "gpt-4o", "messages": [ { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..." } }, { "type": "text", "text": "這張圖片裡有哪些文字?" } ] } ]}注意 Base64 字串可能非常長,上面範例做了截斷。實際使用時完整編碼可能有幾百 KB 到幾 MB。
5. Claude 格式圖像輸入
Section titled “5. Claude 格式圖像輸入”在 /v1/messages 中,圖像透過 content 陣列的 image 類型區塊傳遞,結構與 OpenAI 格式有明顯差異。
content 陣列結構
Section titled “content 陣列結構”{ "role": "user", "content": [ { "type": "image", "source": { "type": "base64", "media_type": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQEAYABgAAD..." } }, { "type": "text", "text": "描述這張圖片" } ]}source 結構
Section titled “source 結構”source 欄位指定圖像來源,有兩種方式:
Base64 方式
Section titled “Base64 方式”| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
type | string | 是 | 固定為 "base64" |
media_type | string | 是 | MIME 類型,如 image/jpeg, image/png |
data | string | 是 | Base64 編碼的圖像資料(不帶 data: 前綴) |
注意 Claude 格式的 Base64 不需要 Data URI 前綴,直接傳編碼字串。
{ "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" }}URL 方式
Section titled “URL 方式”| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
type | string | 是 | 固定為 "url" |
url | string | 是 | 公開可存取的圖像 URL |
{ "type": "image", "source": { "type": "url", "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/320px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" }}完整請求範例
Section titled “完整請求範例”{ "model": "claude-sonnet-4-5", "max_tokens": 1024, "messages": [ { "role": "user", "content": [ { "type": "image", "source": { "type": "url", "url": "https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg" } }, { "type": "text", "text": "這是什麼昆蟲?" } ] } ]}6. Gemini 格式圖像輸入
Section titled “6. Gemini 格式圖像輸入”Gemini 原生格式使用 parts 陣列而非 content,結構差異較大。RouteAPI 會在內部完成轉換,你使用 OpenAI 或 Claude 格式呼叫 Gemini 模型時無需關心原生格式細節。以下僅作參考。
parts 陣列
Section titled “parts 陣列”{ "contents": [ { "role": "user", "parts": [ { "text": "描述這張圖片" }, { "inlineData": { "mimeType": "image/jpeg", "data": "/9j/4AAQSkZJRg..." } } ] } ]}inlineData(Base64)
Section titled “inlineData(Base64)”| 欄位 | 說明 |
|---|---|
inlineData.mimeType | MIME 類型 |
inlineData.data | Base64 編碼資料 |
fileData(URI)
Section titled “fileData(URI)”Gemini 也支援透過檔案 URI 參照已上傳到 Google 服務的檔案:
{ "fileData": { "mimeType": "image/jpeg", "fileUri": "gs://bucket-name/path/to/image.jpg" }}實際使用中,透過 RouteAPI 呼叫 Gemini 模型時,使用 OpenAI 或 Claude 格式即可,RouteAPI 會自動轉換。
7. 多圖像輸入
Section titled “7. 多圖像輸入”所有主流視覺模型都支援在一次請求中傳遞多張圖像。
單次請求多張圖像
Section titled “單次請求多張圖像”在 content / parts 陣列中放多個圖像區塊:
OpenAI 格式:
{ "role": "user", "content": [ { "type": "text", "text": "對比這兩張圖片的差異" }, { "type": "image_url", "image_url": { "url": "https://example.com/image1.jpg" } }, { "type": "image_url", "image_url": { "url": "https://example.com/image2.jpg" } } ]}Claude 格式:
{ "role": "user", "content": [ { "type": "text", "text": "這兩張圖片有什麼相同和不同之處?" }, { "type": "image", "source": { "type": "url", "url": "https://example.com/before.jpg" } }, { "type": "image", "source": { "type": "url", "url": "https://example.com/after.jpg" } } ]}圖像順序和參照
Section titled “圖像順序和參照”模型會按陣列順序理解圖像。如果文字中用「第一張圖」「第二張圖」指代,模型會按出現順序對應。建議把說明文字放在所有圖像之前或之後,不要穿插在中間,這樣語義更清晰:
{ "content": [ { "type": "text", "text": "第一張是使用者介面截圖,第二張是設計稿,請對比兩者的差異並給出修改建議。" }, { "type": "image_url", "image_url": { "url": "..." } }, { "type": "image_url", "image_url": { "url": "..." } } ]}與文字混合排列
Section titled “與文字混合排列”也可以讓文字和圖像交替出現,用於逐步說明:
{ "content": [ { "type": "text", "text": "這是原始介面:" }, { "type": "image_url", "image_url": { "url": "https://example.com/old.jpg" } }, { "type": "text", "text": "這是改進後的介面:" }, { "type": "image_url", "image_url": { "url": "https://example.com/new.jpg" } }, { "type": "text", "text": "請總結改進點。" } ]}實際效果取決於模型對內容區塊順序的理解能力,主流視覺模型通常都能正確處理。
8. 音訊輸入
Section titled “8. 音訊輸入”部分模型支援音訊輸入,用於語音理解、轉錄、情感分析等場景。目前支援程度不如圖像廣泛。
支援的音訊格式
Section titled “支援的音訊格式”取決於具體模型,常見格式包括:
- WAV(
audio/wav) - MP3(
audio/mpeg) - OGG(
audio/ogg) - FLAC(
audio/flac)
音訊傳遞方式
Section titled “音訊傳遞方式”與圖像類似,音訊也支援 URL 和 Base64 兩種方式。以 OpenAI 格式為例(假設模型支援):
{ "role": "user", "content": [ { "type": "input_audio", "input_audio": { "data": "<base64-encoded-audio>", "format": "wav" } }, { "type": "text", "text": "轉錄這段音訊並總結要點" } ]}實際欄位名稱和結構取決於模型協定,使用前請查閱所選模型的文件或透過模型列表介面確認 supports_audio_input 欄位。
9. 完整應用範例
Section titled “9. 完整應用範例”以下範例展示圖像理解的端到端實作,包括 curl、Python、Node.js 三種語言。
圖像理解和描述
Section titled “圖像理解和描述”給定一張圖片,讓模型描述其內容。
curl(OpenAI 格式,URL 方式):
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [ { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/320px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" } }, { "type": "text", "text": "詳細描述這張圖片的內容和氛圍" } ] } ] }'Python(OpenAI SDK,Base64 方式):
import base64import osfrom openai import OpenAI
client = OpenAI( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai/v1",)
# 讀取本機圖像並編碼為 Base64with open("image.jpg", "rb") as f: image_data = base64.b64encode(f.read()).decode("utf-8")
response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{image_data}" }, }, {"type": "text", "text": "這張圖片裡有什麼?"}, ], } ],)
print(response.choices[0].message.content)Node.js(openai 套件,URL 方式):
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.ROUTEAPI_KEY, baseURL: 'https://api.routeapi.ai/v1',});
const response = await client.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'user', content: [ { type: 'image_url', image_url: { url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/320px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg', }, }, { type: 'text', text: '用一句話概括這張圖片的主題' }, ], }, ],});
console.log(response.choices[0].message.content);圖表和資料視覺化分析
Section titled “圖表和資料視覺化分析”上傳圖表截圖,讓模型讀取資料並分析:
Python(Claude 格式,Base64):
import base64import osfrom anthropic import Anthropic
client = Anthropic( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai",)
with open("chart.png", "rb") as f: image_data = base64.b64encode(f.read()).decode("utf-8")
message = client.messages.create( model="claude-sonnet-4-5", max_tokens=1024, messages=[ { "role": "user", "content": [ { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": image_data, }, }, { "type": "text", "text": "這個圖表顯示了什麼趨勢?請提取關鍵資料點並給出分析。", }, ], } ],)
print(message.content[0].text)OCR 文字提取
Section titled “OCR 文字提取”從截圖或照片中提取文字內容:
curl(OpenAI 格式,高解析度):
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [ { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": "https://example.com/document.jpg", "detail": "high" } }, { "type": "text", "text": "提取圖片中的所有文字,保持原有的格式和結構" } ] } ] }'OCR 場景建議用 "detail": "high" 以保證識別精度,尤其是小字或密集文字。
多圖對比分析
Section titled “多圖對比分析”對比兩張或多張圖片的差異:
Python(OpenAI 格式,多圖):
from openai import OpenAIimport os
client = OpenAI( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai/v1",)
response = client.chat.completions.create( model="gpt-5.5", messages=[ { "role": "user", "content": [ { "type": "text", "text": "對比以下兩張圖片,找出它們之間的 5 個主要差異:", }, { "type": "image_url", "image_url": {"url": "https://example.com/before.jpg"}, }, { "type": "image_url", "image_url": {"url": "https://example.com/after.jpg"}, }, ], } ],)
print(response.choices[0].message.content)圖文混合對話
Section titled “圖文混合對話”在多輪對話中混合圖像和文字:
from openai import OpenAIimport os
client = OpenAI( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai/v1",)
messages = [ { "role": "user", "content": [ { "type": "image_url", "image_url": {"url": "https://example.com/product.jpg"}, }, {"type": "text", "text": "這個產品的主要特點是什麼?"}, ], }]
response = client.chat.completions.create(model="gpt-4o", messages=messages)messages.append(response.choices[0].message)print("第一輪:", response.choices[0].message.content)
# 繼續追問(純文字)messages.append({"role": "user", "content": "它適合什麼樣的使用者群體?"})response = client.chat.completions.create(model="gpt-4o", messages=messages)print("第二輪:", response.choices[0].message.content)圖像只需在首輪傳遞一次,後續輪次模型會記住圖像內容(在上下文視窗內),無需重複上傳。
10. 最佳實踐
Section titled “10. 最佳實踐”在上傳圖像前做必要的最佳化,既能降低成本也能提升回應速度:
| 最佳化項 | 建議 |
|---|---|
| 尺寸 | 長邊控制在 2048px 以內,除非確實需要識別更多細節 |
| 格式 | 截圖、圖表用 PNG,照片用 JPEG,追求極致壓縮可用 WebP |
| 壓縮 | JPEG 品質 80-90% 即可,視覺差異很小但體積減少明顯 |
| 裁剪 | 去掉無關區域(如大片空白、浮水印、邊框),只保留關鍵內容 |
不要為了省 token 而把圖像壓縮到無法識別,模型識別不出來反而浪費。
多模態輸入的成本主要由圖像產生:
| 場景 | 典型 Token 消耗 | 成本估算(GPT-4o) |
|---|---|---|
低解析度圖像(detail: "low") | ~85 tokens | ¥0.0001 |
高解析度小圖(500×500,detail: "high") | ~200 tokens | ¥0.0003 |
高解析度大圖(2000×2000,detail: "high") | ~800 tokens | ¥0.0012 |
多張高解析度圖(5 張,detail: "high") | ~4000 tokens | ¥0.006 |
具體費率取決於所選模型,以上僅為範例。生產環境建議:
- 預設用
detail: "auto"或"low",讓模型或使用者需求決定解析度。 - 只在明確需要精細識別(OCR、圖表資料、小物體檢測)時用
"high"。 - 記錄每次請求的 token 用量(回應的
usage欄位),識別成本異常。
多模態輸入引入了額外的失敗點,需要針對性處理:
圖像格式不支援
Section titled “圖像格式不支援”{ "error": { "message": "Unsupported image format", "type": "invalid_request_error" }}解決:確認 MIME 類型正確,或轉換為 PNG/JPEG。
{ "error": { "message": "Image size exceeds limit", "type": "invalid_request_error" }}解決:壓縮圖像或降低解析度後重試。
URL 無法存取
Section titled “URL 無法存取”{ "error": { "message": "Failed to fetch image from URL", "type": "invalid_request_error" }}解決:
- 確認 URL 公開可存取,不需要鑑權。
- 測試上游服務的 IP 能否存取該 URL(防火牆、地域限制)。
- 改用 Base64 方式,避免依賴外部服務。
Base64 解碼失敗
Section titled “Base64 解碼失敗”{ "error": { "message": "Invalid base64 encoding", "type": "invalid_request_error" }}解決:檢查 Base64 編碼是否完整、格式是否正確(OpenAI 格式需要 data: 前綴,Claude 格式不需要)。
| 風險 | 防護措施 |
|---|---|
| URL 圖像洩漏 | 確認 URL 指向的圖像不包含敏感資訊,或使用帶鑑權的臨時連結 |
| Base64 大小攻擊 | 限制使用者上傳圖像的大小上限(如 20 MB),防止超大請求 |
| 注入攻擊 | 不要把使用者上傳的圖像 URL 直接拼接進系統指令或 SQL |
| 模型幻覺 | 圖像理解結果可能不準確,高風險場景(醫療、法律、金融)需人工複核 |
- 視覺能力、支援的圖像格式、最大圖像數取決於所選模型,上線前請測試驗證。
detail參數只在 OpenAI 格式下有意義,Claude 格式無對應參數。- 不同模型對解析度的處理策略不同,相同圖像在不同模型上的 token 消耗可能差異較大。
- 串流回應中,圖像內容的處理結果通常會在串流的早期或晚期一次性返回,而非逐字串流輸出。
- 記錄每次請求的 request ID、模型 ID、狀態碼和 token 用量,便於排查成本和品質問題。詳見錯誤與偵錯。