Files
Mehvar/modules/api_handler.py
T
2026-06-29 15:32:24 +03:30

125 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import re
from openai import OpenAI
from config import API_KEY, BASE_URL, MODEL_NAME
class APIHandler:
def __init__(self):
# ایجاد کلاینت با استفاده از کتابخانه رسمی OpenAI
self.client = OpenAI(
base_url=BASE_URL,
api_key=API_KEY
)
self.model_name = MODEL_NAME
def _call_api(self, prompt, system_prompt="شما یک دستیار هوش مصنوعی دقیق در تحلیل متن هستید.", temperature=0.3):
try:
response = self.client.chat.completions.create(
model=self.model_name,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt}
],
temperature=temperature,
timeout=60 # جلوگیری از گیر کردن برنامه در صورت کندی سرور
)
# استخراج محتوای متنی از ریسپانس استاندارد openai
return response.choices[0].message.content.strip()
except Exception as e:
print(f"API failed {e}")
return None
def get_semantic_unit(self, segment_sentences):
"""تابع ۱: استخراج واحد معنایی (برای جایگزینی در نودهای درخت)"""
text_to_summarize = " ".join(segment_sentences)
prompt = f"""تو یک دستیار هوش مصنوعی متخصص در تحلیل متن و زبان‌شناسی پردازشی هستی.
وظیفه تو این است که متن ورودی را بخوانی و تنها «هسته اصلی واحد معنایی» آن را سنتز و تولید کنی.
تعریف واحد معنایی مورد نظر: یک تک‌جملهٔ خلاصه، دقیق و جامع که یک رویداد کامل را توصیف کند. این جمله باید حتماً دارای ساختار منطقی (شامل عامل/فاعل، مفعول و فعلِ نشان‌دهنده نتیجه) باشد.
قوانین اکید خروجی (Strict Rules):
1. به هیچ‌وجه از کلمات ربط اضافی، پیش‌درآمد (مثل "جمله استخراج شده:"، "خلاصه متن:" یا "بله، حتما") و توضیحات استفاده نکن.
مثال‌ها (Few-Shot Examples):
متن ورودی: "دیروز در پی بارش شدید باران، رودخانه طغیان کرد. این اتفاق باعث شد تا تمام خانه‌های روستای مجاور زیر آب بروند و مردم مجبور به تخلیه سریع منطقه شوند."
خروجی: طغیان رودخانه بر اثر بارش باران منجر به آب‌گرفتگی خانه‌ها و تخلیه روستا شد.
متن ورودی: "تیم توسعه‌دهنده ماه‌ها روی بهینه‌سازی الگوریتم کار کرد. در نهایت موفق شدند زمان پردازش داده‌ها را به نصف کاهش دهند که این موضوع رضایت مدیران را در پی داشت."
خروجی: تلاش تیم توسعه‌دهنده برای بهینه‌سازی الگوریتم باعث کاهش نصف زمان پردازش و جلب رضایت مدیران شد.
متن ورودی اصلی:
{text_to_summarize}
"""
response = self._call_api(prompt)
return response if response else "خطا در استخراج واحد معنایی"
def extract_propositions(self, sentences):
"""تابع ۲: استخراج تک‌تک گزاره‌ها از جملات یک سگمنت (برای شروع ساخت گراف)"""
text = " ".join(sentences)
prompt = f"""
متن زیر را بخوان و تمام گزاره‌های معنایی (اقدامات، واقعیت‌ها یا مفاهیم مستقل) موجود در آن را استخراج کن.
قانون اکید: خروجی را فقط به صورت یک آرایه JSON معتبر از رشته‌ها برگردان و هیچ متن اضافه‌ای ننویس.
مثال خروجی: ["گزاره اول", "گزاره دوم"]
متن:
{text}
"""
response = self._call_api(prompt, temperature=0.2)
if not response:
return []
try:
clean_json = re.sub(r'```json|```', '', response).strip()
propositions = json.loads(clean_json)
if isinstance(propositions, list):
return propositions
return []
except Exception as e:
print(f"خطا در پارس کردن گزاره‌ها (JSON Error): {e}")
print(f"خروجی خام مدل این بود: {response}")
return []
def check_relation(self, prop1, prop2):
"""تابع ۳: بررسی رابطه غایی (هدف-وسیله) یا علت و معلولی بین دو گزاره"""
prompt = f"""
دو گزاره زیر را بررسی کن و ببین آیا رابطه "علت و معلولی" یا "غایی (هدف و وسیله)" بین آن‌ها برقرار است یا خیر.
اگر هیچ ارتباطی از این نوع وجود ندارد، دقیقاً و فقط بنویس: "ارتباط وجود ندارد"
اگر ارتباط وجود دارد، در یک گزاره کوتاه و دقیق این رابطه را توصیف کن (مثلاً: گزاره اول وسیله‌ای برای رسیدن به هدف گزاره دوم است).
گزاره ۱: {prop1}
گزاره ۲: {prop2}
"""
response = self._call_api(prompt, temperature=0.3)
return response if response else "ارتباط وجود ندارد"
def score_relation(self, relation_desc):
"""تابع ۴: امتیازدهی به رابطه از 1 تا 10"""
if not relation_desc or relation_desc.strip() == "ارتباط وجود ندارد" or relation_desc.strip() == "":
return 0
prompt = f"""
با توجه به توصیف رابطه زیر، یک نمره از 1 تا 10 به میزان قوت و منطقی بودن این رابطه علت و معلولی/غایی بده.
قانون اکید: فـــقـــط یک عدد صحیح برگردان. هیچ کاراکتر یا کلمه‌ای غیر از عدد ننویس.
توصیف رابطه:
{relation_desc}
"""
response = self._call_api(prompt, temperature=0.1)
if not response:
return 0
try:
numbers = re.findall(r'\d+', response)
if numbers:
score = int(numbers[0])
return max(1, min(10, score))
return 0
except Exception as e:
print(f"failed to extract scores {e}")
return 0