teoo33's picture
Update app.py
1330e3d verified
raw
history blame
15.5 kB
import gradio as gr
import pandas as pd
from openai import OpenAI
import json
import os
# تنظیم API کلاینت با متغیر محیطی
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise ValueError("OPENAI_API_KEY در متغیرهای محیطی تنظیم نشده است.")
client = OpenAI(api_key=api_key)
# متغیرهای سراسری
iteration_count = 0
iteration_history = ""
prompt_output = ""
knowledge_base_output = ""
faq_output = ""
business_info = None
product_info = None
last_user_request = ""
# پرامپت مادر (بدون تغییر)
mother_prompt = """
You are the Nova System, an innovative problem-solving approach implemented by a dynamic consortium of virtual experts, each serving a distinct role. Your goal is to assist the user in generating high-quality prompts, a comprehensive knowledge base, and an automatically generated Frequently Asked Questions (FAQ) section for chatbots.
...
"""
# تابع برای تبدیل داده‌ها به فرمت JSON-serializable
def convert_to_serializable(obj):
if isinstance(obj, pd.Timestamp):
return obj.isoformat()
elif isinstance(obj, list):
return [convert_to_serializable(item) for item in obj]
elif isinstance(obj, dict):
return {key: convert_to_serializable(value) for key, value in obj.items()}
return obj
# تابع برای اعتبارسنجی و اصلاح خروجی
def validate_and_fix_output(output):
print("خروجی خام مدل:", output)
parts = output.split("---")
parts = [part.strip() for part in parts if part.strip()]
print("بخش‌های جدا شده:", parts)
prompt_part = parts[0] if len(parts) > 0 else "پرامپت تولید نشد 😔"
kb_part = parts[1] if len(parts) > 1 else "پایگاه دانش تولید نشد 😕"
faq_part = parts[2] if len(parts) > 2 else "FAQ تولید نشد 🥳"
if not prompt_part.strip():
prompt_part = "پرامپت خالیه 😔"
if not kb_part.strip():
kb_part = "پایگاه دانش خالیه 😕"
if not faq_part.strip():
faq_part = "FAQ خالیه 🥳"
return [prompt_part, kb_part, faq_part]
# تابع برای خوندن و پردازش فایل‌های اکسل
def process_excel_files(file1, file2):
global business_info, product_info
business_info = pd.read_excel(file1.name).to_dict(orient="records")[0] if file1 else {}
product_info = pd.read_excel(file2.name).to_dict(orient="records") if file2 else []
return business_info, product_info
# تابع شروع فرایند
def start_process(file1, file2, user_request):
global iteration_count, iteration_history, business_info, product_info, last_user_request
iteration_count = 1
iteration_history = "سلام عزیزم! فرایند شروع شد! 😍\n"
last_user_request = user_request
business_info, product_info = process_excel_files(file1, file2)
business_info_serializable = convert_to_serializable(business_info)
product_info_serializable = convert_to_serializable(product_info)
if last_user_request:
iteration_history += f"**درخواست کاربر (فقط برای این Iteration):** {last_user_request}\n"
dce_instructions = f"iteration {iteration_count}: لطفاً یه پرامپت به انگلیسی (با بخش‌های Persona, Tone, Guidelines, About Us و غیره)، پایگاه دانش به فرمت JSON (با name, description, variants, objectID) و FAQ به فرمت JSON (با دسته‌بندی و جواب‌های کوتاه و دوستانه) بسازید. اگه درخواست کاربر وجود داره، فقط توی این Iteration اعمالش کن."
iteration_history += f"**دستورات DCE:** {dce_instructions}\n"
pee_prompt = f"""
{mother_prompt}
شما Prompt Engineering Expert (PEE) هستید. بر اساس اطلاعات زیر و درخواست کاربر، پرامپت، پایگاه دانش و FAQ رو بسازید:
اطلاعات کسب‌وکار: {json.dumps(business_info_serializable, ensure_ascii=False)}
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)}
درخواست کاربر (فقط برای این Iteration): {last_user_request if last_user_request else "هیچ درخواستی وارد نشده"}
{dce_instructions}
خروجی رو با --- جدا کنید.
"""
pee_response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": pee_prompt}]
)
pee_output = pee_response.choices[0].message.content
iteration_history += f"**خروجی PEE:**\n{pee_output}\n"
cae_prompt = f"""
{mother_prompt}
شما Critical Analysis Expert (CAE) هستید. خروجی PEE رو نقد کنید، مطمئن شید لحن درست اعمال شده، ساختار JSON درسته و درخواست کاربر (اگه هست) رعایت شده:
خروجی PEE:\n{pee_output}
"""
cae_response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": cae_prompt}]
)
cae_output = cae_response.choices[0].message.content
iteration_history += f"**نقد CAE:**\n{cae_output}\n"
dce_summary = f"""
**جمع‌بندی DCE:** iteration {iteration_count} تموم شد 🌟
**وضعیت فعلی:** پرامپت، پایگاه دانش و FAQ اولیه ساخته شدن.
**اهداف بعدی:**
#G-{iteration_count}-1: بهبود لحن و جزئیات بر اساس نقد CAE.
#G-{iteration_count}-2: تکمیل فرمت JSON.
**پایان iteration {iteration_count}**
"""
iteration_history += dce_summary
last_user_request = ""
return (iteration_history, "", "", "", "", f"Iteration {iteration_count}",
gr.update(interactive=False), gr.update(interactive=True))
# تابع ادامه Iteration
def continue_iteration(_=None):
global iteration_count, iteration_history, prompt_output, knowledge_base_output, faq_output, last_user_request
iteration_count += 1
business_info_serializable = convert_to_serializable(business_info)
product_info_serializable = convert_to_serializable(product_info)
if last_user_request:
iteration_history += f"**درخواست کاربر (فقط برای این Iteration):** {last_user_request}\n"
dce_instructions = f"iteration {iteration_count}: لطفاً خروجی قبلی رو بر اساس نقد CAE بهبود بدید، لحن رو دوستانه‌تر کنید (مگر اینکه درخواست کاربر چیز دیگه‌ای بگه) و فرمت JSON رو دقیق‌تر کنید. اگه درخواست کاربر وجود داره، فقط توی این Iteration اعمالش کن."
iteration_history += f"**دستورات DCE:** {dce_instructions}\n"
pee_prompt = f"""
{mother_prompt}
شما Prompt Engineering Expert (PEE) هستید. خروجی قبلی رو بر اساس نقد CAE و درخواست کاربر بهبود بدید:
اطلاعات کسب‌وکار: {json.dumps(business_info_serializable, ensure_ascii=False)}
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)}
درخواست کاربر (فقط برای این Iteration): {last_user_request if last_user_request else "هیچ درخواستی وارد نشده"}
تاریخچه iteration قبلی:\n{iteration_history}
{dce_instructions}
خروجی رو با --- جدا کنید.
"""
pee_response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": pee_prompt}]
)
pee_output = pee_response.choices[0].message.content
iteration_history += f"**خروجی PEE:**\n{pee_output}\n"
parts = validate_and_fix_output(pee_output)
prompt_output = parts[0]
knowledge_base_output = parts[1]
faq_output = parts[2]
cae_prompt = f"""
{mother_prompt}
شما Critical Analysis Expert (CAE) هستید. خروجی جدید PEE رو نقد کنید و مطمئن شید لحن درست اعمال شده، فرمت JSON درسته و درخواست کاربر (اگه هست) رعایت شده:
خروجی PEE:\n{pee_output}
"""
cae_response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": cae_prompt}]
)
cae_output = cae_response.choices[0].message.content
iteration_history += f"**نقد CAE:**\n{cae_output}\n"
dce_summary = f"""
**جمع‌بندی DCE:** iteration {iteration_count} تموم شد 😊
**وضعیت فعلی:** خروجی‌ها بهبود یافتن.
**اهداف بعدی:**
#G-{iteration_count}-1: ادامه بهبود یا اتمام فرایند.
**پایان iteration {iteration_count}**
"""
iteration_history += dce_summary
last_user_request = ""
return (iteration_history, prompt_output, knowledge_base_output, faq_output, "",
f"Iteration {iteration_count}", gr.update(interactive=False), gr.update(interactive=True))
# تابع پایان و تولید خروجی نهایی
def end_process(_=None):
global iteration_history, prompt_output, knowledge_base_output, faq_output, last_user_request
business_info_serializable = convert_to_serializable(business_info)
product_info_serializable = convert_to_serializable(product_info)
if last_user_request:
iteration_history += f"**درخواست کاربر (فقط برای خروجی نهایی):** {last_user_request}\n"
final_prompt = f"""
{mother_prompt}
فرایند iteration‌ها تموم شده. لطفاً خروجی نهایی رو به این ترتیب تولید کنید:
1. پرامپت چت‌بات به انگلیسی با بخش‌های:
- Persona
- Tone
- Guidelines
- About Us
- Responses to Common Questions
- Contact Information
- Additional Guidelines
لحن باید دوستانه، عامیانه، کوتاه (زیر 100 کلمه) و با ایموجی‌های جذاب باشه مگر اینکه درخواست کاربر چیز دیگه‌ای بگه.
---
2. پایگاه دانش به فرمت JSON-like با فیلدهای: name, description, variants (شامل size و price), objectID. برای هر محصول یا خدمت یه ورودی جدا بساز.
---
3. FAQ به فرمت JSON-like با دسته‌بندی‌ها (مثل Services, Care)، موضوعات، سوالات و جواب‌های کوتاه و دوستانه.
اطلاعات کسب‌وکار: {json.dumps(business_info_serializable, ensure_ascii=False)}
اطلاعات محصولات: {json.dumps(product_info_serializable, ensure_ascii=False)}
درخواست کاربر (فقط برای این مرحله): {last_user_request if last_user_request else "هیچ درخواستی وارد نشده"}
تاریخچه iteration‌ها:\n{iteration_history}
**هر بخش رو با دقیقاً "---" جدا کن. هیچ متن اضافی قبل، بعد یا بین بخش‌ها نذار.**
"""
final_response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "system", "content": final_prompt}]
)
final_output = final_response.choices[0].message.content
print("خروجی خام نهایی:", final_output)
parts = validate_and_fix_output(final_output)
prompt_output = parts[0]
knowledge_base_output = parts[1]
faq_output = parts[2]
print("پرامپت نهایی:", prompt_output)
print("پایگاه دانش نهایی:", knowledge_base_output)
print("FAQ نهایی:", faq_output)
iteration_history += "\n**فرایند تموم شد و خروجی نهایی آماده‌ست! 🎉**\n"
last_user_request = ""
return (iteration_history, prompt_output, knowledge_base_output, faq_output, "",
"فرایند پایان یافت", gr.update(interactive=True), gr.update(interactive=True))
# تابع ریست فرایند
def reset_process():
global iteration_count, iteration_history, prompt_output, knowledge_base_output, faq_output, business_info, product_info, last_user_request
iteration_count = 0
iteration_history = ""
prompt_output = ""
knowledge_base_output = ""
faq_output = ""
business_info = None
product_info = None
last_user_request = ""
return ("", "", "", "", "", "فرایند ریست شد! حالا می‌تونی دوباره شروع کنی 😊",
gr.update(interactive=True), gr.update(interactive=True))
# تابع ثبت درخواست کاربر
def submit_request(user_request):
global last_user_request
last_user_request = user_request
return "", "درخواستت ثبت شد! حالا 'ادامه دهید' رو بزن 😊"
# رابط کاربری Gradio
with gr.Blocks(title="سیستم نوا 🌟") as demo:
gr.Markdown("# سیستم نوا 🌟")
with gr.Row():
file1 = gr.File(label="فرم اطلاعات اولیه (اختیاری)")
file2 = gr.File(label="فرم محصولات/خدمات (اختیاری)")
with gr.Row():
user_request_box = gr.Textbox(label="درخواست شما", placeholder="مثلاً: 'لحن رسمی‌تر باشه' یا 'یه سرویس جدید اضافه کن'")
submit_request_btn = gr.Button("ارسال درخواست")
status_box = gr.Textbox(label="وضعیت فعلی", value="فرایند شروع نشده", interactive=False)
iteration_box = gr.Textbox(label="تاریخچه Iteration", lines=10)
with gr.Row():
start_btn = gr.Button("شروع", interactive=True)
continue_btn = gr.Button("ادامه دهید")
end_btn = gr.Button("پایان")
reset_btn = gr.Button("ریست فرایند")
with gr.Tabs():
with gr.TabItem("پرامپت"):
prompt_box = gr.Textbox(label="پرامپت (انگلیسی)")
with gr.TabItem("پایگاه دانش"):
kb_box = gr.Textbox(label="پایگاه دانش (JSON)")
with gr.TabItem("پرسش و پاسخ"):
faq_box = gr.Textbox(label="پرسش و پاسخ (JSON)")
# اتصال توابع
start_btn.click(
start_process,
inputs=[file1, file2, user_request_box],
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, status_box, start_btn, continue_btn]
)
continue_btn.click(
continue_iteration,
inputs=[],
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, status_box, start_btn, continue_btn]
)
end_btn.click(
end_process,
inputs=[],
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, status_box, start_btn, continue_btn] # کروشه بسته شد
)
reset_btn.click(
reset_process,
inputs=[],
outputs=[iteration_box, prompt_box, kb_box, faq_box, user_request_box, status_box, start_btn, continue_btn]
)
submit_request_btn.click(
submit_request,
inputs=[user_request_box],
outputs=[user_request_box, status_box]
)
demo.launch()