跳轉到

AI 額度(AI Quota)

功能群:系統管理|選單位置「系統設定 › AI 額度設定」

事實基準:2026-09-30 從 FE src/views/ai-quota/(AiQuotaPage.vue、AiQuotaForm.vue、AiQuotaCeilingTable.vue、AiQuotaUsageCards.vue、aiQuotaForm.js)、src/components/ai-quota/AiQuotaBanner.vue + BE api/ai_quota/、app/ai_quota/service/(ai_quota_setting_service.py、ai_quota_setting_rules.py、ai_quota_service.py)、common/constant/ai_quota.py、core/plugins/_ai_quota_adapter.py + migration scripts/sql/2026-09-29-fr122-ai-quota-page.sql 掃出

變更紀錄

日期 FR 變更
2026-10-04 FR-126(1.24.0) 租戶層「AI 服務設定」只收 api_key,帶 base_url 等其他欄位回 400 SYSTEM_CONFIG_400007;AI 位址一律取平台層設定
2026-09-30 FR-122 首版:租戶額度與每人額度(美金,日/月)、每人每分鐘次數、平台管理員給各租戶設上限;三支 AI 功能頁 80% 黃條、用滿紅條;能力點 ai-quota.read/ai-quota.update

1. 功能描述

AI 額度頁設定用原廠金鑰呼叫外部 AI 時最多能花多少錢、多快。三層由寬到窄:

  1. 平台上限:平台管理員給每個租戶設的天花板;沒設=上限就是系統預設。
  2. 租戶額度:整個租戶一期(日或月)最多花多少美金。
  3. 每人額度:租戶內每位使用者一期最多花多少美金(全員同一個數),加上每人每分鐘最多送幾次。

只計原廠金鑰(平台「AI 服務設定」的金鑰或主機環境變數)的呼叫;租戶在「AI 服務設定」填了自己的金鑰,那些呼叫不計、不擋。ROOT 租戶的設定就是全系統預設,各租戶沒設時沿用。

租戶在「AI 服務設定」只能填金鑰:寫入帶 api_key 以外的欄位(如 base_url)一律回 400 SYSTEM_CONFIG_400007,讀取也不回位址;AI 服務位址永遠取平台層(ROOT)設定,租戶格裡的位址不被讀取。故「改用自己的金鑰」不會讓呼叫改走別的位址。

內建預設(ROOT 也沒設時):租戶 5.00 美金/日、每人 1.00 美金/日、每人每分鐘 20 次。

主要使用者:租戶管理員(調本租戶)、平台管理員(調系統預設、給各租戶設上限)。

角色速覽

角色 一句話
具 ai-quota.read 者 看得到本選單,看本租戶設定與用量
具 ai-quota.update 者 可儲存本租戶設定、還原為系統預設;三支 AI 功能的額度條上看得到「調整額度」連結
平台管理員(在 ROOT 租戶) 另有「給個別租戶設上限」表
所有登入者 看得到自己的額度條(/system/ai-quota/me)

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 用量卡 「本租戶」「你」兩張,本期已用/上限/恢復時間 頁首 §10
2 80% 黃條/用滿紅條 同 AI 功能頁的額度條 頁首 UC-AIQ-02
3 全用自帶金鑰提示 「貴單位目前全部使用自己的金鑰,花費不計入額度。」 頁首 §10
4 租戶額度 美金+週期(日/月);留空=沿用上一層 設定表單 UC-AIQ-01
5 每人額度 美金+週期 設定表單 UC-AIQ-01
6 每人每分鐘次數 正整數 設定表單 UC-AIQ-01
7 儲存 超過平台上限時逐欄標「超過上限,平台給本租戶的上限是 …」 設定表單 §4
8 還原為系統預設 確認後刪掉本租戶設定,全部改回沿用 設定表單 §6
9 給個別租戶設上限 平台管理員在 ROOT 才有:租戶/租戶上限/每人上限/每分鐘/目前生效值,逐列編輯、「儲存上限」 下方表格 UC-AIQ-03

2. Use Case

UC-AIQ-01 租戶管理員調本租戶額度

