把網址分享出去之前,想到一個問題:如果真的有人狂點,要付多少錢?
Day27 拿到公開網址之後,第一個念頭是分享給朋友玩玩看。但緊接著冒出的疑慮是:這支 API 完全沒有身份驗證,CORS 也設成允許所有來源,理論上任何人都能繞過前端介面直接對著 API 打,這代表我完全不知道流量上限在哪裡,如果成本超支了怎麼辦?為了避免這種事情發生,我們先來搞懂「AWS 到底怎麼收錢」,再來看可以為這個專案做了哪些防範,以及哪些防範其實這次沒做成。
1. 用多少付多少(Pay as you go)
雲端跟「月租型」手機方案不一樣,比較像水電費:用得多付得多,沒用就不收錢。好處是小專案很便宜;壞處是沒有人幫你設上限,流量暴增時帳單也會跟著暴增。
2. 每個服務各自算錢,單位都不同
一個專案會用到好幾個服務,每個服務的收費方式不一樣,最後帳單是全部加起來:
| 服務 | 它在做什麼 | 大概按什麼收費 |
|---|---|---|
| S3 | 放網站檔案 | 存了多少資料、被讀取幾次 |
| CloudFront | 讓全世界快速打開網站 | 傳出去多少資料量 |
| API Gateway | API 的大門 | 被呼叫幾次 |
| Lambda | 執行後端程式 | 執行幾次,加上每次跑多久、用多少記憶體 |
| Bedrock | 呼叫 AI 模型 | 按 token 收費(輸入多少字、輸出多少字) |
白話一點:token 就是 AI 讀寫文字的「計價單位」,可以先想成字數。你問得越長、AI 答得越長,就越貴。
3. 免費額度(Free Tier)
多數服務每個月會給一份免費額度,用在額度內不收費,超過才開始算錢。像 S3、CloudFront、API Gateway、Lambda 的額度對小專案都很大方。但免費額度的規則和數字會調整,實際以 AWS 官方價格頁和 Billing 頁面為準,這邊不寫死數字。
4. 重點:不是每個服務都有免費額度
Bedrock 沒有這份「額度緩衝」,用了就計費。所以這個專案的費用風險,幾乎都集中在呼叫 AI 的那一步。
5. 帳單看得到,但不是即時的
Billing 頁面的數字會有延遲,不是花一塊錢就立刻跳一塊錢。這點會影響後面「警報」能多快通知你。
先把 Bedrock 的收費拆開來看,這是整篇最重要的觀念。
1. 按 token 算,不是按呼叫次數
原本直覺以為「打一次 API 就是一筆固定費用」。實際上 Bedrock 看的是「這次用了多少 token」,內容越長就越貴,不是打一次收一次。
2. input 和 output 分開計價
兩者的用量不同,單價通常也不同(output 通常比較貴,實際以 Bedrock 價格頁為準),所以要分開看。
3. 成本主要來自「送進去多少」
專案生成菜單時,會把候選食物清單(每個餐次最多 15 筆真實食物的完整資料)整包放進 prompt 讓 AI 挑,這是大宗的 input;AI 只需要回傳精簡的 JSON(選中的食物編號加一句建議),output 很小。所以這個專案的成本,主要取決於 input 有多長,而不是 AI 回答多長。
4. 一次送出 ≠ 一次呼叫
使用者按一次「送出」,後端其實會呼叫 2 到 3 次 Bedrock(分析、生成菜單,加上可能的重試)。估算成本時要乘上這個倍數。
5. 把它們串成一條粗估式
一次送出的成本 ≈ 呼叫次數 ×(input token 數 × input 單價 + output token 數 × output 單價)
示範(數字都是我假設的,不是實際價格或實際用量):
這條式子是我整理的粗估方法,不是 AWS 的官方公式。想換成真實數字,只要把自己的 token 用量和 Bedrock 價格頁的單價代進去。
6. 模型單價是成本槓桿
同樣的用量,換一個單價較低的模型,成本就跟著降。我的專案用的是 Claude Haiku 4.5,單價較低:因為 AI 在這裡只負責「從候選清單挑食物」,份數等核心計算都是程式算的,對模型能力要求不高,便宜的模型就夠用。反過來說,如果任務很難、必須用更貴的模型,同樣的用量帳單就會明顯變高。
7. 最後用真實帳單核對
估算完,再拿 Bills和估算比對,對不上就代表你的成本模型哪裡估算得不準。
目前的API 沒有任何身份驗證,CORS 也設成允許所有來源。
CORS 只是瀏覽器的規則,不是防護。 Day26 提過,curl 不受同源政策限制。只要知道 API 網址,任何人都可以用程式直接對它發請求,完全不經過我的前端畫面。所以 CORS 不能當作防護網。
把兩件事放在一起看:
這就是「最壞情況」:有人寫個迴圈一直打,帳單就一直長,沒有東西會自動叫停。套用上一節的估算(同樣是示範用的假設數字): 一次送出約 0.0375 美元,被打 1 萬次就是約 375 美元。「次數 × 單次成本」沒有上限。
新手可以把防範想成三種不同性質的東西:
| 類型 | 白話比喻 | 例子 |
|---|---|---|
| 預防:讓別人打不進來 | 大樓門禁 | API Key、身份驗證 |
| 限流:就算打進來也限制速度 | 餐廳限制同時入座人數 | Lambda 保留併發、API Gateway 限流 |
| 警報:花多了會通知你 | 電表超過度數就響鈴 | AWS Budgets |
先認識幾個這篇會用到的名詞:
什麼是「限流」?
限流就是替請求的「速度或數量」設一道上限,超過的就不處理(直接拒絕,請對方稍後再來)。比喻:餐廳門口限制同時入座的人數,客人再多也不會超過。
常見的限法有兩種:
為什麼限流跟省錢有關? 每呼叫一次 Bedrock 就要花錢,限流能讓「最壞情況」從無上限,變成「最多只能這麼快」。注意:只限速度不等於限總額,要限總額得靠「每天最多幾次」這類額度。
什麼是「併發」(concurrency)?
併發就是「同一個瞬間,有幾個 Lambda 正在同時跑」。不是「一天總共跑幾次」,而是「現在這一刻同時有幾個」。
用小吃店比喻:
如果有 10 個爐子,同時來了 15 位客人,那 10 位先煮,剩下 5 位要等(在 Lambda 就是被拒絕,回傳「太多請求」的錯誤)。
併發數大概等於:每秒來幾個請求 × 每個請求要跑幾秒。 例如每秒 5 個請求、每個跑 2 秒,同一瞬間大約就有 10 個在跑。「每個請求要跑幾秒」也包含等 AI 回應的時間。我們的 Lambda 要等 Bedrock 生成內容,每次可能跑好幾秒,所以請求不用很多,併發就會很快被用完。
什麼是「保留併發」?
保留併發(ReservedConcurrentExecutions)是替某個函式「預留 N 個爐子、而且最多只能用這 N 個」。這樣做有兩個效果:
什麼是「TPM」?
TPM 是 Tokens Per Minute,意思是「每分鐘最多能處理多少 token」,是 AWS 替每個 Bedrock 模型設的用量上限。它也是一種限流:前面講的併發是限「同時幾個」,API Gateway 是限「幾次」,TPM 則是用「token 量」來限速。三個重點:
額度可以在 Service Quotas 的 Amazon Bedrock 底下查看,每個帳號不同。
AWS Budgets:花費警報
設定一個預算金額,實際花費超過一定比例時寄信通知你。注意:它只會通知,不會幫你擋下來。
第一步:盤點風險在哪
回頭看上面那張表:S3、CloudFront、API Gateway、Lambda 都有大方的免費額度,風險低。真正的風險集中在 Bedrock,因為它沒有免費額度、按 token 收費,而且流量沒有任何門檻擋著。
所以防範的重點很明確:不要讓人無限制地呼叫會觸發 Bedrock 的 API。
第二步:嘗試 Lambda 保留併發上限(沒成功)
前面提到的限流手段中,最直接的是替 Lambda 設定「保留併發」,限制它同時最多跑幾個。我嘗試設定,結果發現這個 AWS 帳號的 Lambda 總併發額度只有 10,而 AWS 規定「沒被保留的額度不能低於 10」,所以設不了。(額度可以申請調高,步驟寫在後面;目前專案只分享給少數人所以沒有這個需求,就先不申請了。)
為什麼設不了? 用小吃店比喻:
如果總額度是 1000,我就可以預訂例如 5 個,其餘 995 個照樣共用,這個方法才有意義。
為什麼一開始只有 10,而不是文件上寫的 1000?
這個發現本身也是一課:想加一道保護,結果先撞到另一個帳號層級的限制。 雲端服務常常彼此牽制,不是想加就能馬上加。
反過來想: 總額度只有 10,其實等於這個帳號同一瞬間最多只能跑 10 個 Lambda,超過的請求會被拒絕。這在無意中也算一種上限,但它是「帳號本身的限制」,不是我設計的防護,不能當作已經防住,而且一旦額度被調高就不存在了。
第三步:設定 AWS Budgets 帳單警報
因為主動限流做不了,我退而求其次,設定每月 5 美元的預算,實際花費超過 80% 和 100% 各寄一次通知信。下面五張是我實際的 AWS 畫面,照著「設定好之後,怎麼確認它有在運作」的順序看。
圖 1|Budgets 清單頁:我設了哪些預算
ai-diet-copilot-monthly-5usd 是我替這個專案建的,意思是「每月 5 美元」。另一個 My Monthly Cost Budget 是 AWS 範本的預設名稱,這篇只看前者。圖 2|預算詳細頁:現在花了多少、預計花多少
從圖 1 點進預算名稱就會看到。紅框是這頁最重要的兩個數字:
圖 3|點擊左下角的 View all alerts:兩道警報門檻各自的狀態
這就是前面說的「80% 和 100% 各寄一次通知」,兩張卡片各是一道門檻:
圖 4|真正收到的警報信
設定警報最怕「設了卻不知道有沒有用」,所以我去信箱確認:2026/10/09 收到 AWS Budgets 寄來的信,內容翻成白話是:
ai-diet-copilot-monthly-5usd,這個月的實際花費超過了 4.00 美元(門檻)。這封信證明整條通知流程有走通:花費超過門檻,AWS 就會寄信到我設定的信箱。
圖 5|Bills:帳單實際長怎樣
Budgets 說明「花了多少」,Bills 才說明「錢花在哪裡」。入口:Console 搜尋 Billing,左側選 Bills。
看完這五張圖的結論: 警報有觸發、信有寄到,這道「被動警報」確實在運作。但要注意時間點:收到信的時候已經花了 4.39 美元,離 5 美元只差不到 1 美元。警報是「提醒」,不是「幫忙擋住」。
目前的防線總整理
| 防線 | 類型 | 狀態 |
|---|---|---|
| Lambda 保留併發上限 | 限流(主動擋) | 帳號額度只有 10,設定不了 |
| AWS Budgets 帳單警報 | 警報(被動通知) | 已設定,且已實際觸發並收到信(圖 3、圖 4) |
| API Key + Usage Plan | 預防加限流 | 只是規劃,還沒做 |
誠實承認:這只是一道被動警報,不是真正的防護。 因為帳單數字有延遲,等信寄到時,錢可能已經花掉了。它比什麼都沒有好,但不能當作「已經防住」。如果之後真的要開放給更多人用,該做的是申請調高 Lambda 併發額度,或加一個 API Key 加 Usage Plan 限制呼叫來源。這兩件事目前先記錄下來,不急著做。
以下是我讀官方做法整理的步驟,我還沒有實際送出申請,先寫在文章裡當作之後的備忘:
申請時的小提醒:
以下是我讀資料得知的方向,不是我做過的事,先記錄下來:
目前專案只是作品集 Demo、網址只分享給少數人,所以先記錄、不急著做。如果要開放給不特定的人使用,這幾項就必須補上。