anaspro commited on
Commit
76cae54
·
1 Parent(s): df14f5f
Files changed (8) hide show
  1. README.md +29 -66
  2. app.py +19 -222
  3. data/nbtel_company_profile.md +0 -296
  4. rag_requirements.txt +0 -4
  5. requirements.txt +2 -5
  6. simple_rag.py +0 -367
  7. test_rag.py +0 -126
  8. test_tts.py +0 -40
README.md CHANGED
@@ -1,90 +1,53 @@
1
  ---
2
- title: مساعد NBTEL الذكي - الدعم الفني
3
  emoji: 🤖
4
  colorFrom: blue
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 4.44.0
8
  app_file: app.py
9
  pinned: false
10
  models:
11
- - anaspro/Shako-4B-it-v5
12
  tags:
13
  - arabic
14
  - iraq
15
  - iraqi-dialect
16
- - technical-support
17
  - chatbot
18
  - multimodal
19
- - rag
20
- - customer-service
 
21
  ---
22
 
23
- # 🤖 مساعد NBTEL الذكي - الدعم الفني
24
 
25
- مساعد ذكي للدعم الفني مدعوم بتقنية RAG ونموذج شكو العراقي المتطور.
 
 
 
 
 
 
26
 
27
- ## 🚀 المميزات
28
 
29
- - 🇮🇶 **متخصص باللهجة العراقية**: يتحدث بطريقة طبيعية وودية
30
- - � **مدعوم بـ RAG**: يستخدم قاعدة معرفة شاملة عن الشركة وخدماتها
31
- - 🔧 **دعم فني متكامل**: يحل المشاكل التقنية خطوة بخطوة
32
- - 🖼️ **متعدد الوسائط**: يدعم الصور والفيديوهات والملفات الصوتية
33
- - � **قاعدة معرفة ذكية**: معلومات شاملة عن خدمات NBTEL
34
- - 💬 **تفاعلي وسريع**: ردود فورية ومفيدة
35
 
36
- ## �️ الخدمات المقدمة
 
 
 
 
 
37
 
38
- ### خدمات الإنترنت
39
- - خدمة الإنترنت اللاسلكية WiFi
40
- - خدمة الكيبل الضوئي FTTX/FTTH
41
- - دعم فني شامل 24/7
42
 
43
- ### مناطق التغطية
44
- - محافظة نينوى (الموصل)
45
- - محافظة كركوك
46
- - محافظة صلاح الدين
47
-
48
- ## 📞 معلومات التواصل
49
-
50
- - **الدعم الفني**: 6337
51
- - **واتساب**: 0773 633 7777
52
- - **الإيميل**: Info@nbtel.iq
53
- - **المبيعات**: sales@nbtele.net
54
-
55
- ## 🎯 كيفية الاستخدام
56
-
57
- 1. **اكتب استفسارك**: مثل "عندي مشكلة بالواي فاي"
58
- 2. **ارفع صور** إذا كان عندك مشكلة تقنية
59
- 3. **احصل على حل مفصل** خطوة بخطوة
60
- 4. **تواصل مع الدعم المباشر** عند الحاجة
61
-
62
- ## 🔧 التقنيات المستخدمة
63
-
64
- - **النموذج الأساسي**: Shako-4B-it-v5 (نموذج عراقي متطور)
65
- - **تقنية RAG**: Retrieval-Augmented Generation
66
- - **قاعدة المعرفة**: Sentence Transformers + Scikit-learn
67
- - **الواجهة**: Gradio
68
- - **الاستضافة**: Hugging Face Spaces
69
-
70
- ## 📋 أمثلة على الاستخدام
71
-
72
- ```
73
- المستخدم: شنو خدمات شركتكم؟
74
- المساعد: أهلاً وسهلاً بيك! احنا شركة NBTEL عراقية متخصصة بخدمات الإنترنت...
75
-
76
- المستخدم: عندي مشكلة الواي فاي ما يظهر
77
- المساعد: لا تشيل هم، راح نحلها سوا. أول شي تأكد من...
78
-
79
- المستخدم: شگد أسعار الباقات؟
80
- المساعد: عندنا باقات متنوعة: 35 ميگا بـ45,000، 60 ميگا بـ55,000...
81
- ```
82
-
83
- ---
84
-
85
- **تطوير**: فريق NBTEL التقني
86
- **النموذج**: Shako العراقي المتطور
87
- **التحديث**: أكتوبر 2024
88
 
89
  4. **تشغيل Space:**
90
  - اضغط "Restart this space" لإعادة التشغيل
 
1
  ---
2
+ title: شكو - ذكاء شكو العراقي
3
  emoji: 🤖
4
  colorFrom: blue
5
+ colorTo: green
6
  sdk: gradio
7
+ sdk_version: 5.42.0
8
  app_file: app.py
9
  pinned: false
10
  models:
11
+ - anaspro/Shako-4B-it
12
  tags:
13
  - arabic
14
  - iraq
15
  - iraqi-dialect
 
16
  - chatbot
17
  - multimodal
18
+ - voice
19
+ - image
20
+ - video
21
  ---
22
 
23
+ ذكاء صناعي عراقي متقدم يتحدث باللهجة العراقية - موديل شكو المتعدد الوسائط.
24
 
25
+ 🚀 **المميزات:**
26
+ - 🇮🇶 متخصص في اللهجة العراقية واللغة العربية
27
+ - 🧠 موديل شكو 4B المتقدم متعدد الوسائط
28
+ - 🎤 دعم التسجيل الصوتي والرد الصوتي
29
+ - 🖼️ دعم الصور والفيديوهات
30
+ - 💬 إجابات مرحة وودية بالعراقي
31
+ - 🎯 سهل الاستخدام مع واجهة عصرية
32
 
33
+ 📞 احجي مع ذكاء شكو العراقي بالعراقي - يدعم الصوت والصور والفيديو!
34
 
35
+ ## 🚀 كيفية النشر على Hugging Face Spaces ZeroGPU
 
 
 
 
 
36
 
