From 05873471576bfc2246d5ece9161ea0bcb6f4373f Mon Sep 17 00:00:00 2001 From: Hamza Ayed Date: Sat, 3 Oct 2026 19:29:39 +0300 Subject: [PATCH] Validate local OCR retrieval for scanned PDFs --- SovereignAI-Starter/ROADMAP.md | 6 +- .../fixtures/scanned_approval_notice.pdf | Bin 0 -> 79015 bytes .../evals/knowledge_retrieval_extended.jsonl | 1 + .../retrieval_extended_14_2026-10-03.json | 273 ++++++++++++++++++ ...etrieval_scanned_pdf_agent_2026-10-03.json | 49 ++++ 5 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 SovereignAI-Starter/evals/fixtures/scanned_approval_notice.pdf create mode 100644 SovereignAI-Starter/evals/results/retrieval_extended_14_2026-10-03.json create mode 100644 SovereignAI-Starter/evals/results/retrieval_scanned_pdf_agent_2026-10-03.json diff --git a/SovereignAI-Starter/ROADMAP.md b/SovereignAI-Starter/ROADMAP.md index 7151d6f..b4f609d 100644 --- a/SovereignAI-Starter/ROADMAP.md +++ b/SovereignAI-Starter/ROADMAP.md @@ -134,8 +134,8 @@ - [x] فحص استرجاع أولي من 11 سؤالًا عربيًا وإنجليزيًا على API حي. ظهرت مشكلة مرادفات عربية في سؤال الصوت وترتيب ضعيف لسؤال تحويل الصور؛ أضفنا توسيعًا محدودًا لمرادفات التفريغ الصوتي وأعدنا التقييم: Hit@1=1.0 وHit@3=1.0 وMRR=1.0 ومعدل ظهور الدليل=1.0. قبل التحسين كان Hit@1=0.818. حُذفت ملفات التقييم المؤقتة من الفهرس بعد القياس. النتائج: `retrieval_2026-10-02_140339.json` و`retrieval_2026-10-02_140538.json`. تبقى العينة مصطنعة وصغيرة، فلا تثبت جودة عامة. - [x] قياس إضافي على 9 أسئلة عن ملفات الكود الفعلية (`workspace.py`, `knowledge.py`, `pdf_documents.py`, `main.py`). كشف التقييم أن تكرار مقاطع الملف الواحد يزاحم مصادر أخرى؛ حدّثنا البحث لجلب مجموعة أوسع ثم توزيع حتى مقطعين لكل ملف. بعد التعديل: Hit@1=0.667، Hit@3=1.0، MRR=0.833، وظهور الدليل=1.0. النتائج في `retrieval_2026-10-02_141132.json` (قبل التعديل) و`retrieval_2026-10-02_141337.json` (بعده). العينة صغيرة واختبارها معجمي؛ الدقة الدلالية وجودة الإجابة لم تُقاسا. - [x] جولة تحسين استرجاع المقاطع العميقة على 11 سؤالًا من المجموعة المحلية (2026-10-03): توسيع محدود لمرادفات صلاحيات المهارات بالعربية والإنجليزية، ورفع سقف النتائج من 5 إلى 8 مع إبقاء حد 4 مقاطع لكل ملف لحماية تنوع المصادر. على API محلي تجريبي بقاعدة معزولة: `Hit@1=1.0`, `Hit@3=1.0`, `MRR=1.0`, وظهور الدليل `11/11`؛ تقرير `evals/results/retrieval_2026-10-03_160000.json`. اجتازت اختبارات قاعدة المعرفة `12/12`. -- [x] توسيع الحزمة وإضافة جواب الوكيل من الأدلة المفهرسة (2026-10-03): أضيف دليل تقني بطول 15.7 كيلوبايت فيه المعلومة المستهدفة في المقطع 17، وPDF نصي بحد فهرسة 30 صفحة، وأصبح مشغّل التقييم يحتفظ اختياريًا بإجابة الوكيل والمصادر لتراجع بشريًا دون منحها درجة آلية. في الجولة الكاملة على 13 حالة مع الملفات متداخلة: `Hit@1=1.0`, `Hit@3=1.0`, `MRR=1.0`, وظهور الدليل `13/13` (`evals/results/retrieval_extended_2026-10-03.json`). جولة إجابتين تجريبية أعادت حد PDF الصحيح وربطت سياسة الموافقة بالمقطع 17 (`evals/results/retrieval_long_pdf_agent_2026-10-03.json`). هذا لا يغطي OCR لملف PDF ممسوح ولا تقييمًا مستقلًا من المستخدم. -- [ ] متابعة التقييم على PDFs ممسوحة ومجموعات مستندات طويلة متنوعة وأسئلة بشرية جديدة، وجمع مراجعة مستقلة لجودة إجابات النموذج فوق السياق المسترجع. لا تزال النتائج الحالية fixtures مصطنعة؛ الدرجات العالية تصف هذه الحالات فقط ولا تثبت جودة عامة. +- [x] توسيع الحزمة وإضافة جواب الوكيل من الأدلة المفهرسة (2026-10-03): أضيف دليل تقني بطول 15.7 كيلوبايت فيه المعلومة المستهدفة في المقطع 17 وPDF نصي؛ حفظ المشغّل اختياريًا إجابات الوكيل ومصادرها للمراجعة دون منح درجة آلية. الجولة الأولى على 13 حالة أعادت `Hit@1=1.0`, `Hit@3=1.0`, `MRR=1.0`, وظهور الدليل `13/13` (`evals/results/retrieval_extended_2026-10-03.json`). بعد إصلاح وزن OCR المحلي المعطوب وإعادة تشغيله دون تنزيل، أضيف PDF ممسوح فعلي إلى المجموعة؛ على API التطبيق الحالي بقاعدة SQLite الحية المؤقتة ثم حذف عناصرها بعد القياس: `Hit@1=1.0`, `Hit@3=1.0`, `MRR=1.0`, وظهور الدليل `14/14` (`evals/results/retrieval_extended_14_2026-10-03.json`). جواب الوكيل على PDF الممسوح استخرج الموعد `17 October 2026` وذكر مصدره (`evals/results/retrieval_scanned_pdf_agent_2026-10-03.json`). تجربة EasyOCR المباشرة والـAPI استخدمتا أوزانًا محلية فقط؛ النسخة التالفة محفوظة احتياطيًا بجانب الوزن المُصلح. +- [ ] متابعة التقييم على ملفات طويلة وPDFات متنوعة وأسئلة جديدة، وجمع مراجعة مستقلة لجودة إجابات النموذج فوق السياق المسترجع. النتائج الحالية fixtures صغيرة ومصطنعة؛ الدرجات تصف هذه الحالات ولا تثبت جودة عامة. مراجعة إجابات الوكيل محفوظة لكن لا توجد درجات مستقلة من المستخدم بعد. - [x] مهارات محلية أولية قابلة للاختيار من واجهة وضع الوكيل: شرح الكود، مراجعة الكود، وخطة اختبارات. تعرض `/v1/agent/skills` وصف كل مهارة وأدواتها؛ تُحقن التعليمات الموثوقة في سياق الوكيل وتُفلتر قائمة الأدوات، ويرفض الخادم استدعاء أداة خارج صلاحيات المهارة. لمهارة مراجعة الكود معاينة فقط ولا تطبيق مباشر. اجتازت اختبارات الصلاحيات والواجهة؛ يبقى تقييم دقة كل مهارة على أمثلة أكثر قبل اعتمادها افتراضيًا. - [x] قراءة رابط عام محدد عبر `POST /v1/web/read`: استخراج نص HTML الثابت وتمريره إلى Gemma المحلية للإجابة مع إرجاع الرابط والعنوان. - [x] بحث ويب متعدد المصادر تجريبي عبر DuckDuckGo بلا مفتاح API: اختيار نطاقات مختلفة، محاولة جلب الصفحات العامة، تلخيص بالنموذج المحلي مع روابط المصادر، ووسم المقتطفات عند تعذر فتح الصفحة. (2026-10-01: استجابة حية أعادت ملخصًا ومصدرين مختلفين عبر FastAPI/Gemma.) أضيف زمن جلب إجمالي وزمن لكل مصدر إلى الاستجابة لمساعدة تشخيص المصادر البطيئة؛ اختبارات الحجب ومزوّد رسمي اختياري ما زالت لاحقًا. @@ -145,7 +145,7 @@ - الصوت: حاليًا Groq خارجي للتفريغ. Gemma 4 E2B تدعم الصوت بحسب [بطاقة النموذج](https://ai.google.dev/gemma/docs/core/model_card_4)، لكن مسار إرسال الصوت إليها/نسخ محلي لم يُنفّذ؛ Whisper محلي لاحقًا. - [x] الصور: اختيار ورفع PNG/JPG/JPEG/WebP (حتى 3 صور) إلى `POST /v1/agent/images/analyze` محليًا. مع تثبيت `requirements-ocr.txt` يقرأ EasyOCR النص العربي/الإنجليزي ويغذي نصه والصورة معًا إلى نموذج الرؤية. تجربة اللقاء عبر FastAPI وMinistral المحلي أعادت HTTP 200 وتحليلًا لحقول الصورة؛ ترتيب صفوف RTL/LTR جمع العنوان العربي. بقي متوسط الثقة 0.625 وزمن OCR ~71 ثانية بعد تهيئة أولى ~45 ثانية على CPU. حد OCR مليونا بكسل للصورة، وتحليل الرؤية المحلي مسار رجوع عند غياب الحزمة أو الأوزان. راجع النص قبل استخدامه، وراجع ترخيص الأوزان قبل التوزيع التجاري. -- [x] تحليل وفهرسة PDF رقمي أو ممسوح أو مختلط. يحدد الاستخراج حالة كل صفحة؛ النص الرقمي يحفظ ترتيب الصفحة، والممسوح يمر محليًا إلى OCR والرؤية. الحدود: 30 صفحة للملف، 3 صفحات ممسوحة للطلب، 2 مليون بكسل و4MB للصفحة، 8MB إجمالي صور، و8MB لملف PDF. نجحت اختبارات تحليل/استخراج PDF المختلط (2/2) واختبار فهرسة/استرجاع/حذف مختلط (1/1)؛ والتحقق الحي السابق شمل PDF ممسوحًا أيضًا. عند التوزيع يجب إرفاق تراخيص PDFium ومراجعة تراخيص أوزان OCR. +- [x] تحليل وفهرسة PDF رقمي أو ممسوح أو مختلط. يحدد الاستخراج حالة كل صفحة؛ النص الرقمي يحفظ ترتيب الصفحة، والممسوح يمر محليًا إلى OCR والرؤية. الحدود: 30 صفحة للملف، 3 صفحات ممسوحة للطلب، 2 مليون بكسل و4MB للصفحة، 8MB إجمالي صور، و8MB لملف PDF. في 2026-10-03، رفض EasyOCR الوزن المحلي `arabic.pth` لبصمة غير مطابقة؛ استُعيد الوزن الصحيح من أرشيف موجود مسبقًا مع حفظ النسخة القديمة، ثم نجح OCR محليًا والـAPI في قراءة موعد من PDF ممسوح دون تنزيل. عند التوزيع يجب إرفاق تراخيص PDFium ومراجعة تراخيص أوزان OCR. - تصميم الواجهة لتوضيح ما إذا عولج الملف محليًا أم أرسل إلى مزوّد خارجي. ## المرحلة 7 — تقييم النماذج والتدريب diff --git a/SovereignAI-Starter/evals/fixtures/scanned_approval_notice.pdf b/SovereignAI-Starter/evals/fixtures/scanned_approval_notice.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8dff8d94cd68aceef604312340dcecfac6d9ea30 GIT binary patch literal 79015 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 mMqCn?0s~cvOu-r#rO+;{)-L( literal 0 HcmV?d00001 diff --git a/SovereignAI-Starter/evals/knowledge_retrieval_extended.jsonl b/SovereignAI-Starter/evals/knowledge_retrieval_extended.jsonl index 6039419..61e9147 100644 --- a/SovereignAI-Starter/evals/knowledge_retrieval_extended.jsonl +++ b/SovereignAI-Starter/evals/knowledge_retrieval_extended.jsonl @@ -11,3 +11,4 @@ {"id": "skill-permissions-en", "query": "How does the server restrict tools for a selected skill?", "document": "skills.md", "expected_evidence": "allowed_tools", "text": "Each local agent skill declares an allowed_tools set. The server filters the advertised tools and rejects any model call outside that set."} {"id": "long-guide-deep-approval-en", "query": "What must happen before a proposed production change can be saved?", "document": "long_technical_guide.md", "expected_evidence": "two-stage approval", "source_path": "evals/fixtures/long_technical_guide.md"} {"id": "pdf-archive-page-limit-en", "query": "What is the maximum number of pages accepted when indexing one PDF?", "document": "archive_retention_policy.pdf", "expected_evidence": "30 pages", "source_path": "evals/fixtures/archive_retention_policy.pdf"} +{"id": "scanned-pdf-ocr-deadline-en", "query": "What calendar date ends the archive restoration approval window?", "document": "scanned_approval_notice.pdf", "expected_evidence": "17 October 2026", "source_path": "evals/fixtures/scanned_approval_notice.pdf"} diff --git a/SovereignAI-Starter/evals/results/retrieval_extended_14_2026-10-03.json b/SovereignAI-Starter/evals/results/retrieval_extended_14_2026-10-03.json new file mode 100644 index 0000000..3137933 --- /dev/null +++ b/SovereignAI-Starter/evals/results/retrieval_extended_14_2026-10-03.json @@ -0,0 +1,273 @@ +{ + "created_at_utc": "2026-10-03T16:27:51.027447+00:00", + "base_url": "http://127.0.0.1:8000", + "dataset": "evals\\knowledge_retrieval_extended.jsonl", + "indexing": { + "semantic_indexed_documents": 14, + "documents": 14, + "embedding_models": [ + "granite-embedding:278m" + ] + }, + "metrics": { + "cases": 14, + "hit_at_1": 1.0, + "hit_at_3": 1.0, + "mean_reciprocal_rank": 1.0, + "evidence_rate": 1.0 + }, + "results": [ + { + "id": "conversation-storage-ar", + "query": "أين تحفظ المحادثات؟", + "expected_document": "storage.md", + "expected_evidence": "SQLite", + "rank": 1, + "top_paths": [ + "storage.md", + "long_technical_guide.md", + "workspace.md", + "scanned_approval_notice.pdf" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "image-model-ar", + "query": "ما النموذج الذي يعالج الصور تلقائيًا؟", + "expected_document": "images.md", + "expected_evidence": "Ministral 3:3b", + "rank": 1, + "top_paths": [ + "images.md", + "routing.md", + "timeout.md", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "preview-safety-ar", + "query": "كيف نحمي معاينة الملف قبل الموافقة؟", + "expected_document": "preview.md", + "expected_evidence": "SHA256", + "rank": 1, + "top_paths": [ + "preview.md", + "long_technical_guide.md", + "archive_retention_policy.pdf", + "workspace.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "pdf-extraction-ar", + "query": "كيف نستخرج النص من صفحات PDF؟", + "expected_document": "pdf.md", + "expected_evidence": "pypdf", + "rank": 1, + "top_paths": [ + "pdf.md", + "archive_retention_policy.pdf", + "images.md", + "audio.md", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "voice-transcription-ar", + "query": "أي خدمة تفرغ التسجيلات الصوتية؟", + "expected_document": "audio.md", + "expected_evidence": "Groq", + "rank": 1, + "top_paths": [ + "audio.md", + "scanned_approval_notice.pdf", + "archive_retention_policy.pdf", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "workspace-boundary-ar", + "query": "كيف نحمي مساحة العمل من قراءة الملفات المخفية؟", + "expected_document": "workspace.md", + "expected_evidence": ".git", + "rank": 1, + "top_paths": [ + "workspace.md", + "preview.md", + "long_technical_guide.md", + "archive_retention_policy.pdf" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "web-search-en", + "query": "Which provider searches multiple web sources?", + "expected_document": "search.md", + "expected_evidence": "DuckDuckGo", + "rank": 1, + "top_paths": [ + "search.md", + "long_technical_guide.md", + "skills.md", + "routing.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "database-version-en", + "query": "How are old conversation answers migrated?", + "expected_document": "migration.md", + "expected_evidence": "selected_version", + "rank": 1, + "top_paths": [ + "migration.md", + "archive_retention_policy.pdf", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "model-routing-ar", + "query": "ما الحقول التي يعيدها API بعد تحويل الصور: requested_model وauto_routed؟", + "expected_document": "routing.md", + "expected_evidence": "auto_routed", + "rank": 1, + "top_paths": [ + "routing.md", + "images.md", + "storage.md", + "timeout.md", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "api-timeout-ar", + "query": "كيف يعرض API انتهاء مهلة النموذج؟", + "expected_document": "timeout.md", + "expected_evidence": "504", + "rank": 1, + "top_paths": [ + "timeout.md", + "routing.md", + "long_technical_guide.md", + "skills.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "skill-permissions-en", + "query": "How does the server restrict tools for a selected skill?", + "expected_document": "skills.md", + "expected_evidence": "allowed_tools", + "rank": 1, + "top_paths": [ + "skills.md", + "long_technical_guide.md", + "migration.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "long-guide-deep-approval-en", + "query": "What must happen before a proposed production change can be saved?", + "expected_document": "long_technical_guide.md", + "expected_evidence": "two-stage approval", + "rank": 1, + "top_paths": [ + "long_technical_guide.md", + "scanned_approval_notice.pdf", + "migration.md" + ], + "expected_document_chunks": [ + 17, + 4, + 8 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "pdf-archive-page-limit-en", + "query": "What is the maximum number of pages accepted when indexing one PDF?", + "expected_document": "archive_retention_policy.pdf", + "expected_evidence": "30 pages", + "rank": 1, + "top_paths": [ + "archive_retention_policy.pdf", + "pdf.md", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + }, + { + "id": "scanned-pdf-ocr-deadline-en", + "query": "What calendar date ends the archive restoration approval window?", + "expected_document": "scanned_approval_notice.pdf", + "expected_evidence": "17 October 2026", + "rank": 1, + "top_paths": [ + "scanned_approval_notice.pdf", + "archive_retention_policy.pdf", + "long_technical_guide.md" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid" + } + ], + "note": "Small deterministic fixture set. Retrieval metrics cover source ranking and evidence presence, not general RAG quality. Optional agent answers are retained for human review and are not auto-scored." +} diff --git a/SovereignAI-Starter/evals/results/retrieval_scanned_pdf_agent_2026-10-03.json b/SovereignAI-Starter/evals/results/retrieval_scanned_pdf_agent_2026-10-03.json new file mode 100644 index 0000000..305d9b6 --- /dev/null +++ b/SovereignAI-Starter/evals/results/retrieval_scanned_pdf_agent_2026-10-03.json @@ -0,0 +1,49 @@ +{ + "created_at_utc": "2026-10-03T16:18:22.317786+00:00", + "base_url": "http://127.0.0.1:8130", + "dataset": "evals\\knowledge_retrieval_extended.jsonl", + "indexing": { + "semantic_indexed_documents": 1, + "documents": 1, + "embedding_models": [ + "granite-embedding:278m" + ] + }, + "metrics": { + "cases": 1, + "hit_at_1": 1.0, + "hit_at_3": 1.0, + "mean_reciprocal_rank": 1.0, + "evidence_rate": 1.0 + }, + "results": [ + { + "id": "scanned-pdf-ocr-deadline-en", + "query": "What calendar date ends the archive restoration approval window?", + "expected_document": "scanned_approval_notice.pdf", + "expected_evidence": "17 October 2026", + "rank": 1, + "top_paths": [ + "scanned_approval_notice.pdf" + ], + "expected_document_chunks": [ + 0 + ], + "evidence_found": true, + "search_mode": "hybrid", + "agent_answer": "تنتهي فترة موافقة استعادة الأرشيف في 17 أكتوبر 2026. (scanned_approval_notice.pdf · المقطع 0)", + "agent_tool": "search_knowledge", + "agent_files": [ + "scanned_approval_notice.pdf" + ], + "agent_steps": [ + { + "tool": "search_knowledge", + "status": "completed" + } + ], + "human_rating": null + } + ], + "note": "Small deterministic fixture set. Retrieval metrics cover source ranking and evidence presence, not general RAG quality. Optional agent answers are retained for human review and are not auto-scored." +}