使用Qwen-2.5-32b、LangChain和FAISS構建自定義網站聊天機器人

自定義網站聊天機器人

在當今的數字世界中,企業和個人都希望為網站遊客提供即時準確的答案。隨著無縫溝通需求的增加,AI 驅動的聊天機器人已成為使用者互動和在瞬間提供有用資訊的重要工具。聊天機器人可以高效地搜尋、理解和利用網站資料,讓客戶滿意,並提升公司的客戶體驗。在本文中,我們將介紹如何在 Qwen-2.5、LangChain 和 FAISS 的幫助下,構建一個從網站獲取資訊、高效處理資訊並進行有意義對話的聊天機器人。

學習目標

  • 瞭解人工智慧驅動的聊天機器人對企業的重要性。
  • 瞭解如何提取和處理網站資料供聊天機器人使用。
  • 深入瞭解如何使用 FAISS 進行高效文字檢索。
  • 探索擁抱臉嵌入在聊天機器人智慧中的作用。
  • 瞭解如何整合 Qwen-2.5-32b 生成回覆。
  • 使用 Streamlit 構建互動式聊天機器人介面。

為什麼要使用網站聊天機器人?

許多企業都在努力高效處理大量客戶詢問。傳統的客戶支援團隊經常面臨延誤,導致使用者沮喪和運營成本增加。此外,招聘和培訓支援人員的成本也很高,使公司難以有效擴充套件。

聊天機器人可以即時自動回覆使用者問題,無需人工操作。企業能夠大大降低支援成本,增加客戶互動,併為使用者提供即時問題解答。基於人工智慧的聊天機器人能夠處理大量資料,在幾秒鐘內確定正確的資訊,並根據上下文做出正確反應,因此對當今企業非常有益。

網站聊天機器人主要用於電子學習平臺、電子商務網站、客戶支援平臺和新聞網站。

推薦閱讀: 使用 LangChain 和 Qwen-2.5-32B 構建寫作助手

聊天機器人的關鍵元件

  • 非結構化 URL 載入器:從網站中提取內容。
  • 文字分割器:將大型文件分解為易於管理的文字塊。
  • FAISS(Facebook 人工智慧相似性搜尋):高效儲存和檢索文件嵌入。
  • Qwen-2.5-32b:強大的語言模型,可理解查詢並生成響應。
  • Streamlit:建立互動式聊天機器人介面的框架。

AI聊天機器人如何工作?

下面的流程圖解釋了聊天機器人的工作原理。

AI聊天機器人如何工作

使用Qwen-2.5-32b和LangChain構建自定義聊天機器人

現在讓我們看看如何使用 Qwen-2.5-32b、LangChain 和 FAISS 構建自定義網站聊天機器人。

第 1 步:設定基礎

讓我們從設定先決條件開始。

1. 環境設定

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Create a Environment
python -m venv env
# Activate it on Windows
.\env\Scripts\activate
# Activate in MacOS/Linux
source env/bin/activate
# Create a Environment python -m venv env # Activate it on Windows .\env\Scripts\activate # Activate in MacOS/Linux source env/bin/activate
# Create a Environment
python -m venv env
# Activate it on Windows
.\env\Scripts\activate
# Activate in MacOS/Linux
source env/bin/activate

2. 安裝Requirements.txt

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
pip install -r https://raw.githubusercontent.com/Gouravlohar/Chatbot/refs/heads/main/requirements.txt
pip install -r https://raw.githubusercontent.com/Gouravlohar/Chatbot/refs/heads/main/requirements.txt
pip install -r https://raw.githubusercontent.com/Gouravlohar/Chatbot/refs/heads/main/requirements.txt

3. API金鑰設定

API金鑰設定

在 .env 檔案中貼上 API 金鑰。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
API_KEY="Your API KEY PASTE HERE"
API_KEY="Your API KEY PASTE HERE"
API_KEY="Your API KEY PASTE HERE"

現在,讓我們進入實際編碼部分。

第 2 步:處理Windows事件迴圈(為了相容)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import sys
import asyncio
if sys.platform.startswith("win"):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
import sys import asyncio if sys.platform.startswith("win"): asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
import sys
import asyncio
if sys.platform.startswith("win"):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

透過為 asyncio 設定正確的事件迴圈策略,確保與 Windows 相容,因為 Windows 使用不同的預設事件迴圈。

