把關你的荷包:節省 AI API 費用的 7 個實用方法

提示詞少寫幾個字,AI API 帳單卻沒少多少?AI API 要省錢,可以先從資料前處理、去重複、限定答案選項與小量測試著手,再搭配提示詞快取、Batch API、Flex 等省錢機制,並控制推理模型的使用成本。有時調整模型與處理方式,會比單純精簡提示詞省下更多費用。

Photo by Artsy Crafty on StockSnap


1. 資料探索

根據專案目的與分析需求,先了解資料的內容與樣態:是純文字、圖片、PDF,還是簡報檔案。

(1) 文字類型

隨著模型的上下文視窗(context window)越來越長,大部分文章已經不需要像以前那樣,先分割成小段再逐一送進 API。

但是以 OpenAI 為例,gpt-6-astra、gpt-6.1-sol、gpt-6-luna 等模型的價格分為「短脈絡」 (short context) 與「長脈絡」 (long context) 兩種收費方式:單一次請求的輸入超過 272K token 時,就會改用「長脈絡」 的價格計費,輸入單價是「短脈絡」兩倍,輸出也會變貴[^1]。以繁體中文粗估,272K token 大約是二、三十萬字,相當於一到兩本書的篇幅,一般文章不容易達到這個門檻。

(2) PDF 或簡報類型

PDF 或簡報有兩種處理方式:一是先用「光學字元辨識」(Optical Character Recognition, 縮寫OCR) 轉成文字,例如微軟知名的 MarkItDown 專案 的 OCR 外掛,二是直接交給支援多模態的模型分析檔案。兩種做法的費用與準確度都不同。

OCR 轉成純文字比較便宜。但真實世界的簡報往往比想像中複雜,有些簡報內容以圖表、圖片為主,OCR 只能抓到文字,圖表中的資訊就會遺漏,而無法取得理想的分析結果。建議先用少量檔案測試模型的支援程度,確認分析品質與實際費用。

2. 資料前處理與去重複

(1) 移除不需要的內容

視專案需要,事先從文章中移除不影響分析的內容,例如 markdown 常見的分隔線(---)、emoji、網址、重複的頁首頁尾等。

(2) 資料去重複

計算每個檔案的雜湊值 (hash),可以快速比對文字、圖片等不同類型的檔案,避免把重複的資料送進 API 分析。文字資料存在資料庫的話,可以參考 Get-FileHash (Microsoft.PowerShell.Utility) - PowerShell 使用 SHA256 演算法、MySQL 如何尋找重複的文章 (文字類型資料) 等文章

(3) 保存結果,重複利用

如果任務結果不太會變動,可以把結果存下來。下次呼叫 AI API 之前,先檢查是否已經處理過。

視專案需要,可以再額外設計快取過期機制,例如 7 天或 30 天後才重新分析。

3. 提示詞快取(Prompt caching)

以 OpenAI 為例,支援的模型會自動啟用提示詞快取。條件是:每次請求開頭那段固定不變的文字(前綴)至少要有 1,024 個 token[^2],而且必須完全相同,連空白和換行都要一致。命中快取的部分,就能用較低的價格計費。

Anthropic Claude 與 Google Gemini 也有類似功能,但啟用方式和最低長度門檻不同,請參考各自的官方文件 Claude Prompt caching、Google Gemini 脈絡快取。

以 OpenAI 較新的模型為例,第一次寫入快取的費用是一般輸入價的 1.25 倍,之後讀取只要 0.1 倍[^3]。所以快取適合「同一段指示要重複使用很多次」的批次任務。

撰寫原則:固定內容放前面,會變動的資料放後面。指示、規則、範例、專有名詞對照表這些不變的文字,放在提示詞最前面;每次都不同的文章內容,放在最後面。

例子一:翻譯文章

以前常見的提示詞寫法,把文章夾在中間:

請用台灣常用的繁體中文翻譯這篇英文文章:

[貼上英文文章內容]

翻譯規則

1. xxx

2. xxx

3. xxx


這樣寫的話,每次請求從第二行就開始不同,後面的翻譯規則無法被快取。建議改成把固定內容全部往前移:

請用台灣常用的繁體中文翻譯這篇英文文章。


翻譯規則

1. xxx

2. xxx

3. xxx


專有名詞對照表

- English term A → 中文譯名 A

- English term B → 中文譯名 B

...


英文文章:

貼上英文文章內容


要注意的是,如果固定段落只有幾行規則,長度大概只有幾十個 token,達不到 1,024 token 的門檻[^2],就不會觸發提示快取。翻譯任務常需要統一專有名詞、台灣常用用語,把專有名詞對照表或幾段翻譯範例放進固定段落,可以提升翻譯品質,又能讓長度超過門檻。

例子二:修飾訪談逐字稿

下面是反面例子:把經常變動的內容放在提示詞的前段:

