iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
自我挑戰組

從零打造客製化 AI 聊天機器人系列 第 28

[從零打造客製化 AI 聊天機器人] 建立旅遊即時聊天機器人3 (意圖執行功能)

  • 分享至 

  • xImage
  •  

上一回,我們已經完成意圖和景點資料的向量資料庫建立。今天,我們將進一步實作意圖執行的函式,讓系統能夠根據使用者的輸入,提供相應的旅遊資訊。

1. 建立意圖執行函式

主要的意圖執行邏輯,該函式會使用 Azure OpenAI 生成文字嵌入,並透過 ChromaDB 來查詢景點的相關資料:

# chatbot_intents_function.py
import chromadb
from openai import AzureOpenAI
from openai_config import *
import json 

# 初始化 ChromaDB 客戶端
chroma_client = chromadb.PersistentClient(path="./data/cut")
collection_name = "taipei_tourism"
collection = chroma_client.get_collection(name=collection_name)

# 初始化 Azure OpenAI 客戶端
client = AzureOpenAI(
    azure_endpoint=azure_endpoint,
    api_key=api_key,
    api_version=api_version
)

# 生成嵌入向量
def get_embedding(text):
    response = client.embeddings.create(
        input=text,
        model="text-embedding-3-large"  
    )
    return response.data[0].embedding

# 查詢景點資訊
def get_attraction_info(parameters, entity):
    # 生成景點名稱的嵌入向量
    embedding = get_embedding(entity)
    result = collection.query(query_embeddings=[embedding], n_results=1)

    if not result['documents']:
        return False, f"抱歉,找不到關於 {entity} 的資訊。"
    
    # 將查詢結果中的 JSON 字符串轉為 Python 字典
    json_text = result['documents'][0][0]
    json_data = json.loads(json_text)

    # 根據意圖參數處理結果
    info = ""
    found = True

    if "介紹" in parameters:
        intro = json_data.get('介紹', '暫無介紹資料')
        info += f"{entity}的介紹:{intro}\n"
    if "交通" in parameters:
        transport = json_data.get('交通', '暫無交通資訊')
        info += f"{entity}的交通資訊:{transport}\n"
    if "地址" in parameters:
        address = json_data.get('地址', '暫無地址資訊')
        info += f"{entity}的地址是:{address}\n"
    if "營業時間" in parameters:
        hours = json_data.get('營業時間', '暫無營業時間資訊')
        info += f"{entity}的營業時間是:{hours}\n"
    if "照片" in parameters:
        photo_url = json_data.get('照片', '暫無照片')
        info += f"{entity}的照片:{photo_url}\n"

    if not info:
        found = False
        info = "未找到符合條件的相關資訊,請提供更多具體內容。"

    return found, info

# 意圖分析函數
def detect_intent(user_input):
    if "介紹" in user_input or "景點" in user_input:
        return "景點介紹"
    elif "交通" in user_input or "怎麼去" in user_input:
        return "交通資訊"
    elif "地址" in user_input或 "位置" in user_input:
        return "景點地址"
    elif "營業時間" in user_input或 "開放時間" in user_input:
        return "營業時間"
    elif "照片" in user_input或 "圖片" in user_input:
        return "景點照片"
    else:
        return "未知意圖"

# 根據使用者輸入提供資訊
def provide_info(user_input, collection):
    intent = detect_intent(user_input)
    place_name = user_input.split()[0]  # 假設景點名稱為輸入的第一個詞

    # 根據意圖設定查詢參數
    parameters = []
    if intent == "景點介紹":
        parameters.append("介紹")
    elif intent == "交通資訊":
        parameters.append("交通")
    elif intent == "景點地址":
        parameters.append("地址")
    elif intent == "營業時間":
        parameters.append("營業時間")
    elif intent == "景點照片":
        parameters.append("照片")
    else:
        return "抱歉,我無法理解您的請求,請您再具體說明。"

    # 調用查詢函數
    found, response = get_attraction_info(parameters, place_name)
    return response

2. 意圖執行功能整合進 FastAPI 和 WebSocket 實作即時聊天功能

意圖執行功能整合進 FastAPI 框架,並通過 WebSocket 實現即時互動:

from fastapi import FastAPI, WebSocket
from chatbot_intents_function import get_attraction_info, get_embedding, provide_info
from chromadb import PersistentClient
from openai import AzureOpenAI
from openai_config import *

# 初始化 FastAPI
app = FastAPI()

# 初始化 ChromaDB 客戶端和 collection
chroma_client = PersistentClient(path="./data/cut")
collection_name_intents = "taipei_tourist_intents"
intents_collection = chroma_client.get_collection(name=collection_name_intents)

collection_name_tourism = "taipei_tourism"
tourism_collection = chroma_client.get_collection(name=collection_name_tourism)

# 初始化 Azure OpenAI 客戶端
client = AzureOpenAI(
    azure_endpoint=azure_endpoint,
    api_key=api_key,
    api_version=api_version
)

# 意圖識別函數
def detect_intent(user_input):
    user_input_embedding = get_embedding(user_input)
    result = intents_collection.query(
        query_embeddings=[user_input_embedding], n_results=1
    )
    if not result["documents"]:
        return None, "未能識別意圖。"

    # 取得意圖和相應的執行動作
    intents = result["documents"][0][0]
    action = result["metadatas"][0][0]["function"]
    return intents, action

# 處理使用者輸入
def process_user_input(user_input):
    intents, action = detect_intent(user_input)

    if not intents:
        return action  # 返回錯誤訊息

    # 提供景點資訊
    if action == "provide_info":
        response = provide_info(user_input, tourism_collection)
        return response
    
    return "請輸入其他詳細資訊"

@app.websocket("/tourism/chatbot")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:

             # 接收來自前端的訊息
            user_input = await websocket.receive_text()
            print("user_input", user_input)

            # 處理使用者輸入
            response = process_user_input(user_input)
            print("response", response)
            
            # 將回應訊息發送至前端
            await websocket.send_text(response)

    except Exception as e:
        print(f"WebSocket connection closed with exception: {e}")

https://ithelp.ithome.com.tw/upload/images/20241011/20169415fFZCvdMqYH.pnghttps://ithelp.ithome.com.tw/upload/images/20241011/20169415rzITKR0wVx.png

將意圖解析和景點資料查詢的邏輯結合在一起,使用 Azure OpenAI 生成嵌入向量並透過 ChromaDB 查詢資料庫的相似度,再透過 FastAPI 和 WebSocket 的結合,實現即時互動,讓用戶可以在旅遊過程中方便地查詢景點資訊。
https://ithelp.ithome.com.tw/upload/images/20241011/20169415Xc30OMmTU7.png


上一篇
[從零打造客製化 AI 聊天機器人] 建立旅遊即時聊天機器人2 (建立意圖和景點的向量資料庫)
下一篇
[從零打造客製化 AI 聊天機器人] 建立旅遊即時聊天機器人4 (多人聊天)
系列文
從零打造客製化 AI 聊天機器人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言