الـ RAG· الدرس 4 من 4
تبني الـ RAG بإيه؟ — LangChain ولا LlamaIndex ولا من غير Framework؟
في سطر واحد · **القرار الحقيقي مش «أنهي Framework أحسن» — القرار: بتشتري راحة الـ Orchestration الجاهز بكام تحكم وكام Dependency؟ وفي أغلب الحالات في BuildAI: ابدأ من غير Framework، وده ليه…** <!-- Field 3: TL;DR -->
- الـ Framework مش بيضيف ذكاء — الموديل والـ Vector Store والـ Embeddings هما هما في الحالات كلها. اللي بيتغير: مين كاتب الكود اللي بينضمهم.
- تلات اختيارات حقيقية: من غير Framework (تحكم كامل، Boilerplate أكتر)، LlamaIndex (أقوى لما المشكلة Data/Indexing)، LangChain (منظومة Orchestration واسعة، Abstraction أتقل).
- رأي BuildAI: للتعلم ولأنظمة الإنتاج الصغيرة، ابدأ من غير Framework — عشان تفهم اللي بيحصل. الـ Framework بتلجأله لما تعقيد الربط يبقى هو المشكلة فعلًا.
- 💸 الـ Framework مش بيغيّر الفاتورة: التكلفة في نداءات الموديل، ودي واحدة في كل الحالات.
- 🔥 المشهد ده بيتغير بسرعة — الأسماء والـ APIs هنا عليها مراجعة كل 30 يوم.
<!-- Field 4: Why does this matter? -->
ده حرفيًا أول سؤال بيسأله أي حد قرر يبني RAG: «أبدأ بـ LangChain ولا إيه؟». والسؤال بيتجاوب غلط كتير — بالـ Hype: «كل التيوتوريالز بتستخدمه، يبقى هو الصح».
الغلطة دي بتتدفع بعدين بشكلين. الأول وقت الـ Debugging: الاسترجاع رجّع زبالة، وأنت مش عارف الـ Prompt النهائي اللي راح للموديل شكله إيه، لأن 5 طبقات Abstraction بنته بالنيابة عنك. التاني وقت الترقية: إصدار جديد كسر الـ API، وأنت قدام Refactor لكود ما فهمتوش أصلًا وهو شغال.
والعكس غلط برضه: فيه أنظمة Ingestion من 15 مصدر بيتكتب فيها آلاف السطور Boilerplate كان فيه مكتبة ناضجة بتعملها أحسن. القرار ده هندسي، وليه معايير — مش انتماء لفريق.
<!-- Field 5: Explain it simply (Layer 1) -->
افتكر الـ RAG Pipeline اللي بنيتها: تحميل، تقطيع، Embedding، تخزين، بحث، بناء Prompt، توليد. سبع خطوات، كلها كود عادي.
الـ Framework بيقدملك الخطوات دي مكتوبة جاهزة ومتوصلة ببعضها: Loaders لكل نوع ملف، Splitters جاهزة، Connectors لكل Vector Store، وسلاسل بتربط الكل بسطرين.
اللي بتكسبه: سرعة بداية وقطع غيار جاهزة. اللي بتدفعه: طبقة بينك وبين اللي بيحصل — لما تشتغل تمام، ولما تبوظ برضه.
<!-- Field 7: Simple example -->
مثال حقيقي — نفس الـ Pipeline بوشّين
من غير Framework، الاسترجاع والتوليد اللي كتبتهم في المشروع حوالين 30 سطر — أنت شايف فيهم الـ Prompt النهائي حرف حرف، والـ Top-k رقم أنت كاتبه بإيدك.
بالـ Framework، نفس الحاجة شكلها كده:
> 🔥 Volatile fragment *(أسماء APIs بتتغير بين الإصدارات — الفكرة هي اللي تثبت، مش الأسطر)*: > > ``python > # LlamaIndex — the "it's magic" version (API surface as of Aug 2026) > index = VectorStoreIndex.from_documents(documents) > answer = index.as_query_engine().query("What is the return policy?") >
سطرين بدل تلاتين. جميل؟ جدًا. بس اسأل نفسك: التقطيع حصل بحجم Chunk كام؟ البحث رجّع كام نتيجة؟ الـ Prompt اللي راح للموديل فيه إيه بالظبط؟ الإجابة: قرارات افتراضية اتاخدت بالنيابة عنك، وأنت ولا شفتها. كل واحدة فيهم ليها إعداد تقدر تغيره — لو عرفت إنها موجودة أصلًا. الفرق بين المبتدئ والمحترف في التعامل مع الـ Frameworks هو بالظبط معرفة الافتراضيات دي.
<!-- Field 18: Alternatives — the three real options, each with strengths/weaknesses -->
| # | ❌ الغلط | ✅ الصح |
|---|---|---|
| 1 | اختيار بالـ Hype: «كل التيوتوريالز بتستخدمه» | التيوتوريالز بتحسّن للـ Demo السريع — أنت بتحسّن لفهم وصيانة. جدول القرار فوق |
| 2 | Framework فوق Pipeline ما اتعلمتش: أول RAG في حياتك بسطرين سحر | ابني الـ Pipeline مرة بإيدك — بعدها استخدم ما شئت، وأنت عارف الـ Framework بيوفرلك إيه بالظبط |
| 3 | افتراضيات مش متراجعة: Chunk size و Top-k والـ Prompt Template كلها Defaults | أول يوم مع أي Framework: اطبع الـ Prompt النهائي اللي بيروح للموديل، وراجع كل Default بيمسّ الاسترجاع |
| 4 | إصدارات سايبة: pip install من غير تثبيت في سوق 🔥 | Pin versions + ترقية مجدولة ومختبرة — مش ترقية بالصدفة يوم ما حاجة تقع |
| 5 | خلط Frameworks عشوائي: شوية LangChain وشوية LlamaIndex ومحدش عارف مين مسؤول عن إيه | لو هتقسم، قسم على حدود واضحة (واحد للـ Ingestion بس مثلًا) — بقرار موثق مش بتراكم Copy-paste |
<!-- Field 22 (Performance): folded into Field 21 per T5 matrix — latency overhead marginal, covered above -->
<!-- BuildAI opinionated stance — operationalizes «Opinionated with reasons» (Phase 0 §17.2) -->
💸 التكلفة — الحقيقة اللي بتريّح
أخبار كويسة: القرار ده مش قرار فلوس. الفاتورة بتاعتك في نداءات الموديل — Input و Output Tokens — والنداءات دي واحدة سواء بعتها بكود مكتوب بإيدك ولا بـ Chain جاهزة. الـ 570 دولار شهريًا بتوع سيناريو «ليه الـ RAG موجود» هيفضلوا 570 في الحالات التلاتة.
والـ Latency؟ الطبقات الإضافية بتضيف Milliseconds — قدام ثواني توليد الـ LLM دي هامش مش بيبان. الاستثناء الوحيد: لو سلسلة جاهزة بتعمل نداءات موديل إضافية معملتش حسابها (Query rewriting تلقائي، تلخيص وسيط…) — ساعتها الفاتورة بتزيد فعلًا، مش عشان الـ Framework، عشان نداءات ما كنتش عارف إنها بتحصل. وده بيرجعنا لنفس القاعدة: اعرف اللي بيحصل جوه.
<!-- Field 14: Common mistakes -->
| موقفك | القرار | ليه |
|---|---|---|
| بتتعلم RAG لأول مرة | من غير Framework | الهدف هو فهم الـ Pipeline نفسها — الـ Framework هيخبيها عنك بالظبط وأنت أحوج ما تكون ليها |
| نظام إنتاج صغير/متوسط، مصدر أو اتنين للبيانات | من غير Framework / طبقة رفيعة | الـ Pipeline بسيطة، والتحكم والـ Debuggability أغلى من توفير Boilerplate محدود |
| Ingestion تقيل: 10+ مصادر بصيغ مختلفة، Indexes متنوعة | LlamaIndex | إعادة كتابة عشرات الـ Loaders والـ Parsers بإيدك إهدار — دي بالظبط المشكلة اللي هو متبني ليها |
| Orchestration معقد: مكونات كتير، موديلات متعددة، أنماط ربط متشعبة | LangChain | منظومة الـ Integrations والـ Chains بتوفر شغل ربط حقيقي — هنا الـ Abstraction بيكسب تمنه |
| الفلو بقى Agent مصحوب بـ State وتفرعات | بص على LangGraph | ده خرج من نطاق الصفحة دي — كامل في «تبني الـ Agents بإيه؟» |
| إنتاج بشرط أقل Dependencies ممكنة (Compliance، فريق صغير، عمر طويل) | من غير Framework | كل Dependency التزام صيانة وترقية — في 🔥 سوق زي ده الالتزام غالي |
<!-- Field 17: When NOT to use it (Layer 7b) -->
- متبنيش من غير Framework لو المهمة أصلًا مش تعليمية والـ Ingestion وحش متعدد الرؤوس والـ Deadline قريب — ساعتها أنت بتعيد اختراع مكتبة ناضجة على حساب وقت منتجك.
- متجيبش Framework عشان «يمكن نحتاج قدراته بعدين» — YAGNI بتنطبق على الـ AI Stack زي أي Stack. جيبه لما الاحتياج يبقى قدامك مش في خيالك.
- ومتخلطش الاتنين بالطريقة الغلط: Framework للـ Ingestion + كود مباشر للاسترجاع والتوليد = تقسيمة مشروعة وذكية. الغلط هو Framework كامل فوق Pipeline أنت أصلًا مش فاهمها.
<!-- Field 19: Trade-offs -->
الاختيارات التلاتة على حقيقتها
### (أ) من غير Framework — نداءات API مباشرة + Vector Store Client
| ✅ القوة | ❌ الضعف |
|---|---|
| تحكم كامل: كل Prompt وكل قرار شايفه بعينك | Boilerplate أكتر: الـ Loaders والـ Retries والتقطيع عليك |
| Debugging مباشر: الـ Stack Trace بتاعك في كودك | ميزة جديدة = تنفيذ جديد (مفيش «قطع غيار» جاهزة) |
| Dependencies شبه صفر: SDK الموديل + Client الـ Vector Store وخلاص | مع تعدد المصادر والمكونات، كودك بيبدأ يبقى Framework صغير — مكتوب مرة واحدة وغير موثق |
| مفيش Upgrade churn: مفيش إصدار يكسرلك حاجة | — |
ده الافتراضي في BuildAI — للتعلم، ولأنظمة الإنتاج الصغيرة: «عشان تفهم اللي بيحصل». مشروع RAG Knowledge Assistant كله مبني كده عمدًا.
### (ب) LlamaIndex — لما المشكلة في الـ Data
| ✅ القوة | ❌ الضعف |
|---|---|
| أقوى ما فيه: الـ Ingestion والـ Indexing والـ Query Engines — المشاكل الـ Data-centric | لما تخرج برة الـ RAG (Agents، Orchestration عام) بيبقى مش أرضه |
| Loaders جاهزة لعشرات المصادر والصيغ (PDFs، Notion، قواعد بيانات…) | Abstraction بيخبي قرارات الاسترجاع — لازم تتعلم افتراضياته |
| بنية Indexes متنوعة جاهزة لما احتياجك يتعدى الـ Vector البسيط | Upgrade churn حقيقي — الـ APIs بتتحرك 🔥 |
### (ج) LangChain — لما المشكلة في الربط
| ✅ القوة | ❌ الضعف |
|---|---|
| أوسع منظومة Integrations في المجال: أي موديل، أي Vector Store، أي أداة — غالبًا ليها Connector | أتقل Abstraction في الاختيارات التلاتة — أبعد مسافة بينك وبين الـ Prompt النهائي |
| Chains جاهزة للأنماط الشائعة + مجتمع وأمثلة بلا حصر | حجم الـ Dependency وسرعة تغير الـ APIs — أعلى Churn في القايمة 🔥 |
| طريق ممهد للتوسع: LangGraph لما تحتاج Agent flows معقدة (ده Pointer بس — تفاصيله في Decision Guide الـ Agents) | كتير من مشاكل الـ Debugging الشهيرة في المجال أصلها «سلسلة جاهزة معرفش بتعمل إيه جوه» |
### وفيه غيرهم؟
> 🔥 Volatile fragment: آه — Haystack (قوي في الـ Search Pipelines الإنتاجية) وغيره، والقايمة بتطول كل شهر. مش بنغطيهم بالتفصيل: المعايير في الصفحة دي هي هي — طبّقها على أي اسم جديد يظهر.
<!-- Field 16: When to use it (Layer 7a) — decision table by situation -->
الموازنات
| المعيار | من غير Framework | LlamaIndex | LangChain |
|---|---|---|---|
| سرعة البداية | ⚠️ أبطأ — بتكتب كل حاجة | ✅ سريعة للـ RAG تحديدًا | ✅ سريعة ومعاها أمثلة لكل حاجة |
| الشفافية والـ Debuggability | ✅ كاملة — الـ Prompt قدامك | ⚠️ متوسطة — افتراضيات لازم تتعلمها | ❌ الأصعب — أطول سلسلة طبقات |
| قوة الـ Ingestion الجاهزة | ❌ عليك كلها | ✅ الأقوى | ⚠️ كويسة |
| اتساع الـ Integrations | ❌ بتكتبها | ⚠️ كويس | ✅ الأوسع |
| الـ Lock-in | ✅ صفر | ⚠️ متوسط | ⚠️ متوسط لأعلى — بينتشر في كل الكود لو سبته |
| الـ Upgrade churn 🔥 | ✅ صفر | ❌ حقيقي | ❌ الأعلى تاريخيًا |
| المجتمع والتوثيق | ⚠️ توثيق الـ APIs الخام (ممتاز أصلًا) | ✅ قوي | ✅ الأضخم |
⚠️ خد بالك من سطر الـ Churn: «الـ Framework بيكسر الـ APIs بين الإصدارات» مش تشهير — ده الثمن الطبيعي لمجال بيتحرك شهريًا، والـ Frameworks بتجري وراه. ثبّت الإصدارات (Pin versions)، وحط ترقية الـ Framework في حساباتك كبند صيانة دوري مش كمفاجأة.
<!-- Field 21: Cost considerations -->
أسئلة الانترفيو
س1: «بنيت الـ RAG بتاعك بإيه؟ وليه؟» السؤال ده مش عن الاسم — عن وجود معايير. الإجابة القوية: «نداءات مباشرة + Client للـ Vector Store، لأن المصادر محدودة والتحكم في الـ Prompt والـ Debugging كانوا أهم من توفير Boilerplate» — أو العكس بمعيار واضح («15 مصدر بيانات فاخترت LlamaIndex للـ Ingestion»). الإجابة الضعيفة: «استخدمت X لأنه الأشهر».
س2: إيه مشاكل الـ Abstraction العالي في تطبيقات LLM تحديدًا؟ في تطبيقات LLM، الجودة كلها قاعدة في تفاصيل الـ Abstraction بيخبيها: الـ Prompt النهائي، حجم الـ Chunks، عدد النتايج، النداءات الوسيطة. لما الجودة تبوظ — وهي بتبوظ — التشخيص محتاج ترى الحاجات دي بالظبط. زوّد على كده الـ Churn: مجال بيتغير شهريًا معناه Frameworks بتكسر APIs باستمرار.
س3: فريقك عايز يعيد كتابة RAG شغال من LangChain لكود مباشر «عشان التحكم». إيه رأيك؟ سؤال Judgment: إعادة الكتابة ليها تمن ومخاطرة، و«التحكم» المجرد مش مبرر كفاية. الإجابة الناضجة بتسأل الأول: إيه المشكلة الفعلية؟ لو Debugging متكرر بيتعطل على طبقات الـ Framework أو ترقيات بتكسر — فيه Case حقيقية، وتتعمل تدريجيًا (المكون الأكتر ألمًا الأول). لو النظام شغال ومستقر — سيبه، واصرف الجهد على تحسين الاسترجاع نفسه.
<!-- Field 28: Knowledge check (scenario-based per F5) -->
- جوه BuildAI: Provider abstraction — writing switchable code ← الـ Retrievers المتقدمة ← «تبني الـ Agents بإيه؟».
- توثيق الأدوات نفسها: 🔥 اقرا توثيق LlamaIndex و LangChain بعد ما تبني الـ Pipeline بإيدك مرة — هتقرأه ساعتها كمهندس بيقيّم أداة، مش كتايه بيدوّر على طوق نجاة.
<!-- Reading→building exit — single primary CTA per Phase 1 §6 -->