Complete local hybrid search and improve agent reliability

This commit is contained in:
Hamza Ayed
2026-10-02 23:38:02 +03:00
parent 3563a104a3
commit 140f6eb287
62 changed files with 7546 additions and 314 deletions
+44 -5
View File
@@ -65,12 +65,49 @@ python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
- `POST /v1/chat/completions` يمرر الطلب إلى الخادم المحلي عند ضبط المتغيرين أعلاه.
- يمكن التبديل في Swagger بين النموذجين بإضافة `model` إلى جسم الطلب، مثل `gemma4:e2b`.
تثبيت OCR المحلي الاختياري للصور وPDFات الممسوحة:
```powershell
python -m pip install -r requirements-ocr.txt
```
تُحمّل EasyOCR أوزان العربية والإنجليزية لأول مرة إلى `%LOCALAPPDATA%\SovereignAI\models\easyocr` (نحو 300MB في تجربة Windows). الصور والوثائق نفسها تبقى داخل FastAPI ولا تُرفع. يمكن تحديد مجلد الأوزان عبر `LOCAL_OCR_MODEL_DIR`، أو ضبط `LOCAL_OCR_ALLOW_DOWNLOAD=false` بعد وضع الأوزان محليًا. في تجربة صورة اللقاء قرأ OCR العنوان العربي والإنجليزي والمكان والتاريخ والوقت؛ ترتيب الصفوف جمع «لقاء القراءة المجتمعي». متوسط الثقة 0.625، وقراءة الصورة نحو 71 ثانية على CPU بعد تهيئة أولى استغرقت ~45 ثانية. راجع النص قبل استخدامه، وتحقق من تراخيص الحزمة والأوزان قبل التوزيع التجاري.
### تحليل الملفات وتقييم الإجابة
- `POST /v1/agent/files/analyze` يستقبل `multipart/form-data`: حقل `files` (ملف إلى 3 ملفات من النص/الكود)، وحقل `question` اختياري. الحد 256KB لكل ملف و512KB للمجموع. المحتوى يُقرأ في الذاكرة ولا يُحفظ أو يُنفذ.
- `POST /v1/agent/files/analyze` يستقبل `multipart/form-data`: حقل `files` (حتى 3 ملفات نص/كود أو PDF)، وحقل `question` اختياري. النص حتى 256KB للملف، وPDF حتى 8MB للملف و16MB للمجموع. المحتوى يُقرأ في الذاكرة ولا يُحفظ أو يُنفذ. يمكن دمج EasyOCR المحلي مع نموذج الرؤية للصفحات الممسوحة.
- `POST /v1/agent/images/analyze` يستقبل حتى 3 صور؛ عند تثبيت `requirements-ocr.txt` يستخرج نصًا عربيًا/إنجليزيًا محليًا، ويمرره مع الصورة إلى نموذج الرؤية. يعرض الرد النص المستخرج والثقة المتوسطة لمراجعتها.
- `PUT /v1/conversations/{conversation_id}/messages/{message_index}/feedback` يحفظ تقييم إجابة محفوظة. الجسم مثل `{"version_index":0,"rating":1}` للإعجاب أو `rating:-1` لعدم الإعجاب. من الأفضل استخدام زري 👍/👎 في التطبيق لأنهما يحددان المحادثة والنسخة الصحيحين تلقائيًا.
- هذه التقييمات بيانات قياس وتفضيل أولية؛ لا تغيّر أوزان Gemma ولا تعيد تدريبها تلقائيًا.
### تقييم النماذج المحلية
توجد مجموعة عربية/برمجية أولية في `evals/baseline_arabic_programming.jsonl`. تشغّل الطلبات على API المحلي وتسجل الرد والمدة والأداة والفحوص الآلية في JSON لمراجعة بشرية؛ لا تعتبر فحوص التنسيق والقيم تقييمًا كاملًا للجودة.
```powershell
python scripts/run_model_eval.py --model gemma4:e2b --warmup
python scripts/run_model_eval.py --model qwen2.5:1.5b-instruct-q4_K_M --warmup
```
الـAPI يجب أن يكون شغالًا على `127.0.0.1:8000` والنماذج مختارة/مثبتة محليًا. `--warmup` يرسل سؤال إحماء واحدًا قبل قياس الحالات، والتقرير يسجل زمن الإحماء وملخص متوسط/وسيط/أقل/أعلى زمن. كل نتيجة تحفظ في `evals/results/`. المراجعة البشرية الأولية تستخدم مقياسًا من 0 إلى 2 لكل سؤال: 0 إخفاق، 1 جزئي، 2 مستوفٍ للمعيار؛ مرّة واحدة من خمسة أسئلة لا تكفي لقرار نهائي، ولا تقيس استهلاك الذاكرة حتى الآن.
اختبار استرجاع RAG يستخدم مجموعة صغيرة من ملفات عربية مؤقتة عبر API، ويقيس Hit@1/3 وMRR ووجود الدليل ثم يزيل الملفات من الفهرس:
```powershell
python scripts/eval_knowledge_retrieval.py
python scripts/eval_knowledge_retrieval.py --dataset evals/knowledge_retrieval_project.jsonl
```
الاختبار الأول يستخدم 11 سؤالًا وملفات اصطناعية صغيرة؛ نتيجته بعد إضافة مرادفات محدودة للصوت 100% في Hit@1/3 وMRR ووجود الدليل، لكنه لا يقيس جودة الإجابة. الاختبار الثاني يفهرس نسخًا مؤقتة من ملفات المشروع الحقيقية ويقيس 9 أسئلة عن سلوك الكود. بعد توزيع النتائج على مقطعين كحد أقصى لكل ملف، حقق Hit@1=66.7% وHit@3=100% وMRR=83.3% ووجود الدليل=100%. المؤشر الثاني كشف تحسنًا في تغطية المصادر، لكن عدد الأسئلة قليل والبحث معجمي ولا يثبت فهمًا دلاليًا عامًا. التقارير في `evals/results/retrieval_2026-10-02_140339.json`, `...140538.json`, `...141132.json` و`...141337.json`.
يدعم الفهرس بحثًا هجينًا: FTS5 للمطابقة النصية مع متجهات تشابه محلية. للحصول على البحث الدلالي ثبّت نموذج التضمين العربي متعدد اللغات مرة واحدة عبر `ollama pull granite-embedding:278m` (نحو 563MB، ترخيص Apache 2.0)، ثم أعد فهرسة ملفات مساحة العمل حتى تُنشأ متجهاتها. الافتراضي `KNOWLEDGE_EMBEDDING_MODEL=granite-embedding:278m` ويمكن تغييره. يبيّن `POST /v1/agent/knowledge/index` الحقل `semantic_indexed`، ويعيد البحث `search_mode` بقيمة `hybrid` أو `keyword`. إذا لم يتوفر النموذج أو تعذر التضمين، يستمر الفهرس النصي ويعمل البحث دونه؛ لا تُرسل المستندات إلى خدمة خارجية. تجربة محلية بـ3 أسئلة عربية معادَة الصياغة استرجعت الملف الصحيح أولًا في الحالات الثلاث، بتشابه 0.648–0.827. هذه عينة أولية صغيرة وليست قياسًا عامًا للجودة.
رفع `.pdf` مدعوم ضمن مسار تحليل الملفات: يستخرج نص الصفحات الرقمية محليًا مع أرقامها، ويرسم الصفحات المصورة وحدها ثم يمررها إلى OCR المحلي ونموذج الرؤية. في الملفات المختلطة يُحافظ على ترتيب الصفحات؛ حد الطلب 3 صفحات مصورة، 30 صفحة إجمالًا و24,000 محرف للنص المستخرج. فهرس المعرفة يجمع النص الرقمي وOCR لأول 3 صفحات ممسوحة. حد الصور 2 مليون بكسل و4MB لكل صفحة و8MB إجماليًا، وحد PDF 8MB للملف و16MB للمجموع. الملف والصور المؤقتة تبقى في الذاكرة ولا تُرسل لخدمة سحابية. الملفات المشفرة أو غير الصالحة تُرفض.
مسار الصفحات الممسوحة يعتمد على قراءة نموذج الرؤية؛ الاختبار الحي الحالي التقط المكان والتاريخ والوقت، لكنه لم ينسخ العنوان العربي بدقة ثابتة. راجع النص المنسوخ قبل استخدامه؛ OCR متخصص مع درجة ثقة ما زال خطوة لاحقة.
يستخدم تحويل الصفحات `pypdfium2` وPillow. قبل توزيع نسخة تجارية يجب إرفاق إشعارات وتراخيص PDFium واعتمادياته كما يوضح [دليل الترخيص الرسمي](https://pypdfium2.readthedocs.io/en/stable/readme.html#licensing).
### قراءة رابط ويب محدد
يوفر الـAPI المسار `POST /v1/web/read` لقراءة صفحة عامة يرسل المستخدم رابطها، واستخراج نصها، ثم سؤال Gemma المحلية عنها. افتح `/docs`، اختر المسار، وأرسل مثلًا:
@@ -86,7 +123,7 @@ python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
### البحث العميق على الإنترنت
يوفر `POST /v1/web/search` بحثًا أوليًا متعدد المصادر بلا مفتاح API باستخدام نتائج DuckDuckGo العامة. يجلب حتى 8 نتائج من نطاقات مختلفة، يحاول قراءة صفحاتها العامة، ثم يطلب من النموذج المحلي تلخيص المعلومات مع إحالات مرقمة وروابط المصادر. من واجهة Mithqal AI فعّل زر البحث/الكرة الأرضية في الشريط العلوي ثم اكتب موضوع البحث. بعض المواقع تمنع القراءة الآلية أو تعتمد على JavaScript؛ عندها يظهر المصدر بوصفه مقتطف بحث فقط. المسار يرفض العناوين المحلية ويحد أحجام الصفحات ومصادرها.
يوفر `POST /v1/web/search` بحثًا أوليًا متعدد المصادر بلا مفتاح API باستخدام نتائج DuckDuckGo العامة. يجلب حتى 8 نتائج من نطاقات مختلفة، يحاول قراءة صفحاتها العامة، ثم يطلب من النموذج المحلي تلخيص المعلومات مع إحالات مرقمة وروابط المصادر. تتضمن استجابة API زمن جلب المصادر إجمالًا ولكل مصدر. من واجهة Mithqal AI فعّل زر البحث/الكرة الأرضية في الشريط العلوي ثم اكتب موضوع البحث. بعض المواقع تمنع القراءة الآلية أو تعتمد على JavaScript؛ عندها يظهر المصدر بوصفه مقتطف بحث فقط. المسار يرفض العناوين المحلية ويحد أحجام الصفحات ومصادرها.
```json
{
@@ -112,10 +149,12 @@ python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
- لتشغيل النسخة المكتبية، شغّل `start-api.ps1` أولًا، ثم افتح `flutter_app/build/windows/x64/runner/Release/flutter_app.exe` بعد بنائه.
- يعرض شريط المحادثة قائمة النماذج المثبتة من Ollama؛ اختيار النموذج يمرر اسمه مع الطلب.
- زر المجلد يفعّل وضع الوكيل للقراءة فقط، وزر الكرة الأرضية يفعّل البحث العميق متعدد المصادر. عند تشغيل `start-api.ps1` تكون مساحة العمل الافتراضية مجلد المشروع `SovereignAI-Starter`؛ لتغييرها عرّف `SOVEREIGNAI_WORKSPACE` قبل تشغيل الخدمة.
- الوكيل يطابق السؤال مع ملفات النص/الكود المدعومة، ويمرر مقتطفات محدودة للنموذج؛ عند ذكر مسار نسبي مثل `app/main.py` يزيد المقتطف إلى 12,000 حرف كحد أقصى. يعيد أسماء الملفات التي قرأها. الملفات المخفية، مجلدات `.git` وبيئات البناء، والملفات الكبيرة أو خارج جذر مساحة العمل مستثناة.
- زر مشبك الورق يفتح اختيار ملفات الكود/النص (حتى 3 ملفات، 256KB لكل ملف و512KB إجمالًا). يدعم API قائمة أنواع نصية وبرمجية فقط؛ يقرأ المحتوى في الذاكرة، ولا يخزنه أو ينفذه. PDF والصور غير مدعومة في هذا المسار حتى الآن.
- الوكيل يطابق السؤال مع ملفات النص/الكود المدعومة، ويمكنه قراءة PDF رقمي يحدده المستخدم؛ يمرر مقتطفات محدودة للنموذج، وعند ذكر مسار نسبي مثل `app/main.py` يزيد المقتطف إلى 12,000 حرف كحد أقصى. يعيد أسماء الملفات التي قرأها. الملفات المخفية، مجلدات `.git` وبيئات البناء، والملفات الكبيرة أو خارج جذر مساحة العمل مستثناة.
- في وضع الوكيل اختر المهارة من أيقونة الدماغ بجانب زر مساحة العمل: **شرح الكود** أو **مراجعة الكود** أو **خطة اختبارات**. يستعرض `GET /v1/agent/skills` المهارات وأدوات كل منها؛ يتحقق الخادم من صلاحيات الأداة ولا يعتمد على طلب النموذج وحده. مراجعة الكود تستطيع طلب معاينة diff فقط، ولا تطبق تغييرًا.
- فهرس معرفة محلي: في وضع مساحة العمل حدد ملفات UTF-8 أو PDF رقميًا/ممسوحًا ثم اضغط زر الفهرسة بجانب أيقونة المجلد؛ زر الإزالة يحذف الملفات المحددة من الفهرس. يدعم `POST /v1/agent/knowledge/index` و`DELETE /v1/agent/knowledge/index` و`POST /v1/agent/knowledge/search`. يقتصر الطلب على 20 ملفًا و2 ميغابايت إجمالًا، و256 كيلوبايت للملف النصي، وPDF حتى 30 صفحة و24 ألف محرف مستخرج. يجمع PDF المختلط نص الصفحات الرقمية وOCR لأول 3 صفحات ممسوحة، ويضيف تضمينات Granite المحلية الاختيارية إلى FTS5 عند توفر النموذج؛ لا يرفع المحتوى إلى خدمة خارجية. تعذر التضمين يبقي البحث النصي فعالًا. إعادة الفهرسة تستبدل النسخة السابقة، والبحث يحذف تلقائيًا أي مستند تغيّر أو لم يعد ضمن المساحة.
- زر مشبك الورق يفتح اختيار ملفات الكود/النص وPDF (حتى 3 ملفات؛ النص 256KB للملف، وPDF 8MB للملف، والمجموع 16MB). تُقرأ الملفات في الذاكرة؛ يستخرج API نص الصفحات الرقمية حتى 30 صفحة و24,000 محرف، ويرسم أول 3 صفحات ممسوحة ضمن الطلب. يضيف OCR عربي/إنجليزي اختياريًا قبل نموذج الرؤية المحلي مع تحويل تلقائي إلى `ministral-3:3b` إن كان مثبتًا. لا يخزن الملفات أو ينفذ الكود.
- تظهر 👍/👎 تحت إجابات المساعد. يحفظ التقييم مع رقم نسخة الإجابة في SQLite حتى نتمكن من قياس الجودة وتجهيز أمثلة تقييم أو تفضيلات بمراجعة بشرية؛ الضغط لا يدرّب النموذج ولا يغيّر أوزانه تلقائيًا.
- Gemma 4 E2B لديها قدرة نموذجية على إدخال الصور والصوت وفهم المستندات وفق [بطاقة Google الرسمية](https://ai.google.dev/gemma/docs/core/model_card_4)، لكن هذه الواجهة الحالية لا تمرر مدخلات الصور ولا تقرأ PDF بعد؛ نحتاج بناء مسار منفصل لذلك. قراءة ملفات الكود النصية تعمل عبر زر المرفقات أو وضع مساحة العمل.
- Gemma 4 E2B لديها قدرة نموذجية على إدخال الصور والصوت وفق [بطاقة Google الرسمية](https://ai.google.dev/gemma/docs/core/model_card_4). الصور وPDFات الصفحات الممسوحة تمر عبر مسار محلي إلى نموذج الرؤية، مع دعم OCR عربي/إنجليزي اختياري يعرض النص والثقة المتوسطة. ترتيب القراءة تقريبي والثقة غير معايرة؛ قراءة ملفات الكود النصية تعمل عبر زر المرفقات أو وضع مساحة العمل.
- لإنشاء نسخة Release، نفّذ `flutter build windows --release` من داخل `flutter_app`.
- التطبيق المكتبي واجهة أمامية؛ يحتاج Ollama وFastAPI شغّالين على الجهاز. النموذج لا يُضمّن داخل ملف التطبيق التنفيذي، ويظل نسخ الصوت للنص عبر Groq Whisper عند استخدام الميكروفون.