第 3 步:匯入所需庫函式

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import streamlit as st
import os
from dotenv import load_dotenv
import streamlit as st import os from dotenv import load_dotenv
import streamlit as st
import os
from dotenv import load_dotenv
  • Streamlit 用於建立聊天機器人使用者介面。
  • os 用於設定環境變數。
  • dotenv 可幫助從 .env 檔案載入 API 金鑰。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
os.environ["STREAMLIT_SERVER_FILEWATCHER_TYPE"] = "none"
os.environ["STREAMLIT_SERVER_FILEWATCHER_TYPE"] = "none"
os.environ["STREAMLIT_SERVER_FILEWATCHER_TYPE"] = "none"

這將停用 Streamlit 的檔案監視器,透過減少不必要的檔案系統監視來提高效能。

第 4 步:匯入LangChain模組

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import UnstructuredURLLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_groq import ChatGroq
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import FAISS from langchain_community.document_loaders import UnstructuredURLLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_groq import ChatGroq from langchain.chains import create_retrieval_chain from langchain.chains.combine_documents import create_stuff_documents_chain from langchain_core.prompts import ChatPromptTemplate
from langchain_huggingface import HuggingFaceEmbeddings  
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import UnstructuredURLLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_groq import ChatGroq
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
  • HuggingFaceEmbeddings:將文字轉換為向量嵌入。
  • FAISS:根據查詢儲存和檢索相關文件塊。
  • UnstructuredURLLoader:從網頁 URL 載入文字內容。
  • RecursiveCharacterTextSplitter:將大文字分割成小塊進行處理。
  • ChatGroq:使用 Groq API 進行人工智慧響應。
  • create_retrieval_chain:構建一個管道,先檢索相關文件,然後再將其傳遞給 LLM。
  • create_stuff_documents_chain:將檢索到的文件合併為適合 LLM 處理的格式。

第 5 步:載入環境變數

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
load_dotenv()
groq_api_key = os.getenv("API_KEY")
if not groq_api_key:
st.error("Groq API Key not found in .env file")
st.stop()
load_dotenv() groq_api_key = os.getenv("API_KEY") if not groq_api_key: st.error("Groq API Key not found in .env file") st.stop()
load_dotenv()
groq_api_key = os.getenv("API_KEY")
if not groq_api_key:
st.error("Groq API Key not found in .env file")
st.stop()
  • 從 .env 檔案中載入 Groq API 金鑰。
  • 如果缺少金鑰,應用程式會顯示錯誤並停止執行。

1. 載入網站資料的功能

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def load_website_data(urls):
loader = UnstructuredURLLoader(urls=urls)
return loader.load()
def load_website_data(urls): loader = UnstructuredURLLoader(urls=urls) return loader.load()
def load_website_data(urls):
loader = UnstructuredURLLoader(urls=urls)
return loader.load()
  • 使用 UnstructuredURLLoader 從 URL 列表中獲取內容。

2. 分塊檔案功能

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def chunk_documents(docs):
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
return text_splitter.split_documents(docs)
def chunk_documents(docs): text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) return text_splitter.split_documents(docs)
def chunk_documents(docs):
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
return text_splitter.split_documents(docs)
  • 將大段文字分割成 500 個字元的片段,片段間有 50 個字元的重疊,以更好地保留上下文。

3. 建立FAISS向量儲存的功能

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def build_vectorstore(text_chunks):
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
return FAISS.from_documents(text_chunks, embeddings)
def build_vectorstore(text_chunks): embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2") return FAISS.from_documents(text_chunks, embeddings)
def build_vectorstore(text_chunks):
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
return FAISS.from_documents(text_chunks, embeddings)
  • 使用 all-MiniLM-L6-v2 將文字塊轉換為向量嵌入。
  • 將嵌入儲存在 FAISS 向量資料庫中,以便高效檢索。

4. 載入Qwen-2.5-32b的功能

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def load_llm(api_key):
return ChatGroq(groq_api_key=api_key, model_name="qwen-2.5-32b", streaming=True)
def load_llm(api_key): return ChatGroq(groq_api_key=api_key, model_name="qwen-2.5-32b", streaming=True)
def load_llm(api_key):
return ChatGroq(groq_api_key=api_key, model_name="qwen-2.5-32b", streaming=True)
  • 載入用於生成響應的 Groq Qwen-2.5-32b 模型。
  • 啟用流媒體,獲得即時響應體驗。

5. Streamlit UI設定

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
st.title("Custom Website Chatbot(Analytics Vidhya)")
st.title("Custom Website Chatbot(Analytics Vidhya)")
st.title("Custom Website Chatbot(Analytics Vidhya)")

