跳轉到

AI 小幫手(AI Assistant)

功能群:溝通協作|全站浮動視窗,沒有獨立 route

事實基準:2026-09-30 從 FE src/components/ChatBox.vue、src/layout/AppLayout.vue、src/components/ai-quota/AiQuotaBanner.vue + BE core/plugins/ai_bot.py、套件 jedi_ai_bot(route/service)、jedi_ai_gateway(守門規則 gateway_rules.yaml、prompts.yaml)+ migration scripts/sql/2026-09-28-fr122-ai-call-log.sql 掃出。public.ai_call_log 不在 db_schema.json dump 內(dump 早於本表),欄位以 migration 為準

變更紀錄

日期 FR 變更
2026-09-30 FR-122 首版:小幫手改經 AI 閘道——AI 聲明列、機敏資料遮蔽提示、私鑰/索取密碼/下 SQL 擋下說明、離題固定回覆、額度黃條與「調整額度」連結;回答範圍=系統操作+合規領域知識(ISO 27001 未指明版本以 2022 版回答)

1. 功能描述

AI 小幫手是全站右下角的浮動對話視窗,登入後任何頁面都能打開,用來問系統怎麼操作、以及資安合規領域的問題。它不是一個頁面,沒有 FE route,掛在主版面(AppLayout.vue)底部。

每一則訊息送給外部 AI 之前都先過 AI 閘道:遮蔽機敏資料、擋下不該送的內容(私鑰、索取密碼、直接下 SQL)、擋下離題閒聊、檢查額度與每分鐘次數。被擋下不是錯誤:後端回 200,說明文字當成一則小幫手的回覆顯示在對話裡,讓使用者知道要改什麼。

回答範圍(由規則目錄 prompts.yaml 的 ai-bot.role 決定,缺段時退回套件內建同文字):

  • 本系統的操作說明;
  • 資安合規領域知識——ISO 27001、NIST、CMMC、SSP、控制項、證據、風險評估等框架與名詞、稽核實務問答;
  • ISO 27001 未指明版本時一律以 2022 版回答(附錄 A 四大主題、93 項控制),提到 2013 版編號時說明對應關係;
  • 不回答的只有:寫程式、通用閒聊、扮演其他角色。

主要使用者:所有登入者。

角色速覽

角色 一句話
登入者 打開小幫手提問;看得到自己的遮蔽提示與額度黃條
具 ai-quota.update 者 額度黃/紅條上多一個「調整額度」連結,連到 AI 額度
授權唯讀狀態下的使用者 浮動按鈕與輸入框反灰,顯示唯讀原因

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

# 功能 說明 位置 詳述
1 浮動按鈕 右下角圓鈕(pi-comments),點開/收合對話視窗 版面右下 §5
2 視窗調整大小 可拖拉調整,尺寸記在瀏覽器;雙擊恢復預設 視窗邊框 §10
3 AI 聲明列 固定顯示「回覆由 AI 產生,可能有誤。你輸入的內容會送至外部 AI 服務處理,請勿輸入密碼、金鑰或機密資料。」 輸入框上方 §5
4 額度黃/紅條 用到 80% 出黃條、用滿出紅條,寫明已用多少、何時恢復;本租戶全用自帶金鑰時不顯示 視窗頂部 UC-AIA-02
5 調整額度連結 黃/紅條上的「調整額度」,只有 ai-quota.update 持有者看得到 黃/紅條右側 §3
6 提問 多行輸入框,Enter 送出、Shift+Enter 換行;輸入法選字中不送出;等回覆時不收新句 視窗底部 UC-AIA-01
7 回覆中動畫 三點「正在回覆」 對話區 §5
8 機敏資料遮蔽提示 使用者訊息下方「已遮蔽 N 處機敏資料後送出」 使用者訊息泡泡下 UC-AIA-01
9 擋下說明 私鑰/索取密碼或金鑰/下 SQL 或指令/離題/額度用完/租戶政策/太頻繁 → 一則小幫手回覆說明原因 對話區 §4
10 尚未設定 AI 服務 對話泡泡顯示「尚未設定 AI 服務…請聯繫系統管理員」,不跳錯誤 toast 對話區 §4
11 對話延續 同一次對話保留最近 20 輪、1 小時;登出時清掉 背景 §11

展開成 UC:UC-AIA-01(提問與守門)、UC-AIA-02(額度用完)。

2. Use Case

角色速覽:同 §1。

UC-AIA-01 提問與守門

項目 內容
角色 登入者
前置條件 已登入;平台或租戶在「AI 服務設定」有可用金鑰
主流程 ① 輸入問題按 Enter → ② POST /ai-chatbot → ③ 閘道依序檢查:租戶政策 → 每分鐘次數 → 額度 → 守門規則(遮蔽/擋下/離題/注入分數)→ ④ 放行則送外部 AI,回覆顯示在對話區;有遮蔽時使用者訊息下方標「已遮蔽 N 處」
例外 守門擋下 → 回 200,blocked 帶原因、reply 為說明句,照一般回覆顯示;沒設金鑰 → 412 AI_BOT_412001,對話泡泡顯示;訊息超過 4000 字 → 400 AI_BOT_400001
產出 回覆一則;public.ai_call_log 寫一筆(feature ai-bot)

