الفصل 2: استراتيجيات تقسيم النص
مقدمة
تقسيم النص (chunking) حاسم لأداء RAG. يؤثّر حجم الـ chunk والاستراتيجية المناسبة كثيرًا في جودة الاسترجاع ودقة التوليد.
لماذا يهم الـ Chunking
مشكلات غياب الـ chunking:
- الوثائق الكاملة أكبر من اللازم
- يعيد الاسترجاع محتوى غير ذي صلة
- يهدر نافذة سياق LLM
المعاملات الأساسية
حجم الـ Chunk
عدد الأحرف أو الـ tokens لكل chunk:
| حجم الـ Chunk | المزايا | العيوب |
|---|---|---|
| صغير (256) | استرجاع دقيق | قد يفقد السياق |
| متوسط (512-1024) | متوازن | مناسب لمعظم الحالات |
| كبير (2000+) | سياق أكثر | استرجاع أقل دقة |
تداخل الـ Chunk
نص مشترك بين chunks متتالية:
Chunk 1: [_______________]
Chunk 2: [_______________]
^overlap^
لماذا التداخل؟
- يمنع قطع الجمل في منتصف الفكرة
- يحافظ على السياق عبر حدود الـ chunks
- نموذجيًا: 10-20% من حجم الـ chunk
استراتيجيات التقسيم
1. التقسيم التكراري بالأحرف
المقاربة الأكثر شيوعًا - تقسّم حسب تسلسل فواصل:
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", ". ", " ", ""]
)
chunks = splitter.split_documents(documents)
تسلسل الفواصل:
- أسطر فارغة مزدوجة (فقرات)
- أسطر جديدة مفردة
- نقاط (جمل)
- مسافات (كلمات)
- أحرف (الملاذ الأخير)
2. التقسيم القائم على الـ Tokens
يستخدم عدد الـ tokens الفعلي (مهم لحدود LLM):
from langchain.text_splitter import TokenTextSplitter
splitter = TokenTextSplitter(
chunk_size=500, # tokens, not characters
chunk_overlap=50,
encoding_name="cl100k_base" # GPT-4 tokenizer
)
3. التقسيم بالجمل
يحافظ على حدود الجمل:
from langchain.text_splitter import SentenceTransformersTokenTextSplitter
splitter = SentenceTransformersTokenTextSplitter(
chunk_overlap=50,
tokens_per_chunk=256
)
4. التقسيم الدلالي
يقسّم بناءً على التشابه الدلالي:
from langchain_experimental.text_splitter import SemanticChunker
from langchain.embeddings import OpenAIEmbeddings
splitter = SemanticChunker(
OpenAIEmbeddings(),
breakpoint_threshold_type="percentile"
)
# Chunks based on semantic similarity
semantic_chunks = splitter.split_documents(documents)
5. التقسيم حسب عناوين Markdown
يحترم بنية الوثيقة:
from langchain.text_splitter import MarkdownHeaderTextSplitter
headers_to_split_on = [
("#", "Header 1"),
("##", "Header 2"),
("###", "Header 3"),
]
splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=headers_to_split_on
)
اختيار حجم الـ Chunk
def optimal_chunk_size(embedding_model, llm_context_window, top_k):
"""
Calculate optimal chunk size
"""
# Leave room for prompt template and response
available_tokens = llm_context_window * 0.6
# Divide by number of chunks to retrieve
chunk_tokens = available_tokens / top_k
# Convert to characters (roughly 4 chars per token)
return int(chunk_tokens * 4)
# Example: GPT-4 with 8K context, retrieving 5 chunks
optimal = optimal_chunk_size(
embedding_model="text-embedding-3-small",
llm_context_window=8192,
top_k=5
)
# Result: ~3900 characters per chunk
جدول المقارنة
| الاستراتيجية | الأنسب لـ | جودة الـ Chunk |
|---|---|---|
| Recursive Character | غرض عام | جيدة |
| Token-Based | إدارة سياق LLM | ممتازة |
| Sentence | أنظمة الأسئلة والأجوبة | جيدة |
| Semantic | محتوى متغيّر | ممتازة |
| Markdown Headers | وثائق منظّمة | ممتازة |
أفضل الممارسات
- ابدأ بالافتراضيات - 1000 حرف، تداخل 200
- اختبر أحجامًا مختلفة - قيّم جودة الاسترجاع
- طابق المحتوى - الوثائق التقنية قد تحتاج chunks أكبر
- راعِ embeddings - لبعض النماذج حدود tokens قصوى
- احفظ metadata - تتبّع مصدر الـ chunk وموضعه
# Production chunking pipeline
def chunk_documents(documents, chunk_size=1000, overlap=200):
splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=overlap,
length_function=len,
add_start_index=True # Track position
)
chunks = splitter.split_documents(documents)
# Add chunk index to metadata
for i, chunk in enumerate(chunks):
chunk.metadata["chunk_index"] = i
chunk.metadata["total_chunks"] = len(chunks)
return chunks
ملخص
- حجم الـ chunk يؤثّر في دقة الاسترجاع مقابل السياق
- التداخل يمنع فقدان المعلومات عند الحدود
- الاستراتيجية ينبغي أن تطابق نوع وثيقتك
- اختبر وكرّر لإيجاد الإعدادات المثلى
الخطوات التالية
تابع إلى الفصل 3: أنواع الملفات للتعرّف على التعامل مع الوثائق المعقّدة.