import gradio as gr
from llm_rag_setup import query_rag
custom_css = """
.container {
max-width: 1200px;
margin: auto;
}
.source-box {
background-color: #f0f0f0;
padding: 10px;
border-radius: 5px;
margin: 5px 0;
border-left: 3px solid #2196F3;
}
.footer {
text-align: center;
margin-top: 20px;
color: #666;
}
"""
def format_sources(source_documents):
if not source_documents:
return "Kaynak bulunamadı."
sources_html = ""
for i, doc in enumerate(source_documents[:3], 1):
metadata = doc.metadata
source_type = metadata.get("source_type", "genelge")
if source_type == "kanun":
madde_no = metadata.get("madde_no", "N/A")
madde_baslik = metadata.get("madde_baslik", "")
title = f"📜 Noterlik Kanunu - Madde {madde_no}"
if madde_baslik:
title += f" ({madde_baslik})"
kisim = metadata.get("kisim", "")
content = f"{kisim}\n\n{doc.page_content[:200]}..."
else:
genelge_no = metadata.get("genelge_no", "N/A")
madde_no = metadata.get("madde_no", "N/A")
title = f"📋 Genelge {genelge_no} - Madde {madde_no}"
genelge_baslik = metadata.get("genelge_baslik", "N/A")
content = f"{genelge_baslik}\n\n{doc.page_content[:200]}..."
sources_html += f"""
{i}. {title}
{content}
"""
return sources_html
def chat_with_rag(message, history):
if not message.strip():
return "", history
try:
history.append((message, "⚙️ Sistemi başlatıyor — lütfen bekleyin..."))
result = query_rag(message)
if result is None:
answer = "❌ Sistem başlatılamadı veya veri eksik. Lütfen sunucu günlüklerini kontrol edin."
else:
answer = result.get("result", "(Cevap alınamadı)")
sources_html = ""
if result and "source_documents" in result and result["source_documents"]:
sources_html = (
"
📚 Kaynaklar:
"
+ format_sources(result["source_documents"])
)
full_response = answer + sources_html
if history:
history[-1] = (message, full_response)
else:
history.append((message, full_response))
return "", history
except Exception as e:
error_message = f"❌ Hata oluştu: {str(e)}"
history.append((message, error_message))
return "", history
def clear_chat():
return [], []
examples = [
"Araç satış işlemlerinde hangi belgeler gereklidir?",
"Noterlik işlemlerinde harç ve karar pulu nasıl hesaplanır?",
"Vekaletname düzenlenirken dikkat edilmesi gereken hususlar nelerdir?",
"Gayrimenkul satış vaadi sözleşmesi nedir?",
]
with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
gr.Markdown(
"""
# ⚖️ NoterLLM - Türk Noter Hukuku Asistanı
Noterlik Kanunu ve Türkiye Noterler Birliği genelgelerine dayalı AI destekli soru-cevap sistemi.
**Kaynaklar:**
- 📜 Noterlik Kanunu (1512) - 213 madde
- 📋 TNB Genelgeleri - 125+ genelge
*Bu sistem genelgelere dayalı bilgi sağlar ancak resmi hukuki danışmanlık yerine geçmez.*
"""
)
with gr.Row():
with gr.Column(scale=4):
chatbot = gr.Chatbot(
label="Sohbet Geçmişi",
height=500,
show_label=True,
avatar_images=("👤", "⚖️"),
bubble_full_width=False,
)
with gr.Row():
msg = gr.Textbox(
label="Sorunuz",
placeholder="Noterlik hukuku ile ilgili sorunuzu yazın...",
show_label=False,
scale=9,
container=False,
)
submit_btn = gr.Button("Gönder", variant="primary", scale=1)
clear_btn = gr.Button("🗑️ Sohbeti Temizle", size="sm")
with gr.Column(scale=1):
gr.Markdown("### 💡 Örnek Sorular")
gr.Examples(
examples=examples,
inputs=msg,
label="Aşağıdaki sorulardan birini seçebilirsiniz:",
)
gr.Markdown(
"""
### ℹ️ Bilgi
**Model:** Mistral-7B-Instruct-v0.2
**Embedding:** multilingual-e5-base
**Retrieval:** FAISS + BM25 (Hybrid)
**Özellikler:**
- 🔍 Semantic & Keyword Search
- 📚 Kaynak Referansları
- 🇹🇷 Türkçe Optimizasyonu
"""
)
submit_btn.click(
fn=chat_with_rag,
inputs=[msg, chatbot],
outputs=[msg, chatbot],
)
msg.submit(
fn=chat_with_rag,
inputs=[msg, chatbot],
outputs=[msg, chatbot],
)
clear_btn.click(
fn=clear_chat,
inputs=None,
outputs=[msg, chatbot],
)
gr.Markdown(
"""
"""
)
demo.launch()