APrmn8 commited on
Commit
132f0a2
·
verified ·
1 Parent(s): 010ad71
Files changed (2) hide show
  1. app.py +226 -264
  2. requirements.txt +6 -7
app.py CHANGED
@@ -1,279 +1,241 @@
1
- import os
2
  import gradio as gr
3
- from datasets import Dataset
 
 
 
 
 
 
4
  from langchain.text_splitter import RecursiveCharacterTextSplitter
5
  from langchain_community.embeddings import HuggingFaceEmbeddings
6
  from langchain_community.vectorstores import FAISS
7
- from langchain_community.llms import HuggingFaceHub
8
  from langchain.chains import RetrievalQA
9
- from langchain.agents import AgentExecutor, create_react_agent, Tool
10
- from langchain_core.prompts import PromptTemplate
11
- from langchain_core.messages import SystemMessage
12
- from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
13
- from langchain_core.documents import Document
14
- import arxiv # Import library arxiv
15
-
16
- # --- Konfigurasi dan Setup Awal ---
17
- # Pastikan Anda memiliki token API Hugging Face.
18
- # Anda bisa mendapatkannya dari https://huggingface.co/settings/tokens
19
- # Simpan sebagai variabel lingkungan di Hugging Face Spaces (Settings -> Repository secrets)
20
- # dengan nama HUGGINGFACEHUB_API_TOKEN.
21
- os.environ["HUGGINGFACEHUB_API_TOKEN"] = "HUGGINGFACEHUB_API_TOKEN" # Jangan hardcode di sini!
22
-
23
- # Periksa apakah token API telah disetel
24
- if "HUGGINGFACEHUB_API_TOKEN" not in os.environ:
25
- print("WARNING: Variabel lingkungan 'HUGGINGFACEHUB_API_TOKEN' tidak disetel.")
26
- print("Silakan setel token Anda sebagai 'Repository secret' di Hugging Face Spaces.")
27
- # Jika token tidak disetel, kita akan menggunakan placeholder untuk LLM
28
- # Untuk demo ini, jika token tidak ada, LLM akan menghasilkan pesan peringatan.
29
-
30
- # --- Fungsi untuk Mengambil Paper dari ArXiv ---
31
- def fetch_papers_from_arxiv(query: str, max_results: int = 5) -> list[Document]:
32
- """
33
- Mengambil paper dari arXiv berdasarkan query pencarian.
34
- Mengembalikan list objek Document Langchain.
35
- """
36
- client = arxiv.Client()
37
- search_query = arxiv.Search(
38
- query=query,
39
- max_results=max_results,
40
- sort_by=arxiv.SortCriterion.Relevance,
41
- sort_order=arxiv.SortOrder.Descending
42
- )
43
-
44
- papers = []
45
- try:
46
- for result in client.results(search_query):
47
- # Menggabungkan judul, abstrak, dan penulis sebagai konten dokumen
48
- # Anda bisa memilih untuk mengunduh full text jika diperlukan,
49
- # namun abstrak biasanya cukup untuk RAG awal.
50
- content = f"Title: {result.title}\nAuthors: {', '.join([a.name for a in result.authors])}\nAbstract: {result.summary}"
51
 
