""", unsafe_allow_html=True)
else:
st.markdown("")
# استایلها برای چرخش و پیام در حال فکر کردن
st.markdown("""
""", unsafe_allow_html=True)
folder_path = '46'
normalizer = Normalizer()
sentence_tokenizer = SentenceTokenizer()
@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)
sentences = normalized
return sentences
except Exception as e:
print(f"Error processing {filename}: {e}")
return []
with concurrent.futures.ThreadPoolExecutor() as executor:
results = executor.map(process_docx, [f for f in os.listdir(path) if f.endswith(".docx")])
return list(results)
all_sentences = load_and_process_documents(folder_path)
def clean_text(text):
cleaned_text = re.sub(r'[^آ-ی۰-۹0-9،.؟!؛+\-* ]+', '', text)
return cleaned_text
def compute_similarity(sentence, query, threshold):
similarity = fuzz.partial_ratio(sentence, query)
if similarity >= threshold:
return sentence
return None
import string
from hazm import word_tokenize, sent_tokenize
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity
from concurrent.futures import ThreadPoolExecutor
# تابع خلاصهسازی متن با استفاده از KMeans
def summarize_text_with_kmeans(text, num_sentences=3):
sentences = sent_tokenize(text) # تقسیم متن به جملات
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(sentences) # تبدیل جملات به ماتریس TF-IDF
# الگوریتم خوشهبندی KMeans
kmeans = KMeans(n_clusters=1) # یک خوشه برای استخراج خلاصه
kmeans.fit(tfidf_matrix)
# پیدا کردن جملات نزدیک به مرکز خوشه
closest_centroid = kmeans.cluster_centers_[0]
similarities = cosine_similarity(tfidf_matrix, closest_centroid.reshape(1, -1))
similar_sentences_indices = similarities.flatten().argsort()[-num_sentences:][::-1] # انتخاب jملات نزدیک
summary = [sentences[i] for i in similar_sentences_indices]
return ' '.join(summary)
# فرض بر این است که query و all_sentences قبلاً تعریف شدهاند
if query:
threshold = 75
keywords = query
# خلاصهسازی متن قبل از ارسال به LLM
text_to_summarize = "\n".join(all_sentences) # تمام جملات را با هم ترکیب کنید
summarized_text = summarize_text_with_kmeans(text_to_summarize)
# استفاده از پردازش موازی برای افزایش سرعت fuzzy matching
with ThreadPoolExecutor(max_workers=8) as executor:
futures = [executor.submit(compute_similarity, sentence, query, threshold) for sentence in all_sentences]
matched_sentences = [future.result() for future in futures if future.result()]
if matched_sentences:
found_sentences = [sentence for sentence in matched_sentences if any(keyword in sentence for keyword in keywords)]
if found_sentences:
matched_text = "\n".join(found_sentences)
prompt = f"""
تعدادی پاسخ برای سوال زیر تولید شده است. لطفاً ابتدا این پاسخها را بررسی کن، سپس با در نظر گرفتن محتوای سوال و لحن آن، یک پاسخ نهایی حرفهای، دقیق و روان از داخل پاسخها ارائه کن که هم به سوال پاسخ دهد و هم از نظر نگارشی و ساختاری در سطح بالایی باشد. پاسخ نهایی باید حداکثر 2048 کاراکتر و حداقل 512 باشد، خلاصه و واضح نوشته شود و فقط به زبان فارسی باشد. از تکرار اضافی پرهیز کن و فقط از پاسخهای زیر استفاده کن. در صورت نیاز، محتوای چند پاسخ را با هم ترکیب کن.
سوال:
{query}
پاسخها:
{summarized_text}
پاسخ نهایی حرفهای بازنویسیشده:
"""
response = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt)
])
rewritten = clean_text(response.content.strip())
review_prompt = f"""
لطفاً بررسی کن که آیا پاسخ زیر به سوال دادهشده مرتبط، دقیق و معتبر است یا خیر. اگر پاسخ قابل قبول و دقیق است بنویس 'تأیید شد'. اگر متوسط است بنویس 'کمی خوب'. اگر بیربط یا اشتباه است بنویس 'نیاز به اصلاح دارد'.
سوال:
{query}
پاسخ:
{rewritten}
"""
review_response = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=review_prompt)
])
review_result = review_response.content.strip()
if "تأیید شد" in review_result:
st.markdown(f'
{rewritten}
', unsafe_allow_html=True)
elif "کمی خوب" in review_result:
final_prompt = f"""
لطفاً برای سوال زیر پاسخی حرفهای، دقیق و روان تولید کن که مرتبط و معتبر باشد. از زبانی جز فارسی استفاده نکن. از محتوای زیر استفاده کن و یک پاسخ نهایی خوب بنویس:
سوال:
{query}
پاسخ اولیه:
{rewritten}
پاسخ نهایی:
"""
new_response = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=final_prompt)
])
final_answer = clean_text(new_response.content.strip())
st.markdown(f'
{final_answer}
', unsafe_allow_html=True)
else:
fallback_prompt = f"""
لطفاً برای سوال زیر پاسخی حرفهای، دقیق و روان تولید کن که مرتبط و معتبر باشد. اگر اطلاعات کافی وجود ندارد، صادقانه بگو. فقط به زبان فارسی پاسخ بده:
سوال:
{query}
"""
fallback_response = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=fallback_prompt)
])
final_fallback = clean_text(fallback_response.content.strip())
st.markdown(f'
{final_fallback}
', unsafe_allow_html=True)
else:
fallback_prompt = f"""
لطفاً برای سوال زیر یک متن مرتبط و معتبر تولید کن. اگر اطلاعات کافی وجود ندارد، صادقانه اعلام کن. فقط به زبان فارسی پاسخ بده:
سوال:
{query}
"""
response = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=fallback_prompt)
])
rewritten = clean_text(response.content.strip())
st.markdown(f'