""", unsafe_allow_html=True)
else:
st.markdown("")
# استایلها برای چرخش و پیام در حال فکر کردن
st.markdown("""
""", unsafe_allow_html=True)
import os
import re
import docx
import streamlit as st
import concurrent.futures
from hazm import Normalizer
from rapidfuzz import fuzz
from langchain.schema import SystemMessage, HumanMessage
folder_path = '46'
normalizer = Normalizer()
@st.cache_data(show_spinner="در حال پردازش اسناد... لطفاً صبور باشید.")
def load_and_process_documents(path):
def process_docx(filename):
try:
full_path = os.path.join(path, filename)
doc = docx.Document(full_path)
text = "\n".join([para.text for para in doc.paragraphs])
normalized = normalizer.normalize(text)
return filename, normalized
except Exception as e:
print(f"Error processing {filename}: {e}")
return filename, ""
filenames = [f for f in os.listdir(path) if f.endswith(".docx")]
doc_texts = {}
with concurrent.futures.ThreadPoolExecutor() as executor:
for filename, content in executor.map(process_docx, filenames):
doc_texts[filename] = content
return doc_texts
doc_texts = load_and_process_documents(folder_path)
def clean_text(text):
return re.sub(r'[^آ-ی۰-۹0-9،.؟!؛+\-* ]+', '', text)
def find_closest_filenames(query, filenames, top_n=3):
scores = [(f, fuzz.partial_ratio(query, f)) for f in filenames]
scores.sort(key=lambda x: x[1], reverse=True)
return [score[0] for score in scores[:top_n]]
from transformers import pipeline
def summarize_text(text):
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
summary = summarizer(text, max_length=1024, min_length=512, do_sample=False)
return summary[0]['summary_text']
def find_best_answer(query, top_files, doc_texts):
best_match = None
best_score = 0
best_text = ""
for filename in top_files:
text = doc_texts[filename]
similarity = fuzz.partial_ratio(query, text)
if similarity > best_score:
best_score = similarity
best_match = filename
best_text = text
# خلاصه کردن متن برای خروجی بهتر
if best_text:
summary = summarize_text(best_text)
else:
summary = "متنی برای خلاصهسازی پیدا نشد."
return summary
# حالا این رو در کد اصلی استفاده میکنیم:
if query:
# مرحله 1: درخواست از مدل برای بررسی وجود پاسخ در نام فایلها
top_files = find_closest_filenames(query, list(doc_texts.keys()), top_n=3)
best_file, matched_text = find_best_answer(query, top_files, doc_texts)
if best_file: # اگر پاسخ از اسم فایلها پیدا شد
prompt_for_model_1 = f"""
لطفاً با توجه به سوال زیر و محتوای سند موجود، یک پاسخ نهایی حرفهای، دقیق و روان تولید کن. فقط از متن سند استفاده کن. اگر اطلاعات کافی در متن وجود ندارد، صادقانه اعلام کن.
سوال:
{query}
محتوای سند:
{matched_text}
پاسخ نهایی:
"""
response_model_1 = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt_for_model_1)
])
rewritten = clean_text(response_model_1.content.strip())
# مرحله 2: بررسی پاسخ مدل اول
prompt_for_model_2 = f"""
سوال:
{query}
آیا مدل اول به درستی جواب داده است؟
پاسخ مدل اول:
{rewritten}
لطفاً تایید کن که آیا این پاسخ مناسب است یا خیر. اگر مناسب نیست، لطفاً اطلاعات بیشتری از متن موجود در سند بده.
"""
response_model_2 = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt_for_model_2)
])
answer_model_2 = clean_text(response_model_2.content.strip())
if "تایید" in answer_model_2: # اگر تایید شد که پاسخ درست است
st.markdown(f'
{rewritten}
', unsafe_allow_html=True)
else:
# مرحله 3: جستجو در متن کل سندها
best_file_from_text = None
best_answer_from_text = ""
top_files_for_text = find_closest_filenames(query, list(doc_texts.keys()), top_n=3)
for filename in top_files_for_text:
text = doc_texts[filename]
similarity = fuzz.partial_ratio(query, text)
if similarity > 50: # حداقل شباهت برای انتخاب پاسخ
best_file_from_text = filename
best_answer_from_text = text
break # اگر جواب خوبی پیدا شد، جستجو را متوقف میکنیم
if best_file_from_text: # اگر جوابی از متن پیدا شد
prompt_for_model_3 = f"""
لطفاً با توجه به سوال زیر و محتوای سند موجود، یک پاسخ نهایی حرفهای، دقیق و روان تولید کن. فقط از متن سند استفاده کن. اگر اطلاعات کافی در متن وجود ندارد، صادقانه اعلام کن.
سوال:
{query}
محتوای سند:
{best_answer_from_text}
پاسخ نهایی:
"""
response_model_3 = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt_for_model_3)
])
rewritten_model_3 = clean_text(response_model_3.content.strip())
# بررسی تایید مدل 2
prompt_for_model_4 = f"""
سوال:
{query}
آیا مدل دوم به درستی جواب داده است؟
پاسخ مدل دوم:
{rewritten_model_3}
لطفاً تایید کن که آیا این پاسخ مناسب است یا خیر.
"""
response_model_4 = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt_for_model_4)
])
answer_model_4 = clean_text(response_model_4.content.strip())
if "تایید" in answer_model_4: # اگر تایید شد که پاسخ درست است
st.markdown(f'
{rewritten_model_3}
', unsafe_allow_html=True)
else:
# مرحله آخر: اگر تایید نشده بود، از دانش خود مدل استفاده کن
prompt_for_model_5 = f"""
سوال:
{query}
لطفاً جواب دقیقی از دانش خودت بده.
"""
response_model_5 = llm([
SystemMessage(content="You are a knowledgeable assistant."),
HumanMessage(content=prompt_for_model_5)
])
rewritten_model_5 = clean_text(response_model_5.content.strip())
st.markdown(f'