mhuseyina commited on
Commit
44facf0
·
verified ·
1 Parent(s): 199b960

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +394 -0
  2. requirements.txt +14 -0
app.py ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # RAG Temelli Eğitim Chatbot (EğitBot)
2
+ import os
3
+
4
+ # Hugging Face cache klasörlerini uygulama dizini içine yönlendir
5
+ os.environ["HF_HOME"] = "./cache"
6
+ os.environ["HF_DATASETS_CACHE"] = "./cache/hf_datasets"
7
+ os.environ["TRANSFORMERS_CACHE"] = "./cache/transformers"
8
+ os.environ["SENTENCE_TRANSFORMERS_HOME"] = "./cache/sentence_transformers"
9
+
10
+ # Gerekli kütüphaneleri ekliyoruz.
11
+ import os
12
+ import requests
13
+ import streamlit as st
14
+ from datasets import load_dataset
15
+ from langchain_huggingface import HuggingFaceEmbeddings
16
+ from langchain.text_splitter import TokenTextSplitter
17
+ from langchain_community.vectorstores import FAISS
18
+ from langchain.text_splitter import CharacterTextSplitter
19
+ from langchain.chains import RetrievalQA
20
+ from langchain.prompts import PromptTemplate
21
+ from langchain_google_genai import ChatGoogleGenerativeAI
22
+ import datetime
23
+
24
+ # Streamlit secrets üzerinden API anahtarını al
25
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
26
+ HUGGINGFACEHUB_API_TOKEN = os.getenv("HUGGINGFACEHUB_API_TOKEN")
27
+
28
+ MODEL_NAME = "models/gemini-2.5-pro"
29
+
30
+ # -----------------------------
31
+ # 📄 VERİ SETİ & VEKTÖR VERİTABANI HAZIRLAMA
32
+ # -----------------------------
33
+ # Veri hazırlama işlemi de sadece bir kez yapılır.
34
+ # Burda 4 farklı veri seti ekliyoruz.
35
+ # Veri setlerinden math_word problem tarzı sorular için
36
+ # math_hard daha derin işlemler için
37
+ # edu eğitim temalı genel soru-cevap için
38
+ # wiki_sum bu veri setide tarih ve fen alanında daha verimli cevaplar için kullanılmıştır.
39
+ @st.cache_resource
40
+ def prepare_retriever():
41
+ try:
42
+ dataset_math_word = load_dataset("duxx/orca-math-word-problems-tr", split="train[:2000]")
43
+ dataset_math_hard = load_dataset("Karayel-DDI/Turkce_Lighteval_MATH-Hard", split="train[:2000]")
44
+ dataset_edu = load_dataset("korkmazemin1/turkish-education-dataset", split="train[:2000]")
45
+ dataset_wiki_sum = load_dataset("musabg/wikipedia-tr-summarization", split="train[:2000]")
46
+
47
+
48
+ documents = []
49
+ # 1. Orca Math Word Problems
50
+ for item in dataset_math_word:
51
+ question = item.get("question", "").strip()
52
+ answer = item.get("answer", "").strip()
53
+ if question and answer:
54
+ documents.append(f"Soru: {question}\nCevap: {answer}")
55
+
56
+ # 2. Karayel-DDI Math Hard
57
+ for item in dataset_math_hard:
58
+ question = item.get("question", "").strip()
59
+ answer = item.get("solution", "").strip()
60
+ if question and answer:
61
+ documents.append(f"Soru: {question}\nCevap: {answer}")
62
+
63
+ # 3. Korkmazemin1 Turkish Education Dataset
64
+ for item in dataset_edu:
65
+ question = item.get("soru", "").strip()
66
+ answer = item.get("cevap", "").strip()
67
+ if question and answer:
68
+ documents.append(f"Soru: {question}\nCevap: {answer}")
69
+
70
+ # 4. Musabg Wikipedia Turkish Summarization Dataset
71
+ for item in dataset_wiki_sum:
72
+ text = item.get("text", "").strip()
73
+ summary = item.get("summary", "").strip()
74
+ if text and summary:
75
+ documents.append(f"Metin: {text}\nÖzet: {summary}")
76
+
77
+ # Metinleri parçalara ayıralım
78
+ text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=100)
79
+ docs = text_splitter.create_documents(documents)
80
+
81
+ # Embedding modeli
82
+ embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
83
+
84
+ # FAISS dizini
85
+ FAISS_PATH = "faiss_index"
86
+
87
+ # Daha önce kayıtlı FAISS varsa onu yükle
88
+ if os.path.exists(FAISS_PATH):
89
+ vectorstore = FAISS.load_local(FAISS_PATH, embedding_model, allow_dangerous_deserialization=True)
90
+ else:
91
+ vectorstore = FAISS.from_documents(docs, embedding_model)
92
+ vectorstore.save_local(FAISS_PATH)
93
+
94
+ return vectorstore.as_retriever(search_kwargs={"k": 3})
95
+
96
+ except Exception as e:
97
+ st.error(f"Veri seti hazırlanırken hata oluştu: {e}")
98
+ return None
99
+ # Eğer retriever None dönerse uygulamayı durdurabilirsin
100
+ retriever = prepare_retriever()
101
+ if retriever is None:
102
+ st.stop()
103
+
104
+ # -----------------------------
105
+ # 🔗 ÖZEL PROMPT OLUŞTURMA
106
+ # -----------------------------
107
+ # Burada modelden gelen bilgiyi nasıl kullanacağını söylüyoruz.
108
+ prompt_template = """
109
+ Sadece sorulan soruya net ve kısa cevap ver. Gereksiz ek açıklama yapma.
110
+ Sadece yukarıdaki soruya cevap ver. Başka konulara girmeyin veya yeni sorular sormayın.
111
+
112
+ Bilgiler:
113
+ {context}
114
+
115
+ Soru:
116
+ {question}
117
+
118
+ Cevap:
119
+ """
120
+
121
+ PROMPT = PromptTemplate(
122
+ template=prompt_template,
123
+ input_variables=["context", "question"]
124
+ )
125
+
126
+ # -----------------------------
127
+ # 🔗 Gemini LLM (LangChain üzerinden)
128
+ # -----------------------------
129
+ llm = ChatGoogleGenerativeAI(
130
+ model=MODEL_NAME,
131
+ google_api_key=GOOGLE_API_KEY
132
+ )
133
+
134
+ # -----------------------------
135
+ # 🔗 LangChain QA Zinciri Kurulumu
136
+ # -----------------------------
137
+ # LLM ve retriever’ı bağlayarak "Soru-Cevap" zinciri oluşturuyoruz.
138
+ qa_chain = RetrievalQA.from_chain_type(
139
+ llm=llm,
140
+ retriever=retriever,
141
+ return_source_documents=False,
142
+ chain_type="stuff",
143
+ chain_type_kwargs={"prompt": PROMPT}
144
+ )
145
+
146
+ # -----------------------------
147
+ # 🖥️ Streamlit Arayüzü (EğitBot)
148
+ # -----------------------------
149
+ # Sayfa başlığı, simgesi ve genişlik ayarlandı
150
+ st.set_page_config(page_title="📘 EğitBot - Eğitim Asistanı", page_icon="🎓", layout="wide")
151
+
152
+ # -----------------------------
153
+ # 👤 Oturum Durumu: Sohbet Geçmişi ve İstatistikler Başlatma
154
+ # -----------------------------
155
+ # Streamlit session_state ile kalıcı sohbet geçmişi ve sayaçları tutuyoruz.
156
+ if "chat_history" not in st.session_state:
157
+ st.session_state.chat_history = []
158
+
159
+ if "total_questions" not in st.session_state:
160
+ st.session_state.total_questions = 0
161
+
162
+ if "total_answers" not in st.session_state:
163
+ st.session_state.total_answers = 0
164
+
165
+ # Örnek sorular veri yapısı
166
+ EXAMPLE_QUESTIONS = {
167
+ "İlkokul": {
168
+ "Matematik": [
169
+ "Bir çantada 5 kitap varsa, 3 çantada kaç kitap olur?",
170
+ "10 - 4 işleminin sonucu kaçtır?",
171
+ "2 ile 3'ün toplamı kaçtır?",
172
+ "Bir elma 3 TL ise, 4 elma kaç TL eder?",
173
+ "5 elma ve 2 armut kaç meyvedir?"
174
+ ],
175
+ "Türkçe": [
176
+ "'Ev' kelimesi kaç harflidir?",
177
+ "Cümlenin baş harfi nasıl yazılır?",
178
+ "Bir cümleye örnek veriniz.",
179
+ "Sesli harfler nelerdir?",
180
+ "Hangi kelimede 'a' harfi vardır?"
181
+ ],
182
+ "Tarih": [
183
+ "Türkiye'nin başkenti neresidir?",
184
+ "Atatürk kimdir?",
185
+ "Türkiye hangi kıtadadır?",
186
+ "Bayrak neden önemlidir?",
187
+ "Okulun ilk günü nasıl geçer?"
188
+ ],
189
+ "Fen Bilimleri": [
190
+ "Bitkiler nasıl büyür?",
191
+ "Güneş neden parlar?",
192
+ "Su neden akar?",
193
+ "Hayvanlar ne yer?",
194
+ "Hangi nesne sıcak olur?"
195
+ ]
196
+ },
197
+ "Ortaokul": {
198
+ "Matematik": [
199
+ "3x + 5 = 20 denkleminde x kaçtır?",
200
+ "Bir dik üçgenin özellikleri nelerdir?",
201
+ "5 ile 7'nin ortalaması kaçtır?",
202
+ "Bir sayının karesi nedir?",
203
+ "Alan ve çevre farkı nedir?"
204
+ ],
205
+ "Türkçe": [
206
+ "Cümledeki yüklem nedir?",
207
+ "Fiil nedir, örnek veriniz.",
208
+ "Anlam bilgisi nedir?",
209
+ "Noktalama işaretleri nelerdir?",
210
+ "Cümlenin ögesi nedir?"
211
+ ],
212
+ "Tarih": [
213
+ "Osmanlı Devleti ne zaman kurulmuştur?",
214
+ "Türk tarihi önemli olayları nelerdir?",
215
+ "Cumhuriyet ne zaman ilan edildi?",
216
+ "Atatürk'ün hayatı hakkında bilgi verin.",
217
+ "Tarih neden önemlidir?"
218
+ ],
219
+ "Fen Bilimleri": [
220
+ "Fotosentez nedir?",
221
+ "Maddenin halleri nelerdir?",
222
+ "İnsan vücudundaki organlar nelerdir?",
223
+ "Güç nedir?",
224
+ "Enerji türleri nelerdir?"
225
+ ]
226
+ },
227
+ "Lise": {
228
+ "Matematik": [
229
+ "Türev nedir ve nasıl hesaplanır?",
230
+ "Bir üçgenin iç açılarının toplamı kaçtır?",
231
+ "Kareköklü ifadeler nasıl sadeleştirilir?",
232
+ "Fonksiyon nedir?",
233
+ "Olasılık hesaplaması nasıl yapılır?"
234
+ ],
235
+ "Türkçe": [
236
+ "Fiil çekimi nasıl yapılır?",
237
+ "Anlatım bozukluğu nedir, örnek veriniz.",
238
+ "Cümledeki ögeler nelerdir?",
239
+ "Sözcük türleri nelerdir?",
240
+ "Metin türleri nelerdir?"
241
+ ],
242
+ "Tarih": [
243
+ "Birinci Dünya Savaşı'nın nedenleri nelerdir?",
244
+ "Osmanlı Devleti'nin yıkılış süreci nasıl oldu?",
245
+ "Cumhuriyet'in ilanı ne zaman gerçekleşti?",
246
+ "Atatürk'ün inkılapları nelerdir?",
247
+ "Soğuk Savaş dönemi hakkında bilgi verin."
248
+ ],
249
+ "Fen Bilimleri": [
250
+ "Kimyasal reaksiyon nedir?",
251
+ "Elektrik akımı nasıl oluşur?",
252
+ "Fotosentezde ışığın rolü nedir?",
253
+ "Biyoloji alanında DNA'nın önemi nedir?",
254
+ "Newton'un hareket kanunları nelerdir?"
255
+ ]
256
+ }
257
+ }
258
+
259
+ # -----------------------------
260
+ # 📚 Sidebar - İstatistikler, Butonlar ve Örnek Sorular
261
+ # -----------------------------
262
+ with st.sidebar:
263
+ st.title("📚 Örnek Sorular & Kontroller")
264
+
265
+ # İstatistikler
266
+ st.markdown(f"- Toplam Sorulan Soru: **{st.session_state.get('total_questions', 0)}**")
267
+ st.markdown(f"- Toplam Alınan Cevap: **{st.session_state.get('total_answers', 0)}**")
268
+ st.markdown("---")
269
+
270
+ # "Geçmişi Temizle" butonu, tıklanınca tüm sohbeti ve sayacı sıfırlıyor
271
+ if st.button("♻️ Geçmişi Temizle", key="clear_history"):
272
+ st.session_state.chat_history = []
273
+ st.session_state.total_questions = 0
274
+ st.session_state.total_answers = 0
275
+
276
+ # Sohbet geçmişini dosya olarak kaydetmek için fonksiyon
277
+ def save_chat_history():
278
+ now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
279
+ filename = f"chat_history_{now}.txt"
280
+ with open(filename, "w", encoding="utf-8") as f:
281
+ for sender, msg in st.session_state.get("chat_history", []):
282
+ f.write(f"{'Kullanıcı' if sender == 'user' else 'Bot'}: {msg}\n")
283
+ return filename
284
+
285
+ # "Sohbeti Kaydet" butonuna basıldığında sohbet dosyasını oluşturup indirilebilir yapıyoruz
286
+ if st.button("💾 Sohbeti Kaydet", key="save_chat"):
287
+ filename = save_chat_history()
288
+ with open(filename, "rb") as f:
289
+ st.download_button(
290
+ label="⬇️ Dosyayı İndir",
291
+ data=f,
292
+ file_name=filename,
293
+ mime="text/plain"
294
+ )
295
+
296
+ # Örnek sorular için seçimler
297
+ grade = st.selectbox("Sınıf Seviyesi Seçiniz:", options=list(EXAMPLE_QUESTIONS.keys()), key="grade_select")
298
+ subjects = list(EXAMPLE_QUESTIONS[grade].keys())
299
+ subject = st.selectbox("Konu Seçiniz:", options=subjects, key="subject_select")
300
+
301
+ # Liste olarak örnek soruları göster
302
+ example_questions = EXAMPLE_QUESTIONS[grade][subject]
303
+ st.markdown("### Örnek Sorular:")
304
+ for idx, question in enumerate(example_questions, 1):
305
+ st.markdown(f"{idx}. {question}")
306
+
307
+ # Ana sayfa başlığı
308
+ st.title("📘 EğitBot - Eğitim Asistanı")
309
+
310
+ # Kullanıcının sorusunu al
311
+ user_question = st.text_input("Sorunuzu buraya yazınız veya yukarıdaki örnek sorulardan birini yazabilirsiniz:", key="user_question_input")
312
+
313
+ # Gönder butonu
314
+ if st.button("Gönder", key="send_question"):
315
+ if user_question.strip() == "":
316
+ st.warning("Lütfen bir soru yazınız veya örnek sorulardan birini kullanınız.")
317
+ else:
318
+ with st.spinner("Cevap aranıyor..."):
319
+ try:
320
+ answer = qa_chain.run(user_question)
321
+ st.session_state.chat_history.append(("user", user_question))
322
+ st.session_state.chat_history.append(("bot", answer))
323
+ st.session_state.total_questions += 1
324
+ st.session_state.total_answers += 1
325
+ except Exception as e:
326
+ st.error(f"Cevap alınırken hata oluştu: {e}")
327
+
328
+ # Sohbet geçmişi balonlar halinde gösterimi
329
+ def render_message(sender, message):
330
+ if sender == "user":
331
+ color = "#DCF8C6" # Açık yeşil (Kullanıcı için)
332
+ align = "flex-end"
333
+ border_radius = "15px 15px 0 15px"
334
+ else:
335
+ color = "#EAEAEA" # Açık gri (Bot için)
336
+ align = "flex-start"
337
+ border_radius = "15px 15px 15px 0"
338
+ st.markdown(
339
+ f"""
340
+ <div style="
341
+ display: flex;
342
+ justify-content: {align};
343
+ margin: 5px 0;
344
+ ">
345
+ <div style="
346
+ background-color: {color};
347
+ padding: 10px 15px;
348
+ border-radius: {border_radius};
349
+ max-width: 70%;
350
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
351
+ ">
352
+ {message}
353
+ </div>
354
+ </div>
355
+ """,
356
+ unsafe_allow_html=True
357
+ )
358
+
359
+ if st.session_state.chat_history:
360
+ st.markdown("---")
361
+ st.subheader("💬 Sohbet Geçmişi")
362
+ for sender, message in reversed(st.session_state.chat_history):
363
+ if sender == "user":
364
+ st.markdown(
365
+ f"""
366
+ <div style="
367
+ background-color: #A3C4F3; /* Soft mavi */
368
+ padding: 12px;
369
+ border-radius: 15px;
370
+ margin: 5px 0px;
371
+ max-width: 80%;
372
+ color: black; /* Yazı siyah */
373
+ ">
374
+ <b>Kullanıcı:</b> {message}
375
+ </div>
376
+ """,
377
+ unsafe_allow_html=True
378
+ )
379
+ else:
380
+ st.markdown(
381
+ f"""
382
+ <div style="
383
+ background-color: #8FBC8F; /* Soft yeşil */
384
+ padding: 12px;
385
+ border-radius: 15px;
386
+ margin: 5px 0px;
387
+ max-width: 80%;
388
+ color: black; /* Yazı siyah */
389
+ ">
390
+ <b>Bot:</b> {message}
391
+ </div>
392
+ """,
393
+ unsafe_allow_html=True
394
+ )
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ pip
2
+ streamlit
3
+ python-dotenv
4
+ langchain
5
+ langchain-community
6
+ langchain-google-genai
7
+ sentence-transformers
8
+ faiss-cpu
9
+ datasets==2.18.0
10
+ requests
11
+ torch
12
+ transformers
13
+ huggingface-hub
14
+ tiktoken