<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>RAG on kenji.blog</title><link>http://kenji.blog/ar/tags/rag/</link><description>Recent content in RAG on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ar</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 13:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ar/tags/rag/index.xml" rel="self" type="application/rss+xml"/><item><title>【مقدمة في تنفيذ RAG】كيفية جعل الذكاء الاصطناعي المحلي يقرأ مستنداتك</title><link>http://kenji.blog/ar/p/rag-local-ai-implementation-guide/</link><pubDate>Fri, 11 Sep 2026 13:00:00 +0900</pubDate><guid>http://kenji.blog/ar/p/rag-local-ai-implementation-guide/</guid><description>&lt;img src="http://kenji.blog/p/rag-local-ai-implementation-guide/img/eyecatch.jpg" alt="Featured image of post 【مقدمة في تنفيذ RAG】كيفية جعل الذكاء الاصطناعي المحلي يقرأ مستنداتك" />&lt;h1 id="مقدمة">مقدمة
&lt;/h1>&lt;p>في السنوات الأخيرة، كان التطور في نماذج اللغة الكبيرة (LLM) ملحوظًا، حيث تغلغل العديد من أنظمة الذكاء الاصطناعي مثل ChatGPT و Claude في حياتنا وأعمالنا. ومع ذلك، هناك نقطة ضعف واضحة في نماذج LLM العامة. وهي أنها لا تعرف سوى &amp;ldquo;المعلومات العامة المتاحة وقت التدريب&amp;rdquo;. بالطبع، لا يمكنها الإجابة على الأسئلة المتعلقة بـ &amp;ldquo;المستندات الخاصة&amp;rdquo; مثل لوائح الشركة، والمذكرات الشخصية، ومواد المشاريع غير المنشورة. إذا حاولت إجبارها على الإجابة، فهناك خطر كبير من أنها ستولد أكاذيب تبدو معقولة ولكنها بعيدة عن الحقيقة (الهلوسة - Hallucination).&lt;/p>
&lt;p>لذلك، فإن البنية المعمارية التقنية التي تنتشر حاليًا بشكل هائل في جميع أنحاء العالم هي &lt;strong>RAG (Retrieval-Augmented Generation: التوليد المعزز بالاسترجاع)&lt;/strong>. باستخدام RAG، يصبح من الممكن تزويد LLM بالمعرفة الخاصة ديناميكيًا من قاعدة بيانات خارجية، وجعلها تولد إجابات دقيقة وموثوقة بناءً على ذلك.&lt;/p>
&lt;p>علاوة على ذلك، عند التعامل مع مجال الشركات أو المعلومات الشخصية السرية، غالبًا ما يكون إرسال البيانات إلى واجهات برمجة التطبيقات (APIs) المستندة إلى السحابة مثل OpenAI غير مسموح به بموجب سياسة الأمان. ما هو مطلوب هنا هو بناء &amp;ldquo;RAG محلي&amp;rdquo; مدمج مع &lt;strong>الذكاء الاصطناعي المحلي&lt;/strong> (LLM يعمل بالكامل على جهاز الكمبيوتر الخاص بك أو الخادم المحلي - On-Premise).&lt;/p>
&lt;p>في هذه المقالة، سنشرح بالتفصيل كل شيء بدءًا من النظريات الأساسية لـ RAG، وطرق التنفيذ المحددة لـ RAG المحلي باستخدام Python، والخلفية الرياضية (آلية البحث عن المتجهات)، إلى التقنيات المتقدمة لتشغيل النظام في بيئة الإنتاج.&lt;/p>
&lt;hr>
&lt;h1 id="1-البنية-المعمارية-العامة-لـ-rag">1. البنية المعمارية العامة لـ RAG
&lt;/h1>&lt;p>RAG ليس نموذج ذكاء اصطناعي واحد، بل هو بنية نظام تتعاون فيها مكونات متعددة. يتكون بشكل رئيسي من مرحلتين: &amp;ldquo;مرحلة الاستيعاب (إدخال البيانات)&amp;rdquo; و &amp;ldquo;مرحلة الاسترجاع والتوليد (البحث والتوليد)&amp;rdquo;.&lt;/p>
&lt;p>يوضح مخطط Mermaid التالي الصورة العامة لنظام RAG.&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "مرحلة الاستيعاب (التحضير المسبق)"
Doc["مستندات خاصة (PDF, TXT, إلخ.)"] --> Loader["محمل المستندات"]
Loader --> Splitter["تقسيم النص (Chunking)"]
Splitter --> EmbedModel1["نموذج التضمين (Embedding)"]
EmbedModel1 --> VectorDB["قاعدة بيانات المتجهات"]
end
subgraph "مرحلة الاستدلال (عند استعلام المستخدم)"
User["سؤال من المستخدم (استعلام)"] --> EmbedModel2["نموذج التضمين (Embedding)"]
EmbedModel2 --> QueryVector["متجه الاستعلام"]
QueryVector --> Search["بحث التشابه (بحث المتجهات)"]
VectorDB --> Search
Search --> Context["استخراج القطع ذات الصلة (السياق)"]
User --> PromptBuilder["بناء الموجه (Prompt)"]
Context --> PromptBuilder
PromptBuilder --> LocalLLM["LLM محلي"]
LocalLLM --> Answer["توليد الإجابة النهائية"]
end&lt;/div>
&lt;h2 id="مرحلة-الاستيعاب-التحضير-المسبق">مرحلة الاستيعاب (التحضير المسبق)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>تحميل المستندات&lt;/strong>: تحميل البيانات غير المهيكلة مثل ملفات PDF، Word، والملفات النصية.&lt;/li>
&lt;li>&lt;strong>التقسيم (Chunking)&lt;/strong>: تقسيم النصوص الطويلة إلى كتل ذات معنى (Chunks) لتتناسب مع قيود الإدخال في LLM (نافذة السياق) ولتحسين دقة البحث.&lt;/li>
&lt;li>&lt;strong>التضمين (Embedding / تحويل إلى متجهات)&lt;/strong>: إدخال الكتل المقسمة إلى نموذج التضمين (Embedding Model) وتحويلها إلى مصفوفات من الأرقام (متجهات) ذات مئات إلى آلاف الأبعاد.&lt;/li>
&lt;li>&lt;strong>الحفظ في قاعدة البيانات&lt;/strong>: حفظ المتجهات المحولة مرتبطة بالبيانات النصية الأصلية في قاعدة بيانات المتجهات (Vector DB).&lt;/li>
&lt;/ol>
&lt;h2 id="مرحلة-الاستدلال-أثناء-التشغيل">مرحلة الاستدلال (أثناء التشغيل)
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>تحويل الاستعلام إلى متجهات&lt;/strong>: تحويل سؤال المستخدم إلى متجه باستخدام نفس نموذج التضمين المستخدم في التحضير المسبق.&lt;/li>
&lt;li>&lt;strong>بحث التشابه&lt;/strong>: حساب التشابه بين متجه الاستعلام ومتجهات المستندات في قاعدة البيانات، واسترداد أعلى الكتل النصية الأقرب دلاليًا (ذات الصلة العالية).&lt;/li>
&lt;li>&lt;strong>بناء الموجه (Prompt)&lt;/strong>: دمج النصوص المستردة ذات الصلة كـ &amp;ldquo;سياق (معرفة خلفية)&amp;rdquo; مع سؤال المستخدم لإنشاء موجه الإدخال لـ LLM.&lt;/li>
&lt;li>&lt;strong>توليد الإجابة&lt;/strong>: يتلقى LLM الموجه الموسع ويولد إجابة بناءً على معلومات السياق المرفقة.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="2-الفهم-العميق-للبحث-في-المتجهات-والتضمين-embeddings">2. الفهم العميق للبحث في المتجهات والتضمين (Embeddings)
&lt;/h1>&lt;p>جوهر RAG هو &amp;ldquo;البحث في المتجهات (البحث الدلالي)&amp;rdquo;. بينما يعتمد بحث الكلمات الرئيسية التقليدي (مثل BM25) على المطابقة التامة للكلمات وتكرارها، يعتمد البحث في المتجهات على &amp;ldquo;التشابه الدلالي&amp;rdquo;. على سبيل المثال، حتى الكلمات المختلفة مثل &amp;ldquo;كلب&amp;rdquo; و &amp;ldquo;جرو&amp;rdquo;، أو &amp;ldquo;حاسوب&amp;rdquo; و &amp;ldquo;كمبيوتر&amp;rdquo;، ستظهر في نتائج البحث إذا كانت معانيها متقاربة.&lt;/p>
&lt;h2 id="ما-هو-نموذج-التضمين-embedding-model">ما هو نموذج التضمين (Embedding Model)؟
&lt;/h2>&lt;p>نموذج التضمين هو شبكة عصبية تأخذ النصوص باللغة الطبيعية كإدخال وتخرج متجهًا كثيفًا ثابت الطول (Dense Vector). النماذج الشائعة (مثل &lt;code>text-embedding-3-small&lt;/code> أو النماذج مفتوحة المصدر مثل &lt;code>multilingual-e5-large&lt;/code>) تقوم بتعيين النص إلى متجه حقيقي بأبعاد 384 أو 1024.&lt;/p>
&lt;p>في هذا الفضاء متعدد الأبعاد (الفضاء الكامن - Latent Space)، يتم تدريب النموذج بحيث تكون المسافة في فضاء الإحداثيات أقرب كلما كانت الجمل متشابهة في المعنى.&lt;/p>
&lt;h2 id="الخلفية-الرياضية-لحساب-التشابه-تشابه-جيب-التمام-cosine-similarity">الخلفية الرياضية لحساب التشابه: تشابه جيب التمام (Cosine Similarity)
&lt;/h2>&lt;p>عندما تبحث قاعدة بيانات المتجهات عن المستندات ذات الصلة، فإن مقياس المسافة الأكثر استخدامًا هو &lt;strong>تشابه جيب التمام (Cosine Similarity)&lt;/strong>. على عكس المسافة الإقليدية (المسافة المطلقة المكانية)، يركز تشابه جيب التمام على &amp;ldquo;الزاوية بين متجهين&amp;rdquo;. نظرًا لأنه أقل تأثرًا بطول الجملة (معيار المتجه)، فهو مناسب جدًا لحساب تشابه النصوص.&lt;/p>
&lt;p>يتم التعبير عن تشابه جيب التمام للمتجهين $\mathbf{A}$ و $\mathbf{B}$ رياضياً كالتالي:&lt;/p>
$$ \text{Cosine Similarity}(\mathbf{A}, \mathbf{B}) = \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$
&lt;ul>
&lt;li>$\mathbf{A} \cdot \mathbf{B}$ يمثل الجداء النقطي (Dot Product).&lt;/li>
&lt;li>$\|\mathbf{A}\|$ يمثل معيار L2 (الطول) للمتجه $\mathbf{A}$.&lt;/li>
&lt;li>$n$ هو عدد أبعاد المتجه.&lt;/li>
&lt;/ul>
&lt;p>يأخذ تشابه جيب التمام قيمًا من -1 إلى 1.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>قريب من 1&lt;/strong>: اتجاه كلا المتجهين هو نفسه تقريبًا (المعنى متشابه جدًا)&lt;/li>
&lt;li>&lt;strong>قريب من 0&lt;/strong>: المتجهان متعامدان (غير مرتبطين)&lt;/li>
&lt;li>&lt;strong>قريب من -1&lt;/strong>: المتجهان في اتجاهين متعاكسين (المعنى معاكس)&lt;/li>
&lt;/ul>
&lt;p>تستخدم قواعد بيانات المتجهات الحديثة (مثل Chroma، FAISS، Qdrant) خوارزمية بحث أقرب جار تقريبي (ANN) تسمى HNSW (Hierarchical Navigable Small World)، والتي تم تحسينها للبحث عن المستندات ذات تشابه جيب التمام العالي من بين ملايين البيانات المتجهة في أجزاء من الثانية.&lt;/p>
&lt;hr>
&lt;h1 id="3-حزمة-التقنيات-لبناء-rag-محلي">3. حزمة التقنيات لبناء RAG محلي
&lt;/h1>&lt;p>لبناء RAG محلي بالكامل لا يعتمد على السحابة، سنستفيد من نظام المصادر المفتوحة. نوصي بحزمة التقنيات التالية:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>نموذج اللغة (LLM)&lt;/strong>
&lt;ul>
&lt;li>الأداة: &lt;code>Ollama&lt;/code> أو &lt;code>Llama.cpp&lt;/code>&lt;/li>
&lt;li>النماذج: نماذج مفتوحة خفيفة وعالية الأداء مثل &lt;code>Llama-3-8B-Instruct&lt;/code>، &lt;code>Gemma-2-9B-It&lt;/code>، &lt;code>Qwen2-7B-Instruct&lt;/code>. للمهام باللغة اليابانية، تعتبر النماذج المضبوطة لليابانية مثل &lt;code>Llama-3-ELYZA-JP-8B&lt;/code> مناسبة (يمكن استخدام نماذج تدعم اللغة العربية للمهام العربية).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>نموذج التضمين (Embedding)&lt;/strong>
&lt;ul>
&lt;li>النماذج: &lt;code>intfloat/multilingual-e5-large&lt;/code> أو &lt;code>BAAI/bge-m3&lt;/code>. لتشغيله محليًا، من الشائع تنزيله من Hugging Face وتشغيله باستخدام Sentence-Transformers.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>قاعدة بيانات المتجهات (Vector DB)&lt;/strong>
&lt;ul>
&lt;li>&lt;code>ChromaDB&lt;/code>: مبني على Python وسهل الإعداد للغاية. مثالي للتطوير المحلي.&lt;/li>
&lt;li>&lt;code>FAISS&lt;/code>: مكتبة بحث متجهات سريعة طورتها Meta.&lt;/li>
&lt;li>&lt;code>Qdrant&lt;/code> / &lt;code>Milvus&lt;/code>: مخصص للبيئات الأكبر وبيئات الإنتاج.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>إطار عمل التنسيق (Orchestration Framework)&lt;/strong>
&lt;ul>
&lt;li>&lt;code>LangChain&lt;/code>: المعيار الفعلي لربط المكونات (Chain).&lt;/li>
&lt;li>&lt;code>LlamaIndex&lt;/code>: إطار عمل للاتصال بالبيانات متخصص بشكل خاص في RAG.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>في هذه المرة، سنقوم بالتنفيذ باستخدام المزيج الأسهل في التقديم: &lt;strong>LangChain + ChromaDB + Ollama + HuggingFaceEmbeddings&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h1 id="4-دورة-تعليمية-للتنفيذ-بناء-rag-محلي-كامل-باستخدام-python">4. دورة تعليمية للتنفيذ: بناء RAG محلي كامل باستخدام Python
&lt;/h1>&lt;p>من هنا، سنقوم ببناء RAG محلي من خلال كتابة كود Python فعليًا. مسبقًا، يرجى تثبيت Ollama على جهاز الكمبيوتر الخاص بك وتشغيله في الخلفية. أيضًا، قم بسحب (Pull) النموذج على Ollama (مثال: &lt;code>ollama run llama3&lt;/code>).&lt;/p>
&lt;h2 id="الخطوة-1-تثبيت-المكتبات-المطلوبة">الخطوة 1: تثبيت المكتبات المطلوبة
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install langchain langchain-community langchain-huggingface
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install chromadb sentence-transformers pypdf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="الخطوة-2-الكود-البرمجي-الكامل-للتنفيذ">الخطوة 2: الكود البرمجي الكامل للتنفيذ
&lt;/h2>&lt;p>فيما يلي برنامج نصي كامل بلغة Python لقراءة ملف PDF، وتحويله إلى متجهات، وجعل نموذج LLM المحلي يجيب على الأسئلة.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;span class="lnt">85
&lt;/span>&lt;span class="lnt">86
&lt;/span>&lt;span class="lnt">87
&lt;/span>&lt;span class="lnt">88
&lt;/span>&lt;span class="lnt">89
&lt;/span>&lt;span class="lnt">90
&lt;/span>&lt;span class="lnt">91
&lt;/span>&lt;span class="lnt">92
&lt;/span>&lt;span class="lnt">93
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.document_loaders&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_text_splitters&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_huggingface&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.vectorstores&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Chroma&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.llms&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_core.prompts&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain.chains&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 1. تحميل المستندات&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري تحميل المستندات...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># حدد مسار ملف PDF الذي تريد قراءته&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">file_path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;sample_company_policy.pdf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">loader&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PyPDFLoader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_path&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">loader&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 2. تقسيم النص (Text Splitting)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># التقسيم إلى أحجام مناسبة دون تدمير معنى الجمل&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">text_splitter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RecursiveCharacterTextSplitter&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_size&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># أقصى عدد من الأحرف لكل كتلة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunk_overlap&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># عدد الأحرف المتداخلة بين الكتل (لمنع انقطاع السياق)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">separators&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;。&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;、&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34; &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chunks&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">text_splitter&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split_documents&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;تم التقسيم إلى &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> كتلة.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 3. تهيئة نموذج التضمين (Local HuggingFace Model)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># استخدام نموذج متعدد اللغات&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري تحميل نموذج التضمين...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embeddings&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">HuggingFaceEmbeddings&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;intfloat/multilingual-e5-large&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;device&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;cpu&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="c1"># &amp;#39;cuda&amp;#39; أو &amp;#39;mps&amp;#39; إذا كان لديك وحدة معالجة رسومات (GPU)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 4. بناء قاعدة بيانات المتجهات (Chroma)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري بناء قاعدة بيانات المتجهات...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./chroma_db&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectorstore&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Chroma&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_documents&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">chunks&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embedding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">embeddings&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">persist_directory&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">persist_directory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># إنشاء المسترد (Retriever). إعداد لجلب أفضل 3 مستندات ذات صلة&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorstore&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">as_retriever&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">search_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;k&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 5. تهيئة LLM المحلي (Ollama)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;جاري الاتصال بـ LLM المحلي...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># تأكد من الحصول على النموذج مسبقًا باستخدام شيء مثل &amp;#39;ollama pull llama3&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama3&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 6. تعريف قالب الموجه (Prompt Template)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">prompt_template&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;أنت مساعد ممتاز على دراية بلوائح الشركة والمعلومات الداخلية.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">يرجى الإجابة على سؤال المستخدم بالتفصيل باستخدام السياق (معلومات الخلفية) التالي فقط.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">إذا لم تتمكن من العثور على الإجابة في السياق، فلا تخمن من نفسك وأجب بصدق &amp;#34;لا يمكن المعرفة من المعلومات المقدمة&amp;#34;.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【السياق】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{context}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【السؤال】
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&lt;/span>&lt;span class="si">{question}&lt;/span>&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">【الإجابة】:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PROMPT&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">PromptTemplate&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">template&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">prompt_template&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">input_variables&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;context&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;question&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 7. بناء سلسلة RAG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qa_chain&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">RetrievalQA&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_chain_type&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">llm&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">llm&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;stuff&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">retriever&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">retriever&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">return_source_documents&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># إعداد لإرجاع مصدر المعلومات&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">chain_type_kwargs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;prompt&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">PROMPT&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 8. تنفيذ السؤال&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">query&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;يرجى إخباري عن شروط دفع نفقات النقل المتعلقة بالعمل عن بعد.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">السؤال: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">qa_chain&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">invoke&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;query&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">query&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【الإجابة】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;result&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【مصادر المعلومات المرجعية】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">doc&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;source_documents&amp;#39;&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- صفحة &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">metadata&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;غير معروف&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">doc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">page_content&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">50&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="شرح-نقاط-الكود">شرح نقاط الكود
&lt;/h2>&lt;ol>
&lt;li>&lt;strong>RecursiveCharacterTextSplitter&lt;/strong>:
وهو المقسم الموصى به بشدة عند تقسيم اللغة الطبيعية. يحاول التقسيم بترتيب الفقرات (&lt;code>\n\n&lt;/code>)، الأسطر (&lt;code>\n&lt;/code>)، وعلامات الترقيم (&lt;code>。&lt;/code>)، بحيث يتناسب مع &lt;code>chunk_size&lt;/code> المحدد مع الحفاظ على وحدة المعنى قدر الإمكان. عن طريق تعيين &lt;code>chunk_overlap&lt;/code>، فإنه يمنع فقدان المعلومات بسبب انقطاع الحدود السياقية.&lt;/li>
&lt;li>&lt;strong>HuggingFaceEmbeddings&lt;/strong>:
&lt;code>intfloat/multilingual-e5-large&lt;/code> هو نموذج تضمين مفتوح المصدر قوي جدًا يدعم لغات متعددة. يتيح لك تحويل النصوص إلى متجهات على الذاكرة المحلية دون اتصال بالإنترنت، دون استخدام واجهات برمجة التطبيقات السحابية (مثل &lt;code>text-embedding-ada-002&lt;/code> الخاص بـ OpenAI).&lt;/li>
&lt;li>&lt;strong>ChromaDB&lt;/strong>:
نظرًا لأنه يعمل في الذاكرة (In-memory) أو في التخزين المحلي (مبني على SQLite)، فلا حاجة لإعداد خادم قاعدة بيانات معقد. بتحديد &lt;code>persist_directory&lt;/code>، يمكنك تخطي عملية التحويل إلى متجهات عند إعادة التشغيل وقراءة قاعدة البيانات من القرص.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h1 id="5-تقنيات-rag-المتقدمة-advanced-rag-techniques">5. تقنيات RAG المتقدمة (Advanced RAG Techniques)
&lt;/h1>&lt;p>النظام الأساسي (Naive RAG) الذي بنيناه في الدورة التعليمية أعلاه يعمل، ولكن إذا كانت هناك حاجة إلى دقة إجابة عالية في بيئة الإنتاج، فمن الضروري تقديم تقنيات متقدمة مثل ما يلي.&lt;/p>
&lt;h2 id="51-البحث-الهجين-hybrid-search">5.1 البحث الهجين (Hybrid Search)
&lt;/h2>&lt;p>البحث في المتجهات ممتاز في التقاط &amp;ldquo;المعنى&amp;rdquo;، ولكنه قد يعاني مع عمليات البحث الدقيقة بالكلمات الرئيسية مثل &amp;ldquo;أسماء الأعلام الخاصة&amp;rdquo;، &amp;ldquo;أرقام طرازات المنتجات&amp;rdquo;، أو &amp;ldquo;معرفات الموظفين&amp;rdquo;.
لذلك، من خلال إجراء &lt;strong>البحث الدلالي&lt;/strong> عبر بحث المتجهات والبحث بالكلمات الرئيسية باستخدام خوارزميات مثل BM25 بشكل متوازٍ، ثم تسجيل ودمج نتائج كليهما (باستخدام طرق مثل دمج الترتيب المتبادل؛ Reciprocal Rank Fusion; RRF)، يمكن تقليل حالات الإخفاق في البحث بشكل كبير.&lt;/p>
&lt;h2 id="52-إعادة-الترتيب-re-ranking">5.2 إعادة الترتيب (Re-ranking)
&lt;/h2>&lt;p>البحث في المتجهات سريع، ولكنه لا يقيّم بالضرورة الملاءمة السياقية الدقيقة للسياق. خط أنابيب المعالجة (Pipeline) الشائع لتحسين دقة البحث هو كالتالي:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>البحث الأولي (First-stage Retrieval)&lt;/strong>: استرجاع حوالي 20 إلى 30 كتلة نصية ذات صلة بشكل واسع وسطحي من قاعدة بيانات المتجهات.&lt;/li>
&lt;li>&lt;strong>إعادة التقييم (Re-ranking)&lt;/strong>: استخدام نموذج تعلم آلي آخر أثقل يُعرف باسم Cross-Encoder (مثل &lt;code>bge-reranker&lt;/code>)، وإدخال زوج من استعلام المستخدم والكتل المستردة لإعادة حساب درجة الملاءمة الدلالية.&lt;/li>
&lt;li>&lt;strong>الفرز&lt;/strong>: تمرير أفضل 3 إلى 5 كتل ذات أعلى الدرجات كـسياق نهائي إلى موجه LLM.&lt;/li>
&lt;/ol>
&lt;p>من خلال هذه الطريقة، يمكن منع تمرير معلومات الضوضاء غير ذات الصلة إلى LLM، مما يزيد بشكل كبير من دقة الإجابة (Precision).&lt;/p>
&lt;div class="mermaid">graph LR
Query["استعلام"] --> VSearch["بحث المتجهات (أفضل 20)"]
VSearch --> Reranker["نموذج إعادة الترتيب (Cross-Encoder)"]
Query --> Reranker
Reranker --> TopK["أفضل 3 بدقة عالية"]
TopK --> LLM["توليد LLM"]&lt;/div>
&lt;h2 id="53-التقسيم-الدلالي-semantic-chunking-والبحث-في-المستند-الأصلي">5.3 التقسيم الدلالي (Semantic Chunking) والبحث في المستند الأصلي
&lt;/h2>&lt;p>بدلاً من تقسيم النص ميكانيكيًا بعدد ثابت من الأحرف، توجد طريقة تسمى &amp;ldquo;التقسيم الدلالي&amp;rdquo; (Semantic Chunking) تكتشف تغيرات المعنى في الجملة باستخدام الذكاء الاصطناعي لتقسيمها.
أيضًا، في طريقة تُعرف باسم &amp;ldquo;البحث في المستند الأصل&amp;rdquo; (Parent Document Retriever)، يتم تحويل النص إلى متجهات بوحدات صغيرة جدًا (مثل الجمل) لأغراض البحث لتحقيق بحث عالي الدقة، وعند تمريره إلى LLM، يتم تمرير &amp;ldquo;الفقرة الكبيرة الأصلية (المستند الأصل)&amp;rdquo; التي تحتوي على تلك الجملة، مما يوفر سياقًا كافيًا لـ LLM.&lt;/p>
&lt;hr>
&lt;h1 id="6-تحديات-وحلول-عند-تشغيل-rag-محلي">6. تحديات وحلول عند تشغيل RAG محلي
&lt;/h1>&lt;p>عند بناء وتشغيل RAG في بيئة محلية، توجد عقبات محددة.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>نفاد ذاكرة الفيديو (VRAM)&lt;/strong>:
لتشغيل LLM محلي بسرعة عملية (عشرات الرموز في الثانية)، يجب تحميل النموذج في ذاكرة الفيديو (VRAM) الخاصة بوحدة المعالجة الرسومية (GPU). لتشغيل نموذج من فئة 8B بصيغة fp16 (نقطة عائمة 16 بت)، يتطلب الأمر حوالي 16 غيغابايت من VRAM، ولكن باستخدام تقنيات &lt;strong>التكميم (Quantization)&lt;/strong> (تقنيات الضغط إلى 4 بت أو 8 بت مثل صيغ GGUF و AWQ)، من الممكن تشغيلها بسرعة كافية حتى على 8 غيغابايت من VRAM (مثل أجهزة الكمبيوتر المخصصة للألعاب). يدعم كل من Llama.cpp و Ollama تنسيقات التكميم هذه افتراضيًا.&lt;/li>
&lt;li>&lt;strong>حدود نافذة السياق&lt;/strong>:
إذا كان حجم السياق المسترد كبيرًا جدًا، فقد يتجاوز الحد الأقصى لإدخال LLM (حد الرموز)، أو قد ينسى النموذج الجزء الأوسط من المعلومات (ظاهرة الضياع في المنتصف - Lost in the middle). من الضروري تعديل عدد الكتل المستخرجة والاختيار الدقيق من خلال تقنية إعادة الترتيب المذكورة أعلاه.&lt;/li>
&lt;li>&lt;strong>إدارة حداثة البيانات&lt;/strong>:
عند تحديث المستندات المصدرية، يجب أيضًا تحديث المتجهات أو حذفها (عمليات CRUD) للمستندات المقابلة في قاعدة بيانات المتجهات. نظرًا لأن ChromaDB يدعم التحديثات بناءً على معرف المستند (Document ID)، فمن العملي إدارة قيم التجزئة (Hash) للملفات وإعداد معالجة مجمعة (Batch Processing) لمزامنة التغييرات فقط.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="الخاتمة">الخاتمة
&lt;/h1>&lt;p>RAG (التوليد المعزز بالاسترجاع) هو نموذج قوي يطور الذكاء الاصطناعي من مساعد عام عادي إلى &amp;ldquo;خبيرك الشخصي&amp;rdquo; أو &amp;ldquo;خبير متخصص في الأعمال الداخلية&amp;rdquo;.&lt;/p>
&lt;p>حتى في المتطلبات شديدة السرية حيث لا يمكن استخدام الخدمات السحابية، وجدنا أنه من السهل نسبيًا بناء بيئة &amp;ldquo;RAG محلي&amp;rdquo; كاملة من خلال الجمع بين أنظمة المصادر المفتوحة مثل Ollama، LangChain، و ChromaDB.&lt;/p>
&lt;p>بناءً على الفهم الرياضي للفضاء المتجه، والأساليب المتقدمة مثل تقسيم النصوص وإعادة الترتيب الموضحة في هذه المقالة، يرجى محاولة تطوير نظام ذكاء اصطناعي خاص بك باستخدام بياناتك الخاصة. إن سرعة تطور الذكاء الاصطناعي المحلي مذهلة، والنظام الذي تبنيه اليوم يمكن ترقية أدائه في لحظة بمجرد استبداله بنموذج خفيف الوزن وأكثر ذكاءً قد يظهر غدًا.&lt;/p>
&lt;hr>
&lt;p>&lt;em>في هذه المدونة، سنستمر في نشر مقالات متعمقة حول تكنولوجيا الذكاء الاصطناعي و RAG. إذا كان لديك أي أسئلة أو ملاحظات، يرجى تركها في قسم التعليقات.&lt;/em>&lt;/p></description></item></channel></rss>