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
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å
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.
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
┌─────────────────────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────────────────────┘
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 |
Det här systemet gör explicit inte försök att:
Deduplikering är helt deterministisk
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
mål: Reduzera lagring och förhindra intrareundans på dokument
Problemet: Dokument innehåller ofta upprepade innehåll:
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.
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.
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
src/Mostlylucid.DocSummarizer.Core/Services/BertRagSummarizer.cs
DeduplicateSegments()
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 | ||
|---|---|---|
similarityThreshold |
♫ 0.90 ♫ ♫ | ♫ Kosinelikhet ovanför vilka segmenter anses vara duplikater ♫ |
salienceThreshold |
♫ 0.05 ♫ ♫ | ♫ Minimala drag att ta hänsyn till ♫ |
boostPerNearDuplicate |
♫ 0.15 ♫ ♫ |
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)
src/LucidRAG.Core/Services/AgenticSearchService.cs
DeduplicateByEmbeddingPostRanking()
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 | ||
|---|---|---|
similarityThreshold |
♫ 0.90 ♫ ♫ | ♫ Kosineliknande tröskel för cross ♫ |
RRF (Reciprocal Rank Fusion) kombinerar fyra signalerM SK2
Att duplicera AFTER RRF betyder att vi håller segmentet som bäst matchar queryn över alla dimensioner
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.
| 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 |
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
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
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?
Införing:
[dim]Deduplication: 150 → 98 segments[/]
Att hämta data:
Post-ranking deduplication: 50 → 42 segments (removed 8 cross-doc duplicates)
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 |
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
}
}
}
}
| 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 |
| Parameter | ||
|---|---|---|
Enabled |
true |
Aktivera |
SimilarityThreshold |
0.90 |
Kosinelikhets tröskel |
MinRelevanceScore |
0.25 |
Minimum RRF-värde för att inkludera |
| 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 |
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:
| Fas | Kompleksitet | Typisk storlek M | Inverkan m | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Införing | O | n | МSK3 | 4 | 5 | segmenter | ||||
| Tillförseln | OmM SK3 ♫ ♫ | ♫ |
För väldigt stora dokument (10,000+ segmenter):
Den nuvarande implementeringen är optimerad för typiska dokumentstorlekar. LSH lägger till komplexitet utan nytta för de flesta användande fallen.
| 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
| 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 |
| 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 |
Den här dupliceringsstrategin:
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.