@@ -297,7 +297,8 @@ Both are sent to Qdrant in a single call, which runs each retriever independentl
297297from each, and produces two separate ranked lists.
298298
299299Qdrant then uses ** Reciprocal Rank Fusion (RRF)** to merge those two ranked lists into one before returning the
300- final top K results. For example, using the query _ "find the method that retries failed payments"_ merge looks like this:
300+ final top K results. For example, using the query _ "find the method that retries failed payments"_ merge looks like
301+ this:
301302
3023031 . Dense retriever returns its ranked list:
303304 ` [retryWithBackoff (rank 1), processPayment (rank 2), PlaceOrderRequest (rank 3), ...] `
@@ -316,22 +317,22 @@ RRF rewards consistent rank across retrievers. The score it produces answers a s
316317"how consistently did this result appear near the top across both dense and sparse retrievers?"
317318---
318319
319- ## Section 7 — Takeaways
320+ ## Conclusion
320321
321- - Symbol-level chunking + rich, language-aware embedding inputs are the foundation
322- - Hybrid dense+sparse with RRF gives you both "intent" and "exact name" search for free, server-side
323- - The payload is half the system — invest in it
324- - Incremental indexing via blob SHAs is what makes this affordable at repo scale
322+ Building a RAG system for code has its own challenges, is not just RAG with a different file types —
323+ it requires rethinking every layer of the pipeline, from how you chunk (by symbol, not paragraph)
324+ to how you embed (rich context for dense vectors, exact tokens for sparse vectors) to how you store
325+ (named vectors with a payload that carries as much signal as the vectors themselves). Hybrid
326+ dense+sparse retrieval with server-side RRF bridges the gap between intent-based queries and exact identifier lookups,
327+ giving you both in a single round-trip. The payload is half the system: without language, service, and type fields
328+ indexed as filters, every search scans the entire collection regardless of how good the vectors are. And without
329+ incremental indexing via blob SHAs, the embedding cost alone would make continuous reindexing impractical at any serious
330+ repository scale. Together these choices form a pipeline that stays accurate, stays fast, and stays affordable as the
331+ codebase grows.
325332
326333---
327334
328- ## Appendix — Suggested diagrams
329-
330- 1 . Pipeline overview: file → Tree-sitter → ` CodeSymbol ` → dense input + sparse input → Qdrant
331- 2 . Qdrant point anatomy: two named vectors + payload fields, annotated
332- 3 . Query-time RRF: query → two encoders → two ranked lists → fused result
333-
334335## Reference
335336
336- https://qdrant.tech/articles/sparse-vectors/
337- https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion
337+ [ Sparse Vectors ] ( https://qdrant.tech/articles/sparse-vectors/ )
338+ [ Reciprocal Rank Fusion (RRF) ] ( https://www.elastic.co/docs/reference/elasticsearch/rest-apis/reciprocal-rank-fusion )
0 commit comments