項目 內容
角色 具 ai-quota.update 者
主流程 ① 進頁看用量卡 → ② 改租戶額度/每人額度/每分鐘次數 → ③ 儲存 PUT /system/ai-quota
例外 超過平台上限(金額較大或週期不同、次數較大)→ 400 GRC_400136,data.violations 逐欄帶上限;選「月」但紀錄保留天數不足 31 天 → 400 GRC_400137

UC-AIQ-02 使用者用到 80%/用滿

項目 內容
角色 任何使用 AI 功能的登入者
主流程 AI 小幫手、AI 儀表板、證據自動分類頁頂端讀 /system/ai-quota/me:用到 80% 黃條「…已用 N%(已用 / 上限 美金),用完後 AI 功能暫停到 …」;用滿紅條「…已用完…恢復」
分支 具 ai-quota.update → 條上多「調整額度」連結到本頁
用滿後 原廠金鑰的呼叫一律被閘道擋下,各功能回說明句(見 §11)

UC-AIQ-03 平台管理員給租戶設上限

項目 內容
角色 平台管理員,登入 ROOT 租戶
主流程 「給個別租戶設上限」表 → 點某租戶 → 填三欄 → 「儲存上限」PUT /system/ai-quota/tenants/<id>/ceiling
限制 目標不可是 ROOT 本身(400 GRC_400138)

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
看頁面/讀設定 route_capabilities 綁 ai-quota.read ai-quota.read,否則 403 GRC_403022 app/ai_quota/service/ai_quota_setting_service.py
儲存/還原 表單按鈕依 ai-quota.update ai-quota.update,否則 403 GRC_403022 同上
各租戶上限讀寫 ROOT 且平台管理員才顯示 require_platform_admin,否則 403 GRC_403060 api/ai_quota/
自己的額度狀態 登入即讀 登入即可;回 can_adjust=是否持有 ai-quota.update 同上
一般系統設定端點改 AI_QUOTA — 一律擋 403 GRC_403068「AI 額度請由 AI 服務設定頁調整」 app/system_config/service/ai_quota_config_guard.py

能力點預設授予:ai-quota.read 授予目前持有 storage-config.read 的角色;ai-quota.update 只授予管理員角色(roles.is_admin = 1)。

4. 狀態機與前置條件

無狀態機。儲存時的驗證(ai_quota_setting_rules.py):

規則 違反時
只接受 tenant_budget、user_budget、user_rpm 三欄(warn_ratio 會被丟棄,固定 0.8) 其他欄位 → GRC_400138
預算欄只有 usd、period;period 為 day 或 month GRC_400138
usd 為有限數、不為負、最多兩位小數;null=清掉改沿用上一層;0=這一層不准用原廠金鑰 GRC_400138
user_rpm 為大於 0 的整數 GRC_400138
非 ROOT 租戶:金額不超過平台上限、週期與上限相同、次數不超過上限 GRC_400136,data.violations=[{field, ceiling}]
任一預算選「月」時,AI 呼叫紀錄保留天數須為 0(永久)或 ≥ 31 天 GRC_400137

5. UI 設計

📸 實際畫面截圖待補。

頁首兩張用量卡與額度條 → 設定表單(三欄,每欄旁顯示目前生效值與上限)→(ROOT 平台管理員)各租戶上限表。

6. API 規格

6.1 總清單(前綴 /api/1.0)

Method + Path 權限 說明
GET /system/ai-quota ai-quota.read 本租戶設定、生效值、上限
PUT /system/ai-quota ai-quota.update 儲存本租戶設定
DELETE /system/ai-quota ai-quota.update 還原為系統預設
GET /system/ai-quota/tenants 平台管理員 各租戶上限與生效值
GET /system/ai-quota/tenants/<id>/ceiling 平台管理員 單一租戶上限
PUT /system/ai-quota/tenants/<id>/ceiling 平台管理員 設單一租戶上限
GET /system/ai-quota/me 登入 自己的額度狀態、can_adjust(三支 AI 功能頁的額度條用)

6.2 儲存 body

