ابنِ نموذجاً محلياً لاسترجاع نافذة الجمل دون تبعيات، وافهم لماذا يحتاج الاسترجاع الدقيق إلى سياق محيط، وقيّم الأدلة قبل ربط هذا النمط بمنظومة RAG إنتاجية.
ما الذي يغطيه هذا الشرح العملي
يوفر التوليد المعزز بالاسترجاع، والذي يُختصر عادةً باسم RAG، لنظام الإجابة نصوصاً خارجية يرجع إليها وقت الاستعلام. ومن الخيارات الشائعة في التنفيذ تقسيم كل مستند إلى مقاطع ثابتة الحجم ثم استرجاع المقاطع الأكثر ارتباطاً بالسؤال. هذا النهج مفيد، لكنه يفرض مفاضلة تصميمية مستمرة. فالمقاطع الصغيرة قد تجعل الاسترجاع دقيقاً، لكنها قد تحذف التعريفات والشروط والاستثناءات. أما المقاطع الكبيرة فقد تعيد السياق، لكنها تضيف مواد غير ذات صلة إلى الـPrompt.
يعالج استرجاع نافذة الجمل هذه المفاضلة عبر فصل الوحدة المستخدمة في الاسترجاع عن الوحدة المستخدمة في التفسير. إذ يفهرس النظام الجمل الفردية، وعند اختيار جملة يوسّعها إلى نافذة محلية تضم الجمل القريبة من المستند نفسه. تظل إشارة الاسترجاع دقيقة، بينما يحصل القارئ على مقطع أكثر اكتمالاً.
يستخدم هذا الشرح العملي مكتبة Python القياسية فقط عن قصد. ولا يثبت السياق الموثق واجهات API الحالية أو إصدارات الحزم أو توافر النماذج أو سلوك الاستمرارية لأي إطار RAG أو مزود نماذج بعينه. لذلك يُعد النموذج المحلي الطريقة الأدق لعرض التقنية من دون تقديم بنية غير متحقق منها كحقيقة. وبعد فهم السلوك واختباره، طبّق المفاهيم ذاتها على المكونات التي تحققت منها مؤسستك بصورة مستقلة.
لماذا يهم السياق المحلي في RAG
غالباً ما تتضمن الجملة الكلمات الأكثر تطابقاً مع سؤال المستخدم، لكنها لا تحمل المعنى كاملاً. تخيل مقطعاً من سياسة يتضمن قاعدةً واستثناءً وموعداً نهائياً. قد يطابق الاستعلام الجملة التي تحتوي الموعد النهائي، بينما تنص الجملة السابقة على أن السياسة تنطبق على دور وظيفي محدد فقط. ويمكن أن يؤدي إرجاع الموعد وحده إلى إجابة مضللة.
يحدد سياق البحث الموثق مشكلة مرتبطة في RAG التقليدي: استرجاع معلومات كثيرة جداً قد يخلق ضغطاً على حدود الـtokens ومشكلة «الضياع في الوسط»، حيث تصبح التفاصيل المهمة أقل فائدة وسط سياق مفرط. ويقترح البحث ذاته استرجاع المقاطع عبر مستويات متعددة من التجريد، تشمل مستوى عدة جمل والفقرة والقسم والمستند. وفي تقييمه لأوراق Glycoscience، حسّن هذا النهج صحة الإجابات عن الأسئلة التي قيّمها الذكاء الاصطناعي بنسبة ٢٥.٧٣٩٪ مقارنةً بالنهج التقليدي أحادي المستوى. وهذه نتيجة بحثية لذلك التقييم، وليست وعداً بتحسن كل corpus أو إعداد لنافذة الجمل بالمقدار نفسه.
تمثل نافذة الجمل نمطاً عملياً واحداً لسياق متعدد الجمل. وهي مناسبة خصوصاً عندما تكون الحقائق وتأهيلاتها موجودة عادةً قرب بعضها. لكنها أقل ملاءمة عندما تكون الأدلة اللازمة للإجابة موزعة بين أقسام متباعدة أو مستندات متعددة. في هذه الحالات، قد يحتاج النظام إلى استرجاع أوسع أو مستويات تجريد إضافية أو بنية مستندات مصممة للمهمة.
المتطلبات المسبقة
- Python ٣.١٠ أو إصدار أحدث.
- طرفية قادرة على تشغيل أوامر Python.
- مجموعة صغيرة من مستندات النص العادي أو Markdown الموثوقة بترميز UTF-٨.
- إلمام بأساسيات التنقل عبر سطر الأوامر وملفات Python.
لا يستدعي هذا النموذج API لأي نموذج. بل يسترجع الأدلة ويطبع نوافذ السياق المحددة. وهذا الحد مقصود، إذ يتيح لك فحص ما إذا كان الاسترجاع قد حدد أدلة كافية قبل إدخال توليد الإجابة.
الخطوة ١: أنشئ corpus صغيراً يتضمن قواعد واستثناءات
أنشئ مجلد مشروع ومستندين قصيرين بصيغة Markdown. إن corpus النموذجي خيالي، والغرض منه تسهيل رؤية سبب عدم كفاية تطابق جملة بمفردها لحمل السياق اللازم.
mkdir sentence-window-rag
cd sentence-window-rag
mkdir data
cat > data/travel_policy.md <<'EOF'
# Travel Policy
Employees must use the approved travel portal when inventory is available. Economy class is required for flights shorter than six hours. Premium economy may be booked for flights of six hours or longer.
Business class requires written approval from a vice president before booking. A manager approval is not sufficient. The approval email must be attached to the expense report.
EOF
cat > data/security_policy.md <<'EOF'
# Security Policy
Privileged production access requires multi-factor authentication and an approved access request. Shared user accounts are prohibited. Temporary production access expires automatically after eight hours unless an incident commander extends it during an active incident.
Employees must report suspected security incidents immediately through the incident portal. If the portal is unavailable, employees must contact the on-call security engineer.
EOF
أبقِ المستندات التي تفهرسها ضمن حدود الصلاحيات الخاصة بالمستخدمين المستهدفين. هذا المثال المحلي لا يتضمن مصادقة أو تصفية أو خدمة بعيدة. لا تتعامل معه كنظام جاهز للمستندات السرية.
الخطوة ٢: ابنِ فهرس جمل ونوافذ سياق محلية
أنشئ ملف sentence_window_rag.py. يقرأ البرنامج النصي ملفات Markdown والنصوص، ويفصل النص إلى وحدات بسيطة شبيهة بالجمل، ويحسب درجة شفافة للصلة المعجمية، ويوسع كل نتيجة إلى جمل مجاورة من ملف المصدر نفسه. وهو تنفيذ تعليمي، وليس محللاً لغوياً للجمل أو محرك استرجاع يعتمد المتجهات الدلالية.
from __future__ import annotationsimport argparse
import math
import re
from collections import Counter
from dataclasses import dataclass
from pathlib import PathTOKEN_PATTERN = re.compile(r"[a-z0-9]+")
SENTENCE_PATTERN = re.compile(r"(?<=[.!?])s+")@dataclass(frozen=True)
class SentenceRecord:
source_file: str
position: int
text: strdef tokenize(text: str) -> list[str]:
return TOKEN_PATTERN.findall(text.lower())def split_sentences(text: str) -> list[str]:
cleaned = re.sub(r"^#+s+.*$", "", text, flags=re.MULTILINE)
cleaned = re.sub(r"s+", " ", cleaned).strip()
if not cleaned:
return []
return [part.strip() for part in SENTENCE_PATTERN.split(cleaned) if part.strip()]def load_records(data_dir: Path) -> list[SentenceRecord]:
records: list[SentenceRecord] = []
for path in sorted(data_dir.rglob("*")):
if not path.is_file() or path.suffix.lower() not in {".md", ".txt"}:
continue
...تابع القراءة
سجل دخولك مجاناً لقراءة المقال كاملاً والوصول إلى أدوات الذكاء الاصطناعي.
تسجيل الدخول / إنشاء حساب