Deduplikacja i wersjonowanie wiedzy w RAG: jak nie karmić modelu 12 kopiami tego samego PDF
Jak w RAG wykrywać duplikaty i zarządzać wersjami dokumentów: hashing, near-duplicate, lineage/provenance, wpływ na retrieval, pipeline ingest, retencja, testy i monitoring.
1. Dlaczego deduplikacja i wersjonowanie są krytyczne w RAG
W architekturach RAG (Retrieval-Augmented Generation) jakość odpowiedzi modelu jest bezpośrednio ograniczona jakością i organizacją bazy wiedzy. Dwa najczęstsze, a zarazem najbardziej podstępne źródła degradacji to duplikaty (te same lub niemal te same treści występujące wielokrotnie) oraz brak kontroli wersji (różne wydania dokumentu mieszają się ze sobą bez jasnych reguł, które są aktualne). W praktyce oba problemy często występują jednocześnie: ten sam PDF krąży w kilku katalogach, po drodze bywa konwertowany, dzielony na strony, a potem „wgrywany” ponownie jako rzekomo nowe źródło.
Deduplikacja odpowiada na pytanie: czy w indeksie mamy tę samą informację więcej niż raz? Jej celem jest usunięcie lub kontrolowanie powtórzeń, które nie wnoszą wartości. Wersjonowanie odpowiada na pytanie: która z kilku podobnych treści jest właściwa na dany moment i w jakim kontekście? Jego celem jest uporządkowanie zmian w czasie, tak aby system potrafił preferować aktualne informacje, a starsze traktować jako historyczne, archiwalne lub obowiązujące tylko w określonym okresie.
W RAG te dwa mechanizmy są krytyczne z kilku powodów:
- Jakość odpowiedzi i ryzyko halucynacji: duplikaty i niekontrolowane wersje zwiększają szansę, że do kontekstu trafią fragmenty sprzeczne lub nieaktualne. Model może wtedy „uśrednić” treści, wybrać losowo jedną z wersji albo zbudować odpowiedź łącząc niepasujące fragmenty.
- Stabilność zachowania systemu: jeśli ta sama treść występuje wielokrotnie, wyniki wyszukiwania mogą być podatne na drobne zmiany zapytania i rankingów, bo redundantne wpisy konkurują ze sobą. Efekt: raz system odpowiada poprawnie, innym razem zaskakująco gorzej, mimo że dane „teoretycznie” się nie zmieniły.
- Redundancja kontekstu i marnowanie okna kontekstowego: w RAG każdy token ma koszt i alternatywę. Gdy retriever zwraca kilka kopii tego samego fragmentu, okno kontekstowe jest wypełniane powtórzeniami zamiast komplementarnych informacji. To obniża pokrycie tematu i zwiększa ryzyko, że zabraknie miejsca na kluczowy wyjątek, definicję lub ograniczenie.
- Koszty infrastruktury i operacji: duplikaty mnożą rozmiar indeksu, liczbę embeddingów oraz czas wyszukiwania i reindeksacji. Wersjonowanie bez zasad prowadzi do „puchnięcia” kolekcji, bo każde odświeżenie źródła staje się kolejną równorzędną kopią, zamiast kontrolowanej zmiany.
- Zgodność, audyt i wiarygodność: w zastosowaniach biznesowych istotne jest, aby móc wskazać, z której wersji dokumentu pochodzi informacja i czy była aktualna w momencie generowania odpowiedzi. Bez wersjonowania trudniej obronić odpowiedź w audycie, a bez deduplikacji łatwiej o „fałszywe wzmocnienie” jednej tezy przez to, że pojawia się ona wielokrotnie w bazie.
- Bezpieczeństwo merytoryczne: zmiany w procedurach, regulaminach czy specyfikacjach często unieważniają poprzednie zasady. Jeśli starsza wersja dokumentu nadal jest wysoko dostępna w retrievalu, system może generować instrukcje niezgodne z aktualnym stanem wiedzy.
Warto też odróżnić dwa typowe scenariusze:
- Duplikaty techniczne (kopie plików, re-eksport PDF, różne ścieżki, powtórne ingestowanie) – tutaj celem jest usunięcie nadmiaru, bo nie wnosi on nowej treści.
- Duplikaty semantyczne (ta sama informacja opisana inaczej) – tutaj celem nie zawsze jest usuwanie. Czasem lepiej zachować kilka ujęć, ale kontrolować, by nie dominowały wyników i nie zjadały kontekstu.
Deduplikacja i wersjonowanie to zatem nie „optymalizacja na później”, lecz fundament jakości RAG. Pozwalają utrzymać indeks jako spójne, przewidywalne źródło wiedzy: zminimalizować powtórzenia, jasno rozdzielić historię od aktualności oraz ograniczyć ryzyko, że model będzie wzmacniał przypadkowe kopie zamiast opierać się na najbardziej właściwych i aktualnych treściach.
2. Wykrywanie duplikatów: hashing (exact) i podobieństwo (near-duplicate)
W RAG „duplikat” rzadko oznacza wyłącznie ten sam plik w identycznej postaci. Częściej spotyka się mieszankę: identyczne treści pod różnymi nazwami, ten sam dokument po konwersji (PDF → tekst), ten sam PDF z inną metryką (np. inne metadane), albo dokumenty prawie takie same, różniące się jedną stroną czy datą. Dlatego wykrywanie duplikatów warto podzielić na dwa uzupełniające się podejścia: exact (identyczność) oraz near-duplicate (prawie identyczność).
Podczas szkoleń Cognity ten temat wraca regularnie – dlatego zdecydowaliśmy się go omówić również tutaj.
Exact dedup odpowiada na pytanie: „czy to dokładnie ten sam artefakt?”. Near-duplicate odpowiada na pytanie: „czy to w praktyce ta sama treść (lub jej bardzo bliska wersja)?”. W ingest pipeline oba są potrzebne, bo rozwiązują inne klasy problemów i mają inne koszty oraz ryzyka.
Hashing (exact): szybkie wykrywanie identycznych kopii
Hashing w kontekście deduplikacji to najprostszy i najszybszy sposób wyłapania sytuacji, gdy ten sam byt pojawia się wielokrotnie bez zmian. Najczęściej stosuje się go do:
- identycznych plików (ta sama zawartość binarna),
- identycznych wyników ekstrakcji (ten sam tekst po OCR/parsingu),
- identycznych chunków po pocięciu treści.
Kluczowa różnica polega na tym, co haszujesz. Hash pliku wykryje powielone kopie tego samego PDF, ale nie wykryje dokumentu „tego samego znaczeniowo”, jeśli ktoś go ponownie zapisał, zmienił metadane, dodał znak wodny lub nastąpiła inna drobna modyfikacja binarna. Hash znormalizowanego tekstu jest bardziej odporny na takie zmiany, ale nadal wymaga, by tekst po przetworzeniu był identyczny. Hash na poziomie chunków pozwala usuwać powtórzenia nawet wtedy, gdy dokumenty różnią się układem, ale zawierają identyczne fragmenty.
Zastosowanie hashy jest zwykle deterministyczne i tanie obliczeniowo, ale ma ograniczenie: wykrywa głównie „kopie 1:1”. W praktyce to pierwszy filtr, który usuwa oczywiste powielania zanim przejdziesz do droższych metod podobieństwa.
Podobieństwo (near-duplicate): wykrywanie „prawie tego samego”
Near-duplicate detection jest potrzebne tam, gdzie treść jest w dużej mierze ta sama, ale nie identyczna. Typowe przypadki:
- aktualizacje dokumentów (np. dopisana sekcja, podmieniona tabela, zmieniona data),
- różne formaty tego samego materiału (PDF, DOCX, HTML),
- różne wyniki OCR (literówki, różnice w łamaniu wierszy),
- re-edycje: ta sama treść w innym układzie, z innymi nagłówkami, stopkami, numeracją stron.
Wykrywanie podobieństwa można realizować na kilku poziomach granularity: na poziomie całego dokumentu, akapitów lub chunków. Im drobniejszy poziom, tym łatwiej wykryć powtarzalne fragmenty w różnych źródłach, ale rośnie liczba porównań i ryzyko „fałszywych duplikatów” (np. standardowe klauzule prawne, stopki, szablonowe polityki).
Near-duplicate z definicji operuje na progu podobieństwa i dlatego jest bardziej heurystyczny: trzeba zdecydować, kiedy „podobne” oznacza „wystarczająco podobne, by traktować jako duplikat”. Ten próg będzie inny dla instrukcji technicznych, inny dla umów, a jeszcze inny dla artykułów czy notatek. W RAG szczególnie ważne jest, by near-duplicate nie usuwał treści, które różnią się istotnym szczegółem (np. numerem wersji procedury), ale jednocześnie ograniczał karmienie modelu wieloma wariantami tego samego przekazu.
Jak dobrać podejście do celu
Najczęściej skuteczne jest podejście warstwowe: najpierw hashing jako szybki filtr na oczywiste duplikaty, a potem podobieństwo tam, gdzie chcesz wychwycić re-edycje, warianty formatów i aktualizacje. Różnią się też typowe decyzje po wykryciu:
- Przy exact dedup zwykle bezpiecznie jest odrzucić kopię i zachować pojedynczy egzemplarz wraz z informacją o źródłach, z których się pojawił.
- Przy near-duplicate częściej potrzebujesz reguł: czy łączyć, czy wybierać „kanoniczną” wersję, czy trzymać kilka wariantów (np. gdy różnice mogą być semantycznie istotne).
Ważne jest też, by odróżniać duplikaty treści od duplikatów sygnałów w retrieval. Nawet jeśli przechowasz oba podobne dokumenty, pipeline może później ograniczać redundancję w kontekście odpowiedzi. Jednak im wcześniej zidentyfikujesz duplikaty na etapie ingest, tym mniejsze koszty indeksowania, mniej szumu w rankingu i mniejsze ryzyko, że model dostanie wielokrotnie ten sam fragment w różnych opakowaniach.
Typowe pułapki
- Stopki, nagłówki, boilerplate: mogą powodować, że wiele dokumentów wydaje się podobnych; warto rozumieć, że „podobieństwo” może wynikać z szablonu, a nie z właściwej treści.
- Różnice w normalizacji: drobne rozbieżności w białych znakach, kodowaniu czy kolejności elementów potrafią zepsuć exact dedup, jeśli haszujesz „surowy” tekst.
- OCR i ekstrakcja: ten sam PDF może dawać różne teksty w zależności od narzędzia i ustawień, co utrudnia wykrywanie identyczności i przesuwa ciężar na metody podobieństwa.
- Zbyt agresywny próg near-duplicate: usuwa treści, które są „prawie takie same”, ale zawierają krytyczne różnice (np. zmiany w limitach, procedurach, wymaganiach).
Wykrywanie duplikatów w RAG to więc nie jednorazowa operacja, tylko zestaw decyzji: co porównujesz (plik, tekst, chunk), jak porównujesz (identyczność vs podobieństwo) i po co (oszczędność kosztów, poprawa jakości retrieval, ograniczenie redundancji w kontekście).
3. Wersjonowanie dokumentów: modele wersji, zmiany i identyfikatory
W RAG dokumenty nie są „stałe”: polityki, instrukcje, regulaminy i FAQ ewoluują, a pipeline ingest często wielokrotnie przetwarza te same źródła (np. ponowny eksport PDF, nowy skan, korekta literówki). Bez wersjonowania łatwo pomylić to samo z nowszym i utrzymywać w indeksie sprzeczne lub przeterminowane treści. Wersjonowanie porządkuje te relacje: odpowiada na pytania co się zmieniło, kiedy, względem czego i który wariant ma być preferowany podczas odpowiedzi.
Modele wersjonowania: kiedy który ma sens
W praktyce spotyka się kilka prostych modeli. Różnią się tym, czy wersję przypisuje się do „pliku jako artefaktu”, do „treści logicznej”, czy do „rekordu w systemie”.
| Model | Na czym opiera wersję | Zastosowanie | Ryzyko / ograniczenia |
|---|---|---|---|
| Wersja oparta o czas (timestamp) | data publikacji/ingestu | proste źródła, gdy „najnowsze wygrywa” | czas nie mówi, czy treść faktycznie się zmieniła; podatne na ponowne wgrania |
| Wersja oparta o rewizję/semver | numer wersji z systemu źródłowego (np. 1.2, 2024-03) | dokumenty kontrolowane (procedury, polityki) | wymaga wiarygodnego pola wersji; bywa niespójne między działami |
| Wersja oparta o treść (content-derived) | hash treści znormalizowanej | gdy brak metadanych wersji; wykrywanie „ta sama treść w nowym pliku” | zmiany formatowania mogą wyglądać jak zmiana merytoryczna (jeśli normalizacja słaba) |
| Wersja jako „stan w systemie” (snapshot) | stan repozytorium/rekordu (np. eksport bazy) | źródła generowane (CMS, bazy wiedzy) | trudniej mapować na pojedyncze sekcje i cytowania, jeśli snapshot jest duży |
W RAG często łączy się podejścia: numer wersji (jeśli jest) jako deklaracja, a sygnatura treści jako weryfikacja, czy rzeczywiście zaszła zmiana.
Co to znaczy „zmiana” i dlaczego warto ją klasyfikować
Nie każda różnica między plikami powinna generować nową „ważną” wersję w indeksie. W praktyce przydatny jest podział zmian na:
- Merytoryczne – zmieniają znaczenie (np. progi, procedury, wyjątki). Zwykle powinny tworzyć nową wersję logiczną i dezaktualizować poprzednią.
- Redakcyjne – stylistyka, literówki, kolejność akapitów. Często można traktować jako nową rewizję, ale bez zmiany „obowiązywania”.
- Formatowe/techniczne – inny układ PDF, inne fonty, skan vs. tekst, inne nagłówki generowane. W idealnym przypadku nie powinny tworzyć nowej wersji treści, jeśli semantyka jest ta sama.
Taka klasyfikacja pomaga ustalić, czy trzeba reindeksować całość, czy tylko podmienić artefakt, a także które fragmenty mają być preferowane podczas budowania kontekstu.
Identyfikatory: rozdziel „dokument”, „wersję” i „fragment”
Żeby wersjonowanie działało, identyfikatory muszą być stabilne i rozłączne dla różnych poziomów:
- Document ID (ID logicznego dokumentu) – stały identyfikator „tej polityki / tej instrukcji” niezależnie od pliku. Przykład: ścieżka w repozytorium, URL w CMS, klucz rekordu.
- Version ID (ID wersji) – identyfikator konkretnego wydania dokumentu logicznego. Może być numerem wersji ze źródła, timestampem publikacji albo hashem treści znormalizowanej.
- Artifact ID – identyfikator pliku/artefaktu (konkretny PDF, DOCX, HTML eksport). Przydatny, gdy ten sam dokument logiczny ma wiele reprezentacji.
- Chunk/Fragment ID – identyfikator fragmentu używanego w indeksie (np. rozdział/akapit). Powinien zawierać co najmniej parę: Document ID + Version ID + lokalizacja.
Kluczowa zasada: chunk nigdy nie powinien „udawać” stabilności, jeśli jego źródłowy dokument ma różne wersje. W przeciwnym razie w indeksie pojawiają się fragmenty o tym samym ID, ale z inną treścią, co utrudnia kontrolę aktualności i cytowania.
Minimum metadanych wersji, które warto utrzymywać
Nawet przy prostym wdrożeniu opłaca się trzymać zestaw pól umożliwiających jednoznaczne wybieranie właściwej wersji:
- document_id – identyfikator logiczny dokumentu
- version_id – identyfikator wersji (z systemu lub z treści)
- published_at / effective_from – kiedy wersja zaczyna obowiązywać
- supersedes_version_id (opcjonalnie) – którą wersję zastępuje
- status – np. robocza / obowiązująca / wycofana
- source_ref – odnośnik do źródła (URL/ścieżka/klucz rekordu)
Dzięki temu można budować proste reguły: preferuj status=obowiązująca, a przy remisie wybieraj najwyższą wersję lub najnowszą datę publikacji.
Przykładowa konwencja identyfikatorów (uzupełniająco)
{
"document_id": "polityka/bezpieczenstwo-hasel",
"version_id": "2026-02-15" ,
"artifact_id": "sha256:...",
"chunk_id": "polityka/bezpieczenstwo-hasel@2026-02-15#sec3_p2"
}Takie rozdzielenie pozwala jednocześnie: (1) wiedzieć, że to wciąż ten sam dokument logiczny, (2) wybrać właściwą wersję, (3) utrzymać spójne referencje do fragmentów w indeksie.
4. Lineage i provenance: śledzenie źródeł, transformacji i mapowanie na cytowania
W RAG problemem nie jest tylko to, co zostało zindeksowane, ale też skąd to pochodzi, jak zostało przetworzone i dlaczego znalazło się w kontekście odpowiedzi. Lineage (rodowód danych) i provenance (pochodzenie) to zestaw praktyk oraz metadanych, które pozwalają wiarygodnie przejść od wygenerowanej odpowiedzi do konkretnych fragmentów źródłowych i całego procesu ich przygotowania. Zespół trenerski Cognity zauważa, że właśnie ten aspekt sprawia uczestnikom najwięcej trudności — bo bez porządnego „łańcucha dowodowego” trudno odróżnić błąd retrieval od efektu transformacji albo złej wersji dokumentu.
Lineage vs provenance — po co oba pojęcia?
W praktyce oba terminy bywają używane zamiennie, ale warto rozdzielić ich akcent:
| Pojęcie | Co opisuje | Najczęstsze zastosowanie w RAG |
|---|---|---|
| Provenance | Skąd pochodzi treść (źródło, autor, system, link, identyfikator dokumentu) | Cytowania, audyt, zgodność, zaufanie do źródła |
| Lineage | Jak treść została wytworzona/zmieniona w pipeline (OCR, czyszczenie, chunking, tłumaczenie) | Debugging jakości, reindeksacja, odtwarzalność wyników, wykrywanie „skażenia” transformacjami |
Minimalny „łańcuch dowodowy” dla fragmentu (chunku)
Aby móc wiarygodnie mapować wyniki retrieval na cytowania, każdy chunk powinien nieść minimalny zestaw metadanych, które tworzą spójny „łańcuch dowodowy”:
- Identyfikator źródła: np. URI/ścieżka, ID rekordu w DMS, podpisany link do obiektu w storage.
- Identyfikator dokumentu: stabilny klucz niezależny od lokalizacji (żeby przeniesienie pliku nie zrywało historii).
- Zakres w źródle: strona/sekcja/offset znaków, ewentualnie współrzędne (dla PDF jako layout).
- Sygnatura transformacji: wersja pipeline, tryb ekstrakcji (np. OCR), parametry chunkingu.
- Sygnatura treści: skrót tekstu chunku (do weryfikacji niezmienności i detekcji rozjazdów).
Ten zestaw nie rozwiązuje jeszcze deduplikacji ani wersjonowania, ale umożliwia ich egzekwowanie i audyt: jeśli dwa chunki wyglądają podobnie, można sprawdzić, czy pochodzą z tego samego dokumentu, z innej wersji, czy są skutkiem innej transformacji.
Transformacje jako „pierwszej klasy” obywatel
RAG rzadko indeksuje „surowy” dokument. Tekst przechodzi przez ekstrakcję i normalizację, które mogą zmieniać znaczenie (np. błędy OCR), usuwać kontekst (np. nagłówki/stopki) albo mieszać kolejność (np. układ wielokolumnowy). Dlatego lineage powinien traktować transformacje jako element, który:
- da się nazwać (typ transformacji),
- da się wersjonować (wersja narzędzia/pipeline),
- da się odtworzyć (te same wejścia + te same parametry → ten sam wynik),
- da się porównać (czy różnice w odpowiedziach wynikają z modelu, retrieval czy z preprocessing).
Mapowanie na cytowania: od chunku do źródła bez „teleportacji”
Użytkownikowi nie wystarczy informacja, że model „wziął to z bazy”. Cytowanie powinno być możliwie precyzyjne i weryfikowalne. Typowe podejście to mapowanie:
- od odpowiedzi → do listy chunków użytych w kontekście,
- od chunku → do fragmentu dokumentu (strona/sekcja/offset),
- od dokumentu → do stabilnego źródła (link/ID), z informacją o transformacjach.
Ważne jest, by cytowanie odzwierciedlało konkretną reprezentację (np. tekst po OCR) i równolegle wskazywało oryginał (np. PDF), tak aby użytkownik mógł zweryfikować treść w kontekście. W praktyce cytowanie jest wiarygodne tylko wtedy, gdy metadane nie pozwalają na „zgubienie” relacji między chunkami a źródłem.
Wzorzec danych: „karta fragmentu” (bez narzucania technologii)
Poniższy przykład pokazuje, jak może wyglądać uustrukturyzowany zapis pochodzenia chunku. To tylko ilustracja formatu, nie rekomendacja konkretnego narzędzia:
{
"chunk_id": "...",
"document_id": "...",
"source": {
"uri": "s3://.../file.pdf",
"mime": "application/pdf"
},
"span": {
"page": 12,
"start_char": 340,
"end_char": 980
},
"transform": {
"pipeline_version": "...",
"steps": ["pdf_extract", "ocr", "normalize", "chunk"]
},
"content_fingerprint": "sha256:..."
}
Dlaczego lineage/provenance ogranicza ryzyko w RAG
- Wiarygodne cytowania: łatwiej uniknąć „halucynowanych” źródeł i podać sprawdzalny odnośnik.
- Rozliczalność: wiadomo, z jakich dokumentów i jakich etapów pipeline pochodzi wiedza w odpowiedzi.
- Kontrola jakości: można wskazać, czy problem jest w źródle, ekstrakcji, chunkingu, czy w samym generowaniu.
- Bezpieczne aktualizacje: zmiana pipeline nie musi niszczyć historii — można porównać efekty po metadanych transformacji.
W skrócie: deduplikacja i wersjonowanie mówią, co jest czym i która wersja jest właściwa, a lineage/provenance sprawia, że system potrafi to udowodnić i pokazać użytkownikowi w postaci sensownych cytowań.
5. Wpływ duplikatów i wersji na retrieval: ranking, dywersyfikacja i kontrola redundancji kontekstu
W RAG etap retrieval decyduje, które fragmenty trafią do kontekstu LLM. Gdy w indeksie znajdują się duplikaty lub wiele wersji tych samych treści, mechanizmy wyszukiwania zaczynają „pomagać” w zły sposób: wzmacniają powtarzalne źródła, zawężają różnorodność kontekstu i podnoszą ryzyko cytowania nieaktualnej wersji. Efekt bywa subtelny (gorsze odpowiedzi) albo bardzo widoczny (model dostaje 12 niemal identycznych chunków).
Jak duplikaty psują ranking (i dlaczego to nie jest tylko problem „kosmetyczny”)
- Dominacja w top-k – jeśli ta sama treść występuje wiele razy, jej embeddingi będą blisko zapytania i wzajemnie „zajmą” miejsca w wynikach, wypychając inne, komplementarne źródła.
- Bias na źródło – algorytmy scoringu (wektorowe, BM25, hybrydowe) wzmacniają często reprezentowane dokumenty. W praktyce „częstość występowania” staje się niejawnie sygnałem relewancji.
- Fałszywe poczucie pewności – wiele podobnych trafień wygląda jak silna zgodność, choć to tylko wielokrotna kopia tego samego.
- Wyższy koszt kontekstu – redundancja w top-k zwiększa liczbę tokenów bez wzrostu pokrycia informacyjnego, co pogarsza jakość odpowiedzi przy stałym limicie okna kontekstu.
Wersje dokumentów: relewancja vs. aktualność
Wersjonowanie w retrieval to nie tylko „nowsze jest lepsze”. W zależności od pytania użytkownika, istotna może być wersja historyczna (np. „jak to działało w 2022?”) albo najbardziej aktualna. Problem pojawia się, gdy system nie rozróżnia wersji i:
- Miesza wersje w top-k – kontekst zawiera fragmenty sprzeczne (stara i nowa definicja), co zwiększa ryzyko halucynacji lub niejednoznacznej odpowiedzi.
- Preferuje starsze treści – np. dlatego, że były częściej ingested, lepiej pocięte na chunki, lub mają „łatwiejszy” język i wyższy scoring.
- Utrudnia cytowanie – model nie wie, czy cytuje wersję obowiązującą, czy archiwalną, jeśli metadane nie są spójne i egzekwowane w selekcji.
Dlaczego dywersyfikacja wyników staje się konieczna
Nawet przy deduplikacji na wejściu, podobne fragmenty mogą istnieć naturalnie (np. różne dokumenty opisujące tę samą procedurę). Dlatego retrieval powinien umieć dywersyfikować wyniki, czyli celowo mieszać źródła i redukować nadmiar podobnych chunków. Najczęstsze skutki braku dywersyfikacji:
- Wąski kontekst – model widzi jeden punkt widzenia zamiast przekroju (np. definicja bez wyjątków, procedura bez ograniczeń).
- Gorsza odporność na błędy – jeśli „dominujący” dokument zawiera błąd, system powiela go wielokrotnie.
- Brak pokrycia – kontekst nie obejmuje różnych aspektów pytania, bo kilka slotów zajęły warianty tego samego fragmentu.
Kontrola redundancji kontekstu: gdzie to robić
Redundancję można ograniczać na różnych etapach. Kluczowa różnica: deduplikacja usuwa duplikaty w danych, a redundancy control zarządza tym, co finalnie trafia do promptu.
| Mechanizm | Cel | Najlepszy moment | Ryzyko/Trade-off |
|---|---|---|---|
| Filtr po ID duplikatu / „canonical” | Nie zwracać wielu kopii tej samej treści | Przed rankingiem lub tuż po nim | Może ukryć różnice, jeśli ID zbyt agresywne |
| Preferencja najnowszej wersji | Aktualność odpowiedzi | Re-ranking (po wstępnym retrieval) | Może pominąć istotny kontekst historyczny |
| Dywersyfikacja (np. po źródle / dokumencie) | Pokrycie wielu dokumentów | Po wstępnym rankingu | Może obniżyć precyzję, jeśli zbyt restrykcyjna |
| Próg podobieństwa między chunkami | Wyciąć near-duplicate w kontekście | Przy budowie finalnego kontekstu | Dobór progu bywa wrażliwy domenowo |
| Kompresja/merge kontekstu | Zastąpić powtórzenia streszczeniem | Bezpośrednio przed promptem | Ryzyko utraty cytowalnych detali |
Praktyczne zasady: jak unikać „12 kopii PDF” w top-k
- Limit na dokument: nie pozwalaj, by jeden dokument (lub jedna rodzina duplikatów) zajął większość top-k.
- Re-ranking z metadanymi: wprowadzaj do scoringu sygnały typu: wersja, data obowiązywania, status (aktualny/archiwalny), typ źródła.
- Wybór reprezentanta: jeśli istnieje kanoniczna wersja treści, preferuj ją jako „entry point” do kontekstu.
- Separacja celów: inne ustawienia dla zapytań „co jest teraz” (preferuj aktualność), inne dla „jak było” (preferuj pokrycie wersji lub filtr dat).
- Kontrola podobieństwa w kontekście: po zebraniu kandydatów buduj finalny kontekst tak, aby kolejne chunki wnosiły nową informację, a nie wariant tego samego akapitu.
Minimalny przykład: odrzucanie zbyt podobnych chunków przy budowie kontekstu
Poniższy wzorzec pokazuje ideę: po wstępnym rankingu wybierasz kolejne fragmenty tylko wtedy, gdy nie są zbyt podobne do już wybranych (redundancy control na wyjściu retrieval).
# candidates: lista (chunk_text, chunk_embedding, meta, score) posortowana malejąco po score
selected = []
selected_embs = []
SIM_THRESHOLD = 0.90
MAX_K = 8
for c in candidates:
if len(selected) >= MAX_K:
break
too_similar = any(cosine(c.embedding, e) >= SIM_THRESHOLD for e in selected_embs)
if too_similar:
continue
selected.append(c)
selected_embs.append(c.embedding)
# selected - finalne chunki do promptu, bardziej różnorodne informacyjnie
To nie zastępuje deduplikacji ani wersjonowania, ale znacząco ogranicza „zapychanie” kontekstu powtórzeniami i poprawia pokrycie odpowiedzi.
6. Rekomendacje dla ingest pipeline: chunking, normalizacja, dedup i reindeksacja
Ingest pipeline w systemach RAG decyduje o tym, co trafia do indeksu i w jakiej postaci. Jeśli na tym etapie nie opanujesz fragmentacji (chunkingu), normalizacji, deduplikacji i zasad reindeksacji, będziesz utrzymywać zbędne kopie treści, rozmywać ranking wyników i płacić za przechowywanie oraz embeddingi, które nie wnoszą wartości.
6.1. Chunking: jak dzielić, żeby nie mnożyć redundancji
Chunking to kompromis między kontekstem a precyzją. Z perspektywy deduplikacji jest też ważny dlatego, że zbyt drobne lub niestabilne fragmenty utrudniają wykrywanie duplikatów i powodują częste „fałszywe zmiany” między wersjami.
- Stabilność granic chunków: staraj się ciąć po naturalnych granicach (nagłówki, akapity, punkty list), bo drobne zmiany w dokumencie nie będą przesuwały całej siatki fragmentów.
- Rozmiar i overlap: utrzymuj stały docelowy zakres znaków/tokenów; overlap stosuj oszczędnie (zwiększa koszty i ryzyko duplikacji w kontekście), tylko gdy realnie poprawia spójność odpowiedzi.
- Chunking semantyczny vs. techniczny: semantyczny (np. po sekcjach) zwykle daje lepszą stabilność, techniczny (stała długość) bywa szybszy, ale generuje więcej driftu przy edycjach.
- Metadane chunków: do każdego fragmentu zapisuj co najmniej document_id, source_uri, version_id, offsety (start/koniec) i ścieżkę sekcji (np. „H1/H2”). To ułatwia późniejsze odświeżanie i kontrolę duplikatów.
6.2. Normalizacja: ujednolicenie treści przed porównaniami
Normalizacja powinna być przewidywalna i deterministyczna. Jej celem jest usunięcie różnic „kosmetycznych”, które nie zmieniają znaczenia, ale psują deduplikację i wersjonowanie. Kluczowe jest, by normalizować przed liczeniem hashy i embeddingów oraz by przechowywać zarówno wersję „clean”, jak i referencję do oryginału.
- Tekst: ujednolicenie białych znaków, usunięcie nagłówków/stopki z każdej strony, normalizacja myślników i cudzysłowów, scalanie łamań wierszy.
- Struktura: zachowanie hierarchii nagłówków i list; ostrożnie z usuwaniem numeracji, bo bywa istotna w dokumentach proceduralnych.
- Tabele i kolumny: spłaszczanie do formatu tekstowego (np. wiersz po wierszu) w sposób stabilny; losowe kolejności kolumn to częste źródło pozornych zmian.
- Elementy nietekstowe: OCR dla skanów; dla obrazów/wykresów co najmniej podpisy i otoczenie tekstowe, aby uniknąć „pustych” chunków.
- Język: nie „tłumacz” w ingest jako normalizacji, jeśli nie masz twardego wymagania. To często tworzy równoległe wersje i komplikuje dedup.
6.3. Dedup w ingest: gdzie i w jakiej kolejności
Najlepszy efekt daje deduplikacja wieloetapowa: tania i szybka na początku, droższa dopiero wtedy, gdy ma to sens. Celem ingest jest odsiać nadmiar zanim zapłacisz za embeddingi i zaindeksujesz treść.
- Dedup „na wejściu” (source-level): nie ingestuj ponownie tego samego pliku/artefaktu, jeśli identyfikator źródła i jego fingerprint się nie zmieniły.
- Dedup po normalizacji (content-level): po czyszczeniu tekstu licz fingerprinty treści; to redukuje duplikaty wynikające np. z różnych eksportów PDF.
- Dedup na poziomie chunków: wykrywaj identyczne lub bardzo podobne fragmenty, aby nie przechowywać wielu kopii tych samych akapitów z różnych dokumentów.
- Polityka „keep one”: zdefiniuj, którą kopię zachować (np. najnowsza wersja, najlepsza jakość OCR, źródło o wyższym priorytecie), a pozostałe oznacz jako duplikaty z referencją do „kanonicznej”.
| Etap | Co wykrywa | Koszt | Po co w ingest |
|---|---|---|---|
| Przed parsowaniem | Powtórne dostarczenie tego samego artefaktu | Niski | Uniknięcie niepotrzebnego OCR/parsowania |
| Po normalizacji | Różne „opakowania” tej samej treści | Niski–średni | Oszczędność embeddingów i miejsca w indeksie |
| Po chunkingu | Powtarzalne akapity/sekcje między dokumentami | Średni | Zmniejszenie redundancji kontekstu w odpowiedziach |
| Po embeddingach (opcjonalnie) | Duże podobieństwo semantyczne | Wysoki | Domknięcie przypadków near-duplicate, gdy to konieczne |
6.4. Reindeksacja: kiedy przeliczać i jak ograniczać koszty
Reindeksacja to kontrolowane „odświeżenie” indeksu po zmianach w dokumentach, regułach chunkingu, normalizacji lub modelu embeddingów. W ingest warto od razu zaprojektować mechanizm, który wspiera zarówno aktualizacje przyrostowe, jak i pełne przebudowy — ale nie miesza ich bez kontroli.
- Rozdziel „zmianę treści” od „zmiany pipeline”: jeśli modyfikujesz normalizację/chunking, możesz wymusić reindeksację nawet bez zmian w źródle.
- Identyfikatory deterministyczne: stabilne chunk_id (np. oparte o document_id + ścieżkę sekcji + offsety) ułatwia update zamiast „delete+insert wszystkiego”.
- Tryb przyrostowy: przeliczaj embeddingi tylko dla fragmentów, które realnie się zmieniły (po normalizacji), a nie dla całego dokumentu.
- Dwufazowe wdrożenie: indeksuj równolegle (stary i nowy indeks/pola), przełącz ruch po walidacji jakości, a potem sprzątaj stare dane.
- Walidacja jakości: minimalny zestaw testów regresji (retrieval na stałych zapytaniach, liczba duplikatów w top-k, koszt kontekstu) powinien blokować wdrożenie, jeśli jakość spada.
6.5. Minimalny „szkielet” ingest: kolejność kroków
Poniższa kolejność jest praktycznym punktem wyjścia, który zwykle ogranicza duplikaty i ułatwia późniejsze utrzymanie:
- Pobranie źródła + wstępny fingerprint artefaktu (by nie przetwarzać tego samego ponownie).
- Ekstrakcja tekstu (PDF/HTML/OCR) + zapis surowego artefaktu do archiwum.
- Normalizacja treści (deterministyczna) + zapis wersji „clean”.
- Chunking stabilny + wzbogacenie metadanymi (sekcje, offsety, source_uri).
- Dedup chunków (exact/near) i wybór kopii kanonicznej.
- Embeddingi tylko dla unikalnych chunków + indeksacja.
- Mechanizm reindeksacji: update przyrostowy + opcja pełnej przebudowy.
# Pseudokod (skrót) pokazujący kolejność, nie implementację
artifact = fetch(source_uri)
if is_same_artifact(artifact):
exit
raw_text = extract_text(artifact) # PDF/HTML/OCR
clean_text = normalize(raw_text)
chunks = chunk(clean_text, strategy="semantic")
unique_chunks = dedup(chunks)
embeddings = embed(unique_chunks)
index(upsert=unique_chunks, vectors=embeddings)
6.6. Praktyczne zasady (checklista) dla zespołu
- Jedna prawda o treści: przechowuj referencję do chunku kanonicznego zamiast wielu identycznych kopii.
- Deterministyczność: ta sama treść + te same reguły pipeline = ten sam wynik (hash, chunking, metadane).
- Obserwowalność: loguj liczbę odrzuconych duplikatów, koszt embeddingów, odsetek chunków zmienionych między przebiegami.
- Bezpieczeństwo zmian: każda zmiana chunkingu/normalizacji powinna mieć wersję konfiguracji i możliwość rollbacku.
- Ostrożnie z overlap: traktuj go jako świadomy koszt, a nie domyślną protezę jakości.
7. Polityki retencji i archiwizacja: przechowywanie wersji, TTL, zgodność i koszty
W RAG retencja i archiwizacja to nie „porządkowanie po fakcie”, tylko mechanizmy, które decydują o tym, co system może w ogóle odzyskać podczas wyszukiwania. Bez jasnych zasad łatwo skończyć z indeksem pełnym historycznych wariantów, duplikatów i artefaktów po przetwarzaniu, co podnosi koszty i ryzyko prawne oraz utrudnia utrzymanie jakości odpowiedzi.
W praktyce polityki retencji odpowiadają na trzy pytania: jak długo trzymać dane, które wersje są aktywne, oraz gdzie przechowywać materiały, których nie chcemy usuwać, ale nie powinny wpływać na bieżące odpowiedzi.
Przechowywanie wersji: aktywne, historyczne i „do audytu”
Nie każda wersja dokumentu powinna żyć w tym samym miejscu i mieć ten sam wpływ na odpowiedzi. Typowy podział obejmuje:
- Wersję aktywną – jedyną, która domyślnie zasila kontekst w zapytaniach; minimalizuje ryzyko, że model zobaczy sprzeczne instrukcje z przeszłości.
- Wersje historyczne – trzymane dla porównania zmian, rozliczalności lub odtworzenia stanu na dany dzień; zwykle powinny być wyłączone z domyślnego retrieval albo dostępne tylko w trybie „as-of”.
- Wersje archiwalne/audytowe – przechowywane długoterminowo, często w tańszej warstwie storage; służą głównie kontroli, zgodności i ewentualnym postępowaniom, nie bieżącej pracy systemu.
Kluczowe jest rozdzielenie retencji treści źródłowej od retencji artefaktów indeksowania. To, że przechowujesz oryginalny dokument, nie oznacza, że musisz trzymać wszystkie jego dawne reprezentacje w indeksie wykorzystywanym do odpowiedzi.
TTL i wygaszanie: kiedy dane „przestają istnieć” dla retrieval
TTL (time-to-live) pozwala automatycznie wygaszać dane po określonym czasie. W RAG TTL warto stosować osobno dla różnych warstw:
- Źródła (pliki, rekordy) – retencja zwykle wynika z regulacji lub potrzeb biznesowych.
- Indeks wyszukiwania – często powinien mieć krótszy cykl życia, bo to on bezpośrednio wpływa na odpowiedzi; wygaszanie ogranicza „dryf wiedzy” i rozrost redundancji.
- Cache i logi zapytań – mogą rosnąć najszybciej i zawierać dane wrażliwe; tu TTL bywa najbardziej krytyczny.
Ważne rozróżnienie: „wygaszenie” może oznaczać usuniecie fizyczne albo wycofanie z użycia (np. niedostępność dla retrieval). W systemach z wymaganiami audytowymi często najpierw wycofuje się dane z odpowiedzi, a dopiero później usuwa z magazynu zgodnie z harmonogramem.
Zgodność i ryzyka: prywatność, licencje, prawo do usunięcia
RAG przenosi klasyczne obowiązki compliance na nowe komponenty: indeks, cache, logi i zmaterializowane reprezentacje treści. Polityki retencji powinny uwzględniać co najmniej:
- Minimalizację danych – przechowuj tylko to, co jest potrzebne do celu; ogranicza koszty i ekspozycję prawną.
- Prywatność i dane wrażliwe – zdefiniuj zasady przechowywania oraz okresy retencji dla danych osobowych i poufnych, w tym w logach i śladach użycia.
- Prawo do usunięcia/wycofania – jeżeli treść ma zostać usunięta, trzeba usunąć ją nie tylko ze źródła, ale również z indeksów, cache i kopii/warstw pośrednich, inaczej nadal może pojawić się w odpowiedzi.
- Licencje i warunki użycia – nawet poprawnie pozyskane materiały mogą mieć ograniczenia co do czasu lub sposobu przechowywania; dotyczy to także przetworzonych reprezentacji.
- Legal hold – możliwość wstrzymania automatycznego usuwania na potrzeby postępowań, bez rozbijania całego procesu retencji.
Dobrą praktyką jest traktowanie indeksu i logów jako elementów objętych tymi samymi zasadami co repozytorium dokumentów, bo z perspektywy ryzyka mogą zawierać równie dużo informacji.
Koszty: gdzie naprawdę „ucieka” budżet
Brak polityk retencji zazwyczaj nie kończy się tylko większym dyskiem. Koszty w RAG kumulują się w kilku miejscach:
- Storage – wielokrotne wersje i artefakty potrafią rosnąć szybciej niż same dokumenty, zwłaszcza przy częstych reindeksacjach.
- Utrzymanie indeksów – większy indeks to dłuższe aktualizacje, więcej zasobów i wyższe ryzyko błędów operacyjnych.
- Retrieval i generowanie – redundancja zwiększa liczbę kandydatów i objętość kontekstu; w efekcie rosną czasy odpowiedzi i koszty wykorzystania modelu.
- Ryzyko jakości – stare wersje w kontekście mogą obniżać trafność i spójność odpowiedzi, co przekłada się na koszty obsługi, poprawiania i eskalacji.
Polityka retencji jest więc narzędziem optymalizacji: mniej „martwych” danych w aktywnych warstwach to niższy koszt operacyjny i mniejsze prawdopodobieństwo, że model dostanie sprzeczne informacje.
Archiwizacja: odciążenie bez utraty rozliczalności
Archiwizacja polega na przeniesieniu danych z warstw aktywnych do warstw tańszych i rzadziej używanych. W kontekście RAG jej celem jest:
- Oddzielenie wiedzy „do odpowiadania” od wiedzy „do przechowania” – dzięki temu retrieval nie musi walczyć z nadmiarem historycznych treści.
- Utrzymanie możliwości audytu – zachowanie ścieżki rozliczeniowej bez obciążania bieżącej infrastruktury.
- Kontrolowane przywracanie – możliwość ponownego uaktywnienia archiwalnych materiałów w jasno zdefiniowanych sytuacjach (np. spór, analiza, odtworzenie stanu).
Dobrze zaprojektowana archiwizacja nie jest „koszem na wszystko”, tylko procesem z regułami: co trafia do archiwum, kiedy, na jak długo i w jakim trybie może wrócić do warstwy aktywnej.
Zasady praktyczne: proste reguły, które działają
- Domyślnie jedna wersja aktywna na dokument dla retrieval, a reszta poza ścieżką odpowiedzi.
- Osobne retencje dla źródeł, indeksów, cache i logów; najkrótsze cykle życia zwykle powinny mieć komponenty najbardziej „rozrastające się”.
- Wycofanie przed usunięciem dla treści ryzykownych: najpierw zdejmij z retrieval, potem usuń zgodnie z procedurą.
- „Right to be forgotten” end-to-end: usunięcie musi objąć wszystkie warstwy, w których treść mogła się zmaterializować.
- Archiwum jako warstwa nieprodukcyjna – trzymane dla zgodności i audytu, a nie do codziennego odpowiadania.
Retencja i archiwizacja spinają jakość, koszty i zgodność w jeden zestaw decyzji. Jeśli nie zdefiniujesz ich świadomie, system sam „zdecyduje” za Ciebie — przechowując za długo, za dużo i w miejscach, które najmocniej wpływają na odpowiedzi.
8. Testy i metryki: wykrywanie „inflacji” kontekstu, regresje jakości i monitoring
W RAG deduplikacja i wersjonowanie mają sens tylko wtedy, gdy da się je mierzyć i utrzymać w czasie. W praktyce problemy wracają: do indeksu trafiają ponownie te same pliki, różne eksporty tego samego dokumentu albo niekontrolowane wersje. Skutkiem jest „inflacja” kontekstu (wiele podobnych fragmentów w promptcie), spadek trafności oraz rosnące koszty tokenów. Dlatego warto wprowadzić zestaw testów i metryk, które szybko wykryją zarówno duplikaty, jak i regresje jakości po zmianach w pipeline.
Metryki „inflacji” kontekstu
Celem jest wychwycenie sytuacji, w której system zamiast różnorodnych źródeł zwraca kilka wariantów tego samego. Mierniki powinny działać na dwóch poziomach: retrieval (co zostało dobrane) i kontekst (co finalnie trafiło do modelu po ewentualnym łączeniu/obcinaniu).
- Redundancja wyników: udział wyników, które są identyczne lub bardzo podobne do siebie (np. w obrębie top-k). Wysoki poziom to sygnał, że deduplikacja nie działa albo ranking promuje klony.
- Unikalność źródeł: liczba unikalnych dokumentów/wersji reprezentowanych w kontekście. Jeśli kontekst składa się z wielu chunków z jednego pliku, a zapytanie wymaga przekroju, to jest to objaw „zawężenia przez duplikaty”.
- Overlap treści w kontekście: stopień nakładania się fragmentów (np. podobieństwo semantyczne między chunkami wybranymi do promptu). Wysoki overlap oznacza marnowanie budżetu kontekstu.
- Token waste: odsetek tokenów zajętych przez powtarzalne lub niemal identyczne fragmenty. To metryka bezpośrednio wiążąca jakość z kosztem.
- Stabilność top-k: jak często te same dokumenty/wersje dominują wyniki dla różnych zapytań w danej domenie. Nienaturalna dominacja bywa skutkiem masowych duplikatów lub błędnego wersjonowania.
Testy regresji jakości RAG
Zmiana w ingest, chunkingu, embeddingach, filtrach wersji czy logice łączenia kontekstu może nieoczekiwanie pogorszyć odpowiedzi. Testy regresji powinny obejmować zarówno jakość retrieval, jak i końcową odpowiedź modelu.
- Zestaw zapytań kontrolnych: stała paczka pytań reprezentujących typowe potrzeby użytkowników, w tym pytania wrażliwe na wersję (np. „jaka jest aktualna procedura”). Ważne, by obejmowała przypadki, gdzie starsza wersja jest myląca.
- Spójność cytowań i źródeł: czy odpowiedź odwołuje się do właściwych dokumentów i czy nie miesza wersji (np. cytuje fragment z nieaktualnej wersji, mimo że istnieje nowsza).
- Trafność kontekstu: czy dobrane fragmenty rzeczywiście zawierają informację potrzebną do odpowiedzi, a nie tylko są podobne tematycznie lub powielają się.
- Odporność na szum: scenariusze, w których w indeksie celowo istnieją duplikaty lub wersje archiwalne — test powinien sprawdzać, czy system nadal preferuje właściwą wersję i nie „zapętla się” w redundancji.
- Metryki użytkowe: wskaźniki typu skuteczność odpowiedzi w zadaniu (np. czy użytkownik osiąga cel) oraz spadki w satysfakcji mogą ujawniać problemy, których nie widać w samym retrieval.
Monitoring produkcyjny: sygnały ostrzegawcze
Testy offline nie zastąpią monitoringu, bo duplikaty często pojawiają się w wyniku procesów operacyjnych (ponowne zasilenie, import kopii, błędy ETL, migracje). Monitoring powinien wykrywać zarówno nagłe skoki, jak i powolne „zarastanie” indeksu.
- Tempo przyrostu podobnych treści: jeżeli liczba nowych chunków rośnie szybciej niż liczba unikalnych dokumentów lub unikalnych źródeł, to sygnał inflacji.
- Rozkład wersji w wynikach: jeśli starsze wersje zaczynają częściej pojawiać się w top-k mimo istnienia nowszych, to problem z filtrowaniem lub identyfikacją wersji.
- Skoki kosztów tokenów: wzrost średniej długości kontekstu lub kosztu na zapytanie przy niezmienionym ruchu często oznacza redundancję w kontekście.
- Wzrost odsetka „odpowiedzi niepewnych”: częstsze odpowiedzi z zastrzeżeniami, niespójnościami lub prośbami o doprecyzowanie mogą wynikać z konfliktujących wersji w kontekście.
- Alerty na duplikaty w ingest: wykrywanie podejrzanych paczek danych (np. masowe podobieństwo nowych dokumentów do już zindeksowanych) zanim trafią do produkcji.
Jak interpretować wyniki, żeby nie walczyć z objawami
Nie każda redundancja jest błędem: czasem różne fragmenty tego samego dokumentu są potrzebne, a czasem powtarzalność wynika z natury zapytań. Kluczowe jest rozróżnienie między uzasadnioną koncentracją a patologiczną inflacją. Jeżeli rośnie redundancja, ale jakość odpowiedzi nie spada i koszt jest akceptowalny, problem może być kosmetyczny. Jeśli jednak jednocześnie rosną koszty, spada unikalność źródeł i pogarsza się trafność, to zwykle oznacza realny defekt: duplikaty w indeksie, niekontrolowane wersje lub błędne filtrowanie.
Dobrze dobrane testy i metryki pozwalają szybko wskazać, czy problem leży w danych (duplikaty), w interpretacji wersji (konflikty), czy w mechanice budowy kontekstu (redundancja i marnowanie tokenów). Dzięki temu można reagować precyzyjnie, zamiast „dokręcać śruby” w promptach lub losowo zmieniać parametry retrieval.
W Cognity łączymy teorię z praktyką – dlatego te zagadnienia rozwijamy także w formie ćwiczeń na szkoleniach.
Najczęściej zadawane pytania i odpowiedzi odnośnie Deduplikacja i wersjonowanie wiedzy w RAG: jak nie karmić modelu 12 kopiami tego samego PDF
Duplikaty obniżają jakość odpowiedzi, bo zajmują kontekst i wzmacniają jedną treść pozornie wieloma źródłami. Gdy retriever zwraca kilka kopii tego samego fragmentu, model dostaje mniej miejsca na uzupełniające informacje, wyjątki i aktualne zasady. To zwiększa ryzyko odpowiedzi niepełnych, sprzecznych albo opartych na przypadkowo dominującym wariancie dokumentu.
Exact dedup wykrywa kopie 1:1, a near-duplicate wykrywa treści prawie identyczne. Exact opiera się zwykle na hashach pliku, tekstu albo chunków i dobrze usuwa oczywiste powtórzenia. Near-duplicate działa na progach podobieństwa i pomaga wychwycić re-edycje, różne formaty oraz dokumenty z drobnymi zmianami, które nadal niosą niemal tę samą informację.
Najlepiej haszować kilka warstw, bo każda wykrywa inny typ duplikatu. W praktyce warto łączyć:
- hash pliku do wykrywania identycznych artefaktów,
- hash znormalizowanego tekstu do różnych eksportów tej samej treści,
- hash chunków do powtarzalnych fragmentów między dokumentami.
Taki układ daje szybką filtrację bez ograniczania się tylko do jednego rodzaju kopii.
Nowa wersja zmienia relację czasową lub merytoryczną dokumentu, a duplikat tylko powiela tę samą treść. Pomaga tu rozdzielenie document_id, version_id i artifact_id. Jeśli zmienia się tylko plik lub format, ale nie treść logiczna, zwykle mówimy o duplikacie artefaktu. Jeśli zmienia się znaczenie, data obowiązywania albo rewizja, mamy do czynienia z wersją.
Minimum to metadane pozwalające jednoznacznie wskazać dokument, jego wersję i status. Najbardziej przydatne pola to:
- document_id,
- version_id,
- published_at lub effective_from,
- status,
- source_ref.
Taki zestaw pozwala preferować wersje obowiązujące, odróżniać historię od aktualności i budować bardziej wiarygodne cytowania w odpowiedziach.
Najlepiej usuwać duplikaty jak najwcześniej, jeszcze przed liczeniem embeddingów. Artykuł wskazuje podejście warstwowe: najpierw filtracja na poziomie źródła i artefaktu, potem dedup po normalizacji treści, a następnie na poziomie chunków. Dzięki temu ograniczasz koszty parsowania, embeddingów, indeksu i zmniejszasz szum, który później trafia do retrieval.
Nie, sama deduplikacja przy ingest nie wystarczy, bo redundancja może wrócić na etapie wyboru kontekstu. Nawet poprawnie zindeksowane dane mogą zawierać naturalnie podobne fragmenty z różnych źródeł. Dlatego retrieval powinien dodatkowo ograniczać nadmiar przez dywersyfikację, limity na dokument, preferencję właściwej wersji i odrzucanie chunków zbyt podobnych do już wybranych.
Najlepiej sprawdzić to przez metryki redundancji, unikalności źródeł i kosztu kontekstu. Sygnałami ostrzegawczymi są powtarzające się dokumenty w top-k, niski udział unikalnych źródeł, wysoki overlap treści oraz wzrost tokenów bez poprawy jakości odpowiedzi. Dobrze działa też stały zestaw pytań kontrolnych, szczególnie takich, które wymagają rozróżnienia wersji aktualnej i historycznej.