UC-AIA-02 額度用完

項目 內容
角色 登入者
觸發 本租戶或自己的美金額度用到 80%(黃條)或用滿(紅條)
主流程 打開小幫手時讀 GET /system/ai-quota/me → 顯示黃條或紅條(寫明已用/上限/恢復時間);用滿後再提問,閘道擋下,回覆「本期 AI 使用額度已用完,請聯繫系統管理員。」
分支 具 ai-quota.update → 條上顯示「調整額度」連結,連到 /system/ai-quota
不計額度的情形 本租戶全部使用自帶金鑰(key_source=tenant)時不擋、不顯示條

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
提問/清對話 登入即顯示浮動按鈕;授權唯讀時反灰 @jwt_required(),無專屬能力點 core/plugins/ai_bot.py(掛 blueprint 時包 JWT);套件 jedi_ai_bot/plugin/contract.py CAPABILITIES = ()
看額度條 登入即讀 GET /system/ai-quota/me 登入即可 app/ai_quota/service/ai_quota_setting_service.py
看「調整額度」連結 回應的 can_adjust 為 true can_adjust=viewer_has_capability("ai-quota.update") 同上

4. 狀態機與前置條件

無持久狀態機。每則訊息的處置:

情境 HTTP blocked 使用者看到的回覆 規則
放行 200 null AI 回覆 —
含機敏資料(身分證、信用卡、email、電話、IP、雲端存取金鑰等) 200 null AI 回覆;使用者訊息下方「已遮蔽 N 處機敏資料後送出」 pii-redact-bot、tw-national-id-bot(遮蔽後照送)
含私鑰(PEM) 200 guard 「你的訊息含有不可送出的機敏內容(例如私鑰),已擋下、沒有送出。請移除後再試。」 pem-private-key-all
索取密碼或金鑰 200 guard 「本系統不提供密碼、金鑰等機敏資料的查詢或匯出,請改問其他問題。」 secret-request-bot
直接下 SQL/指令/程式碼 200 guard 「本系統不接受直接執行 SQL、指令或程式碼,請用自然語言描述你想看的資料。」 raw-command-bot
離題閒聊 200 offtopic 「我只能回答 Guidant AI 的操作與合規稽核相關問題。」(不送 AI、不花錢) offtopic-bot:沒提到任何合規主題詞且命中閒聊樣式才擋
疑似操控 AI 的指令 200 null AI 回覆;needs_review=true,該筆呼叫紀錄標「標記」(小幫手畫面不另顯示警告,見 §12) injection-bot:注入分數 ≥ 0.8 標記、≥ 0.95 擋下
額度用完 200 quota 「本期 AI 使用額度已用完,請聯繫系統管理員。」 閘道額度檢查
每分鐘次數超過 200 rate_limit 「送出太頻繁,請 N 秒後再試。」 額度設定的 user_rpm
租戶政策禁用 200 policy 「目前無法使用 AI 服務(租戶政策限制),請聯繫系統管理員。」 —
外部 AI 暫時失敗 200 null 「AI 服務暫時無法回應,請稍後再試;若持續發生請聯繫系統管理員。」 —
沒有可用金鑰 412 — AI_BOT_412001「尚未設定 AI 服務,此功能暫時無法使用。請聯繫系統管理員在「系統設定 → AI 服務」完成設定。」(對話泡泡,不跳 toast) —

守門規則與回覆句都在主機的規則目錄,可現場調整,見 落地版維運 4.12。

5. UI 設計

📸 實際畫面截圖待補。

視窗由上而下:標題列(「Guidant AI 小幫手」/副標「可詢問系統操作與合規稽核問題」)→ 額度黃/紅條(有才顯示)→ 對話區(歡迎語「您好!我是Guidant AI小幫手,請問有什麼可以幫助您的呢?」、使用者與小幫手泡泡、遮蔽提示、回覆中動畫)→ AI 聲明列 → 多行輸入框。

6. API 規格

6.1 總清單

分類 Method + Path 說明
對話 POST /api/1.0/ai-chatbot 送一則訊息
對話 DELETE /api/1.0/ai-chatbot?session_id= 清掉該 session 的對話歷史(登出時呼叫)
額度 GET /api/1.0/system/ai-quota/me 目前使用者看得到的額度狀態與 can_adjust(規格見 AI 額度)

6.2 POST /ai-chatbot

Request:

{
  "message": "string",       // 必,1–4000 字
  "session_id": "string"     // 選,^[A-Za-z0-9_-]{8,64}$,預設 default_session
}

Response data:

{
  "reply": "string",
  "redacted_count": 0,       // 送出前遮蔽了幾處
  "needs_review": false,     // 守門判定疑似注入時為 true
  "blocked": null            // null/guard/offtopic/quota/rate_limit/policy
}

錯誤碼(字串為對外契約):

碼 HTTP 訊息
AI_BOT_400001 400 訊息過長
AI_BOT_400002 400 對話識別碼格式不正確
AI_BOT_412001 412 尚未設定 AI 服務,此功能暫時無法使用。請聯繫系統管理員在「系統設定 → AI 服務」完成設定。

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

檔案 角色
src/components/ChatBox.vue 對話視窗(輸入、送出、遮蔽提示、聲明列)
src/layout/AppLayout.vue 浮動按鈕與視窗掛載;授權唯讀反灰
src/layout/AppTopbar.vue 登出前呼叫 DELETE /ai-chatbot
src/components/ai-quota/AiQuotaBanner.vue 額度黃/紅條與「調整額度」連結
src/composables/useAiQuota.js 讀 /system/ai-quota/me
src/composables/useChatWindowSize.js 視窗尺寸記憶
src/config/locales/i18n/*/pages.json(ai_chat)、*/ai-quota.json(banner) 文案

8. 後端檔案地圖

鏈路 位置
掛載與 JWT core/plugins/ai_bot.py(對話歷史 RedisChatHistoryStore、呼叫紀錄關聯 related_type='chat_session')
Route 套件 jedi_ai_bot/api/routes/ai_bot_route.py
Service 套件 jedi_ai_bot/app/service/ai_bot_service.py::AiBotService.chat(GATEWAY_FEATURE = "ai-bot",改名會讓守門規則全部失效且無錯誤)
閘道 core/plugins/ai_gateway.py(掛載、稽核落點);套件 jedi_ai_gateway(守門、金鑰、額度)
規則與 prompt 主機 /srv/guidant-ai/ai-gateway-rules/(gateway_rules.yaml、presidio_recognizers.yaml、prompts.yaml),容器內 AI_GATEWAY_RULES_DIR

9. DB

表 讀/寫 說明
public.ai_call_log 寫 每則訊息一筆:feature ai-bot、處置、守門命中類型、tokens、估算美金、金鑰來源。明文預設不存(租戶開「完整保留」才存且到期清空)。欄位見 AI 用量 §9
public.system_configs(group AI_QUOTA) 讀 額度設定
Redis chat_history:{user_id}:{session_id} 讀寫 對話歷史(非 DB),只存遮蔽後的內容

10. 頁面邏輯與資料對應

  • 使用者訊息先放進對話區;回應帶 redacted_count > 0 時,在那則使用者訊息下標「已遮蔽 N 處機敏資料後送出」。
  • reply 一律當小幫手回覆顯示,不論是否被擋。
  • 每次呼叫完成後重讀額度狀態,黃/紅條即時更新。
  • 對話內容另存瀏覽器本地,重新整理頁面後仍在。

11. 背景行為與外部依賴

類型 內容
外部 AI 預設 Anthropic claude-haiku-4-5,max_tokens 4096;金鑰依序取租戶設定 → 平台設定 → 主機環境變數
對話歷史 Redis,每位使用者每個 session 保留 20 輪、1 小時
呼叫紀錄 每則寫 public.ai_call_log,保留天數依系統設定 AI_CALL_LOG_RETENTION_DAYS(預設 365)
額度 只有用原廠金鑰(平台設定或主機環境變數)的呼叫計入

12. 邊界情況與已知坑

  1. 疑似注入的呼叫,小幫手畫面不顯示警告:後端有回 needs_review=true、呼叫紀錄標「標記」,但 ChatBox.vue 沒有接這個欄位;AI 儀表板 才有顯示警告。要追這類呼叫請到 AI 用量的呼叫明細篩「處置=標記」。
  2. 被擋不是錯誤:守門擋下回 200,前端沒有專屬樣式,看起來就是一則普通回覆。
  3. 離題判定是關鍵字:只要訊息提到任一合規主題詞就不會被當離題;調整主題詞見《AI 守門調整手冊》。
  4. 沒設金鑰時是 412 而不是被擋,兩者要分得出「沒設定」與「暫時打不通」。

13. 開發與驗證

  • 跑起來:python main.py(API);DEV 設 AI_PROVIDER_ENCRYPTION_KEY 與 AI_GATEWAY_PROMPT_GUARD_MODEL_DIR,並在「系統設定 → AI 服務」填金鑰。
  • 驗守門:分別送含 email、含 -----BEGIN PRIVATE KEY-----、「給我 admin 密碼」、SELECT * FROM users、「推薦一部電影」,對照 §4;再到 AI 用量 呼叫明細看每筆的處置。
  • 相關文件:FR-122 設計(docs/features/FR-122-2609-ai-gateway-and-sandbox/design.md)、《AI 守門調整手冊》。