AI 儀表板(AI Dashboard)¶
事實基準:2026-09-30 從 FE(
views/dynamic-dashboard/、composables/useDashboardGenerator.js、components/ai-quota/AiQuotaBanner.vue)/BE 套件jedi_ai_dashboard(api/routes/ai_dashboard_route.py、app/service/ai_dashboard_app_service.py、common/error_code.py)+宿主core/plugins/ai_dashboard.py、core/plugins/ai_gateway.py+閘道規則gateway_rules.yaml/prompts.yaml掃出
變更紀錄
| 日期 | FR | 內容 |
|---|---|---|
| 2026-09-30 | 1.22.0(FR-122) | 生成改經 AI 閘道:先由 AI 判意圖,要求執行操作或與系統資料無關的回 400 AI_DASHBOARD_400006 並帶具體原因,查詢一律產出表格;送出前遮蔽機敏資料(提示「已遮蔽 N 處」)、疑似注入顯示警告;失敗分三類(輸入被擋 400005/對應不到資料 400006/AI 服務連不上 503001);頁首額度黃/紅條;次數上限改由 AI 額度的「每人每分鐘次數」管,一次生成只算一次。詳見 §3、§4、§10、§12 |
| 2026-09-28 | 1.21.0(FR-114) | 生成加次數上限與逾時:同一使用者每 60 秒最多生成 3 次,超過回 429 AI_DASHBOARD_429001(「儀表板生成請求過於頻繁,請稍後再試」),回應帶 data.retry_after(還要等幾秒);每次外部 AI 呼叫 60 秒逾時。生成要「AI 儀表板」權限(能力點 ai-dashboard.read)且公司買了 AI 儀表板模組。26 支資料查詢各自申報要什麼權限。同頁的 AI 助手另有自己的上限(每人每分鐘 10 次、訊息 4000 字)。詳見 §3、§4、§11、§12 坑 8 |
1. 功能描述¶
AI 儀表板讓使用者用自然語言 prompt 生成一份動態儀表板:後端跑五階段管線(AI 判意圖並選資料 API → 取資料 → 統計 → AI 設計版面 → 組裝 JSON),前端渲染成 Ultima UI 元件並抽出圖表。兩次 AI 呼叫都經 AI 閘道(遮蔽機敏資料、擋下不該送的內容、檢查額度與次數、寫呼叫紀錄)。生成結果 per-request、不落 DB(無專屬儀表板表)。
只做查詢:AI 先判斷這句話是「看資料」「要系統執行操作」(重開機、刪除、寄信…)還是「與系統資料無關」(天氣、閒聊)。後兩者不產圖,回一句具體原因;看資料的一律產出表格,AI 選資料主題最相近的那支資料來源。
主要使用者:需快速視覺化 GRC 資料的人(全域工具,任何登入者皆可用)。
角色速覽:
| 角色 | 一句話 |
|---|---|
| 使用者 | 輸入 prompt 生成儀表板(auto-generate 需 JWT;health 免 JWT) |
1.1 功能總覽(本頁全部功能)¶
| # | 功能 | 說明 | 位置 | 詳述 |
|---|---|---|---|---|
| 0 | 額度黃/紅條 | 本租戶或自己的 AI 額度用到 80% 黃條、用滿紅條;具 ai-quota.update 者多「調整額度」連結 |
頁首 | AI 額度 |
| 1 | 後端健康檢查 | 進頁檢查生成服務可用性 → 狀態徽章 | PromptBar | UC-AID-01 |
| 2 | 自然語言 prompt | 輸入描述、按生成或 Enter | PromptBar | UC-AID-01 |
| 3 | 範本快速起手 | 內建範本(個人待辦事項儀表板)點擊帶入 prompt | Templates | §5 |
| 4 | 載入狀態 | 生成中進度條 + 重試次數 | LoadingState | §5 |
| 5 | 錯誤處理 | 錯誤訊息(有具體原因時顯示具體原因);只有「AI 服務連不上」有重試鈕 | ErrorMessage | §10 |
| 5a | 遮蔽提示 | 「已遮蔽 N 處機敏資料後送出」 | PromptBar 下方 | §4 |
| 5b | 疑似注入警告 | 黃條「你的輸入疑似含有操控 AI 行為的指令,結果已產出但請自行判斷可信度;此次呼叫已記入稽核紀錄。」 | PromptBar 下方 | §4 |
| 6 | 生成儀表板渲染 | DynamicPrimeComponent 渲染 Ultima 結構 | 主區 | §10 |
| 7 | 戰情室概覽 | 從結構抽出最多 3 張圖表卡片 | BattleRoom | §10 |
| 8 | 重新生成 | 對同 prompt 再跑一次 | 生成區 | UC-AID-01 |
UC(§2)展開 生成主流程(健康檢查 → prompt → 生成 → 渲染 / 重試)。
2. Use Case¶
角色速覽:
| 角色 | 一句話 |
|---|---|
| 使用者 | 輸入 prompt 生成儀表板(auto-generate 需 JWT;health 免 JWT) |
流程圖視覺慣例:菱形 = 判斷、橘底 = AI 步驟 / 例外、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。
UC-AID-01 生成 AI 儀表板¶
| 項目 | 內容 |
|---|---|
| 角色 | 使用者 |
| 前置條件 | 後端生成服務在線(health 檢查通過);平台或租戶「AI 服務設定」有可用金鑰(或主機環境變數);額度未用完 |
| 產出 / 後置條件 | 回傳 dashboard JSON(object)+ data_count + tokens_used;前端渲染、抽圖表;不儲存 |
3. 權限矩陣¶
| 操作 | FE 判定 | BE 強制 | BE 檢查位置 |
|---|---|---|---|
| 健康檢查 | 進頁自動 | 無 JWT(公開);回供應商 / 速度清單 | api/ai_dashboard/routes/ai_dashboard_route.py::health |
| 生成儀表板 | 選單能力 + 後端在線 | @jwt_required() + @require_license("ai-dashboard") + @require_capability("ai-dashboard.read")(無能力點 403 GRC_403022);prompt 1–2000 字驗證;次數與額度由 AI 閘道檢查(見 §4) |
jedi_ai_dashboard/api/routes/ai_dashboard_route.py::AiDashboardAutoGenerateRoute.post;閘道 core/plugins/ai_gateway.py、core/plugins/_ai_quota_adapter.py |
| 看「調整額度」連結 | /system/ai-quota/me 回 can_adjust |
ai-quota.update |
app/ai_quota/service/ai_quota_setting_service.py |
生成時以 JWT 帶出
DashboardContext(user_uid/user_id/tenant_id/org_unit_id/locale)注入資料 API——查詢受 RLS / tenant 隔離(見 §11)。
4. 狀態機與前置條件¶
本頁無持久狀態機(無儲存)。生成前置與 gate:
| 條件 | 效果 | 出處 |
|---|---|---|
| health 不通過 | 狀態徽章離線、生成鈕停用 | useDashboardGenerator.js(checkBackendStatus) |
| 租戶、平台、主機環境變數都沒有可用金鑰 | 400 AI_DASHBOARD_400001,訊息指路「系統設定 → AI 服務」 |
ai_dashboard_app_service.py(閘道回 NOT_CONFIGURED) |
| 含機敏資料(身分證、信用卡、email、電話、IP、雲端存取金鑰) | 遮蔽後照送;回應 redacted_count > 0,畫面提示「已遮蔽 N 處」。送給第二次 AI 的樣本資料也會遮蔽 |
規則 tw-national-id-dashboard、pii-redact-dashboard |
| 含私鑰(PEM)、索取密碼或金鑰、直接下 SQL/指令/程式碼 | 不送 AI;400 AI_DASHBOARD_400005,message 為該規則的說明句(私鑰規則沒有說明句,顯示通用訊息) |
規則 pem-private-key-all、secret-request-dashboard、raw-command-dashboard |
| 額度用完、每分鐘次數超過、租戶政策禁用 | 不送 AI;400 AI_DASHBOARD_400005,message 為額度或次數說明句(如「送出太頻繁,請 N 秒後再試。」) |
core/plugins/_ai_quota_adapter.py;次數上限=AI 額度的每人每分鐘次數,一次生成只算一次 |
| 疑似操控 AI 的指令 | 照送;回應 needs_review=true,畫面顯示黃色警告 |
規則 injection-*(prompt_guard,flag) |
| AI 判定為要求執行操作或與資料無關 | 400 AI_DASHBOARD_400006,message 為 AI 給的具體原因 |
ai_dashboard_app_service.py(intent != 'query') |
| AI 選到的資料來源呼叫失敗 | 400 AI_DASHBOARD_400006 |
同上 |
| 外部 AI 連不上 | 503 AI_DASHBOARD_503001,可重試 |
同上 |
| 外部 AI 單次呼叫超過 60 秒 | 逾時,走 503 路徑 | 閘道逾時設定 |
| 其他生成失敗 | AI_DASHBOARD_500001(HTTP 400) |
AiDashboardAutoGenerateRoute.post |
5. UI 設計¶
📸 實際畫面截圖待補(一律亮色模式拍攝;截圖另有專責 session)。預計補到
assets/img/: ① 空狀態(PromptBar + 範本)aid-empty.png② 生成中 loadingaid-loading.png③ 生成結果(儀表板 + 戰情室圖表)aid-result.png④ 錯誤訊息aid-error.png
版面骨架與區塊職責:
狀態呈現:PromptBar 狀態徽章由 health 決定(在線 success / 離線 danger);生成鈕在 loading 或離線時停用;未生成且未載入顯示 Templates;生成後主區 DynamicPrimeComponent 渲染 Ultima 結構,chartsFromAI > 0 才顯示戰情室(抽最多 3 圖表、以指紋去重)。
6. API 規格¶
Envelope:成功 {"status": true, "data": …}、失敗 {"error_code": "AI_DASHBOARD_…", "msg": "…"}(400005/400006 的 message 帶具體原因)。
6.1 總清單(本頁呼叫的全部 endpoint)¶
| 分類 | Method + Path | 說明 | 完整規格 |
|---|---|---|---|
| 健康 | GET /ai-dashboard/health |
生成服務狀態 + 供應商 / 速度清單(免 JWT) | §6.2 |
| 生成 | POST /ai-dashboard/auto-generate |
五階段生成儀表板(JWT) | §6.2 |
| 額度 | GET /system/ai-quota/me |
額度條狀態與 can_adjust |
AI 額度 |
6.2 核心 endpoint(欄位對照 route / service,出處標段末)¶
[GET] /ai-dashboard/health¶
免 JWT。回靜態健康狀態 + 可用供應商(claude / openai / google)+ 速度(fast / balanced / powerful)。出處:api/ai_dashboard/routes/ai_dashboard_route.py::health。
[POST] /ai-dashboard/auto-generate¶
Request:
{
"prompt": "string", // 必,1–2000 字
"provider": "claude", // 預設 claude
"speed": "balanced" // 預設 balanced
}
(FE 送 speed:'fast')。以 JWT 組 DashboardContext(user_uid, user_id, tenant_id, org_unit_id, locale)。五階段管線(見 §10)。Response data:
{
"object": {}, // <Ultima Container JSON>
"query_plan": {},
"data_count": 0,
"tokens_used": {
"input": 0,
"output": 0,
"cache_creation": 0,
"cache_read": 0
},
"auto_generated": true,
"redacted_count": 0, // 第一次 AI 呼叫遮蔽了幾處
"needs_review": false // 任一次 AI 呼叫命中注入標記
}
出處:套件 jedi_ai_dashboard/api/routes/ai_dashboard_route.py::AiDashboardAutoGenerateRoute、jedi_ai_dashboard/app/service/ai_dashboard_app_service.py。
錯誤碼(仍會拋出的):
| 碼 | HTTP | 訊息 |
|---|---|---|
AI_DASHBOARD_400001 |
400 | 尚未設定 AI 服務的 API 金鑰。請至「系統設定 → AI 服務」填入金鑰後,AI 小幫手、AI 儀表板與證據自動分類才會啟用。 |
AI_DASHBOARD_400005 |
400 | 你的輸入含有不可送出的內容(例如私鑰)或被安全規則擋下,未送至 AI。請調整後再試。(message 可被具體說明句取代) |
AI_DASHBOARD_400006 |
400 | AI 無法把這個需求對應到系統資料(例如要求執行操作、或資料不在儀表板可查範圍)。請改成描述你想看的資料,例如「各專案的稽核進度」。(message 可被 AI 的具體原因取代) |
AI_DASHBOARD_503001 |
503 | AI 服務暫時無法連線,請稍後再試;持續發生請聯繫系統管理員。 |
AI_DASHBOARD_500001 |
400 | AI 儀表板生成失敗 |
400002/400003/400004/404001/404002/429001 仍有定義但生成流程不再拋出。
7. 前端檔案地圖(compliance-manager-fe/)¶
| 檔案 | 角色 |
|---|---|
src/views/dynamic-dashboard/DynamicDashboard.vue |
主檢視(協調 prompt / 生成 / 渲染;頂端掛額度條) |
src/components/ai-quota/AiQuotaBanner.vue、src/composables/useAiQuota.js |
額度黃/紅條 |
src/views/dynamic-dashboard/components/DashboardPromptBar.vue |
自然語言輸入 + 狀態徽章 + 生成鈕 + 遮蔽提示 + 注入警告 |
src/views/dynamic-dashboard/components/DashboardTemplates.vue |
內建範本卡 |
src/views/dynamic-dashboard/components/DashboardLoadingState.vue |
載入進度 + 重試次數 |
src/views/dynamic-dashboard/components/DashboardErrorMessage.vue |
錯誤 + 建議 + 重試 |
src/views/dynamic-dashboard/components/DashboardBattleRoom.vue |
戰情室(抽取圖表卡片) |
src/composables/useDashboardGenerator.js |
生成狀態機(health / generate / 錯誤分類與具體原因 / 圖表抽取 / 重試 / 生成後刷新額度) |
src/config/router/index.js:648-655 |
route ai-dashboard(/dashboard/ai-dashboard) |
src/config/api/api.js:375-376 |
AI_DASHBOARD_AUTO_GENERATE / AI_DASHBOARD_GENERATE_HEALTH |
src/config/locales/i18n/*/dynamic-dashboard.json |
頁面 i18n |
8. 後端檔案地圖(本頁核心鏈路)¶
| 鏈路 | Route | App Service | 底層 |
|---|---|---|---|
| 健康 | api/ai_dashboard/routes/ai_dashboard_route.py::health |
— | 靜態 |
| 生成 | 套件 jedi_ai_dashboard/api/routes/ai_dashboard_route.py::AiDashboardAutoGenerateRoute |
套件 jedi_ai_dashboard/app/service/ai_dashboard_app_service.py(五階段、意圖判斷、錯誤分類) |
宿主掛載 core/plugins/ai_dashboard.py;AI 閘道 core/plugins/ai_gateway.py(金鑰、守門、額度、呼叫紀錄);資料 API 目錄由各插件申報 |
DDD 提醒:資料查詢透過資料 API 目錄動態路由到既有服務方法,注入 DashboardContext 保留 RLS / tenant 隔離;不繞過既有 domain service 直接查 DB。外部 AI 一律經閘道,不直接持有金鑰。
9. DB¶
9.1 資料表總清單¶
| 表 | 讀/寫 | 說明 |
|---|---|---|
| (無專屬表) | — | AI 儀表板不持久化:每次請求即時生成,結果只在記憶體回傳前端;無儀表板 / 歷史表 |
| (間接讀)GRC 各模組表 | 讀 | 第②階段由 AI 選定的資料 API 透過既有 domain service 讀(依 prompt 而定,如任務佇列 / 專案 / 控制統計) |
public.ai_call_log |
寫(閘道) | 每次生成兩筆:ai-dashboard.select、ai-dashboard.layout;第一次被擋或判定非查詢時只有一筆。欄位見 AI 用量 |
main_app.py曾有「AI Dashboard schema analyzer」啟動初始化,目前已註解不執行(見 §11)。無_trans/ 專屬 dump 表。
10. 頁面邏輯與資料對應¶
生成管線(五階段):
- AI 判意圖並選 API:LLM 判斷
intent(query/action/unrelated);非query直接以 AI 的理由回400006。query時從資料 API 目錄選資料主題最相近的main_api,沒選出時退回通用清單的第一支(專案 → 使用者 → 設備)。 - 取資料(
data_api_service.call_api):動態呼叫該服務方法,注入DashboardContext(RLS / tenant)。 - 統計(
analyze_data_stats):算分布 / 計數(project_name/group_name/control_no/job_status等維度)。 - AI 設計版面(
_ask_ai_to_design_layout):LLM 依統計 + 樣本產出analysis_blocks(stat/status-breakdown/category-breakdown)+table。 - 組裝(
build_dashboard_from_design):組成 Ultima UIContainer / Card / DataTableJSON 樹回傳。
前端渲染:dashboardStructure(object)→ DynamicPrimeComponent 遞迴渲染;extractChartsFromStructure 走訪樹抽出 type==='chart' 節點、指紋去重、限 3 張 → 戰情室。
錯誤對應(三類):
| 類別 | 碼 | 畫面 |
|---|---|---|
| 輸入被擋(守門規則、額度、次數、租戶政策) | 400005 |
標題「發生錯誤」,內文為具體說明句(無則通用訊息),無重試鈕 |
| 需求對應不到資料(要求執行操作、無關、資料來源呼叫失敗) | 400006 |
同上,內文為 AI 給的具體原因 |
| AI 服務連不上 | 503001 |
同上,有「重試」鈕 |
三類都不另跳 toast。其他錯誤(網路、500001、400001)走通用錯誤框,附三條檢查建議與重試鈕。每次生成結束後重讀額度,黃/紅條即時更新。
11. 背景行為與外部依賴¶
| 類型 | 內容 |
|---|---|
| LLM 供應商 | 預設 claude(另支援 openai / google);前端固定送 claude + fast |
模型(套件 _MODEL_MAP) |
claude 三檔皆 claude-sonnet-5-5;openai fast gpt-5.6-luna、其餘 gpt-5.6-terra;google 皆 gemini-3.5-flash;max_tokens 16384 |
| 金鑰 | 由 AI 閘道依序取租戶「AI 服務設定」→ 平台設定 → 主機環境變數(ANTHROPIC_API_KEY 等),都沒有擋 400001 |
| 守門規則與 prompt | 主機規則目錄 gateway_rules.yaml、prompts.yaml(ai-dashboard.select/ai-dashboard.layout 兩段),可現場調整,見 落地版維運 4.12 |
| 次數與額度 | 由 AI 閘道檢查:每人每分鐘次數(預設 20)與美金額度,設定在 AI 額度;只計原廠金鑰 |
| 逾時 | 外部 AI 單次呼叫 60 秒 |
| Socket | 本頁無 socket |
| 持久化 | 無——結果 per-request 生成、不存 DB |
12. 邊界情況與已知坑¶
- 不持久化:生成結果只在記憶體、回傳即渲染;重整頁面 / 重新生成即失,無「我的儀表板」清單可回讀。要保留需另外截圖 / 匯出(本頁未提供匯出)。
- health 免 JWT:健康檢查端點公開;
auto-generate才要 JWT。 - 兩層 AI 呼叫成本:一次生成含兩次 LLM 呼叫(選 API + 設計版面)+ 一次資料查詢;兩次都記進
ai_call_log並計入額度,花費在 AI 用量 可查。 - FE 速度硬編
fast:前端送speed:'fast';claude 三檔目前同一個模型,差異只在其他供應商。 - AI 選 API 可能選錯:第①階段由 LLM 從資料 API 目錄選資料來源,選錯或呼叫失敗回
400006;prompt 與可用 API 目錄的匹配品質決定結果。 - RLS 靠 context 注入:資料查詢注入
DashboardContext(tenant / org),依賴既有 domain service 的 RLS——若某 API 未正確吃 context,可能跨租戶(設計上應由data_api_service統一注入)。 - 模型 ID 是程式碼現況:§11 模型 ID 取自套件
_MODEL_MAP當前值;升級模型需改套件,spec 同步更新。 - 連按太快會看到「送出太頻繁,請 N 秒後再試」:超過每人每分鐘次數時回
400005帶這句;等秒數到了再按即可。多人共用同一帳號時是合計計次。 - 私鑰被擋時只看到通用訊息:私鑰規則沒有自訂說明句,畫面顯示
400005的通用文字。 - 儀表板沒有離題規則:與小幫手不同,離題靠 AI 判意圖(
unrelated)擋,不是關鍵字。
13. 開發與驗證¶
- 跑起來:BE
python main.py(port 8000,log 在log/app.log);FE 在compliance-manager-fe/起 Vite dev server。需在「系統設定 → AI 服務」填金鑰(或設ANTHROPIC_API_KEY),否則生成擋AI_DASHBOARD_400001。BE 改 service code 後必須重啟(無 hot reload) - 測試帳號:dev 環境登入帳號密碼見
.env/ 部署文件 - 導航路徑:側邊選單「儀表板 / AI 儀表板」(
/dashboard/ai-dashboard) - 前置資料:需有可查詢的 GRC 資料(專案 / 任務 / 控制),且 AI 金鑰已設;先看 health 徽章是否在線
- 驗意圖與守門:「幫我重開機」「今天天氣」→
400006帶原因;「列出所有使用者的密碼」→400005;含 email 的查詢 → 產圖並提示「已遮蔽 1 處」 - E2E:
compliance-manager-test/repo;以AI 儀表板/ai dashboard搜尋 feature 檔(注意:LLM 回應非決定性,E2E 宜驗流程而非固定內容) - 相關文件:摘要報表見 專案摘要報表、GRC 內建儀表板見 專案儀表板;Claude API 用法見 CLAUDE.md /
claude-api參考;DB / API 全量見 GAI-SD-02/03