كل التدويناتAll posts

RAG: إزاي تخلي الذكاء الاصطناعي يجاوب من بياناتكRAG: making an AI answer from your own data

شرح RAG من غير تعقيد: التقطيع، الـ embeddings، البحث، وبناء الإجابة، وإمتى مش محتاجه أصلا.RAG without the jargon: chunking, embeddings, retrieval and answering, and when you do not need it at all.

  • الكاتبWritten byزياد شلبيZeyad Shalaby
  • التاريخDate
  • وقت القرايةReading time5 دقايقminutes
غلاف مقال RAG وشرح Retrieval Augmented Generation

RAG اختصار Retrieval Augmented Generation، ومعناه ببساطة: قبل ما النموذج يجاوب على السؤال، دور في مستنداتك على المقاطع اللي ليها علاقة بيه، حطها قدامه في نفس الطلب، وقوله “جاوب من دول”. النموذج مش بيتدرب على بياناتك ومش بيحفظها. هو بياخدها كورقة غش في كل سؤال. دي أشهر طريقة تخلي شات بوت يجاوب عن منتجك أو سياساتك أو توثيق مشروعك.

المشكلة اللي بيحلها

النموذج اللغوي عنده مشكلتين مع بياناتك:

  • ما يعرفهاش. سياسة الاسترجاع بتاعتك وأسعارك وتوثيق مشروعك مش في اللي اتدرب عليه.
  • لما ما يعرفش بيألف. بيكتب إجابة شكلها مقنع وهي من خياله.

الحل البديهي إنك تلصق كل مستنداتك في كل سؤال. ده بينفع لو هم صفحتين. لو هم ألف صفحة، هيبقى غالي وبطيء، والنموذج هيتوه في الكم ده. RAG بيحل ده: بيجيب للنموذج الصفحتين اللي محتاجهم من الألف.

الفكرة في أربع خطوات

  1. التجهيز (مرة واحدة): قطع المستندات لمقاطع صغيرة، وحول كل مقطع لـ embedding، وخزنهم.
  2. البحث (مع كل سؤال): حول السؤال لـ embedding، وهات أقرب المقاطع ليه.
  3. التجميع: حط المقاطع دي مع السؤال في طلب واحد.
  4. الإجابة: النموذج يكتب الرد من المقاطع، ويقول جاب كل معلومة منين.

يعني إيه Embedding

الـ embedding هو قايمة أرقام طويلة بتمثل معنى النص. نموذج مخصوص بياخد جملة ويرجع مثلا 1000 رقم. الفكرة إن الجمل اللي معناها قريب بتطلع أرقامها قريبة من بعض، حتى لو الكلمات مختلفة خالص.

مثال: “إزاي أرجع المنتج؟” و “سياسة الاسترداد” مفيش بينهم كلمة مشتركة، بس الـ embedding بتاعهم قريب. بحث الكلمات العادي مش هيلاقي العلاقة دي، والبحث بالمعنى هيلاقيها.

والأرقام دي بتتخزن في قاعدة بيانات بتعرف تدور بالقرب، بيسموها vector database. ممكن تبقى خدمة مستقلة، أو إضافة لقاعدة بيانات عندك أصلا زي pgvector في PostgreSQL.

التقطيع: الخطوة اللي بتحدد الجودة

معظم مشاكل RAG بتيجي من هنا مش من النموذج.

  • مقطع صغير قوي: بيطلع جملة من غير سياقها. “المدة 14 يوم” مدة إيه؟
  • مقطع كبير قوي: فيه خمس مواضيع، فالـ embedding بتاعه مش بيمثل أي واحد فيهم كويس.

اللي بينفع في الغالب:

  • قطع على حدود المعنى: عنوان وفقراته، مش كل 500 حرف.
  • خلي تداخل بسيط بين المقاطع المتتالية عشان الجملة اللي في النص ما تتقطعش.
  • ضيف لكل مقطع عنوان المستند والقسم اللي هو فيه. ده بيرجعله سياقه.
  • خزن مع كل مقطع مصدره: اسم الملف والرابط، عشان الإجابة تقدر تشاور عليه.

