0
0
Lập trình
NM

Xây Dựng Chatbot với Python và Streamlit

Đăng vào 5 tháng trước

• 5 phút đọc

Chủ đề:

KungFuTech

Hướng Dẫn Xây Dựng Chatbot với Python và Streamlit

Chào mừng bạn đến với hướng dẫn xây dựng một chatbot sử dụng Python và Streamlit. Trong bài viết này, chúng ta sẽ khám phá cách tạo giao diện người dùng cho chatbot RAG (Retrieval-Augmented Generation), xử lý các truy vấn, và tạo câu trả lời bằng API Groq LLM. Hãy cùng bắt đầu!

Mục Đích Chính

  • Tải chỉ mục FAISS và các khối tài liệu đã được xử lý.
  • Nhận đầu vào từ người dùng (câu hỏi).
  • Lấy các khối tài liệu liên quan nhất bằng tìm kiếm ngữ nghĩa.
  • Chuyển ngữ cảnh đã lấy vào Groq LLM để tạo câu trả lời.
  • Hiển thị lịch sử trò chuyện trong một giao diện trò chuyện tùy chỉnh được định dạng bằng CSS.
  • Đảm bảo tính minh bạch bằng cách hiển thị các khối đã lấy.

Cấu Trúc Bài Viết

1. Nhập Khẩu và Cấu Hình

python Copy
import streamlit as st
import pickle
import faiss
from sentence_transformers import SentenceTransformer
from groq import Groq
import os
from dotenv import load_dotenv

load_dotenv()
  • streamlit → khung UI.
  • pickle → tải các khối đã lưu.
  • faiss → tìm kiếm tương tự nhanh trên các embedding.
  • SentenceTransformer → mô hình embedding giống như backend.
  • Groq → client cho LLM.
  • .env loader → tải GROQ_API_KEY một cách an toàn.

Lưu ý: API key được lưu trong các biến môi trường (hoặc Streamlit secrets trong quá trình triển khai).


2. Tải Chỉ Mục và Khối Tài Liệu

python Copy
INDEX_FILE = "faiss_index.bin"
CHUNKS_FILE = "chunks.pkl"
embedder = SentenceTransformer("all-MiniLM-L6-v2")

index = faiss.read_index(INDEX_FILE)
with open(CHUNKS_FILE, "rb") as f:
    chunks = pickle.load(f)
  • Đọc chỉ mục FAISS đã được xây dựng trước đó.
  • Tải các khối tài liệu tương ứng.
  • Đảm bảo mô hình embedding phù hợp với backend.

3. Hàm Tìm Kiếm Ngữ Nghĩa

python Copy
def search_index(query, k=10):
    q_vec = embedder.encode([query])
    D, I = index.search(q_vec, k)
    return [chunks[i] for i in I[0]]
  • Mã hóa truy vấn thành một vector.
  • Tìm kiếm FAISS để lấy k khối tài liệu liên quan nhất.
  • Trả về các khối tài liệu đó để tạo câu trả lời.

4. Tạo Câu Trả Lời Bằng LLM

python Copy
def generate_answer(question, context_chunks):
    context = "\n\n".join(context_chunks)
    prompt = (
        f"Trả lời câu hỏi dựa trên ngữ cảnh đã cho. "
        "Nếu câu hỏi không liên quan đến ngữ cảnh, vui lòng không cố gắng trả lời. "
        "Thay vào đó, hãy trả lời: 'Cơ sở kiến thức của tôi không có thông tin về điều này.'\n\n"
        f"Ngữ cảnh: {context}\n\nCâu hỏi: {question}\nTrả lời:"
    )
    response = client.chat.completions.create(
        messages=[{"role": "user", "content": prompt}],
        model="llama-3.3-70b-versatile",
    )
    return response.choices[0].message.content.strip()
  • Xây dựng một prompt RAG với:
    • Ngữ cảnh đã lấy.
    • Câu hỏi.
  • Gửi tới mô hình LLaMA-3.3-70B của Groq.
  • Trả về một câu trả lời sạch.
  • Đảm bảo rằng nếu không có ngữ cảnh, chatbot sẽ nói:

“Cơ sở kiến thức của tôi không có thông tin về điều này.”


5. Giao Diện Trò Chuyện Tùy Chỉnh (CSS)

python Copy
st.markdown(
    """
<style>
...
</style>
""",
    unsafe_allow_html=True,
)
  • Định nghĩa hai kiểu:
    • Tin nhắn người dùng (màu xanh, căn phải).
    • Tin nhắn bot (màu xám, căn trái).
  • Tạo hiệu ứng bong bóng trò chuyện bên trong một khung cuộn.

