Back to "DoomSummarizer: DocSum marizer 's Younger, Smarter Brother"

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

AI C# Deep Research Knowledge Graph LLM Lucene RAG Time Boxed Tool

DoomSummarizer: DocSum marizer 's Younger, Smarter Brother

Thursday, 29 January 2026

Ricerca profonda senza tasche profonde.

Quando "Deep Research" è atterrato con gli strumenti di alta qualità per l'intelligenza artificiale , Ero curiosoM SK3 cos'è questo?

Il DoomSummarizer sfrutta un flusso di lavoro simile, ma il suo design ottimizza il "read + ridurre il processoM SK3 per renderlo più deterministico e localizzatoMSC4 con il Large Language Model (LLMMST6 usato principalmente per la sintesiMSL7

In questo approccio, la forza della fase di riduzione elimina il bisogno di un modello grande, costoso, per produrre risultati soddisfacenti.

In particolare, Ho già posseduto molti elementi di costruzione essenziali, compresi multiM SK2 ricavamento di sorgenti , estrazione delle entitàM Sk4 grafici di conoscenzaM sk5 e inserzioneMtk6 classifica basata sulla classificaMk7 che sono condivisi con lucidRAG e la serie DocSummarizerMlk8

La componente mancava non era una mancanza di capacità, ma piuttosto la comprensione di come applicare efficacemente questi elementi esistenti.Cosa M SK2La ricerca approfondita ” Di solito Significa

In strumenti commerciali, M SK1Deep Research” di solito significa un lavoro significativo

o

Significante

o

Connotativocolui che pianifica un approccio di ricerca, fa la multi-tassazione-la ricerca in incrementi di passoM SK2l'browsing /la lettura attraverso molte fonti MSC4o spesso il web + i file collegati che hai caricatoMST6le file connesseMSS7 poi scrive un report più lungo con citazioniMSSS8

Una grande parte del valore si ottiene migliorando l'input: trattenere dati più recenti, più altiM SK2 sorgenti di segnali rispetto a qualsiasi modello ’ tagliare i dati di allenamentoMSC4 data di ritardoMST5 affermazioni basate sulle proveM ST6 e ridurre la possibilità che il modello crei delle coseM st7