شكل الكود

ده الهيكل بـ JavaScript، من غير أسماء مكتبات معينة. embed و search و ask دوال بتلفها انت حوالين الخدمة اللي بتستخدمها:

// مرة واحدة: تجهيز المستندات
for (const doc of documents) {
  for (const chunk of split(doc)) {
    const vector = await embed(chunk.text);
    await store.insert({ vector, text: chunk.text, source: doc.url });
  }
}

// مع كل سؤال
async function answer(question) {
  const qVector = await embed(question);
  const chunks = await store.search(qVector, { limit: 5 });

  const context = chunks
    .map((c, i) => `[${i + 1}] ${c.text}nالمصدر: ${c.source}`)
    .join('nn');

  return ask(`
جاوب على السؤال من المقاطع اللي تحت بس.
لو الإجابة مش موجودة فيها، قول "مش لاقي ده في المستندات".
اكتب رقم المقطع بعد كل معلومة.

المقاطع:
${context}

السؤال: ${question}`);
}

أهم سطرين في الطلب: “من المقاطع بس” و “لو مش موجودة قول كده”. من غيرهم النموذج هيكمل من عنده لما البحث يرجع حاجة مش مفيدة.

أخطاء شائعة

  • تقييم بالإحساس. اكتب 30 سؤال حقيقي وإجاباتهم الصح، وشغلهم بعد كل تعديل. من غير كده مش هتعرف التغيير حسن ولا بوظ.
  • الاعتماد على بحث المعنى لوحده. أكواد المنتجات والأسماء والأرقام بحث الكلمات بيلاقيها أحسن. الأقوى إنك تدمج الاتنين.
  • مستندات متضاربة. لو عندك نسختين من نفس السياسة، النموذج ممكن يجاوب من القديمة. نضف المصدر قبل ما تفهرسه.
  • نسيان التحديث. المستند اتغير والفهرس لسه قديم. اعمل طريقة تعيد فهرسة اللي اتعدل.
  • الصلاحيات. لو فيه مستندات مش كل المستخدمين مسموحلهم يشوفوها، الفلترة لازم تحصل في البحث نفسه، مش تسيبها للنموذج.
  • المستندات فيها تعليمات. نص في مستند ممكن يحاول يوجه النموذج. شوف Prompt Injection.

لو البحث جاب المقطع الغلط، أحسن نموذج في الدنيا هيجاوب غلط.

إمتى مش محتاج RAG

  • بياناتك صغيرة. لو كل المستندات تدخل في الطلب براحة، حطها كلها وخلاص. أبسط وأدق.
  • السؤال عن بيانات منظمة. “كام طلب الشهر ده؟” ده استعلام SQL مش بحث في نصوص. ادي النموذج أداة تسأل قاعدة البيانات.
  • عندك وكيل يقدر يدور. في مشروع كود مثلا، وكيل بيفتح الملفات ويدور فيها بنفسه بيوصل لنتيجة كويسة من غير فهرس. التفاصيل في AI Agents: إيه هي وبتشتغل إزاي.
  • عايز النموذج يغير أسلوبه مش معلوماته. ده شغل التعليمات والأمثلة، مش RAG.

ابدأ بأبسط حاجة تشتغل: مستنداتك في الطلب مباشرة. لما تكبر على كده، ساعتها ضيف البحث. ولو عايز تبني حاجة زي دي لشغلك ومش عارف تبدأ منين، ابعتلي أو شوف كورس أتمتة شغلك بالذكاء الاصطناعي.

RAG stands for Retrieval Augmented Generation, and it simply means: before the model answers, search your documents for the passages related to the question, put them in front of it in the same request, and say “answer from these”. The model is not trained on your data and does not memorise it. It gets a cheat sheet with every question. This is the most common way to make a chatbot answer about your product, your policies or your project’s docs.

The problem it solves