6. 對話歷史記錄設定

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if "conversation" not in st.session_state:
st.session_state.conversation = []
if "conversation" not in st.session_state: st.session_state.conversation = []
if "conversation" not in st.session_state:
st.session_state.conversation = []
  • 將聊天曆史記錄儲存在 st.session_state 中,以便資訊在不同互動中持續存在。

第 6 步:獲取和處理網站資料

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
urls = ["https://www.analyticsvidhya.com/"]
docs = load_website_data(urls)
text_chunks = chunk_documents(docs)
urls = ["https://www.analyticsvidhya.com/"] docs = load_website_data(urls) text_chunks = chunk_documents(docs)
urls = ["https://www.analyticsvidhya.com/"]
docs = load_website_data(urls)
text_chunks = chunk_documents(docs)
  • 從分析 Vidhya 中載入內容。
  • 將內容分割成小塊。

第 7 步:構建FAISS向量儲存

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
vectorstore = build_vectorstore(text_chunks)
retriever = vectorstore.as_retriever()
vectorstore = build_vectorstore(text_chunks) retriever = vectorstore.as_retriever()
vectorstore = build_vectorstore(text_chunks)
retriever = vectorstore.as_retriever()

將處理過的文字塊儲存在 FAISS 中。然後將 FAISS 向量儲存轉換為檢索器,以便根據使用者查詢獲取相關的文字塊。

第 8 步:載入Groq LLM

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
llm = load_llm(groq_api_key)
llm = load_llm(groq_api_key)
llm = load_llm(groq_api_key)

第 9 步:設定檢索鏈

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
system_prompt = (
"Use the given context to answer the question. "
"If you don't know the answer, say you don't know. "
"Use detailed sentences maximum and keep the answer accurate. "
"Context: {context}"
)
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
])
combine_docs_chain = create_stuff_documents_chain(llm, prompt)
qa_chain = create_retrieval_chain(
retriever=retriever,
combine_docs_chain=combine_docs_chain
)
system_prompt = ( "Use the given context to answer the question. " "If you don't know the answer, say you don't know. " "Use detailed sentences maximum and keep the answer accurate. " "Context: {context}" ) prompt = ChatPromptTemplate.from_messages([ ("system", system_prompt), ("human", "{input}"), ]) combine_docs_chain = create_stuff_documents_chain(llm, prompt) qa_chain = create_retrieval_chain( retriever=retriever, combine_docs_chain=combine_docs_chain )
system_prompt = (
"Use the given context to answer the question. "
"If you don't know the answer, say you don't know. "
"Use detailed sentences maximum and keep the answer accurate. "
"Context: {context}"
)
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
])
combine_docs_chain = create_stuff_documents_chain(llm, prompt)
qa_chain = create_retrieval_chain(
retriever=retriever,
combine_docs_chain=combine_docs_chain
)
  • 定義系統提示,以確保準確的、基於上下文的回答。
  • 使用 ChatPromptTemplate 來格式化聊天機器人的互動。
  • 組合檢索到的文件(combine_docs_chain),為 LLM 提供上下文。

該步驟透過將檢索器(FAISS)與 LLM 連線起來建立一個qa_chain ,確保回覆基於檢索到的網站內容。

第 10 步: 顯示聊天曆史記錄

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for msg in st.session_state.conversation:
if msg["role"] == "user":
st.chat_message("user").write(msg["message"])
else:
st.chat_message("assistant").write(msg["message"])
for msg in st.session_state.conversation: if msg["role"] == "user": st.chat_message("user").write(msg["message"]) else: st.chat_message("assistant").write(msg["message"])
for msg in st.session_state.conversation:
if msg["role"] == "user":
st.chat_message("user").write(msg["message"])
else:
st.chat_message("assistant").write(msg["message"])

這將顯示之前的對話資訊。

第 11 步:接受使用者輸入

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
user_input = st.chat_input("Type your message here") if hasattr(st, "chat_input") else st.text_input("Your message:")
user_input = st.chat_input("Type your message here") if hasattr(st, "chat_input") else st.text_input("Your message:")
user_input = st.chat_input("Type your message here") if hasattr(st, "chat_input") else st.text_input("Your message:")
  • 使用 st.chat_input(如果可用)以獲得更好的聊天介面。
  • 為相容性起見,會退回到 st.text_input。

