Reza-galaxy21 commited on
Commit
3f672a5
·
verified ·
1 Parent(s): 522002e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -50
app.py CHANGED
@@ -6,7 +6,6 @@ from langchain_community.document_loaders import PyPDFLoader
6
  from langchain_community.embeddings import OpenAIEmbeddings
7
  from langchain_community.vectorstores import FAISS
8
  from langchain_community.chat_models import ChatOpenAI
9
- from langchain.prompts import PromptTemplate
10
 
11
  # تنظیمات لاگ‌گیری
12
  logging.basicConfig(level=logging.INFO)
@@ -14,14 +13,14 @@ logger = logging.getLogger(__name__)
14
 
15
  # تنظیمات مسیرها
16
  UPLOAD_FOLDER = "uploaded_files"
17
- DATABASE_FILE = "/home/user/app/vector_database" # بدون پسوند .pkl
18
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
19
 
20
  # بررسی و بارگذاری دیتابیس برداری
21
  def load_database():
22
  try:
23
  if os.path.exists(DATABASE_FILE):
24
- embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("My_huggingface_key"), model="text-embedding-3-large")
25
  vector_db = FAISS.load_local(DATABASE_FILE, embeddings)
26
  logger.info(f"✅ دیتابیس بارگذاری شد: {DATABASE_FILE}")
27
  return vector_db
@@ -60,13 +59,7 @@ def process_and_store_pdfs(file_paths):
60
 
61
  try:
62
  logger.info("در حال ایجاد embeddings و ذخیره‌سازی در FAISS...")
63
- openai_api_key = os.getenv("My_huggingface_key")
64
-
65
- if not openai_api_key:
66
- logger.error("❌ کلید API مقداردهی نشده است!")
67
- raise ValueError("❌ کلید OpenAI API یافت نشد.")
68
-
69
- embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key, model="text-embedding-3-large")
70
  vector_db = FAISS.from_documents(texts, embeddings)
71
  logger.info(f"✅ ذخیره‌سازی در FAISS با موفقیت انجام شد. تعداد اسناد: {vector_db.index.ntotal}")
72
  return vector_db
@@ -74,6 +67,10 @@ def process_and_store_pdfs(file_paths):
74
  logger.error(f"خطا در ایجاد embeddings یا ذخیره‌سازی در FAISS: {e}")
75
  return None
76
 
 
 
 
 
77
  # پاسخ‌گویی بر اساس اسناد بارگذاری‌شده
78
  def chat_with_doc(query):
79
  try:
@@ -84,56 +81,41 @@ def chat_with_doc(query):
84
  if not query.strip():
85
  return "❌ لطفاً سوال خود را وارد کنید."
86
 
87
- # پاسخ به سوالات عمومی
88
- if query.lower() in ["سلام", "hi", "hello"]:
89
- return "سلام، چه کمکی می‌تونم بکنم؟"
90
-
91
- # بازیابی اسناد مرتبط
92
- retriever = global_vector_db.as_retriever(search_kwargs={"k": 5})
93
  docs = retriever.get_relevant_documents(query)
94
-
95
- # مرتب‌سازی اسناد بر اساس درجه شباهت
96
- docs_sorted = sorted(docs, key=lambda x: x.metadata.get("similarity_score", 0), reverse=True)
97
 
98
- # لاگ‌گیری برای بررسی اسناد بازیابی شده
99
- logger.info(f"تعداد اسناد بازیابی شده: {len(docs_sorted)}")
100
- for doc in docs_sorted:
101
- logger.info(f"سند بازیابی شده: {doc.page_content[:100]}... (درجه شباهت: {doc.metadata.get('similarity_score', 'نامشخص')})")
102
 
103
- context = "\n\n".join([doc.page_content for doc in docs_sorted])
 
 
104
 
105
- if not context:
106
- return "هیچ اطلاعات مرتبطی یافت نشد."
 
 
 
 
 
 
107
 
