完整程式碼 :
# ======================================
# 🧱 STEP 0:安裝必要套件
# ======================================
!pip install -q chromadb sentence-transformers pandas numpy transformers gradio
# ======================================
# 📝 STEP 1:建立 FAQ 資料
# ======================================
import pandas as pd
faq_data = [
{"id":"q1","question":"如何申請退貨?","answer":"請於訂單頁點選退貨申請並上傳商品照片,客服將於 3 個工作天內處理。"},
{"id":"q2","question":"運費如何計算?","answer":"單筆訂單滿 1000 元享免運,未滿則收取 60 元運費。"},
{"id":"q3","question":"可以更改收件地址嗎?","answer":"若訂單尚未出貨,您可在會員中心修改收件地址。"},
{"id":"q4","question":"付款方式有哪些?","answer":"我們支援信用卡、LINE Pay 與貨到付款。"},
{"id":"q5","question":"商品多久可以到貨?","answer":"一般商品 3–5 個工作天內送達,偏遠地區約 7 天。"},
{"id":"q6","question":"如何查詢訂單狀態?","answer":"請至會員中心 → 訂單查詢頁面,即可查看目前狀態。"},
{"id":"q7","question":"發票會如何提供?","answer":"電子發票將寄送至您填寫的 Email,也可於會員中心下載。"},
{"id":"q8","question":"商品有瑕疵怎麼辦?","answer":"請拍照後至客服中心填寫表單,我們將盡快處理換貨或退款。"},
{"id":"q9","question":"有提供客服聯絡方式嗎?","answer":"您可透過線上客服或來電 0800-123-456 與我們聯繫。"},
{"id":"q10","question":"如何使用優惠券?","answer":"在結帳頁面輸入優惠碼,系統會自動折抵。"}
]
df = pd.DataFrame(faq_data)
df.to_csv("faqs.csv", index=False, encoding="utf-8-sig")
print("✅ FAQ 資料建立完成")
# ======================================
# 🧠 STEP 2:建立 Embedding + Chroma DB
# ======================================
import chromadb
from chromadb.config import Settings
from sentence_transformers import SentenceTransformer
import numpy as np
embedder = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
# ✅ 將 question + answer 合併,提升檢索的匹配率
texts = (df["question"] + " " + df["answer"]).tolist()
embeddings = embedder.encode(texts, convert_to_numpy=True).astype("float32")
client = chromadb.Client(Settings(is_persistent=True, persist_directory="./chroma_db"))
if "faq_collection" in [c.name for c in client.list_collections()]:
client.delete_collection("faq_collection")
collection = client.create_collection("faq_collection")
collection.add(
ids=df["id"].tolist(),
documents=texts, # 用合併後的文本
embeddings=embeddings,
metadatas=df.to_dict(orient="records")
)
print("✅ Chroma DB 建立完成,資料筆數:", collection.count())
# ======================================
# 📝 STEP 3:SQLite 對話歷史記錄
# ======================================
import sqlite3, time
conn = sqlite3.connect("chat_memory.db")
cur = conn.cursor()
cur.execute("""CREATE TABLE IF NOT EXISTS chat_history (
user_id TEXT,
role TEXT,
text TEXT,
timestamp REAL
)""")
conn.commit()
def log_message(user_id, role, text):
cur.execute("INSERT INTO chat_history VALUES (?,?,?,?)", (user_id, role, text, time.time()))
conn.commit()
def get_recent_messages(user_id, n=5):
cur.execute("SELECT role,text FROM chat_history WHERE user_id=? ORDER BY timestamp DESC LIMIT ?", (user_id, n))
rows = cur.fetchall()
return list(reversed(rows))
# ======================================
# 🤖 STEP 4:RAG 查詢流程
# ======================================
def rag_answer(query, k=3, score_threshold=14.0):
q_emb = embedder.encode([query], convert_to_numpy=True)
res = collection.query(query_embeddings=q_emb.tolist(), n_results=k, include=["metadatas","distances"])
docs = res["metadatas"][0]
dists = res["distances"][0]
if not docs or dists[0] > score_threshold:
return "查無資料"
top_doc = docs[0]
return top_doc["answer"]
# ======================================
# 💬 STEP 5:互動 Demo(CLI / Colab)
# ======================================
USER_ID = "demo_user"
def chatbot_loop():
print("💬 啟動 FAQ Chatbot(輸入 exit 離開)")
while True:
q = input("你:").strip()
if q.lower() in ["exit","quit"]:
break
log_message(USER_ID, "user", q)
recent = get_recent_messages(USER_ID, n=6)
reply = rag_answer(q)
log_message(USER_ID, "assistant", reply)
print("機器人:", reply)
print("(近期對話)", recent)
# ======================================
# 🧪 STEP 6:測試報表工具
# ======================================
test_data = [
{"query":"我要退貨怎麼申請?","expected":"退貨"},
{"query":"要怎麼查訂單目前的狀態?","expected":"訂單查詢"},
{"query":"發票會怎麼寄給我?","expected":"電子發票"},
{"query":"可以修改收件地址嗎?","expected":"收件地址"},
{"query":"付款方式有什麼?","expected":"信用卡"},
{"query":"多久可以到貨?","expected":"3–5"},
{"query":"商品有瑕疵怎麼辦","expected":"拍照"},
{"query":"免運條件是什麼","expected":"1000"},
{"query":"怎麼用優惠券","expected":"優惠碼"},
{"query":"怎麼聯絡客服","expected":"客服"}
]
results = []
for t in test_data:
ans = rag_answer(t["query"])
acc = t["expected"] in ans
results.append({"query":t["query"],"answer":ans,"expected":t["expected"],"correct":acc})
pd.DataFrame(results).to_csv("test_report.csv", index=False, encoding="utf-8-sig")
print("✅ 測試報表已輸出:test_report.csv")
# ======================================
# 🚀 STEP 7:啟動 Demo
# ======================================
chatbot_loop()