arXiv 2610.36991 · Weighted Chunk Graphs for Token-Budgeted Context Selection

Top-k finds similar. SpectRAG finds enough.

Dense retrieval returns the chunks that look most like your question. SpectRAG adds a ◇ weighted chunk graph and its ∿ spectral structure, then picks a context set that is relevant, non-redundant, connected and ✓ sufficient for multi-hop answers.

71.2Exact match on MultiHopRAG, best of 5 systems
91.8Gold-evidence recall, +15.7 pts over the next best
−83%Index size vs LightRAG (46 MB vs 274 MB)
L legal-corpus 🔒 30 docs · 412 chunks · 2,381 edges GraphChat
Today 10:02
B
You

Which obligations survive termination across the supplier and licence agreements?

◇ Retrieved 13 chunks from 4 sources · 9,840 / 12,000 tokens
SpectRAG

Three obligation groups survive in both contracts. Confidentiality continues for five years S1, and the licence extends it to source code S2. Data return and deletion is governed by the DPA, which the supplier agreement incorporates by reference S3. Liability caps survive, but courts read them narrowly S4.

Supplier §14.3 Licence §9 DPA §11 Digest p.4

Illustrative session. The interface is the React + D3 app in frontend/.

The problem

A ranking isn't a context.

Top-k scores every chunk on its own. It keeps picking near-duplicates from the closest document and skips the chunk that links to the second half of the answer. SpectRAG chooses the set as a whole.

Naive RAG 1 source4 near-duplicatesno second hop
SpectRAG 3 sourcesredundancy filteredbridge chunk reached
Pipeline explorer

Watch every stage run.

A toy corpus of 72 chunks from 6 documents is indexed and queried in your browser with the same steps the code runs. Graph edges, Personalized PageRank, the Laplacian eigenvectors and k-means are all computed live.

    Show the full architecture figure from the paper SpectRAG offline indexing and online query-time retrieval pipeline
    The weighted chunk graph

    Six signals. One edge weight.

    Every signal links chunks for its own reason. Each is min-max normalised, the six are blended with weights that sum to 1, and edges with W < 0.1 are dropped. Hover a signal to see only its edges.

    All signals · colored by strongest contributor
    EdgeWeightsconfig.py · Σ = 1.000
    W(i,j) = Σk wk · normk(i,j)
    Spectral structure

    Coordinates from the graph's own shape.

    The normalised Laplacian of the chunk graph is decomposed once, at index time. Its smallest non-trivial eigenvectors give each chunk a 32-dimensional coordinate that encodes which community it belongs to. Two chunks can be far apart in embedding space and still sit next to each other here.

    L = I − D−½ W D−½
    • 32 eigenvectors kept; the trivial constant one is dropped
    • ARPACK up to 50k nodes, LOBPCG above that
    • Multiplex mode: L = Σ βk Lk, one normalised layer per signal
    • Offline k-means (k = 5) labels reused at query time
    Proximity re-scoring

    Relevance flows along real edges.

    Starting from the seeds, relevance spreads over the chunk graph. Drag t to watch it reach chunks that share no words with the question but are linked to the ones that do. The heat kernel e−tL is computed from the same eigenvectors as above.

    t = 0.00
    combined(c) = (1 − α)·relevance(c) + α·proximity(c)  ·  α = 0.5
    coldhot seed
    Results · from the paper

    Better answers from a smaller index.

    Every system uses the same generator. Numbers are taken from the SpectRAG paper (Tables 4, 6, 7 and 8).

    Best end-to-end accuracy, by an honest margin

    Exact match (%) on 2,556 MultiHopRAG questions.

    Source: SpectRAG paper, Table 7. F1 and "contains" give the same ordering.

    Keeps finding evidence the deeper you look

    Gold-evidence recall (%) on MultiHopRAG. Hybrid leads at the top ranks; SpectRAG wins on breadth.

    Source: SpectRAG paper, Table 6. "All" = recall of the full retrieved context.

    Biggest win where evidence must be connected

    Exact match (%) by MultiHopRAG question type. Large dot = SpectRAG.

    Source: SpectRAG paper, Table 8. Null = unanswerable; higher means correct abstention.

    A ~6× smaller index, fewer nodes on every corpus

    Left: full index on MultiHopRAG. Right: graph nodes (chunks vs LLM-extracted entities).

    Source: SpectRAG paper, Table 4.
    Ablation · Stage-4 selection study (Legal) 13 variants judged pairwise vs NaiveRAG. Above 50% = SpectRAG preferred. ⌄
    60%token_budget win rate vs NaiveRAG. It is now the production default.
    ~35%of relevant chunks the original greedy selector dropped to force diversity

    n = 20 questions on 30 documents, so one question moves the score 5 points. Treat the 60 vs 55 lead as weak evidence.

    Stack

    Runs on your machine.

    Embeddings run locally through Ollama. Switch two config flags and indexing is fully local too: no API key, no cost.

    Embeddingsnomic-embed-textOllama · 768-dim
    Vector indexFAISS IndexFlatIPexact cosine
    LexicalBM25rank-bm25 · RRF fused
    Graph storeNeo4jBolt · Cypher BFS
    SpectralSciPyARPACK / LOBPCG
    Index-time LLMgpt-4o-minior llama3.1:8b / spaCy
    Rerank (opt.)MiniLM cross-encoderms-marco-L-6-v2
    AppFastAPI + ReactVite · D3 v7
    Quickstart

    From folder to answer in four commands.

    Python 3.11, Ollama, Docker and Node 18+. Neo4j starts by itself the first time the server runs. Full instructions are in the official repository.

    ~/SpectRAG — zsh
    
        
    Cite

    SpectRAG: Weighted Chunk Graphs for Token-Budgeted Context Selection in Multi-Hop Retrieval-Augmented Generation

    Zafer Sahinoglu · Abdulazeez Mohammed · Buse Yaren Kazangirler · Cahit Berkay Kazangirler — 2026

    @misc{sahinoglu2026spectragweightedchunkgraphs,
      title={SpectRAG: Weighted Chunk Graphs for Token-Budgeted
             Context Selection in Multi-Hop Retrieval-Augmented Generation},
      author={Zafer Sahinoglu and Abdulazeez Mohammed and
              Buse Yaren Kazangirler and Cahit Berkay Kazangirler},
      year={2026},
      eprint={2610.36991},
      archivePrefix={arXiv},
      primaryClass={cs.AI},
      url={https://arxiv.org/abs/2610.36991},
    }