Esempi: OpenAI Deep Research, Gemini Deep Research, e Perplexity Deep Research ( si chiama anche “Modo di ricerca” nella loro interfaccia grafica

Il DoomSummarizer segue lo stesso flusso di lavoro, ma è’ingegnerizzato così che la maggior parte del M SK2read +reduceMSC4 il lavoro è deterministico e localeMST5 e l'LLM viene usato principalmente per la sintesiMSM6

Se il passo di riduzione è forte, non c'è bisogno di un modello grandeM SK2 costoso per ottenere un buon risultato.

Insieme. lucidRAG e la serie DocSummarizer, Avevo già la maggior parte dei blocchi di costruzione: multiM SK2 ricavamento della fonteMSC3 estrazione delle entità , grafici di conoscenzaMST5 inserzioneMSV6 classifica basata sulla classifica

Il pezzo mancante era't capacità. Era orchestrazione. Come si prendono tutti questi segnali e li si fondono in qualcosa di coerente con un piccolo modello?

Quello's DoomSummarizer. Insegnato dopo lo scrolling del destinoM SK2 perché lo scrolla per il destino così che non dovete ' doverMSC4 puntarlo alle vostre fontiMST5 stabilire una vibrazioneMst6 ottenere una sintesiM st7

Ma questo articolo non riguarda l'outil, ma le idee che lo fanno funzionare.

Rilascio di GitHub

Questo è Parte 5 della serie DocSummarizer.

Se volete il terreno prima:

Questo è anche un strumento con scatola di tempo.


L'idea centrale: RAG ridotta

La RAG standard fa già il rilevamento semantico: i documenti di blocco, li inserisceM SK2 e riporta la parte superiore -k i blocchi più similiMSC4

La sofferenza è l'ultimo passo: finisci ancora per gettare un rumoroso aggregato di pezzi in un LLM che si sovrappone e gli chiede di riconciliare i duplicati , pesare le fonti, e mantenere un filo coerenteMSC4 FunzionaM SK5 ma ti spinge verso le grandi finestre del contesto e i modelli costosi

E se faceste più lavoro? prima. LLM vede qualsiasi cosa?

Che ' è il modello. Riducete prima di generare.. Prendete i documenti scarsi e li riduciamo in maniera determinista a dei segnali essenziali : inserzioni, classiMSC3 segmenti salientiM SK4 profili di entitàMNK5 Quando il LLM vede qualcosaMRK6 il duro lavoro è fattoMMK7

flowchart TD
    subgraph REDUCE["REDUCE: Distil to Signals"]
        Q[Query] --> Decompose[Composite Decomposition]
        Decompose --> S1[Subquery 1]
        Decompose --> S2[Subquery 2]
        S1 & S2 --> Fetch[Multi-Source Fetch]
        Fetch --> Embed[ONNX Embed Each Item]
        Embed --> Rank[6-Signal RRF Fusion]
        Rank --> TextRank[TextRank Extraction]
        TextRank --> NER[Entity Extraction]
        NER --> Profile[Entity Profile Vectors]
        Profile --> Segments[Salient Segment Extraction]
    end

    subgraph SYNTH["SYNTHESIZE"]
        Segments --> Standard["Standard Path - 1 LLM Call"]
        Segments --> LongForm["Long-Form Path - N+3 LLM Calls"]
    end

    style REDUCE fill:#1a1a2e,color:#e0e0e0
    style SYNTH fill:#162447,color:#e0e0e0

La fase di riduzione è deterministica: embeddingsM SK1 ranking, extrazione delle entità , TextRankMSC4 punteggio dei segmentiMST5 Nessun call LLMMSL6

La sintesi è l'unico passo LLM. Per una domanda standard i segnali ridotti sono abbastanza puliti da una sola chiamata. Fa il lavoro. Per i lunghiM SK1documenti formali, un sentinel pianifica la struttura e il modello principale genera sezioni in parallelo (N+3 chiamazioni per sezioni N).

Per i dettagli su questo schema, consultate RAG ridotto.

La fase della mappa: dalla domanda alle fonti

Prima di ridurre qualcosa, la domanda deve diventare un'azione di ricerca.

Un piccolo modello sentinel locale (0.6B nel mio caso,Modus JSONM SK2Temperatura 0.1)interpreta la domanda brutta in un'intenzione strutturataMSC4 Poi un router di sorgente guidato da YAMLMスク5 trasforma quell'intensione in fetchi di cemento.

flowchart TD
    Q["User Query"] --> Sentinel["Sentinel: JSON Interpretation - categories, intent, entities, - temporal hints, tone"]
    Sentinel --> Router["Source Router - YAML category → source mapping"]
    Router --> S1["gnews:AI safety"]
    Router --> S2["search:AI regulation"]
    Router --> S3["bbc:technology"]
    Router --> S4["reddit • hn"]
    S1 & S2 & S3 & S4 --> Fetch["Parallel Fetch - circuit breaking + rate limiting"]
    Fetch --> Merge["Merge + Deduplicate - → reduce phase"]

    style Sentinel fill:#1e3a5f,color:#e0e0e0
    style Router fill:#0d3b2e,color:#e0e0e0

Il sentinel extrae campi strutturati:

  • Catégorie di tema (con pesci di fiduciaM SK1
  • Intenzione della domanda (noti,QAM SK2 ricercaMST3 confrontoMSV4 come fareMSS5
  • Sensibiltà temporale (breaking / oggi / settimanaMSC3
  • Entità chiamate
  • Per le domande complesse: sottoquestioni decomposse (con prononi risoltiM SK2

Selezione della fonte Succede in sei fasi:

  1. Source esplicitate: lo ha detto l'utente. "from HackerNews"hn va dritto dentro.
  2. Cercare le domande: il sentinel' i termini di ricerca ottimizzati diventano vivaciM SK2 le chiamate API qualificate (DuckDuckGoMST4 BraveMst5 Google News RSSMSt6
  3. Il routing delle categorie: mappa i peso dei temi ai feed RSS attraverso la configurazione YAMLM SK1 Una domanda su " regolamentazione AI" percorsi ai feed tecnologici e i feed delle politiche.
  4. Ri arricchimento della ricerca: research o deep_dive intenti aggiungere archivio
  5. Ri arricchimento delle entità: le entità chiamate dal NER ricevono le loro domande gnews. gnews:OpenAI)
  6. Il piano della diversità: se meno di 3 le fonti selezionate, inserisce i predefiniti

Il risultato: M SK1 identificatori di sorgente raggiunti in parallelo con per-interruzione del circuito sorgenteMSC3

Vibes modificano i termini di ricerca prima di colpire qualsiasi API. Per esempio, --vibe doom Prefixi che fanno domande con "questioni che riguardano problemi comportano rischi in ...", rimodellare ciò che ritorna prima di essere classificatoM SK1

Se volete il background dei bit di resilienza, vedete. Usare Polly per la pensione (circuit breakers) e Backpressure in Queueing Systems (limitazione del tasso e pressione posterioreM SK1

Decostruire la domanda

La maggior parte dei sistemi di ricerca tratta "Cosa 'è nuovo nella sicurezza dell'IA e quali sono le ultime normeM SK2 come una domanda . E' l'altra SSK4 le due S. Trattandola come un'altra diluisce entrambi.

Il sentinel decompone le domande complesse:

{
  "is_composite": true,
  "subqueries": [
    "What's new in AI safety?",
    "What are the latest AI regulations?"
  ]
}

La scelta interessante è quello che succede dopo. Ogni sottoquestiona riceve la propria integrazione ONNX ( vedi ONNX: Gestire modelli ML localmente). Quando scorgo gli articoli, prendo il La somiglianza più grande delle cosine su tutti gli inserimenti di sottoquestioni, non la mediaM SK1

Perché max? Un articolo che risponde perfettamente M SK1Sicurezza dell'AI " non dovrebbe' essere punito per non aver detto nulla di "RegulationsMSC5 L'averaging la potesse seppellire sotto corrispondenze parziali mediocreMST6 La somiglianza maximale significaMSV7 se un articolo si piega Qualunque. parte della vostra domanda, si alza. L'alternativaM SK2 mediato , premia articoli blandi che toccano vaguemente tuttoMSC4

Fusing Heterogeneous Signals

Ho sei segnali di classificazione. Hanno scale completamente diverse:

flowchart LR
    subgraph Signals
        BM25[BM25 - Keyword Match]
        Fresh[Freshness - 48h Half-Life]
        Auth[Authority - HN/Reddit Score]
        QSim[Query Similarity - Cosine]
        Vibe[Vibe Alignment - Cosine]
        Qual[Quality - Clickbait Detector]
    end

    subgraph RRF[RRF Fusion]
        direction TB
        R[Rank Each Signal - Independently]
        F["score = Σ weight × 1/(60 + rank)"]
    end

    BM25 & Fresh & Auth & QSim & Vibe & Qual --> R --> F

    style RRF fill:#1e3a5f,color:#e0e0e0

I punti HN vanno a migliaia. La somiglianza delle cossine è M SK1 a 1. La frescozza si decade esponenzialemente. PoteteMSC4non aggiungerli insieme in modo sicuroMST5 Le scale sono incompatibiliMSV6

Il segnale chiave qui è BM25 attraverso diversi campi (BMM SK2FMSC3 Se volete il background di BM 25, vedete. DocSummarizer Part 3.

Fusione di posizione reciproca (Cormack et alM SK1 2009) lo risolve ignorando i punteggi grezzi: ogni segnale classifica gli elementi in modo indipendenteMSC4 poi si combina il Le classifiche sono molto diverse.: score = Σ weight × 1/(k + rank) (con k=60).

Se volete il background completo su RRF, La parte 3 lo copre . Qui c'è la spinta. I pesci si adattano al tipo di domanda.. Il sentinel individua l'intenzione , e il scoratore si riorganizza:

  • Queries temporali ("Cosa è successo oggi?") alzare la frescozza e abbassare la qualità (la ricevuzione conta di piùM SK3
  • Le domande degli spiegatori ("Come funziona la computazione quantisticaM SK1Fa l'opposto (La profondità è più importante della novità).
  • Roundups e confronti hanno i propri profili regolati.

Vibes come dimensione di recupero

Questo cominciò come una barzelletta.

A "vibeM SK1 non è'non è una formulazione in primo luogoMSC3 E' un segnale di classifica prima della classe - embedded into the retrieval pipeline:

flowchart LR
    V["--vibe doom"] --> Expand["Query Expansion - 'concerning risks issues in...'"]
    V --> Embed["Vibe Embedding - 'vulnerability breach layoffs - recession crisis warning...'"]
    Embed --> Score["Cosine Similarity - per article"]
    Score --> RRF["RRF Signal - weight: 0.4"]

    style V fill:#8b0000,color:#e0e0e0

Tre cose accadono quando si crea una vibrazione:

  1. Espansione della domanda - la ricerca viene precedita da mood-qualificatori adeguati
  2. Inserzione di vibrazioni Il testo rappresentativo - viene inserito come 384-dim obiettivo.
  3. Signale di classificazione Gli articoli - valutati in base alla somiglianza di cosine con l'inserzione della vibrazione

Vibe personalizzate funzionano identicamente. --vibe "contemplative philosophical"-il vostro testo diventa sia il prefisso della domanda che l'obiettivo di classificazione. Il sistema non distingue la prededefinita dalla personalizzataM SK3 Semplicemente inserisce tutto quello che gli date.

Profili di Entità, Non Contazioni di Entità

Qui' è un errore che ho fatto prima: contare le entità condivise tra i documentiM SK2

Due articoli menzionano entrambi "CaliforniaM SK1

  1. L'ufficio della California annuncia l'équipe di sicurezza.
  2. "I coltivatori di almonde della California affrontano la siccità"

Numero delle entità condivise: 1. Perciò correlateM SK2 Chiaramente sbagliato .

La soluzione era pensare alle entità come a vettori, non a stringi.

Questo è il Un modello di confusione limitato.: il modello NER propone entità, ma la ponderazione deterministica decide cosa importaM SK2

Ogni documento riceve una Profilo di entità ponderata (a 384-dim codificazione dei vettori Il che Le entità appartengono e quanto sono distintive):

weight = TF × IDF × confidence × type_weight
profile = L2_normalize(Σ entity_embedding × weight)
flowchart TD
    subgraph Doc1["Article: OpenAI Safety Team"]
        E1["OpenAI (ORG) - IDF: high - weight: 2.1"]
        E2["California (LOC) - IDF: low - weight: 0.3"]
        E3["Safety Team (MISC) - IDF: high - weight: 1.8"]
    end

    subgraph Doc2["Article: Almond Farming"]
        E4["California (LOC) - IDF: low - weight: 0.3"]
        E5["Almond Farmers (MISC) - IDF: high - weight: 1.9"]
        E6["Drought (MISC) - IDF: medium - weight: 1.2"]
    end

    Doc1 --> P1["Profile Vector - Dominated by OpenAI + Safety"]
    Doc2 --> P2["Profile Vector - Dominated by Farming + Drought"]
    P1 -. "low similarity" .- P2

    style Doc1 fill:#1a1a2e,color:#e0e0e0
    style Doc2 fill:#2d1a2e,color:#e0e0e0

IDF è la chiave. M SK1California" appare in tonnellate di articoli - bassa IDFMST4 segnale deboleMSSK5 ♫"OpenAIMSC7 è distintivo - alta IDF, domina il profilo\MST10 Adesso la ricerca della somiglianza funziona\MTS11\ OpenAI article cluster together\MSS12\ Farming articles cluster separately\M SS13\ Il compartito \MSKS14\Clifornia\MISS15\ diventa rumore\MSSE16\

La parte intelligente: TF saturante. Invece del numero di menzioni brutte, uso 1 + log(mentions). Una entità menzionata 50 volte in un lungo articolo non ' ottiene 50× il peso di una che è menzionada una volta. ottiena M~5×. Questo impedisce alle entităţi della boilerplate di inondare il profiloM SK6

La scoperta di un grafico semantico

I profili delle entità non sono' solo per capire i documentiM SK1 Sono' uno strumento di dimensione di rilevamento. Ogni documenM SK1t' il profilo delle entità viene indexato in un grafico HNSW (DuckDBMSC4 l'estensione del VSSMNK5 permettendo OMST6log NMSSK7 la scoperta di articoli semanticamente correlati che la ricerca su keyword non avrebbe trovato.

Se volete più dettagli su HNSW e DuckDB VSS, vedete GraphRAG Part 2: Minimum Viable Graph RAG.

flowchart TD
    subgraph Retrieval["Three-Layer Retrieval (UNION)"]
        L1["Lucene FTS - keyword matches"]
        L2["Embedding HNSW - semantic similarity"]
        L3["Entity Profile HNSW - entity fingerprint match"]
        L1 & L2 & L3 --> Union["Union of all candidates"]
    end

    subgraph Enrich["Post-RRF Enrichment"]
        Top["Top 5 Ranked Items"] --> Agg["Aggregate Profile - mean of entity profiles"]
        Agg --> Graph["HNSW Search - min similarity: 0.30"]
        Graph --> Related["+3 Related Articles - scored below existing items"]
    end

    Union --> RRF["RRF Fusion"] --> Enrich

    style Retrieval fill:#1a1a2e,color:#e0e0e0
    style Enrich fill:#0d3b2e,color:#e0e0e0

Funziona in due fasi:

Durante la ricerca: quando il sentinel extrae 2+ entità dalla domanda, un profilo di entity della domanda viene calcolato usando la stessa formula TFM SK3IDFMSC4 Questa ricerca l'indice HNSW per gli articoli con impronte digitali simili dell'entitàMNK5 con una minima somiglianza di \0.25. Un articolo su \ "OpenAI preoccupazioni di sicurezza \ " supera le superfici anche se non menziona mai i termini precisi della domanda | , perché il suo profilo d'entity ( è dominato da un alto |-IDP ♫"\ OpenAI " \ L'+\ \ МSK15\ la sicurezza | ") è vicino alla domanda \

Dopo la classificazione.: gli articoli classificati in alto 5 hanno i loro profili di entità mediati in un vettore aggregato. Questa ricerca aggregata cerca articoli correlati che la parola chiave e le strati di inserzione hanno completamente persoM SK3 Gli articoli trovati vengono classificati appena sotto l'elemento meno classificato ♫(×0.9) e sono etichettati come scoperti " attraverso le entità". Questo cattura le fonti principali a cui si riferiscono gli articoli, ma non ci cita letteralmente.

Tre strati di rilevamento si fusionano attraverso l'unione: La combinazione dei mots chiave Lucene ∪ la combinazione dell'incorporazione del HNSW ∪ il profilo dell'entità HN SW . L'unioni è deliberatamente più ampia dell'intersezioneM SK4 Cattura oggetti su cui potrebbe apparire un singolo segnaleMSC5 La fusione RRF poi seleziona ciò che è realmente rilevanteMNK6

Il percorso di ritorno (per corpora senza profili di entità ancoraM SK1 usa co-entità SQL-calcolo delle occurrenze (HAVING shared_count >= 2). Funziona , ma è 's O(NM SK4 invece di OSSK5log NMSC6 --backfill-entity-profiles Il comando migra le corpora esistenti al percorso HNSW.

Syntesi standard: Un Call LLM

Questo è il percorso normale. scroll "AI safety and regulation" colpisce questo. Dopo la fase di riduzione distilla le tue fonti in segmenti classificatiM SK1 duplicati , entità- segmenti profilatiMSC4 la sintesi è una sola chiamata

flowchart TD
    subgraph REDUCE["Reduce Phase (ALL DETERMINISTIC)"]
        Items[Fetched Items] --> Embed[ONNX Embed All Items]
        Embed --> RRF[6-Signal RRF Fusion]
        RRF --> TR[TextRank Compression]
        TR --> Seg[Segment Extraction + Salience Scoring]
        Seg --> Dedup[Deduplication + Relevance Floor]
    end

    subgraph SYNTH["Synthesis (1 LLM CALL)"]
        Dedup --> Rerank["Semantic Re-Rank - by query similarity"]
        Rerank --> Budget["Smart Evidence Budgeting - redistribute unused chars"]
        Budget --> Gen["Single LLM Call - with curated evidence"]
        Gen --> Output[Final Summary]
    end

    style REDUCE fill:#0d3b2e,color:#e0e0e0
    style SYNTH fill:#1e3a5f,color:#e0e0e0

La fase di riduzione fa un duro lavoro. Quando il LLM vede qualcosa, riceveM SK2

  • Solo items in alto: livello di rilevanza a 30% del miglior articoloM SK2 punteggio, URLMSC4duplicato
  • Diversità delle fonti: è limitato a 3 elementi per dominio per le domande di roundup.
  • Semantic re-ranking: items re-ordered by cosine similarity to the query embedding
  • Budgetazione delle prove intelligenti: elementi brevi donano un budget di caratteri non usati a elementi lunghi , quindi l'area di prove non è sprecata
  • Blocchi di prove strutturati: [E1] Title | topic | relevance con un contenuto ristretto al budget.

Un LLM chiama ., che è la compensazione di RAG ridotto: selezioneM SK1 classificazione, duplicazione , e budgeting tutto accade prima che il LLM veda nienteMSC4

La Long-Form Pipeline: Generazione Parallele Constritta

Long-form M SK1--template blog-article) è una different beastM SK1 Voi' generate un documento multi-sezioneMSC3 da dozzine di fonti , e avete bisogno di coerenza tra le sezioni senza costose chiamate di compressione LLMMST5

La risposta è Il dragging di un contesto fuzzy limitato. Questi sono meccanismi deterministici che mantieneno la coerenza tra le sezioni -e permettendo la generazione parallela

flowchart TD
    subgraph Phase1["Phase 1: Evidence Preparation (DETERMINISTIC)"]
        Articles[Top 20 Articles] --> Segments[Chunk into Segments]
        Segments --> Salience[Score Salience per Segment]
        Salience --> EmbedSeg[Embed Each Segment]
    end

    subgraph Phase2["Phase 2: Document Planning (1 SENTINEL CALL)"]
        EmbedSeg --> Summary[Build Evidence Summary]
        Summary --> Sentinel["Sentinel: Generate Outline - with theme keywords per section"]
        Sentinel --> EmbedThemes[Embed Section Themes]
    end

    subgraph Phase3["Phase 3: Evidence Assignment (DETERMINISTIC)"]
        EmbedThemes --> Assign["Score: 60% theme similarity - + 25% salience + 15% relevance"]
        Assign --> Dedup[Cross-Section Deduplication]
        Dedup --> Gate["Quality Gates - • Min salience 0.35 - • Min theme sim 0.45 - • Max 2 per source per section"]
    end

    subgraph Phase4["Phase 4: Section Generation (N+2 LLM CALLS)"]
        Gate --> Intro["Intro (sequential)"]
        Intro --> Body["N Body Sections (parallel) - max 3 concurrent"]
        Body --> Conclusion["Conclusion (sequential)"]
    end

    subgraph Phase5["Phase 5: Validation (DETERMINISTIC)"]
        Conclusion --> Validate[Citation Validation - URL + Entity Grounding]
    end

    subgraph Phase6["Phase 6: Assembly (DETERMINISTIC)"]
        Validate --> Assemble[Final Document Assembly]
    end

    style Phase1 fill:#0d3b2e,color:#e0e0e0
    style Phase2 fill:#1e3a5f,color:#e0e0e0
    style Phase3 fill:#0d3b2e,color:#e0e0e0
    style Phase4 fill:#1e3a5f,color:#e0e0e0
    style Phase5 fill:#0d3b2e,color:#e0e0e0
    style Phase6 fill:#0d3b2e,color:#e0e0e0

Contare le chiamate LLM: 1 (linea dorsale percentileM SK1 + 1 (intro N. (sezioni del corpoM SK1 + 1 (Conclusione N+3. Quattro delle sei fasi sono deterministiceM SK1

Dragging Contexto Fuzzy Constrained

Il problema con la generazione di sezioni parallele è la coerenza. Se le sezioni non sanno'non sanno cosa gli altri sezioni hanno dettoM SK2 si ottengono ripetimenti e drifti . La soluzione comune è la generazione sequenziale con un contesto completoMSC4 QuelloMST5 è lento e spreca la finestra del contestoMSST6

Invece, ogni sezione riceve un Contexto limitato che' è costruito in maniera determinista:

flowchart LR
    subgraph Context["Per-Section Context (ALL DETERMINISTIC)"]
        RS["Running Summary - 1400 char budget - recent 2 sections: full - older: heading only"]
        NP["Negative Prompts - 'Do NOT discuss: X, Y, Z' - from covered concepts"]
        EC["Entity Continuity - re-introduce entities - last seen 2+ sections ago"]
        Props["Propositions - ~15 atomic facts - per section"]
        Evidence["Curated Evidence - max 12 segments - quality-gated"]
    end

    Context --> LLM["LLM generates - with full awareness - of document state"]

    style Context fill:#1a1a2e,color:#e0e0e0
  • Un riassunto in corso: dopo ogni sezione, la parte in altoM SK2 il segmento della prova di affidamento (200 i caratteriMSC4 viene registratoMST5 le sezioni recentiMst6 vengono completamente digeriteMSt7 le sekzioni più vecchie vengono inserite sotto la prima fraseM st8 la prima frasiMt9 Il budget totaleMstr10 Mstr11 i simboliMtr12 Nessuna sommificazione LLMMr13
  • Prompti negativi: si estraggono i concetti coperti (nomeni adatti, termini tecniciM SK3 parole chiave per i titoliMSC4 max 15 per sezioneMNK6 Le sezioni successive ricevonoMRK7 "Non discutere di questi argomenti (avete già affrontato): XM SK3 YMSC4 ZMST5
  • La continuità dell'entità: le entità non menzionate nelle sezioni 2+ vengono segnate per la ri-introduzioneM SK2 l'introduzione. le enti attive ( menzionato recentementeMNK5 sono monitorateMMK6 Il LLM riceve le istruzioniMRK7 "ReM SK1introduce se rilevante: EntitàMSC3 (ultimamente menzionata
  • Detezione del flusso: dopo che ogni sezione generaM SK1 i suoi primi 1000 caratteri sono inseriti e confrontati con il piano' l'inserzione del temaMSC4 Se la somiglianza di cosine si abbassa sotto 0.35 per le sezioni consecutiveMSL6MLS7 l’inserazione del tema viene ricalibrata dalle prime sezioni MMSL8Msl9

Nel modo parallelo, l'intro genera il primo M SK1stabilisce la linea di base), le sezioni del corpo funzionano simultaneamente ( fino a SSK4 attraverso SemaphoreSlim per limitare la congruenza, ciascuno escludendo i temi intro ma non gli altri), e la conclusione corrisponde alla ultima M SK2esclude tutto ).

Il modo sequenziale dà una coerenza più stretta ( ogni sezione esclude tutti i concetti precedenti in modo cumulativoM SK1 ma parallelo è ~3x più veloce per i grandi documenti.

Assignazione di prove: Il cuore della RAG ridotta

Ogni sezione ha bisogno di prove, ma non Qualunque. Evidenza. Ogni segmento ottiene un punteggio combinatoM SK1 60% somiglianza tematica (distanza cosinusa alla sezioneM SK1inserzione del tema), 25% salienza (come informativo il segmento èM SK1 e 15% rilevanza dell'articolo (come rilevante l'articolo della fonte è in generale). Questa classificazione è completamente deterministaM SK2 Nessun LLM decide cosa sia rilevante 'MSC4

Poi le porte:

  • Il pavimento della Salienza (0.35): bassaM SK1 segmenti di qualità non raggiungono mai l'LLM
  • Suolo di somiglianza del tema (0.45): fuori-la prova del problema rimane fuori.
  • Cross-section dedup (0.80 cosine): lo stesso fatto non appare due volteM SK2
  • Per-cappa di fonte (2 segmenti per articolo per sezione): nessuna singola fonte domina.
  • Sensibilizzazione del ruolo della sezione: le sekzioni intro penalizzano il dettaglio tecnico (-0.3); le sezioni più tardi lo ricompensano
  • Porta di coesione della domanda (0.30): le prove devono essere legate alla domanda originale, non solo al tema della sezione

Il conteggio di parole del target LLM si adatta sulla base della qualità delle prove. Le prove forti ( la salinità ≥ 0.6, \2+ le fontiM SK5 ♫4+ i segmenti ) |→ il conteggio completo delle paroleMSC9 le prove debolie ( la Salinità < | | 0.45, sparseMST13 ♪MST14 MST15 dell'obiettivoMSSK16 Questo impedisce l'allucinazione quando le prove sono sottiliMSS17

Extrazione della proposta: Dense-X in pratica

Prima che le prove raggiungano l'LLM, è stato atomizzato in proposizioni ( ispirate dal Papiero di ricerca denso-X). Ogni segmento è diviso in sei tipi di fatti atomici. i revendicamenti (affermazioni di fatto generali), Citazioni (direzionale dalla fonte), Statistiche ( numeri e parametri), Definizioni ("X è YM SK1 i processi (stepM SK1by-step≥), e i fatti dell'entità chiamata (focused on a specific entity).

Ogni sezione riceve ~15 proposizioni, deduplicate attraverso le sezioni usando la semantice somiglianza (non corrispondenza alle stringheM SK3 Il LLM riceve punti di bolle strutturati raggruppati dalla fonteMSC4 non paragrafi grezziMSL5

Quando il LLM scrive una sezione, la fase di riduzione l'ha data:

  • Un titolo e un tema chiari.
  • Segmenti di prove curate (qualità-distruttoM SK2duplicato )
  • ~15 Proposition atomiche (quotes
  • Un riassunto di ciò che le sezioni precedenti hanno già coperto.
  • I stimoli negativi per cosa? Non. per ripetere
  • Guidance sulla continuità dell'entità

Un piccolo modello può fare un ottimo lavoro con questo tipo di pre-processo.

TextRank: Summarizzazione deterministica

Quando gli articoli sono troppo lunghi per il flusso di prove, Devo comprimerli. Ma non voglio spendere una chiamata LLM sulla sommificazioneM SK3

TextRank (Mihalcea & Tarau, 2004) lo fa deterministamenteM SK4

flowchart LR
    Text[Article Text] --> Split[Split into Sentences]
    Split --> EmbedS[Embed Each Sentence]
    EmbedS --> Graph["Build Similarity Graph - (cosine > 0.15 = edge)"]
    Graph --> PR["PageRank - (20 iterations, d=0.85)"]
    PR --> Select["Select Top-K - in Original Order"]

    style Graph fill:#1e3a5f,color:#e0e0e0

Ogni frase riceve un inserimento. Le somiglianze in scala verticale sopra 0.15 diventano bordi graficiM SK2 PageRank trova la più grande Centrale frasi, quelle più connesse a tutto il resto. Queste sono le frasi che rappresentano meglio il documento

Il dettaglio chiave: le frasi selezionate vengono restituite. in ordine del documento originale.. Questo preserva il flusso narrativo. Si ottiene un riassunto coerente , non una borsa casuale di frasi importantiM SK3

Nessun call LLM. Funziona in millisecondi. La somiglianza di cosine è SIMDM SK2 accelerata tramite TensorPrimitives (System.Numerics.Tensors) (AVX2, AVX≥-512, o ARM NEONM SK4 scelto al runtimeMSC5

Gli articoli riferiscono altri articoli. Queste riferimenti spesso contengono le migliori prove - la prima fonte che un articolo di notizie riassume

DoomSummarizer segue i link, ma selettivamenteM SK1 Ogni link candidato viene valutato:

link_score = 0.7 × query_relevance(anchor_context) + 0.3 × segment_salience

Dove la salienza del segmento si combina:

  • La posizione (60%) - piramide invertitaM SK2 i primi paragrafi sono più importanti
  • Substance (40%) - lunghezza del paragrafo e densità di informazione

I collegamenti sotto un piano di rilevanza (0.15) sono superati. Il sistema segue l'euristica piramidale inversa giornalisticaM SK2 i collegamenti importanti tendono a apparire all'inizio dei lavori beneMSC3 gli articoli scritti .

I risultati sono archiviati con content hashes e ETags. I second run sono veloci. Vedete Caching delle risposte, ETags, e richieste condizionate.

Mode Crawl: Costruire una base di conoscenza locale

Tutto quello che è stato descritto finora presume la fettura del web. Ma potete saltare il web interamente.

crawl inserisce un sito web in una base di conoscenza locale. Fa una larghezza-la prima ricerca M SK2BFS ) da un URL di semiMska4 rispetto alla profondità e ai limiti delle pagineMske5 con un tasso di limitazione adattabile che rallenta il ritardo basato sui tempi di risposta del serverM Ska6

doomsummarizer crawl https://docs.example.com --name example-docs --depth 3 --max-pages 200

Tutto rimane persistente: contenuto completoM SK1 inserzioni ONNX , profili di entità, SQLite FTSMSC4 indice di parole chiave MSSK5 completaMS- ricerca di testoMST7 punteggi di sentimento e di tema ( calcolati tramite ancor di inserzioneMSV9 nessun LLMMSS10 riincremento gradualeMSP11 battute inviate If-None-Match / If-Modified-Since headers. pagine non cambiate restituiscono HTTP 304 e skip reprocessingM SK2 Per server senza supporto ETag , SHAMSC4 content hashes catturano duplicatiMスク5

Una volta fatto crawl, la domanda è interamente offline:

doomsummarizer scroll "how does authentication work?" --name example-docs

L'informazione figura nella parte dispositiva. --name Routes to the local KB instead of web sources. The same three-layer retrieval fires : FTSM SK3 fullMska4text preM Ska5filterM ska6 embedding HNSW searchMske7 entity profile HN SW searchmska8 They are unionMsku9fused and rankedMSKA10 Same reduce pipelineMsko11 same synthesisMsek12 No network requiredMSC13

L'archivio è leggero: SQLite per metadati e FTS5 indexiM SK2 DuckDB con l'estensione VSS per gli index vectori HNSW . Nessuno servizio esternoMSC4 nessun DockerMST5 nessuna chiave APIM ST6 Una base di conoscenza crawlata di centinaia di pagine si inserisce in pochi megabyte e le domande in millisecondiMst7

Metterlo insieme

doomsummarizer scroll "AI safety and regulation" --vibe doom --debug

Composite query detected: 2 subqueries
  • What's new in AI safety?
  • What are the latest AI regulations?

Searching...
├─ Lucene: 18 keyword matches (regulation^3, safety^2)
├─ Embedding: 12 semantic matches (max-sim across 2 subqueries)
├─ RRF fusion: 22 candidates, 6 signals
├─ Entity HNSW: +3 related via entity profiles
├─ TextRank: compressed 4 long articles
└─ Final: 12 items

Long-form: Phase 1 - 187 segments from 12 articles
Long-form: Phase 2 - "AI Safety Landscape" - 5 sections
Long-form: Phase 3 - Evidence assigned (cross-section dedup: 8 removed)
Long-form: Phase 4 - Generating sections...

Le idee che l'hanno fatto funzionare

Queste sono le intuizioni.

  1. Ridurre prima di generare.: il percorso standard ha bisogno solo di 1 l'appello LLM perché il tubo fa tutta la leva pesante in maniera determinista. RAG ridotto è il modello: embeddings , PageRank, heuristicsM SK3 e i porti di qualità producono input così puliti che anche i piccoli modelli sintetizzano beneMSC4
  2. Sentinel-route della fonte guidata: un piccolo modello interpreta le quei domande in un'intenzione strutturata , poi YAML- il routing guidato seleziona la direzione e l'impulsoM SK3 corrisponde a ~10 le fontiMSC5 Il sentinel è abbastanza economico da chiamare ogni questioni.
  3. Una grande somiglianza per le domande complesse.: donM SK1t punteggi medie di sottoquestioni , prendere la migliore combinazione. Un articolo che descrive una parte della vostra domanda è meglio di una metàMSC4la combinazione di tuttoMST5
  4. Combina i gradi, non i punteggi: RRF permette di fusionare i segnali con scale incompatibili. AutoritàM SK2 frescozza , somiglianza embeddingMSC4 alignamento di vibrazioneMNK5 semplicemente classificare e fusionareMRK6
  5. Vibe come inserzioni: ogni testo può essere una dimensione di ricercaM SK1 L'immettere , il punteggio rispetto a lui, weight it in RRFMSC4 Non servono casi specialiMNK5
  6. Profili di entità come vettori: IDFM SK1inserzioni di entità ponderate, non conteggio delle stringhe d'entità . Entità rare dominano il profiloMSC4 Enti comuni diventano rumoreMSSK5 e la ricerca HNSW scopre articoli connessi in O
  7. Trascinare un contesto fuzzy limitato: Gestione del contesto deterministico permette la generazione di sezioni parallele. Somilari in corso, richiami negativiM SK2 continuità delle entità , e rilevamento della deriva mantenere la coerenza senza chiamate di compressione LLMMSC4
  8. Determinista se possibile.: delle sei fasi lunghe-form phaseM SK2 quattro sono deterministiceMSC3 TextRank sostituisce la sommificazione LLMMSL4 L'assignazione di prove sostituisce la selezione LLM

Ressource

Article connessi

Anche.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.