Retrieval splits documents into chunks and sends only the top-ranked ones. The rest of the manual stays out of the prompt entirely.
Ranking quality varies by model and method, so measure it on local notes. Keyword ranking below is deterministic and inspectable, which makes it a good baseline.
Chunk size | Benefit | Cost |
|---|---|---|
Too large | Each chunk keeps full context | Few chunks fit, and most tokens are surplus. |
Balanced | One idea per chunk with its heading | Top chunks answer directly with little surplus. |
Too small | Many precise matches | Ideas split across chunks and ranking spreads thin. |
TF-IDF scores a chunk by term frequency times inverse document frequency. Frequent terms in the chunk raise the score, while terms common across chunks lower it.
With 5 chunks, a term in 2 chunks scores ln(5 / 2), about 0.916. A term in 1 chunk scores ln(5 / 1), about 1.609, so rare matching terms dominate.
N = 5 chunks
df(reset) = 2 -> idf = ln(5 / 2) = ln(2.5) = about 0.916
df(synchronizer) = 2 -> idf = ln(5 / 2) = about 0.916
df(metastability) = 1 -> idf = ln(5 / 1) = ln(5) = about 1.609
a chunk matching all three query terms outscores chunks matching oneQuery term | Chunks containing it | df | idf |
|---|---|---|---|
reset | Chunks 2 and 4 | 2 | about 0.916 |
synchronizer | Chunks 2 and 5 | 2 | about 0.916 |
metastability | Chunk 2 only | 1 | about 1.609 |
The program ranks five short hardware notes against a three-term query. Chunk 2 holds every query term, so it must rank first.
import math
import sys
DOCS = [
"Clock gating saves power by stopping the clock when logic is idle.",
"A reset synchronizer chain guards against metastability when reset crosses clock domains.",
"FIFO pointers use gray code so crossings stay safe.",
"Reset tree buffering limits skew across a large block.",
"A deeper synchronizer adds latency but tolerates skew.",
]
QUERY = ["reset", "synchronizer", "metastability"]
def toks(s):
out = []
for w in s.lower().split():
w = w.strip(".,;:!?()")
if w:
out.append(w)
return out
def main():
dt = [toks(d) for d in DOCS]
n = len(DOCS)
scores = []
for t in dt:
s = 0.0
for q in QUERY:
df = sum(1 for u in dt if q in u)
idf = math.log(n / df) if df else 0.0
s += (t.count(q) / len(t)) * idf
scores.append(s)
ranked = sorted(range(n), key=lambda i: scores[i], reverse=True)
bad = 0
if ranked[0] != 1:
bad += 1
if not (scores[1] > scores[3]):
bad += 1
if not (scores[1] > scores[4]):
bad += 1
if not (scores[0] == 0.0 and scores[2] == 0.0):
bad += 1
if len(ranked) != 5:
bad += 1
if bad == 0:
print(f"PASS: doc 1 top over {n} docs with {len(QUERY)} query terms scored")
else:
print(f"FAIL: {bad} checks wrong")
sys.exit(1)
main()Only chunk 2 matches all three terms, and the rare term metastability lifts it furthest. Chunks 1 and 3 match nothing and score exactly zero.
Chunk 2 matches all three terms including the rare metastability. Chunk 4 matches only reset, so its score stays lower.
They hold none of the three query terms, so every term frequency is zero.