一句話說明
AI 應用的效能瓶頸通常在 LLM API 回應速度和 Token 成本,透過 Streaming、快取和模型選擇可以改善。
為什麼 AI 應用效能很重要
使用者對 AI 應用的等待容忍度大約是 3-5 秒。超過 10 秒沒有任何回應,大部分使用者會離開。但 LLM 的推論時間經常在 5-30 秒之間,取決於輸入長度和輸出長度。效能優化的目標是讓使用者在第一秒內看到回應開始產生。
Streaming Response
Streaming 是 AI 應用效能優化最重要的手段。傳統方式是等 LLM 產生完所有文字才一次回傳,Streaming 則是邊產生邊回傳。使用者在第一個 token 產生時(通常 0.5-2 秒)就能看到文字開始出現。
Server-Sent Events 實作
# FastAPI 範例
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import anthropic
app = FastAPI()
client = anthropic.Anthropic()
@app.post("/chat")
async def chat(request: ChatRequest):
async def generate():
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": request.prompt}]
) as stream:
for text in stream.text_stream:
yield f"data: {text}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
前端用 EventSource 或 fetch 搭配 ReadableStream 接收。飛飛建議用 fetch + ReadableStream,因為 EventSource 只支援 GET 請求,而 AI 應用通常需要用 POST 傳送 prompt。
Prompt Caching
Claude 和 GPT 都支援 Prompt Caching。如果你的 System Prompt 很長(包含大量背景知識或指令),Prompt Caching 可以顯著降低成本和延遲。
Claude 的 Prompt Caching
Claude 的 cache 機制是在 message 中標記可快取的區塊。第一次呼叫會正常計費,後續相同的 cache 區塊會以折扣價計算。
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": "你是一個客服助手,以下是產品知識庫:...(很長的文字)...",
"cache_control": {"type": "ephemeral"}
}
],
messages=[{"role": "user", "content": user_question}]
)
Cache 有效期是 5 分鐘(沒有新的請求就過期)。適合固定 System Prompt + 不同使用者問題的場景。
成本影響
以 Claude Sonnet 為例,快取讀取的成本大約是正常輸入 token 的 10%。如果你的 System Prompt 有 5000 個 token,每次呼叫省下的成本很可觀。一天 1000 次呼叫,一個月可以省下幾十到幾百美金。
語意快取
語意快取的概念是:如果兩個使用者問了意思相近的問題,第二個使用者可以直接拿到第一個使用者的回答,不需要再呼叫 LLM。
實作方式:
把每個問題用 Embedding 模型轉成向量。
查詢向量資料庫中是否有語意相似的問題(cosine similarity > 0.95)。
如果有,直接回傳快取的答案。如果沒有,呼叫 LLM 產生答案並存入快取。
import numpy as np
def get_cached_response(question, cache_db, threshold=0.95):
question_embedding = get_embedding(question)
results = cache_db.query(question_embedding, top_k=1)
if results and results[0].score > threshold:
return results[0].metadata["response"]
return None
語意快取的限制:
對時效性內容不適用(「今天天氣如何」每次都不同)。
相似度閾值設太低會回傳不相關的答案。
回傳快取答案前要考慮使用者的上下文是否相同。
Token 成本估算
各模型的 Token 定價
| 模型 | 輸入(每百萬 Token) | 輸出(每百萬 Token) |
|---|---|---|
| Claude Haiku 4.5 | $0.80 | $4.00 |
| Claude Sonnet 5 | $3.00 | $15.00 |
| Claude Opus 4 | $15.00 | $75.00 |
| GPT-4o | $2.50 | $10.00 |
| GPT-4o mini | $0.15 | $0.60 |
實際成本取決於你的使用模式。一個客服 Chatbot 每次對話平均 2000 token 輸入 + 500 token 輸出,用 Claude Haiku:
每次對話成本 = (2000 / 1M × $0.80) + (500 / 1M × $4.00)
= $0.0016 + $0.002
= $0.0036(約新台幣 0.12 元)
一天 500 次對話,一個月大約 $54 美金。
降低成本的方式
選擇合適的模型。不是所有任務都需要最大的模型。FAQ 回覆用 Haiku 就夠,複雜的技術分析再用 Sonnet 或 Opus。
縮短 System Prompt。把不必要的指令和背景資訊移除。很多 AI 應用的 System Prompt 有一半內容是冗餘的。
限制輸出長度。設定合理的 max_tokens。客服回覆不需要 4096 個 token。
用 Prompt Caching 減少重複的輸入 token 成本。
Batch API
如果你的 AI 任務不需要即時回應(例如每天凌晨處理昨天的客服對話摘要),可以用 Batch API。Batch API 的成本通常是即時 API 的一半,但回應時間可能需要數小時。
適合 Batch 處理的任務:大量文件摘要、歷史資料分析、定期報告生成、內容審核。
不適合 Batch 的任務:即時聊天、搜尋建議、表單驗證。
Rate Limiting 策略
AI 應用需要雙向的 Rate Limiting:
對使用者
防止單一使用者大量呼叫消耗 API 額度:
from slowapi import Limiter
limiter = Limiter(key_func=get_user_id)
@app.post("/chat")
@limiter.limit("20/hour")
async def chat(request: Request):
...
20 次/小時對一般使用者是合理的起點。企業用戶可以設更高的限制。
對上游 API
你的應用呼叫 LLM API 也有速率限制。Claude API 的速率限制依方案不同。超過限制會收到 429 錯誤。實作指數退避(exponential backoff):
import time
def call_with_retry(func, max_retries=3):
for i in range(max_retries):
try:
return func()
except RateLimitError:
wait = 2 ** i
time.sleep(wait)
raise Exception("API rate limit exceeded after retries")
安全考量
快取的回應內容可能包含敏感資訊。如果你的 AI 應用處理不同使用者的不同權限資料,語意快取可能會把 A 使用者的回應提供給 B 使用者。快取策略要考慮使用者身份隔離。
Token 使用量的監控不只是成本問題。異常的 Token 消耗可能代表有人在濫用你的 API(例如用你的端點做 proxy 繞過 AI 服務商的使用政策)。設定 Token 使用量的告警。
Streaming Response 的安全:中間人如果攔截 streaming 資料,可以即時看到 AI 的回應內容。確保 streaming 端點使用 HTTPS。
知識檢測
讀完文章後,測試一下你對這個主題的理解。
常見問題
Streaming 和一般 Response 的成本一樣嗎?
一樣。Token 計費是按輸入和輸出的 token 數量,不是按請求方式。Streaming 只是改變了傳輸方式,不影響計費。
語意快取的命中率大概多少?
取決於你的應用場景。FAQ 類的客服 Chatbot 命中率可以到 30-50%。開放式對話的命中率通常低於 5%。命中率太低的話,維護快取的成本可能超過省下的 API 費用。
如何監控 Token 使用量?
Claude API 的每個回應都包含 usage 欄位,記錄了 input_tokens 和 output_tokens。把這些數字記錄到資料庫或監控系統,設定每日和每月的用量告警。
有沒有免費的 AI API?
Google Gemini API 有免費方案(每分鐘 15 次請求)。Groq 提供限量免費的推論。Ollama 在本機跑模型不需要 API 費用,但需要自己的硬體資源。免費方案的資料使用政策通常比付費方案寬鬆,注意隱私問題。
Prompt Caching 和語意快取可以同時用嗎?
可以,兩者處理不同層級的問題。Prompt Caching 減少 System Prompt 的重複計算,語意快取減少重複問題的 API 呼叫。在 FAQ 類場景中同時使用效果最好。