Creating a Retrieval-Augmented Generation (RAG) based chatbot using AWS Bedrock, Streamlit, and TiDB Serverless can significantly enhance the user experience by providing efficient and accurate responses. This tutorial will guide you through the process of building this robust chatbot step-by-step.
Introduction
Combining AWS Bedrock for model management, Streamlit for the frontend interface, and TiDB Serverless for vector storage creates a powerful and scalable RAG-based chatbot. This tutorial assumes you have basic knowledge of Python and database management.
Prerequisites
Before you begin, ensure you have the following:
- A TiDB Serverless cluster with vector search enabled.
- Python 3.8 or higher.
- An AWS account with access to Amazon Bedrock.
Step 1: Setting Up Your Environment
First, clone the GitHub repository containing the necessary files for this project:
git clone https://github.com/Yoshiitaka/TiDB-Bedrock.git
Next, create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activate
Install the required libraries and packages:
pip install -r requirements.txt
Step 2: Configure Environment Variables
Create a .env
file in the root directory with your TiDB and AWS credentials. Use the provided sample-env
file as a reference:
TIDB_HOSTNAME='your_tidb_hostname'
TIDB_USERNAME='your_tidb_username'
TIDB_PASSWORD='your_tidb_password'
TIDB_DATABASE_NAME='your_tidb_database_name'
Step 3: Preparing the Database
Before running the chatbot, you need to prepare the TiDB database by embedding vector data. This step ensures the chatbot can retrieve relevant information efficiently.
Run the preparation script:
python prepare.py
Step 4: Developing the Chatbot
Here’s the complete code to develop the RAG-based chatbot:
import logging
import sys
import streamlit as st
from sqlalchemy import URL
from llama_index.core import VectorStoreIndex
from llama_index.core.settings import Settings
from llama_index.llms.bedrock import Bedrock
from llama_index.vector_stores.tidbvector import TiDBVectorStore
from llama_index.embeddings.bedrock import BedrockEmbedding
import os
from dotenv import load_dotenv
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logger = logging.getLogger()
# Load environment variables
load_dotenv()
tidb_username = os.environ['TIDB_USERNAME']
tidb_password = os.environ['TIDB_PASSWORD']
tidb_host = os.environ['TIDB_HOSTNAME']
tidb_database = os.environ['TIDB_DATABASE_NAME']
# Initialize LlamaIndex with Amazon Bedrock
llm = Bedrock(model="anthropic.claude-3-sonnet-20240229-v1:0")
embed_model = BedrockEmbedding(model="amazon.titan-embed-text-v1")
Settings.llm = llm
Settings.embed_model = embed_model
# Initialize TiDB Vector Store
if 'tidb_vec_index' not in st.session_state:
tidb_connection_url = URL(
"mysql+pymysql",
username=tidb_username,
password=tidb_password,
host=tidb_host,
port=4000,
database=tidb_database,
query={"ssl_verify_cert": True, "ssl_verify_identity": True},
)
tidbvec = TiDBVectorStore(
connection_string=tidb_connection_url,
table_name="llama_index_rag",
distance_strategy="cosine",
vector_dimension=1536,
drop_existing_table=False,
)
tidb_vec_index = VectorStoreIndex.from_vector_store(tidbvec)
st.session_state['tidb_vec_index'] = tidb_vec_index
query_engine = st.session_state['tidb_vec_index'].as_query_engine(streaming=True)
# Streamlit UI Configuration
st.set_page_config(page_title='TiDB & Bedrock DEMO')
def clear_screen():
st.session_state.messages = [{"role": "assistant", "content": "I'm learning about TiDB. Feel free to ask me anything!"}]
with st.sidebar:
st.title('RAG Application with TiDB and Bedrock 🤖')
st.divider()
st.image('public/tidb-logo-with-text.png', caption='TiDB')
st.image('public/bedrock.png', caption='Amazon Bedrock')
st.button('Clear Screen', on_click=clear_screen)
if "messages" not in st.session_state.keys():
st.session_state.messages = [{"role": "assistant", "content": "I'm learning about TiDB. Feel free to ask me anything!"}]
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.write(message["content"])
if prompt := st.chat_input():
with st.chat_message("user"):
st.markdown(prompt)
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("assistant"):
placeholder = st.empty()
full_response = ''
streaming_response = query_engine.query(prompt)
for chunk in streaming_response.response_gen:
full_response += chunk
placeholder.markdown(full_response)
placeholder.markdown(full_response)
st.session_state.messages.append({"role": "assistant", "content": full_response})
Step 5: Running the Application
Start the Streamlit server to interact with the chatbot:
streamlit run main.py
Open your browser and navigate to http://localhost:8501/
to start using the chatbot.
Conclusion
By following this tutorial, you have successfully built a RAG-based chatbot leveraging AWS Bedrock, Streamlit, and TiDB Serverless. This powerful combination provides an efficient and scalable solution for various applications. Explore further by integrating additional features and fine-tuning the models to fit your specific needs.
Feel free to experiment and expand this setup to suit your requirements. Happy coding!
You can also follow tutorials to learn how to build AI apps and how to use TiDB as vector store:
- OpenAI Embedding: use the OpenAI embedding model to generate vectors for text data.
- Image Search: use the OpenAI CLIP model to generate vectors for image and text.
- LlamaIndex RAG with UI: use the LlamaIndex to build an RAG(Retrieval-Augmented Generation) application.
- Chat with URL: use LlamaIndex to build an RAG(Retrieval-Augmented Generation) application that can chat with a URL.
- GraphRAG: 20 lines code of using TiDB Serverless to build a Knowledge Graph based RAG application.
- GraphRAG Step by Step Tutorial: Step by step tutorial to build a Knowledge Graph based RAG application with Colab notebook. In this tutorial, you will learn how to extract knowledge from a text corpus, build a Knowledge Graph, store the Knowledge Graph in TiDB Serverless, and search from the Knowledge Graph.
- Vector Search Notebook with SQLAlchemy: use SQLAlchemy to interact with TiDB Serverless: connect db, index&store data and then search vectors.
- Build RAG with Jina AI Embeddings: use Jina AI to generate embeddings for text data, store the embeddings in TiDB Vector Storage, and search for similar embeddings.