1 of 13

信託信用卡智能助理

別再被卡片淹沒——根據使用者的需求,得到有來源的推薦

面試者: 余孟潔

2 of 13

使用者不用先懂卡片分類,只要說出消費情境

02

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

  • 使用者只要輸入一句生活情境,例如:「我常用 LINE Pay、偶爾出國,也常看 Netflix,適合哪張卡?」
  • 助理會回傳 Top 3 候選卡、推薦理由、限制提醒、資料來源、卡片圖片與申辦連結。

LINE Pay

旅遊

哩程

網購

加油

foodpanda

停車

保險

新戶

我想幫他快速找到第一批適合申辦的卡,而不是一張一張比。

既有客戶

當消費習慣改變時,可以重新比較哪張卡現在更適合。

客服 / 行銷

同一套資料也能支援一致、有來源的產品說明。

3 of 13

目標使用者與業務問題定義

03

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

使用者端

優惠太多,期限、通路、上限、登錄條件混在一起,容易看完還是不確定。

業務端

官網資訊完整,但使用者很難跨卡比較;也少了最後一步的申辦引導。

4 of 13

我觀察到的官網體驗痛點

使用者用情境思考,但網站通常用產品頁呈現

04

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

資訊分散

卡片頁、活動頁、條款與申請條件散在不同位置。

分類落差

使用者說「出國、網購、LINE Pay」,不一定知道要點哪個卡別。

理解成本高

回饋率、上限、登錄、期間與排除條件常需要反覆確認。

比較不足

使用者需要自己整理差異,下一步申辦也不一定順。

5 of 13

我的解法與預期價值

自然語言需求解析 + RAG + 混合檢索 + 有根據的回答

05

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

使用者價值

少花時間找資料,直接看到適合情境的候選卡和注意事項。

業務價值

提升產品探索與申辦導流,也降低重複客服問答。

營運價值

把使用者問題轉成情境標籤,累積可分析的需求資料。

使用者需求

理解意圖

混合檢索

重新排序

有來源回答

申辦導流

6 of 13

我做的系統架構

前端負責體驗,後端負責 RAG 流程與可追溯性

06

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

React / Vite

呈現 Markdown 回答、卡片圖片、來源與申辦連結。

FastAPI

提供 /chat、/cards/search、/health,也保留 reindex 能力。

CardRAGEngine

整合意圖判斷、推薦卡片、引用來源與回答格式。

HybridRetriever

用 BM25 + dense + RRF 兼顧關鍵字與語意召回。

Chroma / fallback

可接本機或外部 embedding;沒模型時仍可跑 demo。

7 of 13

架構Overview

07

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

8 of 13

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

資料處理

08

cardlist

JSON

detail

pages

clean /

normalize

semantic

chunks

metadata

BM25 +

Chroma

  • 將每張卡切成可找的 chunks:卡片簡介、主要回饋、適合族群、注意事項、申辦或活動提醒、詳細內容 tabs。
  • 每個 chunk 都帶 metadata:card_id、card_name、category、scenario_tags、source_url、apply_url、image_urls、section。
  • 所以後面不只找得到文字,也能回推是哪張卡、哪個段落、圖片和申辦連結。

9 of 13

我怎麼理解問題與找資料

先判斷使用者想做什麼,再用兩種檢索互補

09

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

Intent

分成推薦、單卡問答、跨卡比較、一般規則問題。

Query expansion

把「出國、網購、外送」這類口語需求展開成官網資料常用詞。

BM25

處理卡名、通路、活動關鍵字;中文用斷詞與欄位加權。

Dense + RRF

補足語意相近但字面不同的問題,再用 RRF 融合排序。

10 of 13

我怎麼找資料與排序

BM25 找精準字,Chroma dense 補語意,RRF 負責融合排名

10

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

Chunks

檢索的單位是 chunks:卡片簡介、主要回饋、適合族群、注意事項、活動提醒與詳細 tabs;每個 chunk 都帶卡名、來源、申辦連結和 section。

BM25

BM25 不是只看正文,也看卡名、分類、情境標籤與段落;例如 card_name 3.5、scenario_tags 2.0,讓明確卡名或通路更容易命中。

Chroma dense

用 OpenAI text-embedding-3-small 查語意相近的 chunks,補足使用者口語和官網用語不同的情況。

RRF + card ranking

BM25 與 dense 各自排序後用 RRF 融合;再把 chunks group 回卡片,依提到的卡、比較題、上下架、情境 priority 與 RRF score 排序。

11 of 13

我怎麼讓 OpenAI 回答但不亂猜

LLM 負責把 citations 講清楚,不負責自己查資料或猜答案

11

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

Prompt inputs

我只把 intent、使用者原問題、已檢索出的 citation context 放進 prompt。

Grounding

Prompt 明確要求:只能根據 context 回答,不能編造回饋率、期限、申請條件或活動限制。

Output

用繁中客服語氣整理推薦理由、限制提醒與下一步行動;來源由 citations 欄位呈現。

Fallback

OpenAI 成功會標記 llm_used;如果呼叫失敗,就回 deterministic template,確保 demo 可執行。

12 of 13

我的技術選擇與取捨

我優先確保 Demo 穩定,同時保留上線後可擴充

12

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

React / Vite + FastAPI

前後端分離,Demo 好展示,之後也容易接正式服務。

BM25 + dense + RRF

避免只靠 LLM;關鍵字命中與語意召回可以互補。

OpenAI API

Demo確定穩定性,後續可與地端模型混和搭用,更可以方便在資料控管與效果間切換。

Deterministic + seed fallback

就算沒有 LLM 或網路,也能完整展示資料到回答的流程。

13 of 13

13

ctbc-card-rag-assistant | FastAPI + React/Vite + RAG

Thanks