52
- # Menambahkan metadata seperti URL dan ID ArXiv
53
- metadata = {
54
- "title": result.title,
55
- "authors": [a.name for a in result.authors],
56
- "published": result.published.strftime("%Y-%m-%d"),
57
- "arxiv_url": result.entry_id,
58
- "pdf_url": result.pdf_url
59
- }
60
- papers.append(Document(page_content=content, metadata=metadata))
61
- print(f"Berhasil mengambil {len(papers)} paper dari arXiv untuk query: '{query}'")
62
- except Exception as e:
63
- print(f"Gagal mengambil paper dari arXiv: {e}")
64
- print("Pastikan ada koneksi internet dan query valid.")
65
- return papers
66
-
67
- # --- 1. Memuat Data Paper AI dari ArXiv ---
68
- # Ganti dummy data dengan paper nyata dari arXiv.
69
- # Anda bisa menyesuaikan query dan jumlah hasil yang diinginkan.
70
- arxiv_search_query = "large language models" # Contoh query pencarian
71
- num_arxiv_papers = 5 # Jumlah paper yang ingin diambil
72
- documents = fetch_papers_from_arxiv(arxiv_search_query, num_arxiv_papers)
73
-
74
- # Jika tidak ada dokumen yang diambil, gunakan dummy data sebagai fallback
75
- if not documents:
76
- print("Tidak ada paper yang diambil dari arXiv. Menggunakan dummy data sebagai fallback.")
77
- dummy_ai_papers_content = [
78
- """
79
- Paper Title: Deep Learning for Natural Language Processing: A Review
80
- Abstract: This paper reviews the advancements in deep learning techniques applied to Natural Language Processing (NLP). We discuss various architectures such as Recurrent Neural Networks (RNNs), Convolutional Neural Networks (CNNs), and Transformers, highlighting their impact on tasks like machine translation, sentiment analysis, and text summarization. The rise of large language models (LLMs) has significantly pushed the boundaries of what's possible in NLP.
81
- Keywords: Deep Learning, NLP, Transformers, RNN, CNN, LLM, Machine Translation, Sentiment Analysis.
82
- """,
83
- """
84
- Paper Title: Reinforcement Learning in Robotics: Challenges and Future Directions
85
- Abstract: Reinforcement Learning (RL) has shown promise in enabling robots to learn complex behaviors through interaction with their environment. This paper explores the current challenges in applying RL to robotics, including sample efficiency, sim-to-real transfer, and safety. We also discuss potential future directions and the integration of RL with other AI paradigms like computer vision.
86
- Keywords: Reinforcement Learning, Robotics, AI, Sample Efficiency, Sim-to-Real, Computer Vision.
87
- """,
88
  """
89
- Paper Title: Explainable AI (XAI): Methods and Applications
90
- Abstract: As AI models become more complex, the need for Explainable AI (XAI) grows. This paper surveys various XAI methods, including LIME, SHAP, and attention mechanisms, which aim to make AI decisions more transparent and understandable to humans. We examine their applications in critical domains like healthcare and finance, where interpretability is paramount.
91
- Keywords: Explainable AI, XAI, Interpretability, LIME, SHAP, Healthcare AI, Finance AI.
92
- """,
93
  """
94
- Paper Title: Federated Learning: A Privacy-Preserving Machine Learning Paradigm
95
- Abstract: Federated Learning (FL) is an emerging machine learning approach that enables collaborative model training across decentralized devices or organizations while keeping raw data localized. This paper discusses the architectural principles of FL, its privacy benefits, and challenges such as communication overhead, heterogeneity, and security vulnerabilities.
96
- Keywords: Federated Learning, FL, Privacy, Decentralized AI, Machine Learning, Security.
97
- """,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  """
99
- Paper Title: Generative Adversarial Networks (GANs): Architectures and Applications
100
- Abstract: Generative Adversarial Networks (GANs) are a class of AI algorithms used in unsupervised machine learning, implemented by a system of two neural networks contesting with each other in a zero-sum game framework. This paper reviews the foundational architectures of GANs, including DCGAN, CycleGAN, and StyleGAN, and explores their diverse applications in image synthesis, data augmentation, and anomaly detection.
101
- Keywords: GANs, Generative Models, Image Synthesis, Anomaly Detection, Neural Networks.
102
  """
103
- ]
104
- documents = [Document(page_content=text) for text in dummy_ai_papers_content]
105
-
106
-
107
- print(f"Jumlah dokumen awal: {len(documents)}")
108
-
109
- # --- 2. Pemisahan Teks (Text Splitting) ---
110
- # Memecah dokumen menjadi chunks yang lebih kecil untuk retrieval yang lebih baik.
111
- text_splitter = RecursiveCharacterTextSplitter(
112
- chunk_size=1000,
113
- chunk_overlap=200,
114
- length_function=len,
115
- add_start_index=True,
116
- )
117
- chunks = text_splitter.split_documents(documents)
118
- print(f"Jumlah chunks setelah pemisahan: {len(chunks)}")
119
-
120
- # --- 3. Embeddings ---
121
- # Menginisialisasi model embedding dari Hugging Face.
122
- # Ini akan mengunduh model jika belum ada.
123
- embedding_model_name = "sentence-transformers/all-MiniLM-L6-v2"
124
- embeddings = HuggingFaceEmbeddings(model_name=embedding_model_name)
125
-
126
- # --- 4. Vector Store (FAISS) ---
127
- # Membuat indeks FAISS dari chunks dan embeddings.
128
- print("Membuat indeks FAISS... Ini mungkin butuh waktu tergantung ukuran data.")
129
- vectorstore = FAISS.from_documents(chunks, embeddings)
130
- print("Indeks FAISS berhasil dibuat.")
131
-
132
- # --- 5. Inisialisasi LLM ---
133
- # Menggunakan HuggingFaceHub untuk LLM.
134
- # Anda bisa menggantinya dengan model lokal atau API LLM lainnya jika diinginkan.
135
- if "HUGGINGFACEHUB_API_TOKEN" in os.environ:
136
- llm = HuggingFaceHub(
137
- repo_id="google/gemma-7b-it", # Contoh model yang bagus
138
- model_kwargs={"temperature": 0.1, "max_length": 512}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  )
140
- else:
141
- # Placeholder LLM jika token tidak disetel
142
- class DummyLLM:
143
- def invoke(self, prompt, **kwargs):
144
- return "Maaf, LLM tidak dapat diinisialisasi karena HUGGINGFACEHUB_API_TOKEN tidak disetel. Silakan setel token Anda."
145
- def __call__(self, prompt, **kwargs):
146
- return self.invoke(prompt, **kwargs)
147
- llm = DummyLLM()
148
- print("Menggunakan DummyLLM karena HUGGINGFACEHUB_API_TOKEN tidak disetel.")
149
-
150
-
151
- # --- 6. Membuat Chain RAG (RetrievalQA) ---
152
- # Chain ini akan mengambil dokumen yang relevan dan meneruskannya ke LLM untuk menghasilkan jawaban.
153
- qa_chain = RetrievalQA.from_chain_type(
154
- llm=llm,
155
- chain_type="stuff", # "stuff" menggabungkan semua dokumen ke dalam satu prompt
156
- retriever=vectorstore.as_retriever(),
157
- return_source_documents=True, # Untuk melihat dokumen sumber yang diambil
158
- )
159
-
160
- # --- 7. Membuat Agentic RAG Logic ---
161
- # Kita akan membuat "tool" yang membungkus chain RAG kita.
162
- # Agent kemudian dapat memutuskan kapan harus menggunakan tool ini.
163
- tool_description = (
164
- "Berguna untuk menjawab pertanyaan tentang paper Artificial Intelligence, "
165
- "termasuk konsep, metodologi, tantangan, dan aplikasi yang dibahas dalam paper."
166
- "Gunakan tool ini untuk mengambil informasi dari basis pengetahuan paper AI."
167
- )
168
-
169
- tools = [
170
- Tool(
171
- name="AI_Paper_Retriever",
172
- func=qa_chain.invoke, # Menggunakan .invoke() untuk Langchain Expression Language
173
- description=tool_description,
174
- return_direct=False # Agent akan memproses output tool ini
175
  )
176
- ]
177
-
178
- # Prompt untuk Agent
179
- # Agent akan memutuskan tool mana yang akan digunakan berdasarkan prompt ini.
180
- # Kita menggunakan ReAct (Reasoning and Acting) prompt.
181
- agent_prompt = ChatPromptTemplate.from_messages(
182
- [
183
- SystemMessage(
184
- content=(
185
- "Anda adalah asisten AI yang sangat membantu dan berpengetahuan luas, "
186
- "khususnya dalam bidang Artificial Intelligence dan paper penelitian terkait."
187
- "Tugas utama Anda adalah membantu pengguna memahami dan menavigasi informasi dari paper AI."
188
- "Gunakan tool 'AI_Paper_Retriever' jika pertanyaan pengguna berkaitan dengan konten paper AI "
189
- "atau memerlukan informasi spesifik dari basis pengetahuan Anda."
190
- "Jika pertanyaan bersifat umum atau tidak memerlukan pengambilan data, jawablah langsung."
191
- "Selalu berikan jawaban yang komprehensif dan relevan."
192
- )
193
- ),
194
- MessagesPlaceholder(variable_name="chat_history"),
195
- ("human", "{input}"),
196
- MessagesPlaceholder(variable_name="tools"),
197
- MessagesPlaceholder(variable_name="agent_scratchpad"),
198
- MessagesPlaceholder(variable_name="tool_names"),
199
- ]
200
- )
201
-
202
- # Membuat Agent
203
- # Menggunakan create_react_agent untuk agent yang berbasis ReAct
204
- agent = create_react_agent(llm, tools, agent_prompt)
205
-
206
- # Membuat Agent Executor
207
- # Ini adalah runtime untuk agent, yang menjalankan loop pemikiran-aksi.
208
- agent_executor = AgentExecutor(
209
- agent=agent,
210
- tools=tools,
211
- verbose=True, # Untuk melihat langkah-langkah pemikiran agent
212
- handle_parsing_errors=True, # Menangani kesalahan parsing agent
213
- max_iterations=5 # Batasi iterasi untuk menghindari loop tak terbatas
214
- )
215
-
216
- # --- 8. Gradio Interface ---
217
- # Fungsi untuk memproses pertanyaan pengguna menggunakan agent
218
- def process_query(query, chat_history_tuples):
219
- # Mengubah riwayat chat dari Gradio ke format Langchain
220
- from langchain_core.messages import HumanMessage, AIMessage
221
- formatted_chat_history = []
222
- for human_msg, ai_msg in chat_history_tuples:
223
- formatted_chat_history.append(HumanMessage(content=human_msg))
224
- formatted_chat_history.append(AIMessage(content=ai_msg))
225
-
226
- try:
227
- # Panggil agent executor
228
- response = agent_executor.invoke({
229
- "input": query,
230
- "chat_history": formatted_chat_history
231
- })
232
- answer = response["output"]
233
-
234
- # Jika agent menggunakan tool RAG, kita bisa menampilkan sumbernya juga
235
- # Ini memerlukan sedikit modifikasi jika Anda ingin menampilkan sumber
236
- # secara eksplisit dari dalam agent_executor.invoke().
237
- # Untuk kesederhanaan, kita hanya akan menampilkan jawaban agent.
238
- # Jika Anda ingin menampilkan sumber, Anda perlu memodifikasi tool
239
- # atau agent_executor untuk mengembalikan informasi sumber secara eksplisit.
240
-
241
- except Exception as e:
242
- answer = f"Terjadi kesalahan saat memproses pertanyaan: {e}"
243
- if "HUGGINGFACEHUB_API_TOKEN" not in os.environ:
244
- answer += "\nPastikan HUGGINGFACEHUB_API_TOKEN Anda disetel dengan benar."
245
-
246
- return answer
247
-
248
- # Membuat antarmuka Gradio
249
- with gr.Blocks() as demo:
250
- gr.Markdown("# Agentic RAG untuk Literasi Paper AI")
251
- gr.Markdown("Tanyakan apa pun tentang paper AI yang diambil dari arXiv.")
252
-
253
- chatbot = gr.Chatbot(label="Percakapan")
254
- msg = gr.Textbox(label="Pertanyaan Anda")
255
- clear = gr.Button("Clear")
256
-
257
- def user_message(user_message, history):
258
- return "", history + [[user_message, None]]
259
-
260
- def bot_response(history):
261
- query = history[-1][0]
262
- # Mengirimkan riwayat chat tanpa respons bot terakhir yang masih None
263
- chat_history_for_agent = history[:-1]
264
- response = process_query(query, chat_history_for_agent)
265
- history[-1][1] = response
266
- return history
267
-
268
- msg.submit(user_message, [msg, chatbot], [msg, chatbot], queue=False).then(
269
- bot_response, chatbot, chatbot
270
  )