您的任務是改善中文口語訪談的逐字稿段落。您需要添加標點符號、確保段落連貫、保持原意,並視需要重寫部分文字。請使用台灣常用的繁體中文。


這是前文段落(提供上下文):

<previous_paragraph>

{PREVIOUS_PARAGRAPH}

</previous_paragraph>


這是後文段落(提供上下文):

<next_paragraph>

{NEXT_PARAGRAPH}

</next_paragraph>


請依照以下指引修改內容:

1. 適當添加標點符號

2. 確保修改後的段落與前後文連貫順暢

3. 維持原始語意與用意

4. 必要時重寫部分內容以提升可讀性

5. 使用台灣常用繁體中文字

6. 修正明顯的語法錯誤或口語不順之處

7. 無需額外說明


請以下列JSON格式輸出結果:


```json

{"text": "您修改後的段落內容"}

```

修改方式一樣是把固定內容擺在前面,並拆成兩部分。

第一部分:固定指示(放在 developer 或 system message,內容一字不改)


您的任務是改善中文口語訪談的逐字稿段落。您需要添加標點符號、確保段落連貫、保持原意,並視需要重寫部分文字。請使用台灣常用的繁體中文。


每次請求會提供三個段落:

- <previous_paragraph>:前文段落,僅供理解上下文,不需修改

- <current_paragraph>:需要修改的段落

- <next_paragraph>:後文段落,僅供理解上下文,不需修改

若前文或後文為空,代表該段落位於訪談開頭或結尾。


請依照以下指引修改 <current_paragraph> 的內容:

1. 適當添加標點符號

2. 確保修改後的段落與前後文連貫順暢

3. 維持原始語意與用意

4. 必要時重寫部分內容以提升可讀性

5. 使用台灣常用繁體中文字

6. 修正明顯的語法錯誤或口語不順之處,刪除無意義的贅詞(例如:呃、齁、就是、然後)

7. 只輸出 <current_paragraph> 修改後的內容,不要包含前文或後文的文字

8. 無需額外說明


請以下列 JSON 格式輸出結果:

{"text": "您修改後的段落內容"}


<examples>

提供範例 ...

</examples>


第二部分:變數(放在 user message,由程式替換成實際資料)

<previous_paragraph>

{PREVIOUS_PARAGRAPH}

</previous_paragraph>


<current_paragraph>

{CURRENT_PARAGRAPH}

</current_paragraph>


<next_paragraph>

{NEXT_PARAGRAPH}

</next_paragraph>

範例除了示範修改的程度,還有另一個目的:讓固定段落的長度超過 1,024 token 的快取門檻[^2]。如果長度還是不夠,可以再補幾個範例,或加入受訪者姓名、公司名稱、產品名稱等專有名詞的正確寫法,順便減少錯字。

怎麼確認有沒有命中快取?

呼叫 AI API 後,查看回傳結果中 usage 的 cached_tokens。從第二次請求開始,數值應該大於 0。

固定段落裡不要放日期、檔名、訪談編號這類每次都會變的內容,否則快取會失效。


4. 提示詞設計:精簡輸出與合併請求

模型價格表上,output token 比 input token 貴上好幾倍[^4],所以要視需要縮短模型的回答。

(1) 明確而有限的答案選項

開放式問題通常會得到比較長的答案,成本也比較高。如果想要簡潔又划算的回答,就提供明確且有限的選項,讓 AI 從中選擇。例如:

請判斷這篇文章屬於哪個分類:A、B、C。

只回傳 JSON:{"category": "A"}

如果文章不屬於任何分類,只回傳:{"status": "error"}

不需要額外解釋。

(2) 不符合條件時,不要讓模型解釋

遇到不符合分析需求的資料時,模型常常會寫一大段話說明為什麼無法分析,白白浪費 output token。所以要明確規定,只回傳最短的錯誤結果:

{"status": "error"}

真的需要知道原因時,才要求附上簡短說明:

{"status": "error", "message": "簡短說明"}

(3) 用 Structured Outputs 強制格式

只在提示詞裡用文字要求格式,模型偶爾還是會多寫幾句話。OpenAI 的 Structured Outputs 可以用 JSON Schema 規定輸出格式,例如用 enum 限定分類只能是 A、B、C 或 error,比文字要求更可靠。Google Gemini API 也可以定義 JSON Schema,詳見結構化輸出內容。

要注意的是,schema 也會成為提示詞前綴的一部分。只要 schema 固定不變,就不會影響快取。將 AI API 的回答結構化,也可以省下後續資料清理的功夫。請參自訂 ChatGPT 回答問題的方式,快速結構化。

(4) 合併多次請求

如果每筆資料都很短,例如文章標題或使用者留言,可以把多筆資料合併成一次請求,減少送出AI API 請求數量:

