import pandas as pd import numpy as np import os import sys import json import pickle import gradio as gr import openai from sentence_transformers import SentenceTransformer from pinecone import Pinecone, ServerlessSpec # تنظیم کلیدهای API openai.api_key = os.getenv("openai") api_key = os.getenv("PINECONE_API_KEY") region = os.getenv("PINECONE_ENVIRONMENT", "us-west1-gcp") index_name = os.getenv("PINECONE_INDEX_NAME", "tiyam-chat") # بارگذاری مدل model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') # بارگذاری داده‌ها with open("tiyam_qa_data.json", "r", encoding="utf-8") as f: data = json.load(f) # اتصال به Pinecone pc = Pinecone(api_key=api_key) existing_indexes = pc.list_indexes().names() if index_name not in existing_indexes: pc.create_index( name=index_name, dimension=384, metric="cosine", spec=ServerlessSpec( cloud="aws", region=region ) ) index = pc.Index(index_name) # سیستم کش cache_file = "chat_cache.pkl" try: with open(cache_file, "rb") as f: cache = pickle.load(f) except FileNotFoundError: cache = {} def retrieve_answer(query, threshold=0.4, top_k=1): query_embedding = model.encode([query])[0] result = index.query(vector=query_embedding.tolist(), top_k=top_k, include_metadata=True) try: result_dict = result.to_dict() except Exception: result_dict = str(result) print("=== Pinecone query result ===") if isinstance(result_dict, dict): print(json.dumps(result_dict, indent=2, ensure_ascii=False)) else: print(result_dict) print("============================") if hasattr(result, 'matches') and result.matches and len(result.matches) > 0 and result.matches[0].score > threshold: metadata = result.matches[0].metadata print("Matched answer:", metadata.get('answer')) return metadata.get('answer', 'پاسخ یافت نشد') else: print("No good match found.") return None def generate_human_response(context_text): if not context_text: return "متأسفم، پاسخ دقیقی برای این سوال نداریم. لطفاً با ما تماس بگیرید." if context_text in cache: return cache[context_text] prompt = ( f"این متن پاسخ سوال مشتری است: \"{context_text}\".\n" "لطفاً یک پاسخ کوتاه، رسمی و کاملاً مختصر به زبان فارسی تولید کن که فقط بر اساس همین متن باشد. " "پاسخ باید یک جمله‌ی کامل با یک فعل مناسب و پایان مشخص باشد. از تولید جمله‌های ناقص یا جمله‌هایی با بیش از یک فعل خودداری کن." ) try: response = openai.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "شما یک پاسخگوی رسمی شرکت هستید."}, {"role": "user", "content": prompt} ], temperature=0.3, # افزایش به 0.3 برای انعطاف‌پذیری بیشتر max_tokens=100, ) answer = response.choices[0].message.content.strip() # فقط اطمینان از وجود نقطه در پایان if answer and not answer.endswith(('.', '!', '؟')): answer += '.' cache[context_text] = answer with open(cache_file, "wb") as f: pickle.dump(cache, f) return answer except Exception as e: print("OpenAI API error:", e) return "خطا در پردازش درخواست." def chat_interface(question): answer = retrieve_answer(question) final_answer = generate_human_response(answer) return final_answer demo = gr.Interface( fn=chat_interface, inputs="text", outputs="text", title="چت‌بات تیام", description="سؤالات خود را از آژانس دیجیتال مارکتینگ تیام بپرسید." ) if __name__ == "__main__": demo.launch()