271
- clear.click(lambda: None, None, chatbot, queue=False)
272
 
273
- # Jalankan aplikasi Gradio
274
- # Untuk menjalankan di Hugging Face Spaces, Anda mungkin perlu mengatur share=True
275
- # atau cukup jalankan tanpa share=True jika sudah di dalam lingkungan Space.
276
  if __name__ == "__main__":
277
- print("\nAplikasi Gradio siap dijalankan. Buka URL yang diberikan setelah 'Running on local URL:'.")
278
- print("Jika Anda melihat pesan peringatan tentang HUGGINGFACEHUB_API_TOKEN, pastikan Anda menyetelnya.")
279
- demo.launch(debug=True) # debug=True untuk melihat log di konsol
 
 
1
+ # app.py
2
  import gradio as gr
3
+ import os
4
+ import re
5
+ import shutil
6
+ import torch
7
+
8
+ # LangChain imports
9
+ from langchain_community.document_loaders import ArxivLoader, PyPDFLoader
10
  from langchain.text_splitter import RecursiveCharacterTextSplitter
11
  from langchain_community.embeddings import HuggingFaceEmbeddings
12
  from langchain_community.vectorstores import FAISS
 
13
  from langchain.chains import RetrievalQA
14
+ from langchain_community.llms import HuggingFacePipeline
15
+ from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
16
+
17
+ # --- Configuration ---
18
+ ARXIV_DIR = "./arxiv_papers" # Directory to save downloaded papers
19
+ CHUNK_SIZE = 500 # Characters per chunk
20
+ CHUNK_OVERLAP = 50 # Overlap between chunks
21
+ EMBEDDING_MODEL_NAME = 'all-MiniLM-L6-v2'
22
+ LLM_MODEL_NAME = "google/flan-t5-small"
23
+
24
+ # --- RAGAgent Class ---
25
+
26
+ class RAGAgent:
27
+ def __init__(self):
28
+ self.embedding_model = None
29
+ self.llm = None
30
+ self.vectorstore = None
31
+ self.qa_chain = None
32
+ self.is_initialized = False
33
+
34
+ def _load_models(self):
35
+ """Loads the embedding and generation models if not already loaded."""
36
+ if self.embedding_model is None:
37
+ print(f"Loading Embedding Model: {EMBEDDING_MODEL_NAME}...")
38
+ self.embedding_model = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME)
39
+
40
+ if self.llm is None:
41
+ print(f"Loading LLM Model: {LLM_MODEL_NAME}...")
42
+ tokenizer = AutoTokenizer.from_pretrained(LLM_MODEL_NAME)
43
+ model = AutoModelForSeq2SeqLM.from_pretrained(LLM_MODEL_NAME)
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ # Determine device for pipeline
46
+ device = 0 if torch.cuda.is_available() else -1
47
+
48
+ # Create a Hugging Face pipeline for text generation
49
+ text_generation_pipeline = pipeline(
50
+ "text2text-generation",
51
+ model=model,
52
+ tokenizer=tokenizer,
53
+ max_new_tokens=150, # Set a default max_new_tokens for the pipeline
54
+ min_length=20,
55
+ num_beams=5,
56
+ early_stopping=True,
57
+ device=device
58
+ )
59
+ self.llm = HuggingFacePipeline(pipeline=text_generation_pipeline)
60
+
61
+ self.is_initialized = True
62
+
63
+ def initialize_knowledge_base(self, arxiv_query: str, max_papers: int = 5) -> str:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  """
65
+ Initializes the knowledge base by downloading, extracting, and chunking
66
+ arXiv papers using LangChain components, then building a FAISS vectorstore.
 
 
67
  """
