AI Engineering Academy · Pelajaran

Strategi Pembagian: Tetap vs Kalimat vs Rekursif

Terapkan dan bandingkan pemisah teks berukuran tetap, berbatas kalimat, dan karakter rekursif, serta pahami pengaruh ukuran dan tumpang tindih bagian terhadap kualitas pengambilan.

Pelajaran 2 dari 413 langkah

Strategi Pembagian: Tetap vs Kalimat vs Rekursif adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Mengapa Kualitas Pembagian Potongan Penting

Pembagian potongan adalah proses membagi dokumen yang telah dimuat menjadi bagian-bagian lebih kecil yang muat dalam jendela konteks LLM serta dapat diindeks dan diambil secara individual. Cara Anda membagi potongan lebih menentukan kualitas pengambilan daripada hampir semua faktor lainnya. Potongan yang membagi jawaban ke dalam dua bagian membuat masing-masing bagian tidak cukup untuk menjawab pertanyaan. Potongan yang mencampurkan dua topik yang tidak berhubungan akan diambil untuk pertanyaan tentang keduanya, tetapi tidak berguna untuk salah satunya.

Pembagian Potongan Berukuran Tetap

Pembagian potongan berukuran tetap membagi teks menjadi potongan yang masing-masing memiliki tepat N karakter atau N token, tanpa memedulikan batas kalimat atau paragraf. Ini adalah strategi paling sederhana dan cepat diterapkan. Kekurangan utamanya adalah strategi ini sering memotong kalimat menjadi dua, sehingga potongan dimulai atau diakhiri di tengah gagasan. Strategi ini dapat diterima untuk teks padat dengan format seragam seperti hasil ekspor basis data, tetapi menghasilkan kualitas pengambilan yang buruk pada prosa naratif atau dokumentasi teknis.

def fixed_size_chunks(text, chunk_size=500, overlap=50):
    '''Split text into fixed-size character chunks with overlap'''
    chunks = []
    start = 0
    while start < len(text):
        end = start + chunk_size
        chunk = text[start:end]
        chunks.append(chunk)
        start += chunk_size - overlap  # overlap keeps context at boundaries
    return chunks

example = 'This is a long document. ' * 100
chunks = fixed_size_chunks(example, chunk_size=200, overlap=20)
print(f'Produced {len(chunks)} chunks, first: {chunks[0][:80]}...')

Menambahkan Tumpang Tindih pada Potongan Tetap

Perbaikan utama untuk pembagian potongan berukuran tetap adalah tumpang tindih: setiap potongan berbagi N karakter dengan potongan sebelumnya. Dengan demikian, informasi di dekat batas potongan muncul di kedua potongan yang bersebelahan. Dengan tumpang tindih 50–100 token, kalimat yang melintasi batas akan tertangkap sepenuhnya setidaknya dalam salah satu dari kedua potongan tersebut. Tumpang tindih yang lebih besar berarti cakupan yang lebih baik, tetapi juga ukuran indeks yang lebih besar dan konten berulang dalam hasil pengambilan.

# Overlap example with a sentence at the boundary
text = 'A B C D E F G H I J'
chunk_size = 6  # characters
overlap = 2

i = 0
while i < len(text):
    print(repr(text[i:i+chunk_size]))
    i += chunk_size - overlap

# Output shows overlapping content:
# 'A B C D'
# 'C D E F'
# 'E F G H'
# Each adjacent pair shares 2 chars

Pembagian pada Batas Kalimat

Pembagian pada batas kalimat menggunakan pustaka NLP seperti nltk atau spacy untuk mendeteksi akhir kalimat sebelum melakukan pembagian. Dengan demikian, tidak ada kalimat yang terpotong menjadi dua. Anda mengumpulkan kalimat hingga penambahan kalimat berikutnya akan melebihi ukuran target, lalu memulai potongan baru. Hasilnya adalah potongan yang selalu berisi gagasan lengkap, sehingga kualitas penyematan jauh lebih baik daripada pembagian berdasarkan karakter tetap.

import nltk
nltk.download('punkt', quiet=True)

def sentence_chunks(text, max_tokens=300):
    sentences = nltk.sent_tokenize(text)
    chunks = []
    current = []
    current_len = 0

    for sent in sentences:
        sent_tokens = len(sent.split())
        if current_len + sent_tokens > max_tokens and current:
            chunks.append(' '.join(current))
            current = []
            current_len = 0
        current.append(sent)
        current_len += sent_tokens

    if current:
        chunks.append(' '.join(current))
    return chunks

Pembagian Teks Karakter Rekursif