108
- # بهبود Prompt Engineering
109
- prompt_template = PromptTemplate(
110
- input_variables=["query", "context"],
111
- template="""
112
- شما یک دستیار هوشمند هستید که به سوالات کاربران پاسخ می‌دهید.
113
- سوال: {query}
114
- اطلاعات مرتبط: {context}
115
- لطفاً پاسخ دقیق و مختصر ارائه دهید.
116
- """
117
- )
118
- prompt = prompt_template.format(query=query, context=context)
119
-
120
- # استفاده از مدل gpt-3.5-turbo
121
  llm = ChatOpenAI(model_name="gpt-3.5-turbo", openai_api_key=os.getenv("My_huggingface_key"))
 
122
  response = llm.predict(prompt)
123
 
124
- # بررسی درجه شباهت اسناد
125
- if docs_sorted and docs_sorted[0].metadata.get("similarity_score", 0) < 0.5: # آستانه درجه شباهت
126
- response = f"⚠️ توجه: این پاسخ بر اساس اطلاعات محدود موجود است. برای دریافت پاسخ دقیق‌تر، لطفاً فایل مرتبط را آپلود کنید.\n\n{response}"
127
-
128
- final_response = f"پاسخ:\n{response}\n\nمنابع:\n"
129
- for doc in docs_sorted:
130
- final_response += f"- {doc.metadata.get('source', 'نامشخص')}, صفحه {doc.metadata.get('page', 'نامشخص')} (درجه شباهت: {doc.metadata.get('similarity_score', 'نامشخص')})\n"
131
-
132
  return final_response
133
  except Exception as e:
134
  logger.error(f"خطا در پاسخ‌گویی بر اساس سند: {e}")
135
  return f"❌ خطایی رخ داده است: {e}"
136
 
 
 
 
 
 
 
137
  # ذخیره فایل آپلود شده
138
  def save_uploaded_file(file):
139
  try:
@@ -155,14 +137,14 @@ with gr.Blocks() as demo:
155
  gr.Markdown("# هوش مصنوعی همراه کارشناسان توزیع برق ایران")
156
 
157
  query = gr.Textbox(label="سوال خود را بپرسید", lines=2)
158
- response = gr.Textbox(label="پاسخ", lines=10, interactive=False)
159
  submit_btn = gr.Button("ارسال سوال")
160
 
161
  file = gr.File(label="📎 آپلود فایل", file_types=[".pdf"])
162
  upload_status = gr.Textbox(label="وضعیت آپلود", interactive=False)
163
  upload_btn = gr.Button("ارسال فایل")
164
 
165
- submit_btn.click(chat_with_doc, inputs=[query], outputs=[response])
166
  upload_btn.click(save_uploaded_file, inputs=[file], outputs=[upload_status])
 
167
 
168
- demo.launch()
 
6
  from langchain_community.embeddings import OpenAIEmbeddings
7
  from langchain_community.vectorstores import FAISS
8
  from langchain_community.chat_models import ChatOpenAI
 
9
 
10
  # تنظیمات لاگ‌گیری
11
  logging.basicConfig(level=logging.INFO)
 
13
 
14
  # تنظیمات مسیرها
15
  UPLOAD_FOLDER = "uploaded_files"
16
+ DATABASE_FILE = "/home/user/app/vector_database"
17
  os.makedirs(UPLOAD_FOLDER, exist_ok=True)
18
 
19
  # بررسی و بارگذاری دیتابیس برداری
20
  def load_database():
21
  try:
22
  if os.path.exists(DATABASE_FILE):
23
+ embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("My_huggingface_key"))
24
  vector_db = FAISS.load_local(DATABASE_FILE, embeddings)
25
  logger.info(f"✅ دیتابیس بارگذاری شد: {DATABASE_FILE}")
26
  return vector_db
 
59
 
60
  try:
61
  logger.info("در حال ایجاد embeddings و ذخیره‌سازی در FAISS...")
62
+ embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("My_huggingface_key"))
 
 
 
 
 
 
63
  vector_db = FAISS.from_documents(texts, embeddings)