68
+ self._load_models() # Ensure models are loaded first
69
+
70
+ # Clear existing papers before downloading new ones
71
+ if os.path.exists(ARXIV_DIR):
72
+ shutil.rmtree(ARXIV_DIR)
73
+ os.makedirs(ARXIV_DIR, exist_ok=True)
74
+
75
+ self.vectorstore = None
76
+ self.qa_chain = None
77
+
78
+ print(f"Searching arXiv for '{arxiv_query}' and downloading up to {max_papers} papers...")
79
+ try:
80
+ # Use LangChain's ArxivLoader
81
+ # ArxivLoader downloads PDFs to a temporary directory by default,
82
+ # but we can specify a custom path to ensure cleanup.
83
+ # For simplicity, we'll let it download to its default temp dir
84
+ # and then process. Or, we can manually download and use PyPDFLoader.
85
+ # Let's stick to manual download for better control and consistency with previous code.
86
+
87
+ # Manual download using arxiv library (as it offers more control over filenames)
88
+ search_results = arxiv.Search(
89
+ query=arxiv_query,
90
+ max_results=max_papers,
91
+ sort_by=arxiv.SortCriterion.Relevance,
92
+ sort_order=arxiv.SortOrder.Descending
93
+ )
94
+ pdf_paths = []
95
+ for i, result in enumerate(search_results.results()):
96
+ try:
97
+ safe_title = re.sub(r'[\\/:*?"<>|]', '', result.title)
98
+ filename = f"{ARXIV_DIR}/{safe_title[:100]}_{result.arxiv_id}.pdf"
99
+ print(f"Downloading paper {i+1}/{max_papers}: {result.title}")
100
+ result.download_pdf(filename=filename)
101
+ pdf_paths.append(filename)
102
+ except Exception as e:
103
+ print(f"Could not download {result.title}: {e}")
104
+
105
+ if not pdf_paths:
106
+ return "No papers found or downloaded for the given query. Please try a different query."
107
+
108
+ # Load documents from downloaded PDFs using PyPDFLoader
109
+ all_documents = []
110
+ for pdf_path in pdf_paths:
111
+ try:
112
+ loader = PyPDFLoader(pdf_path)
113
+ all_documents.extend(loader.load())
114
+ except Exception as e:
115
+ print(f"Error loading PDF {pdf_path}: {e}")
116
+
117
+ if not all_documents:
118
+ return "Could not load any documents from downloaded PDFs. Please try a different query or fewer papers."
119
+
120
+ print(f"Loaded {len(all_documents)} raw documents from PDFs.")
121
+
122
+ # Split documents into chunks using RecursiveCharacterTextSplitter
123
+ text_splitter = RecursiveCharacterTextSplitter(
124
+ chunk_size=CHUNK_SIZE,
125
+ chunk_overlap=CHUNK_OVERLAP,
126
+ length_function=len,
127
+ is_separator_regex=False,
128
+ )
129
+ self.knowledge_base_chunks = text_splitter.split_documents(all_documents)
130
+
131
+ if not self.knowledge_base_chunks:
132
+ return "No meaningful text chunks could be created from the papers after splitting."
133
+
134
+ print(f"Total chunks created: {len(self.knowledge_base_chunks)}")
135
+
136
+ # Create FAISS vectorstore from chunks and embeddings
137
+ print("Creating FAISS vectorstore from chunks...")
138
+ self.vectorstore = FAISS.from_documents(self.knowledge_base_chunks, self.embedding_model)
139
+ print(f"FAISS vectorstore created with {len(self.knowledge_base_chunks)} documents.")
140
+
141
+ # Create RetrievalQA chain
142
+ self.qa_chain = RetrievalQA.from_chain_type(
143
+ llm=self.llm,
144
+ chain_type="stuff", # "stuff" puts all retrieved docs into one prompt
145
+ retriever=self.vectorstore.as_retriever(search_kwargs={"k": 3}), # Retrieve top 3 docs
146
+ return_source_documents=False # Set to True if you want to return source docs
147
+ )
148
+
149
+ return f"Knowledge base loaded with {len(self.knowledge_base_chunks)} chunks from {len(pdf_paths)} arXiv papers on '{arxiv_query}'."
150
+
151
+ except Exception as e:
152
+ print(f"Error during knowledge base initialization: {e}")
153
+ return f"An error occurred during knowledge base initialization: {e}"
154
+
155
+ def query_agent(self, query: str) -> str:
156
  """
157
+ Retrieves relevant information from the knowledge base and generates an answer
158
+ using the LangChain RetrievalQA chain.
 
159
  """