第 12 步:處理使用者查詢

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if user_input:
st.session_state.conversation.append({"role": "user", "message": user_input})
if hasattr(st, "chat_message"):
st.chat_message("user").write(user_input)
else:
st.markdown(f"**User:** {user_input}")
with st.spinner("Processing..."):
response = qa_chain.invoke({"input": user_input})
assistant_response = response.get("answer", "I'm not sure, please try again.")
st.session_state.conversation.append({"role": "assistant", "message": assistant_response})
if hasattr(st, "chat_message"):
st.chat_message("assistant").write(assistant_response)
else:
st.markdown(f"**Assistant:** {assistant_response}")
if user_input: st.session_state.conversation.append({"role": "user", "message": user_input}) if hasattr(st, "chat_message"): st.chat_message("user").write(user_input) else: st.markdown(f"**User:** {user_input}") with st.spinner("Processing..."): response = qa_chain.invoke({"input": user_input}) assistant_response = response.get("answer", "I'm not sure, please try again.") st.session_state.conversation.append({"role": "assistant", "message": assistant_response}) if hasattr(st, "chat_message"): st.chat_message("assistant").write(assistant_response) else: st.markdown(f"**Assistant:** {assistant_response}")
if user_input:
st.session_state.conversation.append({"role": "user", "message": user_input})
if hasattr(st, "chat_message"):
st.chat_message("user").write(user_input)
else:
st.markdown(f"**User:** {user_input}")
with st.spinner("Processing..."):
response = qa_chain.invoke({"input": user_input})  
assistant_response = response.get("answer", "I'm not sure, please try again.")
st.session_state.conversation.append({"role": "assistant", "message": assistant_response})
if hasattr(st, "chat_message"):
st.chat_message("assistant").write(assistant_response)
else:
st.markdown(f"**Assistant:** {assistant_response}")

這段程式碼用於處理聊天機器人中的使用者輸入、檢索和回覆生成。當使用者輸入資訊時,資訊會儲存在 st.session_state.conversation 中,並顯示在聊天介面上。聊天機器人使用 qa_chain.invoke({“input”: user_input}) 處理查詢時,會出現一個載入旋轉器,該旋轉器會檢索相關資訊並生成回覆。助手的回覆是從回覆字典中提取的,確保在找不到回覆時有一條後備資訊。最後,助手的回覆將被儲存和顯示,以保持流暢的互動式聊天體驗。

點選此處從 GitHub 獲取完整程式碼

最終輸出

最終輸出

測試聊天機器人

現在,讓我們在剛剛建立的聊天機器人上測試幾個提示。

提示:Can you list some ways to engage with the Analytics Vidhya community?

響應

測試聊天機器人

提示:what other programs they offers?

響應

測試聊天機器人

結論

人工智慧聊天機器人改變了人們在網際網路上交流的方式。使用 Qwen-2.5-32b 這樣的先進模型,企業和個人可以確保聊天機器人做出適當的回應。隨著技術的不斷進步,在網站上使用人工智慧聊天機器人將是大勢所趨,人們將能輕鬆獲取資訊。

未來,長時間對話、語音提問和與更大的知識庫互動等發展將進一步推動聊天機器人的進步。

  • 聊天機器人從 Analytics Vidhya 網站獲取內容,對其進行處理,並將其儲存到 FAISS 向量資料庫中,以便快速檢索。
  • 它將網站內容分割成 500 個字元的小塊,每塊有 50 個字元的重疊部分,確保在檢索相關資訊時能更好地保留上下文。
  • 聊天機器人使用 Qwen-2.5-32b 生成回覆,利用檢索到的文件塊提供準確的上下文感知答案。
  • 使用者可以使用 Streamlit 中的聊天介面與聊天機器人進行互動,並儲存對話歷史記錄以實現無縫互動。

常見問題

Q1. 該聊天機器人如何從網站獲取資料?

A. 它使用 LangChain 的 UnstructuredURLLoader 從指定 URL 提取內容。

Q2. 為什麼在這個聊天機器人中使用 FAISS?

A. FAISS(Facebook 人工智慧相似性搜尋)有助於根據使用者查詢高效地儲存和檢索相關文字塊。

Q3. 使用什麼模型生成回覆?

A. 聊天機器人使用 Groq 的 Qwen-2.5-32B(一種功能強大的 LLM),根據檢索到的網站內容生成答案。

Q4. 這個聊天機器人可以擴充套件到多個網站嗎?

A. 可以!只需修改 urls 列表以包含更多網站,聊天機器人就會從中獲取、處理和檢索資訊。

Q5. 聊天機器人如何確保回覆準確無誤?

A. 它採用檢索-增強生成(RAG)方法,即先檢索相關網站資料,然後使用 LLM 生成答案。

評論留言