6. Giao Diện Ứng Dụng Streamlit

python Copy
st.title("📚 Chatbot RAG")
st.write("Hãy hỏi các câu hỏi dựa trên tài liệu đã được lập chỉ mục.")
  • Thêm tiêu đề và mô tả ngắn gọn.
  • Khởi tạo lịch sử trò chuyện (st.session_state.messages).
  • Hiển thị tất cả các tin nhắn trò chuyện trước đó trong các bong bóng được định dạng.

7. Nhập và Xử Lý Câu Hỏi

python Copy
with st.form(key="chat_form", clear_on_submit=True):
    question = st.text_input("Câu hỏi của bạn:", key="question_input")
    submit_button = st.form_submit_button("Gửi")
  • Nhập liệu cho câu hỏi của người dùng.
  • Khi được gửi:
    • Thêm tin nhắn người dùng vào lịch sử.
    • Lấy các khối qua search_index().
    • Gọi generate_answer() để nhận phản hồi từ LLM.
    • Thêm phản hồi của bot vào lịch sử trò chuyện.

8. Minh Bạch: Các Khối Đã Lấy

python Copy
st.markdown("### 🔍 Các Khối Đã Lấy")
for i, chunk in enumerate(retrieved, 1):
    st.write(f"**Khối {i}:** {chunk[:300]}...")
  • Hiển thị các khối đã lấy thực tế.
  • Giúp debug nếu tài liệu không đúng đang được lấy.
  • Cũng có thể xem trong một expander cho truy vấn cuối cùng.

9. Nút Xóa Trò Chuyện

python Copy
if st.button("Xóa Trò Chuyện"):
    st.session_state.messages = []
    st.rerun()
  • Đặt lại lịch sử trò chuyện.
  • Cho phép bắt đầu một phiên mới.

Quy Trình Làm Việc (Frontend)

  1. Người dùng đặt câu hỏi trong giao diện Streamlit.
  2. Hệ thống mã hóa nó → tìm kiếm FAISS → lấy các khối hàng đầu.
  3. Các khối + câu hỏi được chuyển vào Groq LLM.
  4. Câu trả lời được tạo → hiển thị trong giao diện trò chuyện.
  5. Các khối đã lấy được hiển thị để đảm bảo tính minh bạch.

Những Lưu Ý Quan Trọng

  • Frontend không xây dựng lại chỉ mục. Nó phụ thuộc vào backend (index_docs.py) đã chạy trước đó.
  • Bộ nhớ trò chuyện chỉ dựa trên phiên (xóa khi làm mới).
  • Biến môi trường GROQ_API_KEY phải được thiết lập trong:
    • Tệp .env cục bộ.
    • Bí mật Streamlit (st.secrets["GROQ_API_KEY"]) trong quá trình triển khai.

Các Thực Hành Tốt Nhất

  • Luôn kiểm tra các biến môi trường để đảm bảo an toàn cho API key.
  • Giữ cho mã nguồn rõ ràng và dễ bảo trì bằng cách sử dụng các hàm nhỏ.
  • Thực hiện xử lý lỗi cho các trường hợp không tìm thấy khối tài liệu.

Những Cạm Bẫy Thường Gặp

  • Không xử lý ngữ cảnh dẫn đến câu trả lời không chính xác.
  • Không làm sạch lịch sử trò chuyện có thể dẫn đến thông tin sai lệch.

Mẹo Tối Ưu Hiệu Suất

  • Sử dụng các phiên bản mới nhất của thư viện để cải thiện tốc độ và hiệu suất.
  • Tối ưu hóa mô hình để giảm thời gian phản hồi.

Câu Hỏi Thường Gặp (FAQ)

Q: Làm thế nào để triển khai chatbot trên một máy chủ?
A: Bạn có thể sử dụng Heroku hoặc AWS để triển khai ứng dụng Streamlit của mình.

Q: Có cách nào để cải thiện độ chính xác của câu trả lời không?
A: Có thể cải thiện bằng cách sử dụng mô hình LLM mạnh hơn hoặc đào tạo lại với dữ liệu tốt hơn.

Kết Luận

Trong bài viết này, chúng ta đã tìm hiểu cách xây dựng một chatbot sử dụng Python và Streamlit. Hy vọng rằng bạn đã có thể theo kịp và thực hành thành công. Hãy thử ngay và cho chúng tôi biết trải nghiệm của bạn nhé!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào