跳到內容

多模態輸入

多模態輸入讓模型不僅能處理文字,還能理解圖像、音訊等其他形式的內容。RouteAPI 支援在 /v1/chat/completions(OpenAI 格式)和 /v1/messages(Claude 格式)上傳遞多模態內容,並會自動完成不同上游協定之間的格式轉換。

模態類型說明
圖像(Vision)PNG、JPEG、WebP、GIF 等格式,用於圖像理解、OCR、圖表分析
音訊(Audio)部分模型支援音訊輸入,用於語音理解、轉錄等場景
視訊(Video)部分模型支援視訊幀輸入,將視訊拆分為關鍵幀序列

目前圖像輸入支援最為廣泛,幾乎所有主流視覺模型都支援。音訊和視訊輸入取決於具體模型能力。

以下模型支援圖像輸入(非完整列表):

模型系列典型模型 ID
OpenAI GPT-4 Visiongpt-4o, gpt-4-turbo, gpt-5.5
Claude Visionclaude-sonnet-4-5, claude-opus-4-5
Gemini Visiongemini-2.0-flash, gemini-2.5-pro
Azure OpenAIazure-gpt-4o

先用模型列表介面確認模型在你帳戶下可用:

Terminal window
curl https://api.routeapi.ai/v1/models \
-H "Authorization: Bearer $ROUTEAPI_KEY"

該介面不返回圖像輸入能力欄位。是否支援視覺輸入請以供應商文件或一次實際帶圖請求為準。

格式MIME Type說明
PNGimage/png無損格式,適合截圖、圖表
JPEGimage/jpeg有損壓縮,適合照片
WebPimage/webp現代格式,體積小品質高
GIFimage/gif非動圖格式(只取首幀)

不同模型對圖像大小的限制不同,通用建議:

限制項建議值說明
單張圖像大小< 20 MB超大圖像會增加處理時間和成本
圖像解析度長邊 ≤ 2048px高解析度會被自動縮放或分塊處理
Base64 編碼後< 32 MB總請求大小受上游服務限制

建議在上傳前壓縮圖像,在保證可讀性的前提下降低解析度,這樣既能減少傳輸時間,也能降低 token 成本。

圖像會被轉換為 token 計費。高解析度圖像消耗的 token 數遠高於文字:

  • 低解析度模式(如 OpenAI 的 detail: "low"):固定約 85 tokens/圖。
  • 高解析度模式(如 detail: "high"):根據圖像尺寸分塊,一張 2048×2048 的圖可能消耗 800-1500 tokens。

生產環境建議根據實際需求選擇解析度模式,不需要精細識別時優先用 low 模式。

圖像有兩種傳遞方式:URL 和 Base64 編碼。

傳遞一個公開可存取的圖像 URL,由上游模型服務抓取:

優點:

  • 請求體積小,不占用你的上傳頻寬。
  • 適合已有 CDN 託管的圖像。

缺點:

  • 圖像必須公開可存取,上游服務的 IP 必須能存取到。
  • 如果圖像載入失敗(網路問題、鑑權、過期連結),請求會報錯。

適用場景:已有公開圖床、CDN 託管的圖像,不需要臨時上傳。

把圖像讀取為二進位資料,用 Base64 編碼後直接嵌入請求:

優點:

  • 無需公開可存取的 URL,適合私有圖像。
  • 請求自包含,不依賴外部服務可用性。

缺點:

  • Base64 編碼會讓資料體積增大約 33%。
  • 請求體積大,上傳耗時長。

適用場景:使用者上傳的私有圖像、本機檔案、臨時截圖等無公開 URL 的場景。

對比項URL 方式Base64 方式
請求體積小(僅 URL 字串)大(Base64 編碼後約為原檔案 1.33 倍)
上傳速度快慢
圖像可存取性必須公開可存取無要求,私有圖像可用
外部依賴依賴圖像伺服器和上游抓取無外部依賴
適用場景公開圖床、CDN使用者上傳、本機檔案

在 /v1/chat/completions 中,圖像透過 content 陣列傳遞,每個元素是一個內容區塊,用 type 區分文字和圖像。

content 可以是字串(純文字),也可以是陣列(多模態):

{
"role": "user",
"content": [
{ "type": "text", "text": "這張圖片裡有什麼?" },
{
"type": "image_url",
"image_url": {
"url": "https://example.com/image.jpg"
}
}
]
}

image_url 內容區塊的欄位:

欄位類型必填說明
typestring是固定為 "image_url"
image_url.urlstring是圖像 URL 或 Base64 Data URI
image_url.detailstring否解析度模式: "low", "high", "auto"(預設)

detail 控制圖像處理的解析度和成本:

值行為Token 消耗
"low"低解析度模式,圖像縮小到固定尺寸(如 512×512)固定約 85 tokens
"high"高解析度模式,圖像分塊處理,保留細節按分塊數量,通常幾百到上千 tokens
"auto"模型自動選擇(預設)取決於模型策略

成本差異範例:

  • 一張簡單截圖用 "low" 可能只需 85 tokens(約 ¥0.0001)。
  • 同一張圖用 "high" 可能消耗 800 tokens(約 ¥0.001)。

對於不需要識別小字、細節的場景(如「這是什麼動物」「介面主題色是什麼」),用 "low" 即可滿足需求。需要 OCR、讀取圖表數值、識別小物體時才需要 "high"。