Pembagian karakter rekursif adalah strategi yang paling banyak digunakan dalam sistem RAG produksi. Strategi ini mencoba hierarki pemisah secara berurutan: pertama jeda paragraf (\n\n), lalu baris baru (\n), kemudian titik di akhir kalimat, spasi, dan akhirnya karakter individual. Teks dibagi pada batas bermakna terbesar yang tetap menjaga potongan berada di bawah ukuran target, sehingga potongan sebisa mungkin mengikuti struktur dokumen.

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,       # target size in characters
    chunk_overlap=200,     # overlap between consecutive chunks
    separators=['\n\n', '\n', '. ', '! ', '? ', ' ', ''],
    length_function=len
)

with open('document.txt') as f:
    text = f.read()

chunks = splitter.split_text(text)
print(f'Split into {len(chunks)} chunks')
for i, chunk in enumerate(chunks[:3]):
    print(f'Chunk {i}: {len(chunk)} chars — {chunk[:60]}...')

Pembagian yang Memperhatikan Token

Jumlah karakter adalah perkiraan yang tidak presisi untuk jumlah token. Potongan 1000 karakter mungkin berisi 200 token atau 400 token, bergantung pada panjang kata dan bahasanya. Untuk pengendalian yang presisi, lakukan pembagian berdasarkan jumlah token menggunakan tiktoken. Hal ini penting untuk menyesuaikan potongan dengan jendela konteks model dan memperkirakan biaya secara akurat. TokenTextSplitter milik LangChain membungkus tiktoken untuk melakukan pembagian yang memperhatikan token.

from langchain_text_splitters import TokenTextSplitter
import tiktoken

# Split by actual token count, not characters
splitter = TokenTextSplitter(
    encoding_name='cl100k_base',  # GPT-4 tokenizer
    chunk_size=256,               # target tokens per chunk
    chunk_overlap=32              # overlap in tokens
)

chunks = splitter.split_text(text)

# Verify token count
enc = tiktoken.get_encoding('cl100k_base')
for chunk in chunks[:3]:
    tokens = len(enc.encode(chunk))
    print(f'Chunk: {tokens} tokens')

Memilih Ukuran Potongan yang Tepat

Ukuran potongan adalah parameter hiper yang penting. Potongan kecil (100–200 token) bersifat presisi — potongan ini berisi informasi yang sangat terfokus sehingga dapat disematkan dengan baik. Namun, potongan kecil kehilangan konteks di sekitarnya, sehingga LLM mungkin tidak memiliki cukup informasi untuk menjawab. Potongan besar (500–1000 token) menyediakan lebih banyak konteks, tetapi penyematannya merata-ratakan topik yang lebih luas sehingga lebih sulit diambil untuk kueri tertentu. Sebagian besar sistem produksi menggunakan 256–512 token dengan pengujian empiris pada data mereka.

Menambahkan Konteks ke Potongan

Peningkatan yang ampuh adalah header kontekstual potongan: tambahkan judul dokumen dan judul bagian di awal teks setiap potongan sebelum melakukan penyematan. Dengan demikian, penyematan menangkap bukan hanya isi potongan, tetapi juga asalnya dalam dokumen. Potongan yang berbunyi Manfaat dan Kebijakan Cuti: Karyawan memperoleh 15 hari setiap tahun... akan diambil dengan jauh lebih akurat untuk pertanyaan tentang kebijakan cuti dibandingkan teks yang sama tanpa header.

def create_contextual_chunks(doc, splitter):
    title = doc['metadata'].get('title', '')
    section = doc['metadata'].get('section', '')
    text = doc['text']

    raw_chunks = splitter.split_text(text)
    contextual_chunks = []
    for chunk in raw_chunks:
        # Prepend document context to each chunk
        context_header = f'{title}\n{section}\n\n' if title else ''
        contextual_chunks.append({
            'text': context_header + chunk,
            'metadata': doc['metadata']
        })
    return contextual_chunks

Membandingkan Strategi pada Data Anda

Tidak ada satu strategi pembagian potongan yang selalu terbaik. Buat evaluasi singkat: ambil 20 pertanyaan yang jawabannya Anda ketahui, jalankan pengambilan dengan setiap strategi pembagian potongan, lalu ukur seberapa sering potongan yang benar berada di peringkat 5 hasil teratas (tingkat keberhasilan@5). Penyiapan ini hanya memerlukan waktu satu jam dan dapat menghemat berminggu-minggu waktu untuk menebak. Anda akan sering menemukan bahwa format dokumen tertentu (prosa hukum yang padat dibandingkan dokumentasi teknis yang terstruktur) sangat mendukung satu strategi dibandingkan strategi lainnya.