{
  "tenant_budget": {"usd": 5.00, "period": "day"},
  "user_budget":   {"usd": 1.00, "period": "day"},
  "user_rpm": 20
}

6.3 錯誤碼

碼 HTTP 訊息
GRC_400136 400 超過平台給本租戶的上限
GRC_400137 400 月額度需要紀錄至少保留 31 天,請先調整紀錄保留天數
GRC_400138 400 AI 額度設定格式不正確
GRC_403022 403 使用者不具備此操作所需的權限(能力點)
GRC_403060 403 此操作需平台(root 租戶)管理員權限
GRC_403068 403 AI 額度請由 AI 服務設定頁調整
GRC_412058 412 AI 額度不足,請減少份數或等額度恢復後再送(證據自動分類送出前預估)

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/ai-quota/AiQuotaPage.vue 頁框
src/views/ai-quota/AiQuotaForm.vue、aiQuotaForm.js 三欄表單與驗證
src/views/ai-quota/AiQuotaCeilingTable.vue 各租戶上限表
src/views/ai-quota/AiQuotaUsageCards.vue 用量卡
src/components/ai-quota/AiQuotaBanner.vue、src/composables/useAiQuota.js 額度條(三支 AI 功能頁共用)
src/config/aiQuota.js 頁面網址與能力點常數
src/config/locales/i18n/*/ai-quota.json 文案

8. 後端檔案地圖

鏈路 位置
Route api/ai_quota/
設定讀寫與權限 app/ai_quota/service/ai_quota_setting_service.py、驗證 ai_quota_setting_rules.py
執行期檢查 app/ai_quota/service/ai_quota_service.py;閘道接點 core/plugins/_ai_quota_adapter.py
常數與預設 common/constant/ai_quota.py

9. DB

表 讀/寫 說明
public.system_configs 讀寫 group AI_QUOTA:key CONFIG=租戶額度設定、key CEILING=平台給該租戶的上限;以租戶區分
public.ai_call_log 讀 計算本期已用美金(只計 key_source 為 root/env)
public.capabilities、role_capabilities、route_capabilities、ui_routes 讀 選單與能力點

10. 頁面邏輯與資料對應

  • 每欄「生效值」=本租戶設定 → 平台上限 → ROOT 設定 → 內建預設,取第一個有值的。
  • 用量卡與額度條取「本租戶」「自己」兩層裡最接近用完的那一層顯示。
  • 本租戶全部用自帶金鑰時(counted=false)不顯示額度條,頁首改顯示「花費不計入額度」提示。

11. 背景行為與外部依賴

類型 內容
執行期檢查 每次原廠金鑰的 AI 呼叫前,閘道先查每分鐘次數與本期額度;超過即擋下、不送外部 AI,該次仍寫一筆 ai_call_log(status='blocked')
擋下時各功能的呈現 AI 小幫手:一則回覆「本期 AI 使用額度已用完,請聯繫系統管理員。」;AI 儀表板:400 AI_DASHBOARD_400005,訊息為額度說明句;證據自動分類:送出前預估超過剩餘額度 1.5 倍擋整批 GRC_412058,執行中用完的檔標「額度用完未分類」
恢復時間 日額度:隔天 00:00;月額度:下月 1 日 00:00(以應用容器時區計算,落地版預設台北)

12. 邊界情況與已知坑

  1. 0 與留空不同:0 是「這一層不准用原廠金鑰」,留空是「沿用上一層」。
  2. 月額度綁紀錄保留天數:已用金額由呼叫紀錄加總,保留不到一個月就算不出本月用量,所以強制 ≥ 31 天。
  3. 每分鐘次數以「一次操作」計:AI 儀表板一次生成打兩次外部 AI,只算一次。

13. 開發與驗證

  • 導航路徑:系統設定 › AI 額度設定(/system/ai-quota)
  • 驗證:把每人額度設 0.01 美金/日,用 AI 小幫手問一題後再問 → 第二題被擋、頁首紅條;把額度改回後恢復。
  • 相關文件:AI 用量、AI 小幫手、FR-122 額度討論稿(docs/features/FR-122-2609-ai-gateway-and-sandbox/cost-quota-discussion.md)。