{
"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 需要使用 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。

在 /v1/messages 中,圖像透過 content 陣列的 image 類型區塊傳遞,結構與 OpenAI 格式有明顯差異。

{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "/9j/4AAQSkZJRgABAQEAYABgAAD..."
}
},
{ "type": "text", "text": "描述這張圖片" }
]
}

source 欄位指定圖像來源,有兩種方式:

欄位類型必填說明
typestring是固定為 "base64"
media_typestring是MIME 類型,如 image/jpeg, image/png
datastring是Base64 編碼的圖像資料(不帶 data: 前綴)

注意 Claude 格式的 Base64 不需要 Data URI 前綴,直接傳編碼字串。

{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
}
}
欄位類型必填說明
typestring是固定為 "url"
urlstring是公開可存取的圖像 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"
}
}
{
"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": "這是什麼昆蟲?" }
]
}
]
}

Gemini 原生格式使用 parts 陣列而非 content,結構差異較大。RouteAPI 會在內部完成轉換,你使用 OpenAI 或 Claude 格式呼叫 Gemini 模型時無需關心原生格式細節。以下僅作參考。

{
"contents": [
{
"role": "user",
"parts": [
{ "text": "描述這張圖片" },
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "/9j/4AAQSkZJRg..."
}
}
]
}
]
}
欄位說明
inlineData.mimeTypeMIME 類型
inlineData.dataBase64 編碼資料

Gemini 也支援透過檔案 URI 參照已上傳到 Google 服務的檔案:

{
"fileData": {
"mimeType": "image/jpeg",
"fileUri": "gs://bucket-name/path/to/image.jpg"
}
}

實際使用中,透過 RouteAPI 呼叫 Gemini 模型時,使用 OpenAI 或 Claude 格式即可,RouteAPI 會自動轉換。

所有主流視覺模型都支援在一次請求中傳遞多張圖像。

在 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" }
}
]
}

模型會按陣列順序理解圖像。如果文字中用「第一張圖」「第二張圖」指代,模型會按出現順序對應。建議把說明文字放在所有圖像之前或之後,不要穿插在中間,這樣語義更清晰:

{
"content": [
{ "type": "text", "text": "第一張是使用者介面截圖,第二張是設計稿,請對比兩者的差異並給出修改建議。" },
{ "type": "image_url", "image_url": { "url": "..." } },
{ "type": "image_url", "image_url": { "url": "..." } }
]
}

也可以讓文字和圖像交替出現,用於逐步說明:

{
"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": "請總結改進點。" }
]
}

實際效果取決於模型對內容區塊順序的理解能力,主流視覺模型通常都能正確處理。

部分模型支援音訊輸入,用於語音理解、轉錄、情感分析等場景。目前支援程度不如圖像廣泛。

取決於具體模型,常見格式包括:

  • WAV(audio/wav)
  • MP3(audio/mpeg)
  • OGG(audio/ogg)
  • FLAC(audio/flac)

與圖像類似,音訊也支援 URL 和 Base64 兩種方式。以 OpenAI 格式為例(假設模型支援):

{
"role": "user",
"content": [
{
"type": "input_audio",
"input_audio": {
"data": "<base64-encoded-audio>",
"format": "wav"
}
},
{ "type": "text", "text": "轉錄這段音訊並總結要點" }
]
}

實際欄位名稱和結構取決於模型協定,使用前請查閱所選模型的文件或透過模型列表介面確認 supports_audio_input 欄位。

以下範例展示圖像理解的端到端實作,包括 curl、Python、Node.js 三種語言。

給定一張圖片,讓模型描述其內容。

curl(OpenAI 格式,URL 方式):

Terminal window
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 base64
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ROUTEAPI_KEY"],
base_url="https://api.routeapi.ai/v1",
)
# 讀取本機圖像並編碼為 Base64
with 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);

上傳圖表截圖,讓模型讀取資料並分析:

Python(Claude 格式,Base64):

import base64
import os
from 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)

從截圖或照片中提取文字內容:

curl(OpenAI 格式,高解析度):

Terminal window
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" 以保證識別精度,尤其是小字或密集文字。

對比兩張或多張圖片的差異:

Python(OpenAI 格式,多圖):

from openai import OpenAI
import 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)

在多輪對話中混合圖像和文字:

from openai import OpenAI
import 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)

圖像只需在首輪傳遞一次,後續輪次模型會記住圖像內容(在上下文視窗內),無需重複上傳。

在上傳圖像前做必要的最佳化,既能降低成本也能提升回應速度:

最佳化項建議
尺寸長邊控制在 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

具體費率取決於所選模型,以上僅為範例。生產環境建議:

  1. 預設用 detail: "auto" 或 "low",讓模型或使用者需求決定解析度。
  2. 只在明確需要精細識別(OCR、圖表資料、小物體檢測)時用 "high"。
  3. 記錄每次請求的 token 用量(回應的 usage 欄位),識別成本異常。

多模態輸入引入了額外的失敗點,需要針對性處理:

{
"error": {
"message": "Unsupported image format",
"type": "invalid_request_error"
}
}

解決:確認 MIME 類型正確,或轉換為 PNG/JPEG。

{
"error": {
"message": "Image size exceeds limit",
"type": "invalid_request_error"
}
}

解決:壓縮圖像或降低解析度後重試。

{
"error": {
"message": "Failed to fetch image from URL",
"type": "invalid_request_error"
}
}

解決:

  • 確認 URL 公開可存取,不需要鑑權。
  • 測試上游服務的 IP 能否存取該 URL(防火牆、地域限制)。
  • 改用 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 用量,便於排查成本和品質問題。詳見錯誤與偵錯。