This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Reduktion av grafiska RAG-evidenssegment i klarRAG
Saturday, 17 January 2026
NOTA: Det här är inte en vanlig bloggartikel teknisk specifikation skriven för en konkret egenskap i klarRAG. Iterativt matar jag in det här dokumentet för att koda-", "focused LLMs during development to reason about trade", - "offs" , "validate assumptions" och "M SK3" "converge on a rational implementation"
Detta dokument beskriver ett subsystem från klarRAG, ett projekt Jag utvecklar aktivt
En av de viktigaste kraven klarRAG är förmågan att del av bevis - meningar , paragrafer M SK2 rubriker, , captioner,, rammar, , eller strukturerade blocker, - och se till att dessa segment är duplicerad utan att förstöra användbar signal.
klarRAG arbetar genom att analysera och extrahera bästa tillgängliga bevis från dokumenten , bilder, ljud, och strukturerade dataM SK3 Till skillnad från de flesta RAG-implementeringar inte förvara LLM-genererade sammanfattningar som den primära artefakten . I många fall
I stället, klarRAG tillämpar ett brett spektrum av deterministiska och sannolikhetstekniker på
- extrahera kandidatsegment
- att bedöma deras informationsvärde
- och behålla bara de starkaste representanterna
Duplicering är en viktig del av den här processen.
Enkel strängs jämlikhet är inte tillräckligt. Samma koncept uttrycks ofta med olika ordnelser , struktur, , eller mönster,. Att behandla dem som separerade leder till överskott i lager och dåligt nedgående beteende
Problemet förväxlas vid att få fram data.
När resultaten är extraherade ( via SQL , vektor-inbäddar , BM M SK3 eller hybrider MSC4 genom att mata ett LLM med flera segment som alla uttrycker samma underliggande idé skapar det tråkiga MST5 upprepade svar Mst6 Fem nära M st7 identiska bitar från olika dokument ger inte mer tydlighet Mstr8 de dämpar det M ST9
För att adressera detta, klarRAG hanterar duplicering som en det första problemet med kompilation i klass -, inte ett svar
Resten av detta dokument beskriver hur den här dupliceringsstrategin designades. 'Agile Speccing' anpassat till kod LLMS.
Detta kristalliserar tankarna, olika koncept och tvingar LLM att dokumentera dem. bygger det rätta.
Reduktionsstrategi
klarRAG använder en tvålagig deduplikeringsstrategi för att eliminera överskottsfulla innehåll samtidigt som man bevarar viktiga signaler. signal-bevarande filter, inte normalisering av innehåll
Übersicht
┌─────────────────────────────────────────────────────────────────────────────┐
│ INGESTION (Per Document) │
│ │
│ Document → Extract → Embed → DEDUPE (intra-doc) → Index to Vector Store │
│ │ │
│ ├─ Near-duplicates: boost salience │
│ └─ Exact duplicates: drop (no boost) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ RETRIEVAL (Cross Document) │
│ │
│ Query → Search → Rank (RRF) → DEDUPE (cross-doc) → Top K → LLM Synthesis │
│ │ │
│ └─ Keep segment with highest RRF score │
└─────────────────────────────────────────────────────────────────────────────┘
Designgarantier
Dessa invarianter hållers kvar genom deduplikeringssystemet:
| Gwarant | Beschreibung |
|---|---|
| Ordning bevarad | Duplicering ändrar aldrig semantisk ordning efter RRF-rangering |
| Inget koncept förlust | Duplicering tar aldrig bort alla instanser av ett koncept. |
| Dokumentens gräns respekteras | Duplicering överskrider aldrig dokumentens gränser vid inspegning |
| Inhalt som inte kan förändras | Duplicering ändrar aldrig inbäddar eller textinnehåll |
| Deterministisk | Given identiska ingångar och konfigurationen , gör dupliceringen likadana utgångspunkter |
Inte
Det här systemet gör explicit inte försök att:
- Detektor av faktisk motsägelse - Två segment som säger motsägelsefulla saker är inte duplicerade
- Kanonalisera sanningen - Vi väljer inte ' en korrekt version över hela källorna
- Kollapsera parafraser över dokumente vid intag - Varje dokument har sina egna segment
- Normalisera terminologi - "ML" och " maskininlärning, " i olika dokument bevaras separat
- Ersätta enhetens lösning - Att ', GraphRAG, ', meningen med ,, arbetar på en annan nivå
Determinism & Reproduktivitet
Deduplikering är helt deterministisk
- Embeddings är omöjliga att ändra en gång räknad vid extraktionstid
- Sortering är stabil - segment med lika stor betydelse håller ursprungliga ordning
- Ingen slump - ingen proverning , inga annämningsmässiga ANN M SK2 inga probabilistiska trösklar
- Inget utländskt tillstånd - avbetalningsbeslut beror bara på den nuvarande segmentsättningen
Varför är detta viktigt: Tillverkligare av sökresultat kan lita på att re- som körs med samma inputer ger samma resultat klarRAG' bredare "begränsad fuzziness" filosofi - fuzzy matching with deterministic behavior
Varför två faser?
Fas 1: Duplicering av intag
mål: Reduzera lagring och förhindra intrareundans på dokument
Problemet: Dokument innehåller ofta upprepade innehåll:
- Kolplatta text (header, footers , disclaimersM SK3
- Copy-passerade sektioner
- Samma koncept förklarade flera olika sätt
Lösningen: Duplicera inom varje dokument innan du indekserar
Nyckelinsikten: nära-duplikater behandlas som oberoende bevis för viktOm en författare förklarar ett koncept på tre olika sätt, så är konceptet viktigt.
Etappen 2: Duplicering av att hämta
mål: Att förhindra LLM från att få överskottsfulla information i alla dokument
Problemet: När man söker över flera dokument, kan liknande paragrafer dyka upp i olika källor.
Lösningen: Efter Rangering av RRF: n ( som kombinerar semantisk likhet , nyckelmönster matching M SK2 dragbarhet, , och nyhet
Varför efter RRF? RRF-värdet representerar den bästa holistiska mätningen av relevans.
Varför boostar Salience bara vid ingestion
Trennningen är avsiktlig:
| Fasen | Vad den fångar | |
|---|---|---|
| Intagstillande | Författaren betonar - hur mycket dokumentet betonar ett koncept | |
| Retrievals poäng | Rädsla relevans - hur väl innehållet matchar användarens vilja |
Att blanda dessa vid att hitta skulle förväxla dokumentens syfte med användars syfte. Det är viktigt att konceptet upprepas ♫ 5 ♫ gånger i en dokument till den dokumenten, men kan inte vara relevant till den här sökningen. Genom att öka den vid ingestionen , bevarar vi författarens signal utan att biasera sökresultatet
Fas 1: Duplicering av intag
Lokalisering
src/Mostlylucid.DocSummarizer.Core/Services/BertRagSummarizer.cs
Metod
DeduplicateSegments()
Algoritm
1. Filter segments by minimum salience threshold (0.05)
2. Sort by salience score (highest first)
3. For each segment:
a. If no embedding → keep (can't compare)
b. Check cosine similarity against all selected segments
c. If similarity >= 0.90:
- If same ContentHash → exact duplicate, drop silently
- If different ContentHash → near-duplicate, boost kept segment's salience
d. If no match → add to selected list
4. Apply salience boosts: +15% per near-duplicate merged
5. Cap salience at 1.0 to prevent any single concept from dominating
Parameter
| Parameter | ||
|---|---|---|
similarityThreshold |
♫ 0.90 ♫ ♫ | ♫ Kosinelikhet ovanför vilka segmenter anses vara duplikater ♫ |
salienceThreshold |
♫ 0.05 ♫ ♫ | ♫ Minimala drag att ta hänsyn till ♫ |
boostPerNearDuplicate |
♫ 0.15 ♫ ♫ |
exempel
Exakt Duplikat (Ingen Boost
Segment A: "Contact us at [email protected]" [hash: abc123]
Segment B: "Contact us at [email protected]" [hash: abc123] ← same hash
Result: Keep A, drop B, no boost (likely boilerplate)
nära-Duplikat (Boost Applied
Segment A: "Machine learning models require training data" [hash: abc123]
Segment B: "ML systems need data for training" [hash: def456] ← different hash, 0.92 similarity
Segment C: "Training data is essential for ML" [hash: ghi789] ← different hash, 0.91 similarity
Result: Keep A with +30% salience boost (concept emphasized 3 ways)
Rationalitet för tröskeln
- 0.90 likhet Baserat på forskning (NVIDIA NeMo använder industrystandard för semantisk dedup 0.90-0.92,
- 0.05 relevant Filterar väldigt låga segment med värde, medan de mesta innehållet är kvar
- 15% upphöjning Meningful signal utan överweighting
Etappen 2: Duplicering av att hämta
Lokalisering
src/LucidRAG.Core/Services/AgenticSearchService.cs
Metod
DeduplicateByEmbeddingPostRanking()
Algoritm
1. Receive ranked results (already sorted by RRF or dense score)
2. For each segment (in score order):
a. If no embedding → keep
b. Check cosine similarity against all selected segments
c. If similarity >= 0.90 → skip (higher-scored duplicate already selected)
d. If no match → add to selected list
3. Return deduplicated list (maintains score ordering)
Parameter
| Parameter | ||
|---|---|---|
similarityThreshold |
♫ 0.90 ♫ ♫ | ♫ Kosineliknande tröskel för cross ♫ |
Varför skicka?
RRF (Reciprocal Rank Fusion) kombinerar fyra signalerM SK2
- Dense poäng: Semantisk likhet med en fråga
- BM25 poäng Lexikal/talord match
- Salience poäng: Inriktathet i ett dokument
- Frihetsnotar: Recens boost
Att duplicera AFTER RRF betyder att vi håller segmentet som bäst matchar queryn över alla dimensioner
exempel
Query: "How do I configure authentication?"
Results before dedup:
1. [Doc A] "Authentication is configured via config.yaml..." (RRF: 0.052)
2. [Doc B] "Configure auth using the config.yaml file..." (RRF: 0.048, similarity to #1: 0.93)
3. [Doc A] "Set the API key in environment variables..." (RRF: 0.041)
Results after dedup:
1. [Doc A] "Authentication is configured via config.yaml..." (RRF: 0.052)
2. [Doc A] "Set the API key in environment variables..." (RRF: 0.041)
Doc B's similar paragraph dropped - Doc A's version had higher RRF score.
Förlustsmodi & Handeln -offs
Begränsningar
| Missbruksmöjlighet | Beschreibung | Mitigation | ||||||
|---|---|---|---|---|---|---|---|---|
| Falska positiva (över-dedupM SK2 | Två separata men nära besläktade koncept kan överträffa 0.90 likhet | Akzepterad handel | - | Avslag för reducerad redundans | ||||
| Fals negativa (under-dedupM SK2 | Väldigt korta segment kan inbäddas dåligt, bristande semantisk likhet | Hash | ||||||
| Inbäddad drift | Att ändra inbäddade modeller försämrar avvikande antaganden | Erfordrar full re | - | ingestion | МSK3 | Inbäddar är omvandliga när de blivit lagrade | ||
| Orderkänslighet | Greedy selection means first high - sallivssegment vunnir | Mitigad genom stabil sortering |
Accepted Trade-offs
- Precision over recall: Vi föredrar ibland att hålla nära -duplikater jämfört med att oavsiktligt ta bort olika innehåll
- Storage över precision: Vi lagrar per document rather than global dedup för att bevara källanstribution
- Enkelhet över optimering: O(nM SK1 är accepterad för typiska dokumentsstorlekar ; LSH tillsätter komplexitet
Multilinguella övervägningar
Reduktionsbeteende med flerspråkig innehåll:
| Scenario | Behavior | 2 | Rationale | 3 | |
|---|---|---|---|---|---|
| Samma språk | Den normala deduktionen appliceras | Embeddings fångar semantisk likhet | |||
| Parafraser över språket | inte duplicerad | Bevarar källan- språkbarhet | |||
| Ett blandat document i språket | Dedup inom språkkloster | Embeddingsliknande avseparerar naturligtvis språk |
Designvalen: Cross-språksduppning är explicit inte supporterad . Det bevarar förmågan att hämta samma fakta i användarens prefererade språk eller jämföra hur olika källans fraser saker är
Framväxande förbättringar : Cross-språkiga avvikelser skulle kunna skiftas via översättningen-invarianta inbäddar om det behövsM SK3
säkerhet & Motsägelser
Reduktionssystemet inkluderar indirekta skydd:
| Angriffsvektor | skydd |
|---|---|
| Saliens inflation via repetition | Upphöjt upphöjt vid 1.0; exakta kopior don' inte upphöj |
| Kopiera-pa spam över dokumente | Cross |
| handling av poäng genom duplicerad injiction | Dedup uppstår efter klassificeringen , för att förhindra poäng-inflation |
| Kolplatta översvämningar | Exakt hashmatch-detektor minskar utan upphöjning |
Nota: Deduplikering är inte en säkerhetsgränsen. Den ondskafulla innehållet som passerar intagningsfilterna kommer att indexeras . innehållsfilterning borde ske uppstream
Interaktion med GraphRAG
Reduktion och GraphRAG är avsiktligt ortogonala:
| System | Operaerar på | syfte | МSK3 | ||||
|---|---|---|---|---|---|---|---|
| Reduktion | Segment ( textskivor) | Ta bort överskott av sökresultat | |||||
| GraphRAG | Entityder & Attityder |
Varför separera?
- Ett segment som nämner """, Apple "", " "", och ett annat som näms """, företaget, " "", kan avvika från likvärdigt text men representera samma enhet, - "", som
- Dedup behöver inte entitydmedvetenhet, det fungerar enbart på semantisk likhet.
- Enheten-aware dedup skulle kunna lägga till senare som en förbättring, inte som en ersättning
Observerbarhet & Metrik
Den nuvarande logeringen
Införing:
[dim]Deduplication: 150 → 98 segments[/]
Att hämta data:
Post-ranking deduplication: 50 → 42 segments (removed 8 cross-doc duplicates)
Rekomenderade mätvärden
För produktionsövervakning tänk på spårning
| Metrik | Beskrywing | hälsosamt intervall | МSK3 | ||
|---|---|---|---|---|---|
dedup_ratio_ingestion |
% segment som togs bort vid inspetsning | ||||
dedup_ratio_retrieval |
♫ ♫ % ♫ Segment togs bort vid att hämta ♫ | ||||
avg_salience_boost |
Medelvärde förhöjning för varje dokument | ||||
max_salience_boost |
Den högsta ökningen i en dokument | < | |||
dedup_by_doc_type |
Dedup-värde segmenterat efter dokumenttyp | Variationer |
Debugstips
- Högt intag avföring (>50%): Dokumentet kan ha överdriven boilerplatta eller vara automatiserat
- lågt intag avföring (<5%): Dokumentet har olika innehåll. ( bra ) eller inbäddar är dåliga
- Högt återhämtadedupp (>30%): Frågan kan vara för brett, eller corpus har många liknande dokument
- Saliens närmar sig 1.0: Konceptet betonades kraftigt: ;, verifiera det , "', är lagligt, ,, inte spam.
Konfiguration
Deduplikering är konfigurerad via DocSummarizerConfig.Deduplication sektion i appsettings.json:
{
"DocSummarizer": {
"Deduplication": {
"Ingestion": {
"Enabled": true,
"SimilarityThreshold": 0.90,
"SalienceThreshold": 0.05,
"EnableSalienceBoost": true,
"BoostPerNearDuplicate": 0.15,
"MaxSalienceBoost": 1.0,
"BoostDecayMode": "Logarithmic",
"LogBase": 2.0
},
"Retrieval": {
"Enabled": true,
"SimilarityThreshold": 0.90,
"MinRelevanceScore": 0.25
},
"Analytics": {
"EnableLogging": true,
"EnableMetrics": true,
"HighIngestionDedupThreshold": 0.50,
"HighRetrievalDedupThreshold": 0.30,
"HighSalienceBoostThreshold": 0.60
}
}
}
}
Intag Konfiguration
| Parameter | ||
|---|---|---|
Enabled |
true |
Aktivera |
SimilarityThreshold |
0.90 |
Kosinelikhets tröskel för duplicerad detektion |
SalienceThreshold |
0.05 |
Minimala relevantitet att ta hänsyn till (filterljudsmängdM SK2 |
EnableSalienceBoost |
true |
Upphöjt saliens för nära |
BoostPerNearDuplicate |
0.15 |
Bättring för basen per nära |
MaxSalienceBoost |
1.0 |
Max salens kapsyl |
BoostDecayMode |
Logarithmic |
Linear eller Logarithmic förruttna |
LogBase |
2.0 |
Basis för logaritmisk nedfall |
Lösning Konfiguration
| Parameter | ||
|---|---|---|
Enabled |
true |
Aktivera |
SimilarityThreshold |
0.90 |
Kosinelikhets tröskel |
MinRelevanceScore |
0.25 |
Minimum RRF-värde för att inkludera |
Analytikkonfiguration
| Parameter | ||
|---|---|---|
EnableLogging |
true |
Operationer för logduplikering |
EnableMetrics |
true |
Samma mätvärdena för övervakning |
HighIngestionDedupThreshold |
0.50 |
Varna om |
HighRetrievalDedupThreshold |
0.30 |
Varna om >30% dupliceras vid att hämta |
HighSalienceBoostThreshold |
0.60 |
Varna om ökningen överträffar |
Boosta avbrottsmodi
Linjära Modus ( enkelt , förutsägbart M SK2
boost = boostPerNearDuplicate × count
exempel: M SK1 nära-dupes × | | 4 | 5 | 6 | Steg
Logaritmiska Modus (djupande resultat,vikt
boost = boostPerNearDuplicate × log₂(1 + count)
exempel: M SK1 nära-dupes → | | 0.15 \ × log
Den logaritmiska metoden är tillförlitlig eftersom:
- De första några kopiorna har den starkaste signalen (författaren betonar )
- Många kopior kan indikera att boilerplatet, inte är viktigt
- Försämrar att saliens inflation
Tillvägagångspunkter
Kompleksitet
| Fas | Kompleksitet | Typisk storlek M | Inverkan m | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Införing | O | n | МSK3 | 4 | 5 | segmenter | ||||
| Tillförseln | OmM SK3 ♫ ♫ | ♫ |
Skalerande väg
För väldigt stora dokument (10,000+ segmenter):
- LSH ( Lokalitet -Sensitiv Hashing): O(nM SK1 ungefär
- Vergleich av batterier: Bearbeta i skivor för att minska minnet
- Filterning tidigt: Mer aggressiv salient tröskel
Den nuvarande implementeringen är optimerad för typiska dokumentstorlekar. LSH lägger till komplexitet utan nytta för de flesta användande fallen.
jämförelse med forskning
| tillvägagångspunkt | tröskel | källan | ||
|---|---|---|---|---|
| lucidRAG | ||||
| NVIDIA NeMo Curator SemDeDup dokument | ||||
| MinHash LSH Google C4, GPT-3 papper | ||||
| SemHash GitHub |
Vår tröskel av 0.90 är i harlang med industrins bästa metoder för semantisk deduplikering
Vad är inte duplicerat
| innehållstyp | orsak | |||
|---|---|---|---|---|
| CrossM SK1 dokument vid intag | Bevarar per - källans lösning och tilldelning | |||
| lågtM SK1 likvärdighetsinnehåll (<0.90) | Semantiskt separerad M | |||
| Skillnade segmentstyper | Rubrik och punkt har olika strukturella roller | |||
| Cross-språksförkortningar | Bevarar språk mångfald |
Ingripande status
| Funktionen | Status ♫ | ♫ Lokalisering ♫ | ♫ |
|---|---|---|---|
| Konfigurerade tröskeln | ♫ ♫ ✅ ♫ Rakett ♫ DeduplicationConfig klass |
||
| Förstärkande förruttnande (logskala | ) | BoostDecayMode.Logarithmic |
|
| Analytik med avvikningM SK1 mätningar | ✅ Rakett M | DeduplicationResult<T> rekord |
|
Integration av DI-tjänster IDeduplicationService |
Framtidens förbättringar
- Dedup analytik-dashboard: Visuella spårning av pris per dokumenttyp
- Cross-språksöversättning: Translation-invariant embeddings for multilingual dedup
- Enheten-informerad dedup: Använd GraphRAG-enheter som ytterligare signal ( inte utbytning)
- Prometheus/OpenTelemetry: Export metriker för övervakningsdashboarder
sammanfattning
Den här dupliceringsstrategin:
- Bevarar signal - näraM SK1 duplikater ökar betydelsen snarare än att bli avlägsna
- Omfamnar gränser - Dokument upprätthåller oberoende segmentsgrupper
- Ranger sen filtrerar - använder full RRF-signal innan deduktionen sker
- Det misslyckas säkert - Prefererar att behålla innehållet snarare än att aggressivt ta bort det
- Blir deterministisk - Samma intryck ger alltid samma resultat