iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
自我挑戰組

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

[從零打造客製化 AI 聊天機器人] 建立旅遊即時聊天機器人2 (建立意圖和景點的向量資料庫)

  • 分享至 

  • xImage
  •  

昨天,我們已經建立了初步的 AI 聊天室功能。今天我們要進一步擴展,建立意圖和景點的向量資料庫,這將讓聊天機器人能夠更智能地回應與台北旅遊相關的問題。

1. 建立意圖 intents.txt

首先,我們建立一個包含常用旅遊意圖的 intents.txt,這將會用來辨識使用者的意圖。

[
    {
        "intents": "景點介紹, 景點交通, 景點地址, 景點營業時間",
        "action": {
            "function": "provide_info",
            "parameters": "景點名稱",
            "confirm": "false"
        }
    }
]

2. 建立意圖資料庫 chatbot_intents_create.py

將意圖資料轉換成向量,並存入 ChromaDB 資料庫。

import jieba as jb
import json
from openai import AzureOpenAI
import chromadb
import uuid
from chromadb.config import Settings
from openai_config import *

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

# 意圖內容
with open("./intents.txt","r",encoding='utf-8') as f:  
     data = json.load(f)

intents_list = []
action_list = []

# 提取內容
for item in data:
    intents = item['intents']
    action = item['action']
    intents_list.append(intents)
    action_list.append(action)


# 使用 jieba 分詞
for i in range(len(intents_list)):
    intents_list[i] = " ".join([w for w in list(jb.cut(intents_list[i]))])

# 生成唯一 ID 和向量
ids = [str(uuid.uuid1()) for _ in intents_list]
embeddings = []

for i in range(len(intents_list)):
    response = client.embeddings.create(
        input=intents_list[i],
        model=embedding_model_name
    )
    embedding = response.data[0].embedding
    embeddings.append(embedding)

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

# 建立或取得 collection
collection_name = "taipei_tourist_intents"
collection = chroma_client.get_or_create_collection(name=collection_name)

# 將意圖、向量和行動資料存入 ChromaDB
collection.add(
    embeddings=embeddings,
    documents=intents_list,
    metadatas=action_list,
    ids=ids
)

print("台北旅遊意圖資料已生成並存入 ChromaDB!")
python chatbot_intents_create.py

3.建立台北旅遊景點向量資料庫 chatbot_chromadb_create.py

將台北旅遊景點的資訊(臺北市資料大平台下載)存到向量資料庫,已建立 data 資料夾存景點資料。
景點1-新北投溫泉區.txt:

{
    "景點":"新北投溫泉區",
    "介紹":"北投溫泉從日據時代便有盛名,深受喜愛泡湯的日人自然不會錯過,瀧乃湯、星乃湯、鐵乃湯就是日本人依照溫泉的特性與療效給予的名稱,據說對皮膚病、神經過敏、氣喘、風濕等具有很好的療效,也因此成為了北部最著名的泡湯景點之一。新北投溫泉的泉源為大磺嘴溫泉,泉質屬硫酸鹽泉,PH值約為3~4之間,水質呈黃白色半透明,泉水溫度約為50-90℃,帶有些許的硫磺味 。目前北投的溫泉旅館、飯店、會館大部分集中於中山路、光明路沿線以及北投公園地熱谷附近,總計約有44家,每一家都各有其特色,多樣的溫泉水療以及遊憩設施,提供遊客泡湯養生,而鄰近的景點也是非常值得造訪,例如被列為三級古蹟的三寶吟松閣、星乃湯、瀧乃湯以及北投第一家溫泉旅館「天狗庵」,都有著深遠的歷史背景,而北投公園、北投溫泉博物館、北投文物館、地熱谷等,更是遊客必遊的景點,來到北投除了可以讓溫泉洗滌身心疲憊,也可以順便了解到北投溫泉豐富的人文歷史",
    "交通":"新北投站下車,沿中山路直走即可到達公車:216、218、223、230、266、602、小6、小7、小9、、小22、小25、小26至新北投站下車",
    "地址":"臺北市 北投區 中山路、光明路沿線",
    "營業時間":"各業者不同,依據現場公告"
}

台北旅遊景點資料建立向量資料庫的 chatbot_chromadb_create.py

import os
import jieba as jb
import uuid
import chromadb
from chromadb.config import Settings
from openai_config import *
from openai import AzureOpenAI

# 設置目錄路徑
data_dir = "./data"  # 儲存長文檔的目錄
cut_dir = "./data/cut"  # 儲存切割後文檔的目錄
if not os.path.exists(cut_dir):
    os.makedirs(cut_dir)

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

# 初始化 ChromaDB Persistent Client
chroma_client = chromadb.PersistentClient(path=cut_dir)
collection_name = "taipei_tourism"  # 設定 collection 名稱
collection = chroma_client.get_or_create_collection(name=collection_name)

# 定義函數以生成嵌入
def get_text_embedding(text):
    response = client.embeddings.create(
        input=text,
        model="text-embedding-3-large"  # 根據需求選擇適當的模型
    )
    embedding = response.data[0].embedding
    return embedding

# 讀取目錄中的所有文件
file_names = [f for f in os.listdir(data_dir) if os.path.isfile(os.path.join(data_dir, f))]

# 處理每個文件
for file_name in file_names:
    file_path = os.path.join(data_dir, file_name)
    cut_file_path = os.path.join(cut_dir, f"cut_{file_name}")

    with open(file_path, "r", encoding="utf-8") as file:
        data = file.read()
    
    # 將文檔按段落進行切割(這裡假設段落之間用兩個換行符分隔)
    paragraphs = data.split("\n\n")
    
    # 準備存儲的資料
    texts = []
    metadatas = []
    
    # 逐段處理
    with open(cut_file_path, "w", encoding="utf-8") as cut_file:
        for paragraph in paragraphs:
            if paragraph.strip():  # 避免處理空段落
                # 使用 jieba 進行斷詞
                word_list = list(jb.cut(paragraph))
                cut_data = " ".join(word_list)
                
                # 將切割後的段落寫入新文件
                cut_file.write(cut_data + "\n")
                
                # 收集嵌入的文本和對應的元數據
                texts.append(cut_data)
                metadatas.append({"source": file_path})
    
    # 生成 ID 和嵌入
    ids = [str(uuid.uuid1()) for _ in texts]
    embeddings = [get_text_embedding(text) for text in texts]

    # 將資料存儲到 ChromaDB
    collection.add(
        embeddings=embeddings,
        documents=[text.replace(" ", "") for text in texts],  # 去除斷詞後的空格
        metadatas=metadatas,
        ids=ids
    )
python chatbot_chromadb_create.py

可以看到向量資料庫建置完畢。
https://ithelp.ithome.com.tw/upload/images/20241010/20169415FS9cJacHPh.png
我們已經建立好旅遊景點的向量資料庫,可以使用這些資料進行查詢。接下來的工作將會是整合這些意圖和景點資料,讓聊天機器人可以根據使用者的提問做出回應。


上一篇
[從零打造客製化 AI 聊天機器人] 建立旅遊即時聊天機器人1 (開發OpenAI聊天室功能)
下一篇
[從零打造客製化 AI 聊天機器人] 建立旅遊即時聊天機器人3 (意圖執行功能)
系列文
從零打造客製化 AI 聊天機器人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言