File size: 6,599 Bytes
fa3a9d9 48be6c1 fa3a9d9 728ca87 48be6c1 fa3a9d9 8375d1e 1b427e5 e05be61 fa3a9d9 e05be61 fa3a9d9 e05be61 fa3a9d9 48be6c1 fa3a9d9 991b62f fa3a9d9 8019839 8375d1e fa3a9d9 e05be61 fa3a9d9 8375d1e fa3a9d9 8375d1e fa3a9d9 8375d1e fa3a9d9 8375d1e fa3a9d9 e05be61 fa3a9d9 8375d1e fa3a9d9 8375d1e daf9c31 fa3a9d9 8019839 fa3a9d9 d7622b9 fa3a9d9 8375d1e daf9c31 8375d1e 97fad18 48be6c1 66b8e5f 97fad18 fa3a9d9 97fad18 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | import os
import atexit
import weaviate
import requests
import gradio as gr
from weaviate.classes.init import Auth
from weaviate.classes.query import Rerank
from transformers import AutoTokenizer, pipeline, AutoModelForSeq2SeqLM
from transformers import MBartForConditionalGeneration, MBart50TokenizerFast
# ====== تحميل الإعدادات من البيئة ======
WEAVIATE_CLUSTER_URL = os.environ.get("weaviate_rest")
WEAVIATE_API_KEY = os.environ.get("weaviate_api_key")
COHERE_API_KEY = os.environ.get("cohere_api_key")
PERPLEXITY_API_KEY = os.environ.get("perplexity_api_key")
PERPLEXITY_END_POINT = os.environ.get("perplexity_end_point")
# ========== إعداد الاتصال مع Weaviate ==========
def connect_to_db():
headers = {
"X-Cohere-Api-Key": COHERE_API_KEY
}
weaviate_url = WEAVIATE_CLUSTER_URL
weaviate_api_key = WEAVIATE_API_KEY
client = weaviate.connect_to_weaviate_cloud(
cluster_url=weaviate_url,
auth_credentials=Auth.api_key(weaviate_api_key),
headers=headers
)
return client
# ========== تحميل الموديلات ==========
model_checkpoint = "EN3IMI/RouterAraBERT"
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
classifier = pipeline("sentiment-analysis", model=model_checkpoint)
# ========== دوال البحث ==========
def search_for_faq(user_query, client):
collection = client.collections.use("FAQ")
response = collection.query.hybrid(
query=user_query,
limit=10,
alpha=0.40,
rerank=Rerank(prop="content", query=user_query),
)
queries = [f"{user_query} [SEP] {obj.properties['content']}" for obj in response.objects[:2]]
return queries, response.objects[:3]
def search_for_laws(user_query, client):
collection = client.collections.use("Laws")
response = collection.query.hybrid(
query=user_query,
limit=10,
alpha=0.40,
rerank=Rerank(prop="text", query=user_query),
)
return response.objects[:3]
# ========== دوال القرار ==========
def router_decision(queries):
results = classifier(queries)
labels = [res['label'] for res in results]
numeric_labels = [1 if label == 'LABEL_1' else 0 for label in labels]
return any(numeric_labels)
# ========== LLM responses ==========
def llm_response_faq(query, docs):
chunks = []
for i in docs:
chunks.append(i.properties["content"])
API_KEY = PERPLEXITY_API_KEY
ENDPOINT = PERPLEXITY_END_POINT
system_prompt = """
You are an intelligent assistant specialized in the Jordanian Land and Survey Department. Your task is to provide answers strictly based on the context provided from FAQ files.
Guidelines:
1. Use only the information available in the provided files. Do not hallucinate or invent any information.
2. If the provided context does not contain a relevant answer to the user's question, respond with: "I do not know the answer."
3. Correct any spelling or typographical errors present in the extracted text from the files.
4. Provide brief clarifications or explanations only when necessary to make the answer clear, but do not add new facts.
5. Do not modify the facts or data from the files; respect the sensitivity of the information.
6. Focus only on questions related to Jordanian land, survey, and administrative data.
7. Answer in the language of the user's question. Most questions will be in Arabic, so prioritize answering in Arabic when possible.
Instructions for answering:
- First, identify the most relevant FAQ entry based on the user's question.
- Then, provide the answer exactly as it appears in the file, fixing only spelling mistakes and minor formatting issues.
- AVOID PROVIDIND INORMATION NOT PRESENT IN THE CONTEXT.
- Always maintain accuracy and reliability.
- If you don't know the answer tell the user that you don't know in Arabic
"""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Context:\n" + "\n".join(chunks) + "\n\nQuestion:\n" + query}
]
data = {
"model": "sonar-pro",
"messages": messages,
"max_tokens": 250,
"temperature": 0.5
}
resp = requests.post(ENDPOINT, headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}, json=data)
responsed = resp.json()
return responsed['choices'][0]['message']['content']
def llm_response_laws(query, docs):
chunks = []
for i in docs:
chunks.append(i.properties["text"])
API_KEY = PERPLEXITY_API_KEY
ENDPOINT = PERPLEXITY_END_POINT
system_prompt = """
You are an intelligent assistant specialized in Jordanian laws and legislation.
Your task is to provide answers strictly based on the context provided from the legal documents.
Guidelines:
1. Use only the information available in the provided files. Do not hallucinate.
2. If the provided context does not contain a relevant answer, respond in Arabic with: "لا أعلم الجواب".
3. Correct minor spelling/formatting mistakes if needed.
4. Provide answers in Arabic when possible.
5. Be accurate and concise.
"""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Context:\n" + "\n".join(chunks) + "\n\nQuestion:\n" + query}
]
data = {
"model": "sonar-pro",
"messages": messages,
"max_tokens": 300,
"temperature": 0.5
}
resp = requests.post(
ENDPOINT,
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json=data
)
responsed = resp.json()
return responsed['choices'][0]['message']['content']
# ========== النظام الرئيسي ==========
def rag_system(user_input):
client = connect_to_db()
queries, faq_docs = search_for_faq(user_input, client)
use_laws = router_decision(queries)
if use_laws:
answer = llm_response_faq(user_input, faq_docs)
else:
law_docs = search_for_laws(user_input, client)
answer = llm_response_laws(user_input, law_docs)
client.close()
return answer
"""
@atexit.register
def close_client():
try:
client.close()
except:
pass"""
# ========== واجهة Gradio ==========
with gr.Blocks() as demo:
gr.Markdown("## 🤖 AILS RAG System")
inp = gr.Textbox(label="اكتب سؤالك")
out = gr.Textbox(label="الإجابة")
btn = gr.Button("إرسال")
btn.click(rag_system, inp, out)
if __name__ == "__main__":
demo.launch() |