Series
11 parts
A 1026-line file produces 26 chunks. Most boundaries fall mid-function, with no awareness of code structure. Here's exactly what gets lost — and why it matters for search quality.
One failure is a chunking problem. The other is a vocabulary gap that better chunking can't fix. Here's what the scores reveal about code RAG's limits.
The function name query score jumps from 0.56 to 0.71. The natural language query goes from rank 3 to rank 1. Here's what changes when each function gets its own chunk.
The error query went from not found to rank 7. Here's why rank 7 still isn't good enough — and what the score reveals about the trade-off between code vocabulary and incident vocabulary.
The error query went from rank 7 to rank 3. The lexical bonus is 0.24 — larger than the 0.20 vector contribution. For this query, lexical search is doing most of the work.
The vocabulary gap query is at rank 3. Five functions have identical lexical scores — vector can't break the tie. Cross-encoder re-ranking sees query and document together and pushes the correct function to rank 1.
Upsert is insert-or-update by ID. It doesn't delete old chunks when a function is refactored. Without a registry, stale vectors accumulate silently until your LLM is reading code that was deleted six months ago.
Three operations that sound similar. They are not. Each has different triggers, different costs, and different consequences if you get them wrong.
Without an alias swap, a full rebuild puts your index in a broken state for its entire duration. Queries return a mix of old and new results that never existed as a coherent snapshot.
Two ways to know your RAG is working: a recall harness you run before you ship, and chunk-level tracing that shows what actually retrieved in production. Neither replaces the other.
HyDE pushed the code-vocabulary queries from 0.77 to 0.84. The incident-vocabulary query got worse: rank 3 → rank 5. The hypothetical went in the wrong direction.