64
  logger.info(f"✅ ذخیره‌سازی در FAISS با موفقیت انجام شد. تعداد اسناد: {vector_db.index.ntotal}")
65
  return vector_db
 
67
  logger.error(f"خطا در ایجاد embeddings یا ذخیره‌سازی در FAISS: {e}")
68
  return None
69
 
70
+ # ایجاد لینک منبع
71
+ def generate_source_link(source, page):
72
+ return f'<a href="{source}#page={page}" target="_blank">{source}, صفحه {page}</a>'
73
+
74
  # پاسخ‌گویی بر اساس اسناد بارگذاری‌شده
75
  def chat_with_doc(query):
76
  try:
 
81
  if not query.strip():
82
  return "❌ لطفاً سوال خود را وارد کنید."
83
 
84
+ retriever = global_vector_db.as_retriever(search_kwargs={"k": 8})
 
 
 
 
 
85
  docs = retriever.get_relevant_documents(query)
 
 
 
86
 
87
+ if not docs:
88
+ return "هیچ اطلاعات مرتبطی یافت نشد."
 
 
89
 
90
+ # نمایش لاگ برای بررسی اسناد
91
+ for doc in docs:
92
+ logger.info(f"📄 سند: {doc.metadata.get('source', 'نامشخص')} | صفحه {doc.metadata.get('page', 'نامشخص')}")
93
 
94
+ # تفکیک بخش‌های نقل‌قول شده از متن سند
95
+ citations = []
96
+ context = ""
97
+ for doc in docs:
98
+ quoted_text = f"«{doc.page_content.strip()}»"
99
+ source_info = generate_source_link(doc.metadata.get("source", "نامشخص"), doc.metadata.get("page", "نامشخص"))
100
+ citations.append(f"{quoted_text} ({source_info})")
101
+ context += f"{quoted_text}\n\n"
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  llm = ChatOpenAI(model_name="gpt-3.5-turbo", openai_api_key=os.getenv("My_huggingface_key"))
104
+ prompt = f"""سوال: {query}\n\nاطلاعات مرتبط:\n{context}\n\nلطفاً به سوال پاسخ دهید:"""
105
  response = llm.predict(prompt)
106
 
107
+ final_response = f"**پاسخ:**\n{response}\n\n**نقل‌قول‌های مستقیم:**\n" + "\n".join(citations)
 
 
 
 
 
 
 
108
  return final_response
109
  except Exception as e:
110
  logger.error(f"خطا در پاسخ‌گویی بر اساس سند: {e}")
111
  return f"❌ خطایی رخ داده است: {e}"
112
 
113
+ # فرمت کردن خروجی با HTML برای Gradio
114
+ def format_response(response_text):
115
+ response_text = response_text.replace("**پاسخ:**", "<h3 style='color:blue;'>پاسخ:</h3>")
116
+ response_text = response_text.replace("**نقل‌قول‌های مستقیم:**", "<h4 style='color:green;'>نقل‌قول‌های مستقیم:</h4>")
117
+ return response_text
118
+
119
  # ذخیره فایل آپلود شده
120
  def save_uploaded_file(file):
121
  try:
 
137
  gr.Markdown("# هوش مصنوعی همراه کارشناسان توزیع برق ایران")
138
 
139
  query = gr.Textbox(label="سوال خود را بپرسید", lines=2)
140
+ response = gr.HTML(label="پاسخ", interactive=False) # تغییر از Textbox به HTML
141
  submit_btn = gr.Button("ارسال سوال")
142
 
143
  file = gr.File(label="📎 آپلود فایل", file_types=[".pdf"])
144
  upload_status = gr.Textbox(label="وضعیت آپلود", interactive=False)
145
  upload_btn = gr.Button("ارسال فایل")
146
 
 
147
  upload_btn.click(save_uploaded_file, inputs=[file], outputs=[upload_status])
148
+ submit_btn.click(lambda q: format_response(chat_with_doc(q)), inputs=[query], outputs=[response])
149
 
150
+ demo.launch()