37
+ 1. **إنشاء Space جديد:**
38
+ - اذهب إلى [Hugging Face Spaces](https://huggingface.co/spaces)
39
+ - اضغط "Create new Space"
40
+ - اختر اسم مناسب (مثل: Iraqi-Shako-AI)
41
+ - اختر "Gradio" كـ SDK
42
+ - اختر "ZeroGPU" كـ Hardware
43
 
44
+ 2. **رفع الملفات:**
45
+ - ارفع `app.py`, `requirements.txt`, `README.md`, `system_prompt.txt`
46
+ - تأكد من أن `app.py` هو الملف الرئيسي
 
47
 
48
+ 3. **إعدادات البيئة:**
49
+ - اذهب إلى Settings → Variables and secrets
50
+ - أضف `HF_TOKEN` إذا كنت تحتاج token للوصول للمودل
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  4. **تشغيل Space:**
53
  - اضغط "Restart this space" لإعادة التشغيل
app.py CHANGED
@@ -11,9 +11,6 @@ import torch
11
  from transformers import AutoModelForImageTextToText, AutoProcessor
12
  from transformers.generation.streamers import TextIteratorStreamer
13
 
14
- # استيراد نظام RAG
15
- from simple_rag import SimpleRAG
16
-
17
  # Model configuration
18
  model_id = "anaspro/Shako-4B-it-v5"
19
  processor = AutoProcessor.from_pretrained(model_id)
@@ -33,56 +30,6 @@ TARGET_FPS = int(os.getenv("TARGET_FPS", "3"))
33
  MAX_FRAMES = int(os.getenv("MAX_FRAMES", "30"))
34
  MAX_INPUT_TOKENS = int(os.getenv("MAX_INPUT_TOKENS", "10_000"))
35
 
36
- # تهيئة نظام RAG للدعم الفني
37
- print("🔄 جاري تهيئة نظام RAG للدعم الفني...")
38
- try:
39
- rag_system = SimpleRAG()
40
-
41
- # محاولة تحميل فهرس موجود
42
- if not rag_system.load_index():
43
- print("🔄 إنشاء فهرس جديد...")
44
-
45
- # تحميل ملف شركة NBTEL
46
- nbtel_file = "./data/nbtel_company_profile.md"
47
- if os.path.exists(nbtel_file):
48
- print(f"📁 وجد ملف البيانات: {nbtel_file}")
49
- documents = rag_system.load_markdown_file(nbtel_file)
50
- if documents:
51
- rag_system.add_documents(documents)
52
- rag_system.build_index()
53
- rag_system.save_index()
54
- print("✅ تم إنشاء فهرس RAG بنجاح")
55
- else:
56
- print("⚠️ لم يتم استخراج أي مستندات من الملف")
57
- else:
58
- print(f"⚠️ لم يتم العثور على ملف البيانات: {nbtel_file}")
59
- # إنشاء بيانات تجريبية بسيطة
60
- sample_docs = [
61
- {
62
- 'title': 'معلومات أساسية عن NBTEL',
63
- 'content': 'شركة NBTEL عراقية متخصصة في خدمات الإنترنت والاتصالات. نقدم خدمات WiFi و FTTX في محافظات نينوى وكركوك وصلاح الدين.',
64
- 'source': 'fallback'
65
- },
66
- {
67
- 'title': 'معلومات التواصل',
68
- 'content': 'للدعم الفني: 6337، واتساب: 0773 633 7777، إيميل: Info@nbtel.iq',
69
- 'source': 'fallback'
70
- }
71
- ]
72
- rag_system.add_documents(sample_docs)
73
- rag_system.build_index()
74
- rag_system.save_index()
75
- print("✅ تم إنشاء فهرس تجريبي")
76
-
77
- print(f"✅ نظام RAG جاهز - {len(rag_system.documents)} مستند")
78
- RAG_ENABLED = True
79
-
80
- except Exception as e:
81
- print(f"❌ خطأ في تهيئة نظام RAG: {str(e)}")
82
- print("⚠️ سيتم تشغيل النظام بدون RAG")
83
- rag_system = None
84
- RAG_ENABLED = False
85
-
86
 
87
  def get_file_type(path: str) -> str:
88
  if path.endswith(IMAGE_FILE_TYPES):
@@ -95,83 +42,6 @@ def get_file_type(path: str) -> str:
95
  raise ValueError(error_message)
96
 
97
 
98
- def search_knowledge_base(query: str) -> str:
99
- """البحث في قاعدة المعرفة باستخدام RAG"""
100
-
101
- if not RAG_ENABLED or rag_system is None:
102
- return ""
103
-
104
- try:
105
- # البحث في قاعدة المعرفة
106
- context = rag_system.get_context_for_query(query, max_results=3)
107
-
108
- if context and "لم أجد معلومات" not in context:
109
- return f"\n\n📚 معلومات من قاعدة المعرفة:\n{context}"
110
- else:
111
- return ""
112
-
113
- except Exception as e:
114
- print(f"خطأ في البحث في قاعدة المعرفة: {str(e)}")
115
- return ""
116
-
117
-
118
- def create_technical_support_prompt(user_message: str, knowledge_context: str = "") -> str:
119
- """إنشاء prompt محسن للدعم الفني"""
120
-
121
- base_prompt = """أنت مساعد دعم فني ذكي لشركة NBTEL العراقية.
122
-
123
- هويتك ومهامك:
124
- - اسمك: مساعد NBTEL الذكي
125
- - تتحدث باللهجة العراقية الودية والمرحة
126
- - خبير في خدمات الإنترنت والاتصالات والدعم الفني
127
- - تساعد العملاء في حل مشاكلهم التقنية
128
- - تقدم معلومات عن خدمات وأسعار الشركة
129
-
130
- قواعد التعامل:
131
- 1. رحب بالعميل بطريقة عراقية ودية (أهلاً وسهلاً، مرحبا بيك، الخ)
132
- 2. استخدم المعلومات من قاعدة المعرفة إن وجدت
133
- 3. اطرح أسئلة توضيحية لفهم المشكلة بدقة
134
- 4. قدم حلول عملية خطوة بخطوة
135
- 5. استخدم أمثلة عراقية مفهومة
136
- 6. كن صبور ومساعد مع العملاء
137
- 7. إذا ما تعرف الجواب، اعترف واطلب التواصل مع الدعم المباشر
138
-
139
- أسلوب الكلام:
140
- - استخدم "احنا" بدلاً من "نحن"
141
- - استخدم "شلونك" بدلاً من "كيف حالك"
142
- - استخدم "شنو" بدلاً من "ماذا"
143
- - استخدم "وين" بدلاً من "أين"
144
- - استخدم "اكو" بدلاً من "يوجد"
145
- - اجعل الكلام طبيعي ومرح
146
-
147
- معلومات الشركة الأساسية:
148
- - شركة NBTEL عراقية متخصصة بخدمات الإنترنت والاتصالات
149
- - نخدم محافظات نينوى، كركوك، وصلاح الدين
150
- - نقدم خدمات WiFi و FTTX (الكيبل الضوئي)
151
- - مقرنا الرئيسي في الموصل
152
- - رقم الدعم الفني: 6337
153
- - واتساب: 0773 633 7777
154
-
155
- """
156
-
157
- if knowledge_context:
158
- enhanced_prompt = f"""{base_prompt}
159
-
160
- {knowledge_context}
161
-
162
- الاستفسار: {user_message}
163
-
164
- جاوب بطريقة ودية وعملية، واستخدم المعلومات اللي فوق إذا كانت مفيدة:"""
165
- else:
166
- enhanced_prompt = f"""{base_prompt}
167
-
168
- الاستفسار: {user_message}
169
-
170
- جاوب بطريقة ودية وعملية:"""
171
-
172
- return enhanced_prompt
173
-
174
-
175
  def count_files_in_new_message(paths: list[str]) -> tuple[int, int]:
176
  video_count = 0
177
  non_video_count = 0
@@ -291,19 +161,6 @@ def generate(message: dict, history: list[dict], system_prompt: str = "", max_ne
291
  yield ""
292
  return
293
 
294
- # استخراج النص من الرسالة للبحث في قاعدة المعرفة
295
- user_text = message.get("text", "")
296
-
297
- # البحث في قاعدة المعرفة
298
- knowledge_context = search_knowledge_base(user_text) if user_text else ""
299
-
300
- # إنشاء prompt محسن للدعم الفني
301
- if user_text:
302
- enhanced_prompt = create_technical_support_prompt(user_text, knowledge_context)
303
- # استبدال النص الأصلي بالـ prompt المحسن
304
- message = message.copy()
305
- message["text"] = enhanced_prompt
306
-
307
  messages = []
308
  if system_prompt:
309
  messages.append({"role": "system", "content": [{"type": "text", "text": system_prompt}]})
@@ -333,12 +190,13 @@ def generate(message: dict, history: list[dict], system_prompt: str = "", max_ne
333
  streamer=streamer,
334
  max_new_tokens=max_new_tokens,
335
  do_sample=True,
336
- temperature=0.7, # قللنا الحرارة للردود أكثر منطقية
337
- top_k=50, # قللنا للحصول على ردود أكثر تركيز
338
- top_p=0.9, # قللنا للحصول على ردود أكثر دقة
339
  min_p=0.0,
340
- repetition_penalty=1.1, # زدنا شوي لتجنب التكرار
341
  disable_compile=True,
 
342
  )
343
  t = Thread(target=model.generate, kwargs=generate_kwargs)
344
  t.start()
@@ -351,33 +209,17 @@ def generate(message: dict, history: list[dict], system_prompt: str = "", max_ne
351
 
352
  # Examples for the chat interface (with additional inputs: system_prompt, max_new_tokens)
353
  examples = [
354
- ["أهلاً، شنو خدمات شركتكم؟", "", 800],
355
- ["عندي مشكلة بالواي فاي، ما يظهر عندي", "", 600],
356
- ["شگد أسعار باقات الإنترنت عندكم؟", "", 700],
357
- ["الإنترنت عندي ضعيف، شنو الحل؟", "", 600],
358
- ["كيف أقدر أغير كلمة سر الراوتر؟", "", 500],
359
- ["وين مقر الشركة ومعلومات التواصل؟", "", 400]
360
  ]
361
 
362
- # System prompt محسن للدعم الفني العراقي
363
- system_prompt = """أنت مساعد دعم فني ذكي لشركة NBTEL العراقية.
364
-
365
- تعليمات مهمة:
366
- - تحدث باللهجة العراقية البغدادية الودية والطبيعية
367
- - كن مساعد ومرح في التعامل مع العملاء
368
- - ركز على حل المشاكل التقنية وتقديم المساعدة العملية
369
- - استخدم المعلومات من قاعدة المعرفة عندما تكون متوفرة
370
- - إذا ما تعرف جواب محدد، اعترف واطلب التواصل مع الدعم المباشر
371
-
372
- أسلوب الكلام العراقي:
373
- - استخدم "شلونك" بدلاً من "كيف حالك"
374
- - استخدم "شنو" بدلاً من "ماذا"
375
- - استخدم "وين" بدلاً من "أين"
376
- - استخدم "احنا" بدلاً من "نحن"
377
- - استخدم "اكو" بدلاً من "يوجد"
378
- - استخدم "شگد" بدلاً من "كم"
379
-
380
- كن ودود ومساعد دائماً!"""
381
  # Create the chat interface
382
  demo = gr.ChatInterface(
383
  fn=generate,
@@ -386,66 +228,21 @@ demo = gr.ChatInterface(
386
  file_types=list(IMAGE_FILE_TYPES + VIDEO_FILE_TYPES + AUDIO_FILE_TYPES),
387
  file_count="multiple",
388
  autofocus=True,
389
- placeholder="اكتب استفسارك هنا... مثل: عندي مشكلة بالإنترنت، أو شنو خدماتكم؟"
390
  ),
391
  multimodal=True,
392
  additional_inputs=[
393
- gr.Textbox(
394
- label="System Prompt (اختياري)",
395
- value=system_prompt,
396
- lines=3,
397
- visible=False # مخفي للمستخدم العادي
398
- ),
399
- gr.Slider(
400
- label="Max New Tokens",
401
- minimum=100,
402
- maximum=2048,
403
- step=50,
404
- value=1024,
405
- visible=False # مخفي للمستخدم العادي
406
- ),
407
  ],
408
- title="🤖 مساعد NBTEL الذكي - الدعم الفني",
409
- description=f"""
410
- 🌟 **أهلاً وسهلاً بيك في مساعد NBTEL الذكي!**
411
-
412
- احنا هنا نساعدك في:
413
- • 🔧 حل مشاكل الإنترنت والواي فاي
414
- • 📋 معلومات عن خدماتنا وأسعارنا
415
- • 📞 التواصل والدعم الفني
416
- • 🛠️ إرشادات تقنية مفصلة
417
-
418
- {"✅ **نظام المعرفة متصل** - عندي معلومات شاملة عن الشركة والخدمات" if RAG_ENABLED else "⚠️ **نظام المعرفة غير متصل** - راح أساعدك بالمعلومات العامة"}
419
-
420
- **للدعم المباشر**: 📞 6337 | 📱 واتساب: 0773 633 7777
421
- """,
422
  examples=examples,
423
- stop_btn="إيقاف",
424
  css="""
425
  .gradio-container, .chatbot, .chatbot * {
426
  direction: rtl !important;
427
  text-align: right !important;
428
  unicode-bidi: plaintext !important;
429
- font-family: 'Tajawal', 'Cairo', 'Segoe UI', sans-serif;
430
- }
431
- .chatbot .message {
432
- padding: 15px !important;
433
- margin: 10px !important;
434
- border-radius: 15px !important;
435
- }
436
- .chatbot .message.user {
437
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
438
- color: white !important;
439
- }
440
- .chatbot .message.bot {
441
- background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%) !important;
442
- color: white !important;
443
- }
444
- .title {
445
- color: #2c3e50 !important;
446
- font-size: 2em !important;
447
- font-weight: bold !important;
448
- text-align: center !important;
449
  }
450
  """
451
  )
 
11
  from transformers import AutoModelForImageTextToText, AutoProcessor
12
  from transformers.generation.streamers import TextIteratorStreamer
13
 
 
 
 
14
  # Model configuration
15
  model_id = "anaspro/Shako-4B-it-v5"
16
  processor = AutoProcessor.from_pretrained(model_id)
 
30
  MAX_FRAMES = int(os.getenv("MAX_FRAMES", "30"))
31
  MAX_INPUT_TOKENS = int(os.getenv("MAX_INPUT_TOKENS", "10_000"))
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  def get_file_type(path: str) -> str:
35
  if path.endswith(IMAGE_FILE_TYPES):
 
42
  raise ValueError(error_message)
43
 
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  def count_files_in_new_message(paths: list[str]) -> tuple[int, int]:
46
  video_count = 0
47
  non_video_count = 0
 
161
  yield ""
162
  return
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  messages = []
165
  if system_prompt:
166
  messages.append({"role": "system", "content": [{"type": "text", "text": system_prompt}]})
 
190
  streamer=streamer,
191
  max_new_tokens=max_new_tokens,
192
  do_sample=True,
193
+ temperature=1.0,
194
+ top_k=64,
195
+ top_p=0.95,
196
  min_p=0.0,
197
+ repetition_penalty=1.0,
198
  disable_compile=True,
199
+
200
  )
201
  t = Thread(target=model.generate, kwargs=generate_kwargs)
202
  t.start()
 
209
 
210
  # Examples for the chat interface (with additional inputs: system_prompt, max_new_tokens)
211
  examples = [
212
+ ["What is the capital of France?", "You are a helpful assistant.", 700],
213
+ ["Explain quantum computing in simple terms", "You are a helpful assistant.", 512],
214
+ ["Write a short story about a robot learning to paint", "You are a helpful assistant.", 1000]
 
 
 
215
  ]
216
 
217
+ system_prompt = (
218
+ "انت موديل عراقي ذكي من بغداد. تتحدث باللهجة العراقية فقط. "
219
+ "جاوب على كل سؤال بشرح كامل وموسع، ووضح الأسباب والخلفية والمعلومات المهمة. "
220
+ "استخدم أمثلة عراقية واقعية أو حياتية كلما أمكن. "
221
+ "تجنب الفصحى نهائيًا، وخلي الرد مطول وممتع."
222
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  # Create the chat interface
224
  demo = gr.ChatInterface(
225
  fn=generate,
 
228
  file_types=list(IMAGE_FILE_TYPES + VIDEO_FILE_TYPES + AUDIO_FILE_TYPES),
229
  file_count="multiple",
230
  autofocus=True,
 
231
  ),
232
  multimodal=True,
233
  additional_inputs=[
234
+ gr.Textbox(label="System Prompt", value=system_prompt),
235
+ gr.Slider(label="Max New Tokens", minimum=100, maximum=2048, step=10, value=2048),
 
 
 
 
 
 
 
 
 
 
 
 
236
  ],
237
+ title="Shako IRAQI AI",
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  examples=examples,
239
+ stop_btn=False,
240
  css="""
241
  .gradio-container, .chatbot, .chatbot * {
242
  direction: rtl !important;
243
  text-align: right !important;
244
  unicode-bidi: plaintext !important;
245
+ font-family: 'Tajawal', 'Cairo', sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  }
247
  """
248
  )
data/nbtel_company_profile.md DELETED
@@ -1,296 +0,0 @@
1
- # ملف تعريف شركة NBTEL
2
- **تاريخ الإصدار**: مايو 2024
3
-
4
- ## من نحن
5
-
6
- شركة NBTEL لتكنولوجيا المعلومات، واحدة من أكبر الشركات العراقية في هذا المجال. نوفر خدمات الإنترنت في المحافظات الشمالية العراقية نينوى وكركوك وصلاح الدين بالشراكة مع وزارة الاتصالات العراقية.
7
-
8
- ### خدماتنا الرئيسية
9
- - خدمات الإنترنت الكيبل الضوئي FTTX في محافظة نينوى
10
- - خدمات مختلفة بكل ما يتعلق بالكيبل الضوئي من مد ونصب وتشغيل وصيانة
11
- - توفير الخدمات إلى مشغلين خدمة GSM في العراق: ASIACELL, KOREK TELECOM, ZAIN IRAQ
12
- - شراكة مع وزارة الاتصالات العراقية
13
-
14
- ### شراكاتنا
15
- - شراكات عمل مع العديد من الشركات المحلية في العراق
16
- - شراكات استراتيجية مع شركات عالمية مثل نوكيا
17
- - تعاون مع شركات عالمية كبرى مثل Google (Alphabet), Meta (Facebook)
18
-
19
- ## رؤيتنا
20
-
21
- تقديم نموذجاً متقدماً في العمل، محوره الرئيس سعادة الزبون، وتعزيز جودة الخدمة من خلال:
22
- - العديد من الاستراتيجيات والمؤشرات
23
- - إعادة صياغة مفهوم مبتكر وإطار متكامل لتقديم الخدمات
24
- - رفع كفاءة الخدمات إلى أفضل المستويات العالمية
25
- - السعي المستمر إلى تطوير وتحسين مستوى بيئة أداء الخدمات
26
-
27
- ## ما الذي يميز شركتنا
28
-
29
- ### مبدأ الشراكة
30
- - نجحنا في اكتساب ثقة قاعدة واسعة من العملاء
31
- - نفتخر بأعلى معدلات الاحتفاظ بالعملاء (93%)
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
- - اختيار NBTEL كعلامة تجارية للشركة
95
-
96
- ### التطور
97
- - تضاعف حجم الشركة عدة مرات
98
- - أصبحت واحدة من أكبر الشركات العراقية في مجال تكنولوجيا المعلومات
99
- - شريك رسمي لوزارة الاتصالات العراقية
100
- - وضع الأسس لبناء منظومة محكمة تصوب الأهداف
101
-
102
- ### الإنجازات والعقود
103
-
104
- #### عام 2020
105
- - إضافة نشاط الإنترنت والاتصالات
106
- - عقد تمرير السعات
107
- - عقد المشاركة بتسويق وإمرار سعات الاتصالات عبر شبكة الكيبل الضوئي الوطني
108
- - مدة العقد 3 سنوات في تقديم خدمات الإنترنت اللاسلكية WIFI والمنافذ الحدودية البرية
109
- - شراكة مع شركة ETSI في بغداد
110
-
111
- #### عام 2021
112
- - شراكة مع شركة ضوء الفضاء STS
113
- - عقد منظومة FTTH
114
- - عقود مع شركة SEP لخدمات تكنولوجيا المعلومات والبرمجيات
115
- - عقود صيانة مع شركة ماستر نيتورك
116
-
117
- #### عام 2022
118
- - تسويق السعات
119
- - إضافة نشاط تكنولوجيا المعلومات
120
- - عقد الشراكة الاستراتيجية مع شركة NOKIA
121
- - عقود صيانة مع شركة KOREK TELECOM
122
- - عقود صيانة مع شركة ASIACELL
123
-
124
- #### عام 2023
125
- - عقود صيانة مع شركة ZAIN IRAQ
126
- - ترخيص التسويق لثلاثة محافظات (نينوى، صلاح الدين، كركوك)
127
-
128
- #### عام 2024
129
- - عقد إنشاء وتشغيل وتسويق وصيانة منظومة خدمات FTTH في محافظة نينوى
130
- - أصبحت الخدمة متاحة للمنازل والمباني والقطاع الخاص والعام والأفراد والشركات
131
- - مدة العقد 12 سنة، أصبح اسمها FTTX
132
-
133
- ## مشاركاتنا
134
-
135
- ### المعارض والمؤتمرات
136
- - معرض بغداد الدولي I TEX (فبراير 2022)
137
- - مهرجان الربيع في الموصل (2023، 2024)
138
- - معرض صناعتنا هويتنا في نينوى (سبتمبر 2022)
139
- - الزيارة الأربعينية لكربلاء (2022)
140
-
141
- ### الفعاليات الثقافية والاجتماعية
142
- - دعم راديو الغد افتتاحية متحف الموصل (2020)
143
- - مسرح الربيع أوركسترا وتر (2021)
144
- - مهرجان التعليم الحكومي والأهلي أشور لاند (2022)
145
- - قاعة الهيثم ذكرى تأسيس قناة suroyo TV الفضائية (2022)
146
- - احياء روح وتراث الموصل مع UNESCO (2023)
147
-
148
- ### النشاطات التدريبية والتثقيفية
149
- - استضافة الطلبة من مختلف الجامعات والكليات
150
- - ندوة تدريبية حول خدمة الكيبل الضوئي والأمن السيبراني
151
- - دورة تدريبية عن مشروع FTTH
152
- - تغطية خدمة الإنترنت مجاناً في مؤتمر السنودس المقدس
153
- - دورة تدريبية عملية لكيفية إيصال وربط FTTH للمنازل
154
-
155
- ## خدماتنا
156
-
157
- ### الخدمة الأولى: خدمة الإنترنت اللاسلكية WiFi Internet Service
158
-
159
- #### الوصف
160
- - خدمة الإنترنت اللاسلكية عبر الأبراج
161
- - نقدمها من خلال وكلائنا وبالشراكة معهم ومع وزارة الاتصالات
162
- - تصل للزبون من خلال أبراج الوايرلس WiFi
163
- - نقدمها في نينوى وصلاح الدين وتكريت
164
-
165
- #### شركاؤنا
166
- - شركة بلوسكاي
167
- - شركة سوفت لينك
168
- - تحالف نينوى
169
-
170
- ### الخدمة الثانية: خدمة الإنترنت الكيبل الضوئي FTTX Internet Service
171
-
172
- #### الوصف
173
- - خدمة الإنترنت الضوئي FTTX عبر تمرير مباشر للكيبل الضوئي
174
- - وصولاً إلى آخر نقطة وهو البيت أو الشركة كمستخدم نهائي
175
- - خدمة الكيبل الضوئي إلى المنزل FTTH
176
- - تعتبر الأفضل والأحدث والأكفأ عالمياً
177
-
178
- #### مناطق التغطية
179
- - حصرياً في محافظة نينوى في الوقت الحالي
180
- - في مناطق معينة فقط نظراً للتحديات في البنية التحتية
181
- - تحتاج إلى عمل كبير واستثمار عالي ووقت غير قليل
182
-
183
- #### التحديات
184
- - تدمير كبير في البنية التحتية في السنوات السابقة
185
- - تحديات في التنسيق مع مختلف الجهات
186
- - تنظيم حفر ومد ونصب وتأهيل للبنى التحتية
187
-
188
- ### الخدمات الأخرى
189
-
190
- #### أ. خدمة تهيئة وصيانة البنية التحتية
191
- - متعلقة بالكوابل الضوئية
192
-
193
- #### ب. خدمات تكنولوجيا المعلومات
194
- - التحول الرقمي والأتمتة
195
- - الأمن السيبراني والمراقبة
196
- - ربط منظومات الذكاء الاصطناعي AI
197
- - حلول عالية المستوى بأحدث وأرقى التكنولوجيا العالمية
198
- - تعاون مع رو��د الصناعة العالمية
199
-
200
- ## معلومات الاتصال
201
-
202
- ### الإيميلات
203
- - **الاتصالات العامة**: Info@nbtel.iq
204
- - **المبيعات**: sales@nbtele.net
205
-
206
- ### خدمة العملاء والدعم الفني
207
- - **الهاتف**: 6337 (نحتاج رقم رسمي)
208
- - **الواتساب**: 0773 633 7777
209
-
210
- ### التواصل الاجتماعي
211
- - **فيسبوك**: facebook.com/nbtel/
212
- - **انستغرام**: instagram.com/nb.tel/
213
-
214
- ## الدعم الفني - المشاكل التقنية
215
-
216
- ### مشكلة: شبكة الواي فاي لا تظهر
217
- **الأعراض**: WLAN2.4G, WLAN5G مطفأة
218
- **الحلول**:
219
- - إذا كان جهازك نوكيا: تأكد أنه موصول بالكهرباء وتأكد من ضوء ONU
220
- - اضغط على زر WLAN خلف الجهاز لتشغيل الواي فاي
221
- - إذا كان لديك ONU: تأكد من إعدادات راوترك الشخصي وأضواء الجهاز ON
222
-
223
- ### مشكلة: لا يوجد خدمة
224
- **الحلول**:
225
- - تأكد من أن جهازك موصول بالكهرباء power: ON
226
- - تأكد من Link: ON
227
- - تأكد من عدد الأجهزة المتصلة على الراوتر
228
- - عدا ذلك تواصل مع الدعم الفني
229
-
230
- ### مشكلة: ضعف في الخدمة / الإنترنت ضعيف
231
- **الحلول**:
232
- - تأكد من أنك ضمن مجال تغطية الواي فاي
233
- - تأكد أن الجهاز موصول بمصدر كهرباء ثابت
234
- - عدا ذلك تواصل مع الدعم الفني
235
-
236
- ### مشكلة: عندي انقطاعات
237
- **الحلول**:
238
- - تأكد من أنك ضمن مجال تغطية الواي فاي
239
- - تأكد من جودة المحولة أو العاكسة
240
- - تأكد من جودة الأسلاك
241
- - تأكد من جودة الراوتر
242
-
243
- ### مشكلة: الراوتر الثانوي لا يعمل
244
- **الحلول**:
245
- - تأكد من جودة كابل الإيثرنت وأنه موصل برقم المنفذ المفتوح
246
- - تأكد من إعدادات الجهاز الثانوي
247
-
248
- ### مشكلة: لا أستطيع تسجيل الدخول TOD
249
- **الحلول**:
250
- - يرجى التأكد من إدخال الرقم المسجل بالعقد مع إضافة مفتاح الدولة +964
251
- - التأكد من صحة الرقم السري
252
-
253
- ### تغيير اسم ورمز الواي فاي Nokia ONT
254
- **الخطوات**:
255
- 1. افتح متصفحك وأدخل 192.168.1.254
256
- 2. أدخل معلومات الدخول (اسم المستخدم وكلمة المرور) الموجودة خلف الجهاز
257
- 3. من الإعدادات غيّر كلمة المرور
258
-
259
- ## خدمات التركيب
260
-
261
- ### هل يمكن نقل الخدمة إلى عنوان جديد؟
262
- نعم، يمكن نقل الخدمة ضمن نطاق التغطية بعد التنسيق معنا
263
-
264
- ### هل تتوفر الخدمة في منطقتي؟
265
- تواصل معنا وسنزودك بمعلومات التغطية حسب موقعك
266
-
267
- ### كيف ألغي اشتراكي؟
268
- لإلغاء الاشتراك، تواصل مع خدمة العملاء وسيتم تنفيذ الطلب
269
-
270
- ### هل التركيب مجاني؟
271
- نعم، التركيب مجاني
272
-
273
- ### ما المطلوب حتى أشترك بالخدمة؟
274
- - البطاقة الموحدة مع بطاقة السكن
275
- - المربع الذهبي
276
- - رقم الموبايل
277
- - موقع GPS
278
-
279
- ### كيف أقدم على اشتراك جديد؟
280
- ابعث اسمك الثلاثي على رقم الحجوزات +96477
281
-
282
- ## الاشتراكات والدفع
283
-
284
- ### اشتراكات للمنازل والمؤسسات
285
- - اشتراك Public IP متوفر
286
-
287
- ### الباقات المتوفرة
288
- - **35 Mbps**: 45,000 على موديمك
289
- - **60 Mbps**: 55,000 على موديمك
290
- - **100 Mbps**: 75,000 على موديمك
291
-
292
- ### هل أستطيع تغيير الباقة الخاصة بي؟
293
- نعم، يمكنك تغيير الباقة بعد انتهاء الباقة الحالية عبر التطبيق أو بالتواصل معنا
294
-
295
- ### هل يوجد عروض أو خصومات حالياً؟
296
- تابعنا على منصات التواصل الاجتماعي للاطلاع على العروض
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
rag_requirements.txt DELETED
@@ -1,4 +0,0 @@
1
- # المكتبات الأساسية لنظام RAG البسيط
2
- sentence-transformers>=2.2.0
3
- scikit-learn>=1.0.0
4
- numpy>=1.21.0
 
 
 
 
 
requirements.txt CHANGED
@@ -1,11 +1,8 @@
1
- gradio>=4.44.1
2
  spaces[huggingface]>=0.28.0
3
  transformers>=4.35.0
4
  torch>=2.1.0
5
  av
6
  accelerate>=0.25.0
7
  timm
8
- gTTS>=2.5.0
9
- sentence-transformers>=2.2.0
10
- scikit-learn>=1.0.0
11
- numpy>=1.21.0
 
1
+ gradio>=4.0.0
2
  spaces[huggingface]>=0.28.0
3
  transformers>=4.35.0
4
  torch>=2.1.0
5
  av
6
  accelerate>=0.25.0
7
  timm
8
+ gTTS>=2.5.0
 
 
 
simple_rag.py DELETED
@@ -1,367 +0,0 @@
1
- """
2
- نظام RAG بسيط لشركة NBTEL
3
- يحول ملف PDF إلى قاعدة معرفة قابلة للبحث
4
- """
5
-
6
- import os
7
- import json
8
- import re
9
- from typing import List, Dict, Any
10
- from sentence_transformers import SentenceTransformer
11
- import numpy as np
12
- from sklearn.metrics.pairwise import cosine_similarity
13
- import pickle
14
- from pathlib import Path
15
-
16
-
17
- class SimpleRAG:
18
- """نظام RAG بسيط بدون مكتبات معقدة"""
19
-
20
- def __init__(self):
21
- """تهيئة النظام"""
22
- print("🔄 جاري تحميل نموذج التضمين...")
23
-
24
- # استخدام نموذج صغير وسريع
25
- self.model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
26
-
27
- self.documents = []
28
- self.embeddings = None
29
-
30
- # مجلدات البيانات
31
- os.makedirs("./data", exist_ok=True)
32
- os.makedirs("./rag_index", exist_ok=True)
33
-
34
- print("✅ تم تحميل النظام بنجاح")
35
-
36
- def load_markdown_file(self, file_path: str) -> List[Dict[str, Any]]:
37
- """
38
- تحميل ملف Markdown وتقسيمه إلى أقسام
39
-
40
- Args:
41
- file_path: مسار الملف
42
-
43
- Returns:
44
- قائمة الأقسام
45
- """
46
- documents = []
47
-
48
- try:
49
- with open(file_path, 'r', encoding='utf-8') as f:
50
- content = f.read()
51
-
52
- print(f"📄 قراءة الملف، الحجم: {len(content)} حرف")
53
-
54
- # تقسيم بسيط حسب العناوين
55
- sections = re.split(r'\n(#{1,3}\s+.*?)\n', content)
56
-
57
- current_title = "مقدمة"
58
- current_content = ""
59
-
60
- for i, section in enumerate(sections):
61
- section = section.strip()
62
- if not section:
63
- continue
64
-
65
- # إذا كان عنوان (يبدأ بـ #)
66
- if section.startswith('#'):
67
- # حفظ القسم السابق
68
- if current_content.strip():
69
- documents.append({
70
- 'title': current_title,
71
- 'content': current_content.strip(),
72
- 'source': 'nbtel_profile',
73
- 'section_type': 'main'
74
- })
75
-
76
- # بدء قسم جديد
77
- current_title = section.replace('#', '').strip()
78
- current_content = ""
79
- else:
80
- # إضافة المحتوى للقسم الحالي
81
- current_content += section + "\n"
82
-
83
- # إضافة القسم الأخير
84
- if current_content.strip():
85
- documents.append({
86
- 'title': current_title,
87
- 'content': current_content.strip(),
88
- 'source': 'nbtel_profile',
89
- 'section_type': 'main'
90
- })
91
-
92
- # تقسيم إضافي للأقسام الطويلة جداً
93
- final_docs = []
94
- for doc in documents:
95
- if len(doc['content']) > 1500:
96
- chunks = self._split_long_text(doc['content'], max_length=1200)
97
- for i, chunk in enumerate(chunks):
98
- if chunk.strip(): # تأكد من وجود محتوى
99
- final_docs.append({
100
- 'title': f"{doc['title']} - جزء {i+1}",
101
- 'content': chunk,
102
- 'source': doc['source'],
103
- 'section_type': 'chunk'
104
- })
105
- else:
106
- if doc['content'].strip(): # تأكد من وجود محتوى
107
- final_docs.append(doc)
108
-
109
- # إزالة المستندات الفارغة
110
- final_docs = [doc for doc in final_docs if len(doc['content'].strip()) > 50]
111
-
112
- print(f"✅ تم تحميل {len(final_docs)} قسم من الملف")
113
- return final_docs
114
-
115
- except Exception as e:
116
- print(f"❌ خطأ في تحميل الملف: {str(e)}")
117
- return []
118
-
119
- def _split_long_text(self, text: str, max_length: int = 800) -> List[str]:
120
- """تقسيم النص الطويل إلى أجزاء"""
121
-
122
- # تقسيم حسب الفقرات أولاً
123
- paragraphs = text.split('\n\n')
124
- chunks = []
125
- current_chunk = ""
126
-
127
- for para in paragraphs:
128
- if len(current_chunk + para) < max_length:
129
- current_chunk += para + "\n\n"
130
- else:
131
- if current_chunk.strip():
132
- chunks.append(current_chunk.strip())
133
- current_chunk = para + "\n\n"
134
-
135
- if current_chunk.strip():
136
- chunks.append(current_chunk.strip())
137
-
138
- return chunks
139
-
140
- def add_documents(self, documents: List[Dict[str, Any]]):
141
- """إضافة مستندات جديدة"""
142
-
143
- print(f"🔄 جاري إضافة {len(documents)} مستند...")
144
-
145
- for doc in documents:
146
- # إضافة معرف فريد
147
- doc['id'] = len(self.documents)
148
-
149
- # تنظيف وتحسين المحتوى
150
- content = doc['content']
151
- content = re.sub(r'\s+', ' ', content) # إزالة المسافات الزائدة
152
- content = content.strip()
153
-
154
- doc['content'] = content
155
- doc['content_length'] = len(content)
156
-
157
- self.documents.append(doc)
158
-
159
- print(f"✅ تم إضافة {len(documents)} مستند")
160
-
161
- def build_index(self):
162
- """بناء فهرس البحث"""
163
-
164
- if not self.documents:
165
- print("⚠️ لا توجد مستندات")
166
- return
167
-
168
- print(f"🔄 جاري بناء فهرس لـ {len(self.documents)} مستند...")
169
-
170
- # استخراج النصوص
171
- texts = []
172
- for doc in self.documents:
173
- # دمج العنوان والمحتوى للبحث الأفضل
174
- search_text = f"{doc['title']}\n{doc['content']}"
175
- texts.append(search_text)
176
-
177
- # حساب التضمينات
178
- self.embeddings = self.model.encode(texts, show_progress_bar=True)
179
-
180
- print(f"✅ تم بناء الفهرس - {len(self.documents)} مستند")
181
-
182
- def search(self, query: str, top_k: int = 5) -> List[Dict[str, Any]]:
183
- """
184
- البحث في المستندات
185
-
186
- Args:
187
- query: الاستعلام
188
- top_k: عدد النتائج
189
-
190
- Returns:
191
- النتائج مرتبة حسب الصلة
192
- """
193
-
194
- if self.embeddings is None:
195
- print("⚠️ لم يتم بناء الفهرس")
196
- return []
197
-
198
- # تحويل الاستعلام إلى تضمين
199
- query_embedding = self.model.encode([query])
200
-
201
- # حساب التشابه
202
- similarities = cosine_similarity(query_embedding, self.embeddings)[0]
203
-
204
- # ترتيب النتائج
205
- top_indices = np.argsort(similarities)[::-1][:top_k]
206
-
207
- results = []
208
- for i, idx in enumerate(top_indices):
209
- if similarities[idx] > 0.1: # عتبة التشابه الدنيا
210
- doc = self.documents[idx].copy()
211
- doc['similarity_score'] = float(similarities[idx])
212
- doc['rank'] = i + 1
213
- results.append(doc)
214
-
215
- return results
216
-
217
- def get_context_for_query(self, query: str, max_results: int = 3) -> str:
218
- """
219
- الحصول على السياق للاستعلام
220
-
221
- Args:
222
- query: الاستعلام
223
- max_results: أقصى عدد نتائج
224
-
225
- Returns:
226
- النص المنسق للسياق
227
- """
228
-
229
- results = self.search(query, top_k=max_results)
230
-
231
- if not results:
232
- return "لم أجد معلومات ذات صلة في قاعدة المعرفة."
233
-
234
- context = "معلومات من قاعدة المعرفة:\n\n"
235
-
236
- for result in results:
237
- score = result['similarity_score']
238
- title = result['title']
239
- content = result['content']
240
-
241
- # قطع النص إذا كان طويلاً جداً
242
- if len(content) > 500:
243
- content = content[:500] + "..."
244
-
245
- context += f"📄 **{title}** (درجة الصلة: {score:.2f}):\n"
246
- context += f"{content}\n\n"
247
-
248
- return context
249
-
250
- def save_index(self, path: str = "./rag_index"):
251
- """حفظ الفهرس"""
252
-
253
- path = Path(path)
254
- path.mkdir(exist_ok=True)
255
-
256
- # حفظ المستندات
257
- with open(path / "documents.pkl", "wb") as f:
258
- pickle.dump(self.documents, f)
259
-
260
- # حفظ التضمينات
261
- if self.embeddings is not None:
262
- np.save(path / "embeddings.npy", self.embeddings)
263
-
264
- # حفظ معلومات النظام
265
- info = {
266
- "num_documents": len(self.documents),
267
- "embedding_dim": self.embeddings.shape[1] if self.embeddings is not None else 0,
268
- "model_name": self.model.get_sentence_embedding_dimension()
269
- }
270
-
271
- with open(path / "info.json", "w", encoding="utf-8") as f:
272
- json.dump(info, f, ensure_ascii=False, indent=2)
273
-
274
- print(f"✅ تم حفظ الفهرس في {path}")
275
-
276
- def load_index(self, path: str = "./rag_index") -> bool:
277
- """تحميل فهرس محفوظ"""
278
-
279
- path = Path(path)
280
-
281
- if not path.exists():
282
- print(f"⚠️ لم يتم العثور على فهرس في {path}")
283
- return False
284
-
285
- try:
286
- # تحميل المستندات
287
- with open(path / "documents.pkl", "rb") as f:
288
- self.documents = pickle.load(f)
289
-
290
- # تحميل التضمينات
291
- embeddings_path = path / "embeddings.npy"
292
- if embeddings_path.exists():
293
- self.embeddings = np.load(embeddings_path)
294
-
295
- print(f"✅ تم تحميل الفهرس - {len(self.documents)} مستند")
296
- return True
297
-
298
- except Exception as e:
299
- print(f"❌ خطأ في تحميل الفهرس: {str(e)}")
300
- return False
301
-
302
- def get_stats(self) -> Dict[str, Any]:
303
- """إحصائيات النظام"""
304
-
305
- if not self.documents:
306
- return {"message": "لا توجد مستندات"}
307
-
308
- total_chars = sum(doc['content_length'] for doc in self.documents)
309
- avg_length = total_chars / len(self.documents)
310
-
311
- return {
312
- "total_documents": len(self.documents),
313
- "total_characters": total_chars,
314
- "average_document_length": round(avg_length, 1),
315
- "index_built": self.embeddings is not None,
316
- "embedding_dimension": self.embeddings.shape[1] if self.embeddings is not None else 0
317
- }
318
-
319
-
320
- def main():
321
- """الدالة الرئيسية لاختبار النظام"""
322
-
323
- # إنشاء نظام RAG
324
- rag = SimpleRAG()
325
-
326
- # محاولة تحميل فهرس موجود
327
- if not rag.load_index():
328
- print("🔄 إنشاء فهرس جديد...")
329
-
330
- # تحميل ملف الشركة
331
- file_path = "./data/nbtel_company_profile.md"
332
- if os.path.exists(file_path):
333
- documents = rag.load_markdown_file(file_path)
334
- rag.add_documents(documents)
335
- rag.build_index()
336
- rag.save_index()
337
- else:
338
- print(f"❌ لم يتم العثور على الملف: {file_path}")
339
- return
340
-
341
- # عرض الإحصائيات
342
- stats = rag.get_stats()
343
- print(f"\n📊 إحصائيات النظام:")
344
- for key, value in stats.items():
345
- print(f" {key}: {value}")
346
-
347
- # اختبار البحث
348
- print(f"\n🔍 اختبار البحث:")
349
-
350
- test_queries = [
351
- "ما هي خدمات الشركة؟",
352
- "كيف أتواصل مع الدعم الفني؟",
353
- "ما هي أسعار الباقات؟",
354
- "مشكلة في الواي فاي",
355
- "معلومات عن الشركة"
356
- ]
357
-
358
- for query in test_queries:
359
- print(f"\n❓ السؤال: {query}")
360
- context = rag.get_context_for_query(query, max_results=2)
361
- print(f"📋 السياق:")
362
- print(context[:300] + "..." if len(context) > 300 else context)
363
- print("-" * 50)
364
-
365
-
366
- if __name__ == "__main__":
367
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_rag.py DELETED
@@ -1,126 +0,0 @@
1
- """
2
- تطبيق بسيط لاختبار نظام RAG
3
- """
4
-
5
- from simple_rag import SimpleRAG
6
- import os
7
-
8
-
9
- def interactive_search():
10
- """تطبيق تفاعلي للبحث"""
11
-
12
- print("🤖 مرحباً بك في نظام RAG لشركة NBTEL")
13
- print("=" * 50)
14
-
15
- # تهيئة النظام
16
- rag = SimpleRAG()
17
-
18
- # تحميل البيانات
19
- if not rag.load_index():
20
- print("🔄 إنشاء فهرس جديد...")
21
-
22
- file_path = "./data/nbtel_company_profile.md"
23
- if os.path.exists(file_path):
24
- documents = rag.load_markdown_file(file_path)
25
- rag.add_documents(documents)
26
- rag.build_index()
27
- rag.save_index()
28
- print("✅ تم إنشاء الفهرس بنجاح")
29
- else:
30
- print(f"❌ لم يتم العثور على ملف البيانات")
31
- return
32
-
33
- # عرض الإحصائيات
34
- stats = rag.get_stats()
35
- print(f"\n📊 الفهرس يحتوي على {stats['total_documents']} مستند")
36
-
37
- print("\n💡 اكتب استفسارك أو 'exit' للخروج")
38
- print("=" * 50)
39
-
40
- while True:
41
- try:
42
- # الحصول على الاستعلام
43
- query = input("\n🔍 استفسارك: ").strip()
44
-
45
- if query.lower() in ['exit', 'خروج', 'quit']:
46
- print("👋 شكراً لاستخدام النظام!")
47
- break
48
-
49
- if not query:
50
- continue
51
-
52
- # البحث
53
- print("\n🔄 جاري البحث...")
54
- context = rag.get_context_for_query(query, max_results=3)
55
-
56
- print("\n📋 النتائج:")
57
- print("-" * 30)
58
- print(context)
59
- print("-" * 30)
60
-
61
- except KeyboardInterrupt:
62
- print("\n👋 شكراً لاستخدام النظام!")
63
- break
64
- except Exception as e:
65
- print(f"❌ حدث خطأ: {str(e)}")
66
-
67
-
68
- def test_common_questions():
69
- """اختبار الأسئلة الشائعة"""
70
-
71
- print("🧪 اختبار الأسئلة الشائعة")
72
- print("=" * 50)
73
-
74
- rag = SimpleRAG()
75
-
76
- if not rag.load_index():
77
- print("❌ لا يوجد فهرس محفوظ. قم بتشغيل النظام أولاً")
78
- return
79
-
80
- questions = [
81
- "ما هي خدمات شركة NBTEL؟",
82
- "كيف أتواصل مع الدعم الفني؟",
83
- "ما هي أسعار باقات الإنترنت؟",
84
- "عندي مشكلة الواي فاي ما يظهر",
85
- "كيف أغير كلمة سر الراوتر؟",
86
- "هل يمكن نقل الخدمة لعنوان جديد؟",
87
- "وين مقر الشركة؟",
88
- "شنو تاريخ الشركة؟",
89
- "عندي انقطاعات بالإنترنت"
90
- ]
91
-
92
- for i, question in enumerate(questions, 1):
93
- print(f"\n❓ سؤال {i}: {question}")
94
- context = rag.get_context_for_query(question, max_results=2)
95
-
96
- # عرض أول 200 حرف من النتيجة
97
- preview = context[:200] + "..." if len(context) > 200 else context
98
- print(f"📋 النتيجة: {preview}")
99
- print("-" * 40)
100
-
101
-
102
- def main():
103
- """القائمة الرئيسية"""
104
-
105
- while True:
106
- print("\n🤖 نظام RAG لشركة NBTEL")
107
- print("=" * 30)
108
- print("1. البحث التفاعلي")
109
- print("2. اختبار الأسئلة الشائعة")
110
- print("3. الخروج")
111
-
112
- choice = input("\nاختر خيار (1-3): ").strip()
113
-
114
- if choice == "1":
115
- interactive_search()
116
- elif choice == "2":
117
- test_common_questions()
118
- elif choice == "3":
119
- print("👋 وداعاً!")
120
- break
121
- else:
122
- print("❌ خيار غير صحيح")
123
-
124
-
125
- if __name__ == "__main__":
126
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_tts.py DELETED
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- from gtts import gTTS
4
- import io
5
- import base64
6
- import tempfile
7
-
8
- def generate_speech(text: str, lang: str = 'ar') -> tuple[str, str]:
9
- """Generate speech from text using Google TTS and return audio file path and base64 data."""
10
- try:
11
- # Create TTS object
12
- tts = gTTS(text=text, lang=lang, slow=False)
13
-
14
- # Save to temporary file
15
- temp_audio_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp3')
16
- temp_audio_file.close()
17
-
18
- tts.save(temp_audio_file.name)
19
-
20
- # Also create base64 version for direct playback
21
- audio_buffer = io.BytesIO()
22
- tts.write_to_fp(audio_buffer)
23
- audio_buffer.seek(0)
24
- audio_base64 = base64.b64encode(audio_buffer.read()).decode('utf-8')
25
-
26
- return temp_audio_file.name, f"data:audio/mp3;base64,{audio_base64}"
27
- except Exception as e:
28
- print(f"TTS Error: {e}")
29
- return None, None
30
-
31
- if __name__ == "__main__":
32
- # Test the TTS function
33
- text = "مرحبا، هذا اختبار للصوت"
34
- file_path, audio_data = generate_speech(text)
35
- if file_path and audio_data:
36
- print(f"Audio file created: {file_path}")
37
- print(f"Audio data length: {len(audio_data)}")
38
- print("TTS test successful!")
39
- else:
40
- print("TTS test failed!")