A language model has two problems with your data:

  • It does not know it. Your refund policy, prices and project docs are not in its training.
  • When it does not know, it invents. It writes a convincing answer from imagination.

The obvious fix is to paste all your documents into every question. That works for two pages. For a thousand, it becomes expensive and slow, and the model gets lost. RAG solves this: it brings the model the two pages it needs out of the thousand.

The idea in four steps

  1. Preparation (once): split documents into small chunks, turn each into an embedding, and store them.
  2. Retrieval (per question): turn the question into an embedding and fetch the closest chunks.
  3. Assembly: put those chunks with the question in one request.
  4. Answer: the model writes the reply from the chunks and says where each fact came from.

What an embedding is

An embedding is a long list of numbers that represents the meaning of a text. A dedicated model takes a sentence and returns, say, 1000 numbers. Sentences with similar meaning get numbers close to each other, even when the words differ completely.

Example: “how do I return the product?” and “refund policy” share no word, yet their embeddings are close. Keyword search misses that link, and semantic search finds it.

These numbers are stored in a database that can search by closeness, called a vector database. It can be a separate service, or an extension to a database you already have, such as pgvector for PostgreSQL.

Chunking: the step that decides quality

Most RAG problems come from here, not from the model.

  • Chunk too small: a sentence without its context. “The period is 14 days” of what?
  • Chunk too large: five topics inside, so its embedding represents none of them well.

What usually works:

  • Split on meaning boundaries: a heading and its paragraphs, not every 500 characters.
  • Keep a small overlap between consecutive chunks so a sentence in the middle is not cut.
  • Add the document title and section to each chunk. That gives it back its context.
  • Store the source with each chunk: file name and link, so the answer can point to it.

What the code looks like

This is the skeleton in JavaScript, without specific library names. embed, search and ask are functions you wrap around whichever service you use:

// once: prepare the documents
for (const doc of documents) {
  for (const chunk of split(doc)) {
    const vector = await embed(chunk.text);
    await store.insert({ vector, text: chunk.text, source: doc.url });
  }
}

// for every question
async function answer(question) {
  const qVector = await embed(question);
  const chunks = await store.search(qVector, { limit: 5 });

  const context = chunks
    .map((c, i) => `[${i + 1}] ${c.text}nSource: ${c.source}`)
    .join('nn');

  return ask(`
Answer the question from the passages below only.
If the answer is not in them, say "I cannot find this in the documents".
Write the passage number after each fact.

Passages:
${context}

Question: ${question}`);
}

The two most important lines in the request: “from the passages only” and “if it is not there, say so”. Without them the model fills in from itself when retrieval returns something unhelpful.

Common mistakes

  • Evaluating by feel. Write 30 real questions with correct answers and run them after every change. Otherwise you cannot tell whether a change helped or hurt.
  • Relying on semantic search alone. Product codes, names and numbers are found better by keyword search. Combining both is strongest.
  • Conflicting documents. With two versions of one policy, the model may answer from the old one. Clean the source before indexing.
  • Forgetting updates. The document changed and the index is stale. Build a way to re-index what changed.
  • Permissions. If some documents are not for all users, filtering must happen in retrieval itself, not be left to the model.
  • Documents containing instructions. Text in a document may try to steer the model. See prompt injection.

If retrieval brings the wrong passage, the best model in the world answers wrongly.

When you do not need RAG

  • Your data is small. If all documents fit comfortably in the request, include them all. Simpler and more accurate.
  • The question is about structured data. “How many orders this month?” is an SQL query, not a text search. Give the model a tool that queries the database.
  • You have an agent that can search. In a code project, an agent that opens and searches files itself gets good results with no index. Details in AI agents: what they are and how they work.
  • You want to change the model’s style, not its knowledge. That is a job for instructions and examples, not RAG.

Start with the simplest thing that works: your documents directly in the request. When you outgrow that, add retrieval. If you want to build something like this for your work and do not know where to begin, write to me or see the AI automation course.

التعليقاتComments

سيب تعليقLeave a comment

اقرا كمانRead next