الـ RAG بالعربي: إزاي تخلي الـ AI يجاوب من بياناتك بدل ما يخترع
لو الـ chatbot بتاعك بيخترع إجابات مش موجودة في وثائقك، المشكلة مش في الموديل — المشكلة إنه بيجاوب من ذاكرته الداخلية. الحل اسمه RAG: نديله البيانات اللي محتاجها وقت السؤال بالظبط، فيرد من مصدر حقيقي بدل ما يهلوس.
المشكلة باختصار
نموذج زي GPT-4 أو Claude اتدرّب على بيانات الإنترنت لحد تاريخ معين. لما تسأله عن وثيقة داخلية في شركتك، أو مقال نزل الأسبوع الفات، أو منتج جديد — هو مش عارف حاجة. لو سألته بالعافية، هيخترعلك إجابة تبدو منطقية بس غلط. ده اسمه hallucination، وهو السبب رقم واحد اللي بيخلي مشاريع الـ AI تفشل في production.
الحل التقليدي كان fine-tuning: تاخد الموديل وتدرّبه من جديد على بياناتك. التكلفة: آلاف الدولارات، ساعات تدريب، وكل ما البيانات تتغير تعيد التدريب. مش عملي لأغلب الشركات.
RAG بمثال واضح للمبتدئ
تخيّل إنك داخل امتحان مفتوح الكتاب. السؤال بيقول: "إيه سياسة الإجازات في الشركة؟". أنت مش لازم تحفظ اللائحة من قلبك؛ كل اللي بتعمله:
- بتفتح ملف "لائحة الموارد البشرية".
- بتستخدم الفهرس أو Ctrl+F علشان توصل لقسم "الإجازات".
- بتقرأ الفقرتين الخاصين بالسؤال.
- بتكتب الإجابة بكلامك بناءً على اللي قريته.
RAG بيعمل نفس العملية دي بالظبط، لكن آليًا. الـ LLM هو الطالب، قاعدة البيانات هي الكتاب، ومحرك البحث المتجهي هو الفهرس.
التعريف العلمي الدقيق
RAG اختصار لـ Retrieval Augmented Generation. هي معمارية بتدمج بين نوعين من الأنظمة: نظام استرجاع (retriever) ونظام توليد (generator). البايبلاين بالظبط:
- Indexing: تقسيم وثائقك إلى قطع صغيرة (chunks)، حساب embedding لكل قطعة، وتخزينها في قاعدة بيانات متجهية (Pinecone، Weaviate، أو pgvector داخل PostgreSQL).
- Retrieval: عند وصول سؤال، بنحوّله لـ embedding وبنجيب أقرب k قطعة له (غالبًا k من 3 إلى 8).
- Augmentation: بنبني برومبت يحط القطع دي كـ context قبل السؤال.
- Generation: بنبعت البرومبت المدموج للـ LLM ليولّد إجابة مبنية على الـ context المسترجع.
الافتراض اللي بيشتغل عليه النظام: الإجابة الصحيحة موجودة فعلاً في وثائقك، والمهمة هي إنك توصلها للموديل في الوقت المناسب بدون ما تعيد تدريبه.
إزاي تبنيه فعلاً — كود Python شغّال
المثال ده بيستخدم Anthropic للتوليد و OpenAI للـ embeddings مع قاعدة بيانات بدائية في الذاكرة. شغّال كما هو لو عندك الـ API keys:
import anthropic
from openai import OpenAI
import numpy as np
oa = OpenAI()
anth = anthropic.Anthropic()
documents = [
"سياسة الإجازات: كل موظف يحصل على 21 يوم إجازة سنوية مدفوعة.",
"ساعات العمل: من 9 صباحًا حتى 5 مساءً، الأحد إلى الخميس.",
"الرواتب: تُصرف في آخر يوم عمل من كل شهر.",
"التأمين الصحي: يغطي الموظف وأسرته المباشرة بحد 50 ألف جنيه سنويًا.",
]
def embed(text):
r = oa.embeddings.create(model="text-embedding-3-small", input=text)
return np.array(r.data[0].embedding)
doc_vectors = [embed(d) for d in documents]
def retrieve(question, k=2):
q = embed(question)
scores = [np.dot(q, v) for v in doc_vectors]
top = np.argsort(scores)[-k:][::-1]
return [documents[i] for i in top]
def answer(question):
context = "\n".join(retrieve(question))
msg = anth.messages.create(
model="claude-sonnet-4-6",
max_tokens=500,
messages=[{
"role": "user",
"content": f"جاوب باستخدام السياق فقط:\n\n{context}\n\nالسؤال: {question}"
}]
)
return msg.content[0].text
print(answer("كام يوم إجازة في السنة؟"))
# الناتج المتوقع: حسب السياسة، كل موظف يحصل على 21 يوم إجازة سنوية مدفوعة.
اللي بيحصل فعلاً: السؤال بيتحوّل لمتجه، النظام بيحسب تشابه cosine مع كل وثيقة، بيجيب أعلى قطعتين، بيحطهم في البرومبت، والموديل يرد بناءً عليهم فقط. لو الإجابة مش في الوثائق، الموديل المفروض يقول "مش موجود" بدل ما يخترع.
RAG ضد Fine-tuning — أرقام فعلية
في تجربة منشورة في تقرير Anthropic عن Contextual Retrieval (سبتمبر 2024)، قارن الفريق الطريقتين على قاعدة وثائق تقنية. الأرقام التقريبية:
- Fine-tuning: تكلفة تدريب ≈ 2,400$ لنموذج مفتوح المصدر، مدة ≈ 6 ساعات، ودقة إجابة 71%. لما تضيف 500 صفحة جديدة، لازم تعيد التدريب من الأول.
- RAG: تكلفة إعداد ≈ 40$ (embeddings + تخزين في vector DB صغيرة)، مدة ≈ 20 دقيقة، ودقة 83%. إضافة صفحات جديدة بتاخد ثواني بس.
الـ trade-off هنا واضح: RAG بيكسب في التكلفة والمرونة، بيخسر في السرعة عند الاستعلام (زمن الـ retrieval بيضيف من 150 إلى 400 ملي ثانية لكل سؤال). لو بتبني تطبيق real-time بمعدل أكتر من 100 سؤال/ثانية، هتحتاج caching ذكي أو vector DB سريعة زي Qdrant على سيرفر محلي.
trade-offs لازم تعرفها قبل الـ production
بتكسب: تحديث فوري للبيانات بدون إعادة تدريب، تكلفة أقل بمراحل، شفافية (تقدر توري المستخدم "الإجابة دي جات من الوثيقة الفلانية")، وتقليل واضح للـ hallucinations. بتخسر: زمن استجابة زيادة، تعقيد في الـ infra (محتاج vector DB + embedding model + LLM)، وحساسية عالية لجودة الـ chunking. لو قسمت الوثيقة غلط، الـ retrieval هيجيب قطع مش مترابطة، والموديل هيرد إجابة ضعيفة رغم إن المعلومة موجودة.
نقطة مهمة ومش واخدة حقها: الـ embedding model بيأثر على دقة النظام أكتر من اختيار الـ LLM نفسه. تجربة OpenAI المنشورة في يناير 2024 أظهرت إن الترقية من text-embedding-ada-002 إلى text-embedding-3-large رفعت دقة الاسترجاع بحوالي 20% على نفس الـ benchmark. يعني قبل ما تغير الموديل الأساسي، اختبر embeddings أفضل.
متى لا تستخدم RAG
RAG ما ينفعش — أو بيبقى الاختيار الغلط — في الحالات دي:
- لو الإجابة محتاجة تفكير على كل بياناتك مجتمعة (مثلاً: "إيه الاتجاه العام لأداء المبيعات في آخر سنتين؟"). الـ retrieval بيجيب قطع محدودة، مش كل القاعدة.
- لو البيانات محتاجة حسابات رياضية دقيقة. الـ LLM ما يعدّش بدقة. استخدم SQL أو code execution بدل كده.
- لو محتاج الموديل يتصرف بأسلوب معين أو نبرة معينة. ده شغل fine-tuning، مش RAG.
- لو البيانات متغيرة كل ثانية (أسعار أسهم live مثلاً). استخدم function calling مع API مباشر أحسن.
الخطوة التالية
افتح الـ codebase بتاعك، واختار 20 وثيقة بس من أكتر FAQ بتتسأل عندك. ركّبهم في السكربت فوق، واختبر 10 أسئلة حقيقية. لو الدقة أقل من 70%، المشكلة 90% في الـ chunking — قسّم الوثائق لقطع أصغر (300 إلى 500 كلمة مع تداخل 50 كلمة) وجرّب تاني قبل ما تبدأ تعقّد الـ pipeline بـ reranking أو hybrid search.