Firma z 4000 dokumentów PDF, która indeksuje je z domyślnym ustawieniem „po 500 znaków", dostaje asystenta, który cytuje właściwy paragraf, ale nie rozumie, o jaką umowę chodzi. Precyzja retrieval w takim wariancie spada o 30–50% względem odpowiednio skalibrowanego pipeline. Problem nie leży w modelu językowym ani w bazie wektorowej, lecz w granulacji fragmentów.
Trzy podstawowe strategie i kiedy je stosować
#Stały rozmiar (fixed-size chunking) dzieli dokument na fragmenty o z góry określonej liczbie tokenów lub znaków, z opcjonalnym przesunięciem (overlap). To najprostsze podejście, szybkie w implementacji i przewidywalne w kosztach indeksacji. Sprawdza się, gdy dokumenty mają jednorodną strukturę, np. logi systemowe czy opisy produktów pisane jednym szablonem. Główna wada: splitter nie rozpoznaje granicy zdania, więc często przecina myśl w połowie.
Recursive character splitter (np. RecursiveCharacterTextSplitter w LangChain) próbuje zachować granice semantyczne, dzieląc kolejno po \n\n, \n, . , a dopiero na końcu po znaku. Dla większości polskich dokumentów biznesowych, czyli instrukcji, regulaminów i raportów pisanych prozą, to domyślny wybór, który daje dobry stosunek jakości do nakładu.
Semantyczny chunking grupuje zdania o podobnym znaczeniu na podstawie odległości cosinusowej kolejnych embeddingów. Rozmiar fragmentów jest zmienny, co komplikuje przewidywanie liczby tokenów i kosztu inferencji, ale precyzja retrieval dla długich, gęstych dokumentów (np. wielostronicowych umów) bywa o 10–25% wyższa niż przy fixed-size.
Dobór rozmiaru fragmentu i overlap
#Nie ma jednego właściwego rozmiaru. Zależy on od trzech czynników: modelu embeddingowego, charakteru pytań użytkownika i średniej długości odpowiedzi, której oczekuje asystent.
Praktyczne widełki dla polskich dokumentów biznesowych:
- Pytania faktograficzne (daty, nazwy, kwoty): 256–512 tokenów, overlap 50–80 tokenów.
- Pytania wymagające kontekstu procedury: 512–1024 tokeny, overlap 100–150 tokenów.
- Dokumenty narracyjne, analizy, raporty: 1024–2048 tokenów, overlap 150–200 tokenów.
Overlap nie jest „marnowaniem miejsca". Fragment A kończący się w połowie paragrafu i fragment B zaczynający się 100 tokenów wcześniej razem gwarantują, że wyszukiwanie semantyczne znajdzie odpowiedź nawet przy pytaniu trafiającym dokładnie w granicę podziału.
Modele embeddingowe mają limit kontekstu wejściowego: BGE-M3 obsługuje do 8192 tokenów, ale jego optimum jakościowe leży w przedziale 512–1024 tokenów na fragment. Powyżej tego progu sygnał semantyczny rozkłada się po całym oknie i precyzja retrieval spada.
Chunking tabel i kodu: osobna ścieżka
#Tabele i kod to struktury, których standardowy splitter po znaku niszczy. Tabela rozerwana między dwa fragmenty traci nagłówki kolumn w pierwszym i dane w drugim, więc model nie potrafi powiązać wartości z ich znaczeniem.
Rozwiązanie: wykrywaj tabele i bloki kodu na etapie parsowania dokumentu (np. przez pdfplumber, camelot lub Unstructured.io), a następnie:
- Tabele: przekształć w format tekstowy (Markdown lub JSON row-by-row) i zapisz jako osobny chunk z metadaną
type: table. Jeśli tabela jest dłuższa niż 512 tokenów, podziel ją na bloki po 5–10 wierszy, powtarzając nagłówek w każdym bloku. - Kod: zachowaj jako jeden chunk nie dłuższy niż 1024 tokeny. Jeśli fragment kodu jest dłuższy, dziel po blokach funkcji (linie zaczynające się od
def,function,class), nie po arbitralnej liczbie znaków.
Metadane type: table i type: code pozwalają na późniejsze filtrowanie w zapytaniach hybrydowych. Więcej o tym procesie w artykule jak przygotować dane firmowe pod AI.
Strategia vs typ dokumentu: tabela referencyjna
#| Typ dokumentu | Zalecana strategia | Rozmiar chunka (tokeny) | Overlap (tokeny) |
|---|---|---|---|
| FAQ, listy pytań i odpowiedzi | Semantyczny po pytaniu | 128–256 | 0–30 |
| Umowy, regulaminy (klauzule) | Recursive po nagłówku sekcji | 512–768 | 80–120 |
| Instrukcje obsługi, procedury | Recursive standardowy | 512–1024 | 100–150 |
| Raporty analityczne, narracja | Semantyczny lub fixed-size | 1024–2048 | 150–200 |
| Tabele danych (cenniki, rejestry) | Tabela row-by-row + nagłówek | 256–512 | 0 (powtórz nagłówek) |
| Fragmenty kodu, skrypty | Fixed po granicy funkcji | 512–1024 | 0 |
| E-maile, krótkie wiadomości | Fixed-size lub bez podziału | 128–256 | 0–20 |
Metadane chunka jako drugi sygnał retrieval
#Sam tekst fragmentu to nie wszystko. Każdy chunk powinien nieść metadane, które baza wektorowa może filtrować przed rerankingiem: nazwę pliku źródłowego, numer strony, typ dokumentu, datę aktualizacji, identyfikator klienta lub projektu (jeśli dotyczy).
Filtrowanie metadanami przed wyszukiwaniem wektorowym redukuje przestrzeń przeszukiwania i usuwa z wyników dokumenty nieaktualne lub niezwiązane z kontekstem zapytania. Dla firmy z 4000 dokumentów podzielonych na kategorie (umowy, instrukcje, FAQ) ten krok skraca listę kandydatów o 60–80% przed właściwym rankingiem semantycznym.
Pipeline RAG z filtrami metadanych wygląda następująco: zapytanie użytkownika → embedding zapytania → filtr (np. type: contract AND client_id: X) → wyszukiwanie wektorowe na podzbiorze → reranking top-k → generacja odpowiedzi. Efekt jest mierzalny: precyzja odpowiedzi rośnie, a liczba halucynacji spada, bo model dostaje tylko relevantne fragmenty.
Więcej o ocenie jakości retrieval w artykule RAG: ewaluacja jakości odpowiedzi.
Spróbuj na żywo
#Masz własny zestaw dokumentów i zastanawiasz się, od czego zacząć? Poniższy sandbox pozwala przetestować reasoning dla Twojego przypadku:
FAQ
#Ile tokenów powinien mieć jeden chunk dla dokumentów prawnych?
#Dla umów i regulaminów optimum leży w przedziale 512–768 tokenów z overlap 80–120 tokenów. Ważniejszy od samego rozmiaru jest punkt podziału: dziel po nagłówkach sekcji (§ 1, § 2, „Postanowienia ogólne"), a nie po arbitralnej liczbie znaków. Klauzula, która trafi w całości do jednego chunka, będzie trafniej retrieval-owana niż ta sama klauzula rozerwana na dwa fragmenty.
Czy większy overlap zawsze poprawia jakość retrieval?
#Nie. Overlap powyżej 20–25% rozmiaru chunka podnosi koszty indeksacji i może wprowadzać redundancję, która zaburza ranking. Jeśli dwa fragmenty o 50% wspólnej treści trafiają do top-5 wyników, model dostaje zduplikowany kontekst zamiast różnych perspektyw. Overlap 10–15% rozmiaru chunka to bezpieczny punkt startowy dla większości dokumentów.
Jak chunking wpływa na wyszukiwanie hybrydowe BM25 + wektory?
#Chunking oddziałuje na oba składniki: zbyt krótkie fragmenty tracą słowa kluczowe dla BM25, zbyt długie rozmywają sygnał wektorowy. Dla hybrydowego wyszukiwania optimum leży zwykle w przedziale 512–1024 tokenów, gdzie oba sygnały działają efektywnie. Warto przeprowadzić testy A/B na reprezentatywnym zbiorze pytań przed ustaleniem ostatecznego rozmiaru.
Czy powinienem re-indeksować dokumenty po zmianie strategii chunkingu?
#Tak, pełna re-indeksacja jest konieczna po zmianie strategii lub rozmiaru chunka. Embeddingi generowane z inaczej podzielonych fragmentów nie są porównywalne z poprzednimi. W praktyce: przygotuj nową kolekcję obok starej, przeprowadź testy jakości na golden secie, a dopiero po osiągnięciu lepszych wyników przełącz ruch na nową kolekcję. Więcej o tym procesie w artykule aktualizacja wiedzy RAG i wersjonowanie.
Jak obsłużyć dokumenty PDF z mieszaną strukturą (tekst, tabele, obrazy)?
#Użyj parsera strukturalnego, np. Unstructured.io lub pdfplumber, który wykrywa typy elementów przed splitterem. Tekst ciągły przetwarzasz recursive splitterem, tabele konwertujesz na Markdown row-by-row z powtórzonym nagłówkiem, obrazy (wykresy, schematy) opisujesz za pomocą modelu vision i dołączasz opis jako osobny chunk z metadaną type: image_caption. Taka segmentacja pozwala zachować strukturę semantyczną dokumentu bez utraty informacji w żadnej z warstw.