iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0

昨天我們用 Embeddings 建立了一個小小的 FAQ 知識庫,
能輸入一個問題,找到最接近的答案。

今天要做一個「互動式 QA 系統」,
就像一個迷你客服機器人

我們沿用昨天的 FAQ:

faq_data = [
    {"q": "你們的服務時間是?", "a": "我們的客服時間是週一到週五,早上 9 點到下午 6 點。"},
    {"q": "如何重設密碼?", "a": "請到登入頁面點選『忘記密碼』,系統會寄重設連結到你的信箱。"},
    {"q": "支援哪些付款方式?", "a": "我們支援信用卡、ATM 轉帳,以及超商付款。"},
    {"q": "有提供發票嗎?", "a": "是的,所有訂單都會開立電子發票並寄送到你的信箱。"},
]

先幫 FAQ 問題生成向量

import os
from openai import OpenAI
from dotenv import load_dotenv

from numpy import dot
from numpy.linalg import norm

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def get_embedding(text):
    return client.embeddings.create(
        model="text-embedding-3-small",
        input=text
    ).data[0].embedding

for item in faq_data:
    item["embedding"] = get_embedding(item["q"])

再寫一個搜尋函數

def cosine_similarity(a, b):
    return dot(a, b) / (norm(a) * norm(b))

def search_faq(user_question):
    q_embedding = get_embedding(user_question)
    scores = []
    for item in faq_data:
        score = cosine_similarity(q_embedding, item["embedding"])
        scores.append((score, item))
    scores.sort(key=lambda x: x[0], reverse=True)
    return scores[0][1]["a"]  # 回傳分數最高的答案

最後是問答

print("=== FAQ 智慧客服,輸入 exit 離開 ===")

while True:
    user_q = input("你:")
    if user_q.lower() in ["exit", "quit"]:
        print("客服:謝謝使用,再見!")
        break

    answer = search_faq(user_q)
    print("客服:", answer)

來看看
https://ithelp.ithome.com.tw/upload/images/20250927/201693769z3s1wEZQz.png

我們先把FAQ問題預先轉成向量之後存起來,在使用者輸入問題時也把輸入也轉成向量、比較相似度、找到最相關的 FAQ 答案,最後互動式迴圈做成一個小小客服機器人

今天我們完成了一個互動式QA系統,雖然很簡單,但已經能模擬客服的功能。
明天我們會把這個FAQ系統再進一步。結合 Chat 模型,讓 AI 先找到 FAQ 答案,再用更自然的語氣回覆!


上一篇
Day 12:知識要存哪?用 Embeddings 建立 FAQ 知識庫
下一篇
Day 14:講話更自然!結合 Chat 模型強化 FAQ 系統
系列文
AI 三十天,哎呀每天都很難:OpenAI API 生存指南15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言