def evaluate_chunking_strategy(questions_and_answers, retriever):
    hits = 0
    for qa in questions_and_answers:
        results = retriever.retrieve(qa['question'], top_k=5)
        result_texts = [r['text'] for r in results]
        # Check if answer text appears in any retrieved chunk
        if any(qa['answer'] in text for text in result_texts):
            hits += 1
    hit_rate = hits / len(questions_and_answers)
    print(f'Hit rate@5: {hit_rate:.1%} ({hits}/{len(questions_and_answers)})')
    return hit_rate

Menangani Jenis Dokumen Khusus

Beberapa jenis dokumen memerlukan pembagian khusus. File kode harus dibagi berdasarkan batas fungsi atau kelas, bukan jumlah karakter. File Markdown harus dibagi pada batas header sehingga setiap potongan berhubungan dengan satu bagian. Tabel harus dipertahankan utuh sebagai satu potongan (membaginya di tengah tabel membuat konten tidak dapat dipahami). Rencanakan strategi pembagian berdasarkan jenis dokumen dalam korpus Anda, bukan dengan menerapkan pemisah yang sama untuk semua jenis dokumen.

from langchain_text_splitters import MarkdownHeaderTextSplitter

# Split Markdown by header hierarchy
md_splitter = MarkdownHeaderTextSplitter(
    headers_to_split_on=[
        ('#', 'h1'),
        ('##', 'h2'),
        ('###', 'h3')
    ]
)

with open('documentation.md') as f:
    md_text = f.read()

# Each chunk gets metadata from its heading hierarchy
chunks = md_splitter.split_text(md_text)
for chunk in chunks[:3]:
    print('Section:', chunk.metadata)
    print('Text:', chunk.page_content[:80])
    print()

Melacak Asal Potongan

Setiap potongan memerlukan ID yang stabil dan unik yang diturunkan dari dokumen sumber dan posisinya. Gunakan ID ini untuk memperbarui potongan tertentu ketika dokumen berubah tanpa mengindeks ulang seluruh korpus. Hash deterministik dari jalur sumber dan indeks potongan dapat digunakan dengan baik. Catat juga posisi potongan (potongan 3 dari 12 pada dokumen X) dalam metadata — hal ini membantu menyusun kembali bagian lengkap ketika beberapa potongan yang bersebelahan diambil bersama.

import hashlib

def assign_chunk_ids(chunks, source_path):
    for i, chunk in enumerate(chunks):
        key = f'{source_path}::chunk_{i}'
        chunk_id = hashlib.sha256(key.encode()).hexdigest()[:16]
        chunk['id'] = chunk_id
        chunk['metadata']['chunk_index'] = i
        chunk['metadata']['total_chunks'] = len(chunks)
    return chunks

# IDs are stable across re-runs if source and position match
chunks = sentence_chunks(text)
chunks = [{'text': c, 'metadata': {}} for c in chunks]
assign_chunk_ids(chunks, 'docs/policy_v3.pdf')

Pemeriksaan Singkat

Uji pemahaman Anda tentang konsep Rekayasa AI dari pelajaran ini.

Ringkasan Pelajaran

Dalam pelajaran ini Anda mempelajari: pembagian potongan berukuran tetap sederhana, tetapi memotong kalimat menjadi dua; pembagian pada batas kalimat mempertahankan gagasan lengkap; pembagian karakter rekursif mengikuti struktur dokumen dan merupakan pilihan produksi yang paling umum; serta teknik lanjutan, termasuk pembagian yang memperhatikan token, header kontekstual, pemisah khusus untuk Markdown dan kode, serta ID potongan yang stabil untuk pembaruan bertahap. Selanjutnya kita akan menyematkan dan menyimpan potongan-potongan ini dalam basis data vektor.

Gratis untuk memulai

Belajar Python dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
30
Pelajaran
120

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Strategi Pembagian: Tetap vs Kalimat vs Rekursif” gratis?

Ya — teks lengkap “Strategi Pembagian: Tetap vs Kalimat vs Rekursif” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Strategi Pembagian: Tetap vs Kalimat vs Rekursif”?

Terapkan dan bandingkan pemisah teks berukuran tetap, berbatas kalimat, dan karakter rekursif, serta pahami pengaruh ukuran dan tumpang tindih bagian terhadap kualitas pengambilan. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?

Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Strategi Pembagian: Tetap vs Kalimat vs Rekursif” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Memuat Dokumen dan Mengekstrak Teks
  2. Strategi Pembagian: Tetap vs Kalimat vs Rekursif
  3. Pengindeksan: Menyematkan dan Menyimpan Bagian
  4. Mengueri, Mengambil, dan Menghasilkan
← Kembali ke AI Engineering Academy