DexterSptizu commited on
Commit
cebb474
β€’
1 Parent(s): 24b7df8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +311 -0
app.py ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from langchain_community.document_loaders import PyPDFLoader, TextLoader
3
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
4
+ from langchain_community.embeddings import OpenAIEmbeddings, HuggingFaceEmbeddings
5
+ from langchain_community.vectorstores import FAISS
6
+ from langchain_openai import ChatOpenAI
7
+ from langchain_community.chat_models import ChatOllama
8
+ from langchain.chains import RetrievalQA
9
+ from langchain.prompts import PromptTemplate
10
+ import tempfile
11
+ import os
12
+ import time
13
+
14
+ # Initialize session state
15
+ if 'processed_data' not in st.session_state:
16
+ st.session_state.processed_data = False
17
+ if 'vectorstore' not in st.session_state:
18
+ st.session_state.vectorstore = None
19
+ if 'retriever' not in st.session_state:
20
+ st.session_state.retriever = None
21
+ if 'chain' not in st.session_state:
22
+ st.session_state.chain = None
23
+ if 'chat_history' not in st.session_state:
24
+ st.session_state.chat_history = []
25
+
26
+ st.set_page_config(page_title="πŸ€– RAG Explorer", layout="wide")
27
+ st.title("πŸ€– Retrieval Augmented Generation Explorer")
28
+ st.markdown("""
29
+ Explore how RAG works by uploading documents, configuring the pipeline, and asking questions!
30
+ """)
31
+
32
+ # Main tabs
33
+ setup_tab, chat_tab, learn_tab = st.tabs(["πŸ› οΈ Setup RAG Pipeline", "πŸ’¬ Chat Interface", "πŸ“š Learning Center"])
34
+
35
+ with setup_tab:
36
+ # Pipeline Configuration Section
37
+ st.header("RAG Pipeline Configuration")
38
+
39
+ # Document Processing
40
+ doc_col, process_col = st.columns([1, 1])
41
+
42
+ with doc_col:
43
+ st.subheader("1️⃣ Document Upload")
44
+ file_type = st.selectbox("Select File Type", ["PDF", "Text"])
45
+ uploaded_file = st.file_uploader(
46
+ "Upload your document",
47
+ type=["pdf", "txt"],
48
+ help="Upload a document to create the knowledge base"
49
+ )
50
+
51
+ if uploaded_file:
52
+ try:
53
+ with tempfile.NamedTemporaryFile(delete=False, suffix=f".{file_type.lower()}") as tmp_file:
54
+ tmp_file.write(uploaded_file.getvalue())
55
+ tmp_file_path = tmp_file.name
56
+
57
+ loader = PyPDFLoader(tmp_file_path) if file_type == "PDF" else TextLoader(tmp_file_path)
58
+ documents = loader.load()
59
+ st.success("Document loaded successfully!")
60
+
61
+ # Text splitting configuration
62
+ st.subheader("2️⃣ Text Splitting")
63
+ chunk_size = st.slider("Chunk Size", 100, 2000, 500)
64
+ chunk_overlap = st.slider("Chunk Overlap", 0, 200, 50)
65
+
66
+ text_splitter = RecursiveCharacterTextSplitter(
67
+ chunk_size=chunk_size,
68
+ chunk_overlap=chunk_overlap
69
+ )
70
+ splits = text_splitter.split_documents(documents)
71
+
72
+ # Clean up temp file
73
+ os.unlink(tmp_file_path)
74
+
75
+ with st.expander("Preview Text Chunks"):
76
+ for i, chunk in enumerate(splits[:3]):
77
+ st.markdown(f"**Chunk {i+1}**")
78
+ st.write(chunk.page_content)
79
+ st.markdown("---")
80
+
81
+ st.session_state.splits = splits
82
+
83
+ except Exception as e:
84
+ st.error(f"Error processing document: {str(e)}")
85
+
86
+ with process_col:
87
+ st.subheader("3️⃣ Embedding Configuration")
88
+ embedding_type = st.selectbox(
89
+ "Select Embeddings",
90
+ ["OpenAI", "HuggingFace"],
91
+ help="Choose the embedding model"
92
+ )
93
+
94
+ if embedding_type == "OpenAI":
95
+ api_key = st.text_input("OpenAI API Key", type="password")
96
+ if api_key:
97
+ os.environ["OPENAI_API_KEY"] = api_key
98
+ embeddings = OpenAIEmbeddings()
99
+ else:
100
+ model_name = st.selectbox(
101
+ "Select HuggingFace Model",
102
+ ["sentence-transformers/all-mpnet-base-v2",
103
+ "sentence-transformers/all-MiniLM-L6-v2"]
104
+ )
105
+ embeddings = HuggingFaceEmbeddings(model_name=model_name)
106
+
107
+ st.subheader("4️⃣ LLM Configuration")
108
+ llm_type = st.selectbox(
109
+ "Select Language Model",
110
+ ["OpenAI", "Ollama"],
111
+ help="Choose the Large Language Model"
112
+ )
113
+
114
+ if llm_type == "OpenAI":
115
+ model_name = st.selectbox("Select Model", ["gpt-3.5-turbo", "gpt-4"])
116
+ temperature = st.slider("Temperature", 0.0, 1.0, 0.7)
117
+ if api_key:
118
+ llm = ChatOpenAI(model_name=model_name, temperature=temperature)
119
+ else:
120
+ model_name = st.selectbox("Select Model", ["llama2", "mistral"])
121
+ temperature = st.slider("Temperature", 0.0, 1.0, 0.7)
122
+ llm = ChatOllama(model=model_name, temperature=temperature)
123
+
124
+ if 'splits' in st.session_state:
125
+ if st.button("Create RAG Pipeline"):
126
+ with st.spinner("Creating vector store and RAG pipeline..."):
127
+ # Create vector store
128
+ vectorstore = FAISS.from_documents(
129
+ st.session_state.splits,
130
+ embeddings
131
+ )
132
+ retriever = vectorstore.as_retriever(
133
+ search_type="similarity",
134
+ search_kwargs={"k": 3}
135
+ )
136
+
137
+ # Create RAG chain
138
+ template = """Use the following pieces of context to answer the question at the end.
139
+ If you don't know the answer, just say that you don't know, don't try to make up an answer.
140
+
141
+ {context}
142
+
143
+ Question: {question}
144
+ Answer: """
145
+
146
+ QA_CHAIN_PROMPT = PromptTemplate(
147
+ input_variables=["context", "question"],
148
+ template=template,
149
+ )
150
+
151
+ chain = RetrievalQA.from_chain_type(
152
+ llm=llm,
153
+ chain_type="stuff",
154
+ retriever=retriever,
155
+ chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
156
+ )
157
+
158
+ st.session_state.chain = chain
159
+ st.session_state.processed_data = True
160
+ st.success("RAG pipeline created successfully!")
161
+
162
+ with chat_tab:
163
+ st.header("Chat with your Documents")
164
+
165
+ if not st.session_state.processed_data:
166
+ st.warning("Please set up the RAG pipeline first in the Setup tab!")
167
+ else:
168
+ # Chat interface
169
+ st.markdown("### Ask questions about your documents")
170
+
171
+ # Query input
172
+ query = st.text_input("Enter your question:")
173
+
174
+ if query:
175
+ with st.spinner("Generating response..."):
176
+ try:
177
+ response = st.session_state.chain.invoke(query)
178
+
179
+ # Add to chat history
180
+ st.session_state.chat_history.append(("user", query))
181
+ st.session_state.chat_history.append(("assistant", response['result']))
182
+ except Exception as e:
183
+ st.error(f"Error generating response: {str(e)}")
184
+
185
+ # Display chat history
186
+ st.markdown("### Chat History")
187
+ for role, message in st.session_state.chat_history:
188
+ if role == "user":
189
+ st.markdown(f"**You:** {message}")
190
+ else:
191
+ st.markdown(f"**Assistant:** {message}")
192
+ st.markdown("---")
193
+
194
+ with learn_tab:
195
+ concept_tab, architecture_tab, tips_tab = st.tabs(["Core Concepts", "RAG Architecture", "Best Practices"])
196
+
197
+ with concept_tab:
198
+ st.markdown("""
199
+ ### What is RAG?
200
+
201
+ Retrieval Augmented Generation (RAG) is a technique that enhances Large Language Models by:
202
+ 1. Retrieving relevant information from a knowledge base
203
+ 2. Augmenting the prompt with this information
204
+ 3. Generating responses based on both the question and retrieved context
205
+
206
+ ### Key Components
207
+
208
+ 1. **Document Loader**
209
+ - Imports documents into the system
210
+ - Supports various file formats
211
+
212
+ 2. **Text Splitter**
213
+ - Breaks documents into manageable chunks
214
+ - Maintains context while splitting
215
+
216
+ 3. **Embeddings**
217
+ - Converts text into vector representations
218
+ - Enables semantic search
219
+
220
+ 4. **Vector Store**
221
+ - Stores and indexes embeddings
222
+ - Enables efficient retrieval
223
+
224
+ 5. **Language Model**
225
+ - Generates responses using retrieved context
226
+ - Ensures accurate and relevant answers
227
+ """)
228
+
229
+ with architecture_tab:
230
+ st.markdown("""
231
+ ### RAG Pipeline Architecture
232
+
233
+ ```mermaid
234
+ graph LR
235
+ A[Document] --> B[Text Splitter]
236
+ B --> C[Embeddings]
237
+ C --> D[Vector Store]
238
+ E[Query] --> F[Embedding]
239
+ F --> G[Retriever]
240
+ D --> G
241
+ G --> H[Context]
242
+ H --> I[LLM]
243
+ E --> I
244
+ I --> J[Response]
245
+ ```
246
+
247
+ ### Data Flow
248
+
249
+ 1. **Document Processing**
250
+ - Document β†’ Chunks β†’ Embeddings β†’ Vector Store
251
+
252
+ 2. **Query Processing**
253
+ - Query β†’ Embedding β†’ Similarity Search β†’ Retrieved Context
254
+
255
+ 3. **Response Generation**
256
+ - Context + Query β†’ LLM β†’ Generated Response
257
+ """)
258
+
259
+ with tips_tab:
260
+ st.markdown("""
261
+ ### RAG Best Practices
262
+
263
+ 1. **Document Processing**
264
+ - Choose appropriate chunk sizes
265
+ - Ensure sufficient chunk overlap
266
+ - Maintain document metadata
267
+
268
+ 2. **Retrieval Strategy**
269
+ - Tune the number of retrieved chunks
270
+ - Consider hybrid search approaches
271
+ - Implement relevance filtering
272
+
273
+ 3. **Prompt Engineering**
274
+ - Design clear and specific prompts
275
+ - Include system instructions
276
+ - Handle edge cases gracefully
277
+
278
+ 4. **Performance Optimization**
279
+ - Cache frequent queries
280
+ - Batch process documents
281
+ - Monitor resource usage
282
+
283
+ 5. **Quality Control**
284
+ - Implement answer validation
285
+ - Track retrieval quality
286
+ - Monitor LLM output
287
+ """)
288
+
289
+ # Sidebar
290
+ st.sidebar.header("πŸ“‹ Quick Guide")
291
+ st.sidebar.markdown("""
292
+ 1. **Setup Pipeline**
293
+ - Upload document
294
+ - Configure text splitting
295
+ - Set up embeddings
296
+ - Choose LLM
297
+
298
+ 2. **Ask Questions**
299
+ - Switch to Chat tab
300
+ - Enter your question
301
+ - Review responses
302
+
303
+ 3. **Learn More**
304
+ - Explore concepts
305
+ - Understand architecture
306
+ - Review best practices
307
+ """)
308
+
309
+ # Footer
310
+ st.sidebar.markdown("---")
311
+ st.sidebar.markdown("Made with ❀️ using LangChain 0.3")