iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0
Modern Web

前端工程師的AI應用開發實戰:30天從Prompt到Production - 以打造AI前端面試官為例系列 第 26

應用程式控管:真實世界的成本、安全與容錯機制初探

  • 分享至 

  • xImage
  •  

前言

歡迎來到 Day26~!國慶假期的第一天!我們昨天更新了我們的題庫已經在 Supabase 的知識庫,同時解釋了為什麼我們暫時不打算弄真正的題庫資料庫。經過前面幾天的努力,我們的 AI 前端面試官已經漸趨完整,具備了核心功能:使用者系統、RAG 檢索、Judge0 客觀評測、Streaming 回覆,以及練習紀錄的回顧功能。當然,若要作為一個要上線的產品我們還有非常多可以努力的方向,我們在未來的兩天會試著再加入一個核心的挑戰讓整個應用更實用,但在那之前我們要稍微談一些理論面的東西,也就是當一個 Side Project 真正要上線前我們需要考慮的事情,在過去的文章中其實我們或多或少都已經有稍微帶到這個議題了,比方說 Gemini & Judge0 的成本管理、 Supabse 的用量、整體服務的可靠性等,不過那些資訊有些零散,在最後一波衝刺前我想稍微再談談這些概念。

這其實是個非常大的主題,仰賴著大量的實務經驗,這部分的控管實際上我在之前的工作中也比較少接觸到,因此對我來說也是個有趣的探討,只是礙於篇幅跟我個人經驗的限制(這玩意硬要講的話都可以在寫一系列的鐵人賽了),今天也只能算是摸摸皮毛而已,不過我想作為入門會是個不錯的起點,我們馬上開始吧!

今日目標

  • 成本管理:理解 Gemini 和 Judge0 的計費模式,並學習如何透過 RAG 策略來控制費用。
  • 容錯與限制:探討 API 速率限制 (Rate Limiting) 的影響,並複習我們在程式碼中實作的容錯機制。
  • 安全策略:理解我們目前在資料的安全性上做了什麼限制保證資料庫的安全。

Step 1: 成本考量與 Token 經濟學

我們的應用程式主要有兩項外部服務會產生費用:Gemini API (按 Token 計費) 和 Judge0 (按請求計費),我們這個段落會說明大概的概念以及我們目前在專案中做了哪些相關的舉措。

1. Gemini API (Token-Based)

Gemini 的計費模型依賴於處理的 Token 數量,通常輸出 (Output) Token 比輸入 (Input) Token 貴,每個模型在收費時的標準也不盡相同,以Gemini為例,可以參考我們之前在第一週提出的計價頁面,雖然如果你是跟著我操作的免費仔的話,暫時你還不需要擔心這個問題,但若是產品真正要上線,理解這部分的成本管控就是必然的行為。
大致上來說我們在 Gemini 的使用分為三大部分,一般文本輸入、輸出以及向量化,我們在開發的過程中已經有做了基本的處理確保我們不會太浪費免費的額度,做最基礎的成本控制,如下表的整理:

費用來源 說明 成本控制策略
輸入 Token 我們的 Prompt、RAG Context、對話歷史。 極簡 Prompt:保持 Prompt 簡潔;精準 RAG:將相似度門檻 (match_threshold) 設定高一些,確保只傳送最相關的 keyPoints,避免不必要的上下文佔用 Token。
輸出 Token AI 的回饋 (JSON 評估結果、總結)。 強制 JSON Schema:確保 AI 輸出格式精確且不囉嗦。強制定義的 score、pros、cons 結構,就是在控制輸出的長度。
Embedding 每次執行 seed-vector.js 或 RAG 檢索時,用於生成向量。 使用專用模型:我們採用 gemini-embedding-001,它的設計就是為了 Embedding 任務,效率高且成本低。

實際成本試算(基於免費層)

成本的估算實際上相當複雜,我們通常也只能假設大致的情境並說明這樣大致上是否可以負擔,這也是許多系統面試會接觸到的環節,也是最仰賴經驗的地方,除了多加練習跟實務操作之外別無他法,但我們還是可以試試看!就以一個實際場景來估算:

場景:一位使用者完整練習一題 React 概念題

  1. RAG 檢索 (Embedding):~1,000 tokens × 2 次(題目 + 評估)
  2. 輸入 (含 Prompt + Context + 對話):~3,000 tokens
  3. 輸出 (AI 評估 JSON):~500 tokens
  4. 總計:約 4,500 tokens

Gemini 免費層限制:

  • 每分鐘:15 RPM (Requests Per Minute)
  • 每天:1,500 requests
  • 月度:無限制(但有總 token 上限)

以我們目前的實作:

  • 單次練習消耗:約 4,500 tokens
  • 100 次練習:約 450,000 tokens
  • Gemini 免費層:每月 150 萬 tokens(Flash 模型)
  • Gemini Embedding:免費仔沒有說明額外流量限制,不採計

換句話說,免費層足夠支撐約 300+ 次完整練習,對個人學習綽綽有餘。

但如果是 10 個使用者同時使用:

  • 每人 30 次練習 = 總共 300 次
  • 瞬間可能觸及 RPM 限制(15 requests/min)
  • 這時候就需要重試機制或 Queue 系統

補充說明:強制的用量限制設計

目前市面上的模型多半都有提供限額或是用量警告的功能,若是你真的有串接實際的 llm api,務必在你的專案頁面針對該專案做類似的設置,確保你不會因為過量的非預期服務調用讓你信用卡帳單跟台積電一樣不斷衝高。

2. Judge0 (Request-Based)

Judge0 服務按程式碼的執行次數計費。這部分很客觀,但成本可能比想像中高。

  • 成本控制策略:
    嚴格 Time Limit:在 Day 12 的 Judge0 代理中,我們設定了嚴格的執行時間限制。這不僅是為了避免使用者提交惡意迴圈程式,也是為了防止計費超時。
  • 前端驗證:在前端就對程式碼進行基礎的語法檢查,避免提交明顯的無效程式碼,浪費 Judge0 請求。

Step 2: 速率限制與容錯機制

任何雲端服務都有「速率限制 (Rate Limiting)」,通常以每分鐘請求數 (RPM) 或每分鐘 Token 數 (TPM) 來衡量。一旦超過,API 會回傳 429 Too Many Requests 錯誤。

  1. 容錯的必要性
    想像一下當你的文章被大型社群網站轉發時,短時間內湧入大量使用者開始練習程式題,Judge0 或 Gemini 可能就會超載。一個專業的應用程式不能直接崩潰。
  2. 程式碼中的容錯策略複習 (Day 18 概念)
    我們的架構已經為此打下基礎:
  • 重試機制 (Retry):在 /api/interview/evaluate 處理函式中,如果我們遇到 Judge0 或 Gemini 的 5xx 錯誤或 429 錯誤,我們使用了 指數退避 (Exponential Backoff) 策略,也就是我們的retryAsyncFunction函數,自動進行幾次重試,且每次重試的間隔時間加倍。
  • 如果 Judge0 失敗:讓 AI 判斷,在評估 JSON 中註明 grounded_evidence 無法取得,僅根據使用者文字和 RAG 進行語意評估。
  • 如果 Gemini 失敗:回傳一個通用的錯誤訊息,並要求使用者稍後重試。

Step 3: 安全性討論:RLS 策略

在 Day 24,我們為 practice_records 設定了 SELECT 的 RLS 策略,確保使用者只能讀取自己的紀錄,通常這樣的檢查也會在前/後端同時進行,資料庫這樣的策略便會是你的應用程式最後一層的防護,避免一些漏網之魚或是非預期的操作。
一般來說成熟的軟體大致上都分為幾層的防護,普遍的認知最佳實務是「前後端 + 資料庫三層檢查」:

  • 前端:不顯示其他使用者的資料(UI 層防護)
  • 後端 API:檢查 session.user.id(邏輯層防護)
  • Supabase RLS:最後一道防線(資料層防護)
    即使前兩層被繞過,RLS 仍能保證資料安全。

為什麼這很重要?

想像一個攻擊場景:

  1. 駭客打開瀏覽器開發者工具
  2. 找到你的 API 端點:/api/practice/history
  3. 修改請求參數:user_id: "別人的 UUID"
  4. 如果沒有 RLS → 能看到別人的所有練習紀錄
  5. 有 RLS → Supabase 直接回傳空陣列,攻擊失敗

雖然這稱不上什麼攻擊,不過只要想像一下同樣的情境變為寫入或修改資訊大致上就知道嚴重性了。

當然,你能限定的 Policy 自然也遠遠不止於 SELECT,舉個例子來說,一個完整的安全策略還需要考慮寫入 (Write)。我們必須確保當使用者提交答案時,他們不能偽造 user_id 來將紀錄寫入別人的名下。

這時候你就可以在主控台或是透過直接的 SQL 指令去限制這樣的行為,需要限制怎麼樣的操作、又需要限制怎麼樣的使用者就全依賴你對於你專案的了解,最基礎的當然就是在個人紀錄相關的資料只允許自己的讀取和寫入,其餘的部分就仰賴商業邏輯的設計。

今日回顧

今天的內容應該是整個系列文最短最短的一篇了,我們簡單探討了一些我們在目前專案中做的成本控管與可靠性的設計,雖然都相當的基礎,但足以讓你作為起點往後延伸,之後在開發時可以試著在過程中去思考這些問題,讓你之後的思維變得更為全面一些,大致回顧一下我們今天的內容
✅ 理解成本結構:分析了 Gemini (Token) 和 Judge0 (Request) 的計費模型,並確定了 RAG 和 Prompt 的節約策略。
✅ 確認容錯機制:概念性複習了處理速率限制的必要性,以及應用的降級策略。
✅ 複習RSL資料庫安全防護:了解我們對 practice_records 資料表的保護機制,以及還有什麼可能的額外防護。

明日預告

了解了目前我們在專案功能之外做的一些設計後,明天開始我們就要回到最後的功能衝刺,我們會嘗試在我們的程式實作題目中加入真正的前端測試問題,例如 React & CSS,這實際上是個不小的項目,完全可以獨立成一個全新的主題,我會試著不使用 Docker 之類的獨立環境,用較低成本的實現方式讓你了解整個概念是怎麼實作的,未來若是真的有碰到類似的需求需要用完整的方案,這會是一個很好的切入點。


上一篇
擴充 AI 的大腦:高效擴充題庫與 Embedding 更新
下一篇
打造 React 評測引擎 :試著做出最小可行實作方案
系列文
前端工程師的AI應用開發實戰:30天從Prompt到Production - 以打造AI前端面試官為例29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言