每一行代表文章的編號和內容。請為每篇文章選擇以下關鍵字:keyword1、keyword2、keyword3。

以 CSV 格式回答:"文章編號","逗號分隔的關鍵字"


No1. 第一篇文章的短文內容

No2. 第二篇文章的短文內容

...

合併的筆數不要太多,否則容易漏答或錯位,建議先測試。

5. 選擇適合的模型與推理強度

(1) 不要一開始就用最強的模型

同一家廠商的不同模型,價差可以到上百倍[^5]。我習慣先用稍微舊的模型和主流模型測試,品質不夠時再往上升級。不要一開始就用最強的模型,因為最強的模型也意味著最貴的 API 帳單。選擇時請以價目表為準。

(2) 選擇適合的推理強度

推理模型在回答前會先「思考」,這些推理過程產生的 token 會按「輸出價」計費。如果是分類、萃取關鍵字、格式轉換這類簡單任務,可以選擇不推理的模型,或把推理強度(reasoning effort)調低,就能省下 output token 的費用。

6. 不急的任務:使用 Batch API 或 Flex

如果任務不需要即時回應,例如客戶要一次分析上千篇文章,但可以三天後才交付成果,就可以使用 Batch API 或 Flex:

(1) Batch API:把所有請求整理成一個檔案上傳,非同步處理,完成後再下載結果,價格是標準價的一半[^6]。

(2) Flex processing:寫法和一般 API 呼叫一樣,只要把 service_tier 設為 flex,價格與 Batch API 相同,還能搭配提示詞快取的折扣。代價是回應比較慢,資源不足時可能回傳 429 錯誤[^7],程式要加上重試機制。Flex 目前支援的模型有限。

Batch API 文件雖然寫明會在 24 小時內完成[^8],但批次完成不代表每一筆請求都成功,部分請求可能失敗,需要重新送出到 Batch API,或者改用一般 API 處理。因此仍需預留處理例外的時間。

7. 大量處理前,先小量測試並監控費用

先拿大約十篇資料測試,確認結果符合預期之後,再進行大量呼叫。測試時順便記錄 API 回傳的 usage 與提示快取的命中率,用單篇的 token 數推估全部資料的總費用,避免月底被帳單嚇到。

結論

2023 年寫這篇文章 每個月打開 OpenAI API 帳單,會懷疑它是否多了一個零 提到的觀念:去重複、資料前處理、限定答案選項、批次處理、先小量測試,到現在大多仍然成立。但這幾年 AI API 新增了幾個官方的省錢機制:提示詞快取、Batch API、Flex、推理模型的成本控制,省下的金額會比調整提示詞還多。

參考資料

  • [^1]: OpenAI,Pricing。短 context 指輸入 ≤ 272K token,長 context 指輸入 > 272K token。以 gpt-6.1-sol 標準方案為例,每百萬 token:短 context 輸入 $2.00、輸出 $10.00;長 context 輸入 $4.00、輸出 $15.00。
  • [^2]: OpenAI,Prompt caching。GPT-5.6 及之後的模型,最低可快取長度為 1,024 個可見輸入 token;較早的模型則依請求設定(工具、圖片、輸出 schema、推理強度等)而不同。
  • [^3]: 同註 2。此計費方式適用於 GPT-5.6 及之後的模型:寫入快取為一般輸入價的 1.25 倍;讀取為 0.1 倍,gpt-6.1-sol 為 0.05 倍。GPT-5.5 及較早的模型沒有額外的快取寫入費用。快取內容在最後一次寫入或讀取後,至少保留 30 分鐘。
  • [^4]: 同註 1。以 gpt-6.1-sol 標準方案(短 context)為例,每百萬 token 輸入 $2.00、輸出 $10.00,輸出是輸入的 5 倍。
  • [^5]: 同註 1。標準方案(短 context)每百萬 token:gpt-6-astra 輸入 $10.00、輸出 $50.00;gpt-6-luna 輸入 $0.10、輸出 $0.50,相差 100 倍。
  • [^6]: OpenAI,Batch API。Batch API 比同步 API 便宜 50%,並有獨立且較高的速率限制。以 gpt-6.1-sol 為例,Batch 價格為每百萬 token 輸入 $1.00、輸出 $5.00(見註 1 價目表)。
  • [^7]: OpenAI,Flex processing。Flex 的 token 以 Batch API 價格計費,並可再疊加提示詞快取折扣;資源不足時會回傳 429 Resource Unavailable。官方 SDK 的預設逾時為 10 分鐘。
  • [^8]: 同註 6。目前完成期限只能設定為 24 小時。超過期限未完成的批次會變成 expired 狀態,未處理的請求會被取消,但已完成的請求仍會計費。失敗與過期的請求會寫入錯誤檔(error_file_id),可以用 custom_id 找出來重新送出。

留言