160
+ if not query.strip():
161
+ return "Please enter a question."
162
+ if not self.is_initialized or self.qa_chain is None:
163
+ return "Knowledge base not loaded. Please initialize it by providing an arXiv query."
164
+
165
+ print(f"\n--- Querying LLM with LangChain QA Chain ---\nQuestion: {query}\n----------------------")
166
+
167
+ try:
168
+ # Use the RetrievalQA chain to get the answer
169
+ result = self.qa_chain.invoke({"query": query})
170
+ answer = result["result"].strip()
171
+ except Exception as e:
172
+ print(f"Error during generation: {e}")
173
+ answer = "I apologize, but I encountered an error while generating the answer. Please try again or rephrase your question."
174
+
175
+ return answer
176
+
177
+ # --- Gradio Interface ---
178
+
179
+ # Instantiate the RAGAgent
180
+ rag_agent_instance = RAGAgent()
181
+
182
+ print("Setting up Gradio interface...")
183
+
184
+ with gr.Blocks() as demo:
185
+ gr.Markdown("# 📚 Educational RAG Agent with arXiv Knowledge Base (LangChain)")
186
+ gr.Markdown("First, load a knowledge base by specifying an arXiv search query. Then, ask questions!")
187
+
188
+ with gr.Row():
189
+ arxiv_input = gr.Textbox(
190
+ label="arXiv Search Query (e.g., 'Large Language Models', 'Reinforcement Learning')",
191
+ placeholder="Enter a topic to search for papers on arXiv...",
192
+ lines=1
193
+ )
194
+ max_papers_slider = gr.Slider(
195
+ minimum=1,
196
+ maximum=10,
197
+ step=1,
198
+ value=3,
199
+ label="Max Papers to Download"
200
+ )
201
+ load_kb_button = gr.Button("Load Knowledge Base from arXiv")
202
+
203
+ kb_status_output = gr.Textbox(label="Knowledge Base Status", interactive=False)
204
+
205
+ with gr.Row():
206
+ question_input = gr.Textbox(
207
+ lines=3,
208
+ placeholder="Ask a question based on the loaded arXiv papers...",
209
+ label="Your Question"
210
+ )
211
+ answer_output = gr.Textbox(label="Answer", lines=7, interactive=False)
212
+
213
+ submit_button = gr.Button("Get Answer")
214
+
215
+ load_kb_button.click(
216
+ fn=rag_agent_instance.initialize_knowledge_base, # Call method of instance
217
+ inputs=[arxiv_input, max_papers_slider],
218
+ outputs=kb_status_output
219
  )
220
+
221
+ submit_button.click(
222
+ fn=rag_agent_instance.query_agent, # Call method of instance
223
+ inputs=question_input,
224
+ outputs=answer_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  )
226
+
227
+ gr.Examples(
228
+ examples=[
229
+ ["What is the transformer architecture?"],
230
+ ["Explain attention mechanisms in deep learning."],
231
+ ["What are the challenges in reinforcement learning?"],
232
+ ],
233
+ inputs=question_input
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  )
 
235
 
236
+ # Launch the Gradio app
 
 
237
  if __name__ == "__main__":
238
+ print("Launching Gradio app...")
239
+ demo.launch(share=False)
240
+ ```
241
+ ```text
requirements.txt CHANGED
@@ -1,11 +1,10 @@
1
  huggingface_hub==0.25.2
2
- datasets
3
  transformers
4
- torch
5
- langchain
6
  faiss-cpu
7
- gradio
8
- huggingface_hub
9
  arxiv
10
- langchain_community
11
- sentence-transformers
 
 
1
  huggingface_hub==0.25.2
2
+ gradio
3
  transformers
4
+ sentence-transformers
 
5
  faiss-cpu
6
+ torch
 
7
  arxiv
8
+ pypdf2
9
+ langchain
10
+ langchain-community