fastrag.retrieval#
Retrieval: turning one query into the documents that answer it.
Retrieval is a first-class, composable layer — not an implementation detail
of prompting or chat. A retriever is fully specified as an object: k and
whatever else it needs are constructor configuration, so it can be passed
around, swapped, and benchmarked without its call sites knowing anything
about it. VectorRetriever is the base case; RerankingRetriever wraps
a vector search to narrow its over-fetch on relevance with a Reranker
such as CohereReranker. BM25Retriever and HybridRetriever add lexical retrieval and
replaceable rank fusion across any SDK retrievers. LanguageAwareRetriever
keeps one translation of each page and prefers the question’s language.
- class fastrag.retrieval.SectionContext(document_id, section_id, content, source_spans, heading_path)[source]#
Bases:
objectOriginal retained section syntax, with document-scoped provenance.
- class fastrag.retrieval.SectionIndex(documents=())[source]#
Bases:
objectKeep source parents outside vector chunks and resolve merged sections.
- Parameters:
documents (Iterable[NormalizedDocument])
- add(document)[source]#
Register a validated parent; conflicting document IDs are rejected.
- Parameters:
document (NormalizedDocument)
- Return type:
None
- class fastrag.retrieval.BM25Retriever(*, store, filter=None)[source]#
Bases:
RetrieverRank query terms with the store’s BM25 implementation.
storeis anyLexicalStore: the same open vector store a siblingVectorRetrieversearches, when the backend supports both, or a separate lexical database when it does not.- Parameters:
store (LexicalStore)
filter (str | None)
- class fastrag.retrieval.HybridRetriever(*, retrievers, fusion=None, candidate_k=40)[source]#
Bases:
RetrieverFetch candidates from each retriever concurrently, then fuse their ranks.
- Parameters:
fusion (RankFusion | None)
candidate_k (int)
- class fastrag.retrieval.LanguageAwareRetriever(*, retriever, detector, candidate_k=40, other_language_weight=0.8)[source]#
Bases:
RetrieverPrefer documents in the question’s language, one translation per page.
Over-fetches
candidate_kdocuments fromretriever, best first, and detects the language of the question and of each document (a document’s ownmetadata["language"]wins over detection). Then:Translations collapse. Documents whose
source_uridiffers only by a leading locale path segment naming one ofdetector.languages(/docs/a,/en/docs/a,/ca/docs/a) are copies of one page, and only one URL’s documents are kept: one written in the question’s language, preferably under its locale, if any was retrieved, else the best-ranked one. The same file served under every locale collapses too.Documents written in another language have their
scorescaled byother_language_weightand the rest are re-sorted, so they yield to documents of similar relevance in the question’s language but still outrank much weaker ones. Documents without a numericscorekeepretriever’s order.
The first
kare returned with theirrankrestated and theirmetadata["language"]set where known, so a prompt can show it. A question whose language is not detected skips step 2.retriever = LanguageAwareRetriever( retriever=RerankingRetriever(retriever=hybrid, reranker=reranker), detector=LinguaLanguageDetector(["en", "es", "ca", "zh"]), )
- Parameters:
retriever (Retriever) – Ranks the candidates. A
RerankingRetrieverreturns comparable scores across languages.detector (LanguageDetector) – Detects the question’s and the documents’ languages.
candidate_k (int) – How many documents to fetch from
retrieverbefore choosingk.other_language_weight (float) – Factor, in
(0, 1], applied to the score of a document written in another language than the question. A negative score is divided by it instead, so it always demotes.
- class fastrag.retrieval.LanguageDetector[source]#
Bases:
ABCNames the language each text is written in.
- languages#
The ISO 639-1 codes
detect()can return. A URL path segment naming one of them is read as a locale (seeLanguageAwareRetriever).
- class fastrag.retrieval.LinguaLanguageDetector(languages, *, minimum_relative_distance=0.0)[source]#
Bases:
LanguageDetectorDetects languages offline with Lingua, choosing among a corpus’s own.
Needs the “language” extra (
lingua-language-detector). Naming only the languages the corpus is written in keeps short questions reliable: a short Catalan question is told apart from Spanish far more often when those are among a handful of candidates rather than 75.detector = LinguaLanguageDetector(["en", "es", "ca", "zh"]) detector.detect(["How can I obtain a credential?"]) # ["en"]
- Parameters:
- class fastrag.retrieval.RerankingRetriever(*, reranker, retriever=None, vector_store=None, embedder=None, candidate_k=None)[source]#
Bases:
RetrieverOver-fetch with a retriever, then narrow on relevance.
Composition, not configuration: a plain
VectorRetrieverover-fetcheskcandidates on cosine similarity, andrerankerthen narrows them totop_kon relevance — a cross-encoder reading query and document together, which similarity search alone cannot do. The returnedscore/rankare the reranker’s own, not the vector search’s — seererank().async with MilvusVectorStore(url=MILVUS_URI) as vector_store: retriever = RerankingRetriever( vector_store=vector_store, embedder=Model2VecEmbedder(model=EMBEDDING_MODEL), reranker=CohereReranker( model="rerank-v3.5", base_url=RERANK_BASE_URL, api_key=api_key ), ) documents = await retriever.retrieve("What is AgrospAI?", k=200, top_k=5)
- Parameters:
vector_store (VectorStore | None) – The collection to over-fetch from. Opened by the caller; this retriever neither opens nor closes it.
embedder (Embedder | None) – Embeds the query text — see
VectorRetriever.retriever (Retriever | None) – Any SDK retriever, including a hybrid retriever. Mutually exclusive with the legacy vector_store/embedder pair.
candidate_k (int | None) – Optional over-fetch count used even when the caller requests only the final k results.
reranker (Reranker) – Scores the over-fetched documents against the query.
- class fastrag.retrieval.Retriever[source]#
Bases:
ABCTurns one query into the documents that answer it, best first.
One method, one required argument. Every other knob —
k, filters, thresholds — is constructor configuration, so a retriever is a fully specified object that can be passed around, swapped, and benchmarked without its call sites knowing anything about it.
- class fastrag.retrieval.VectorRetriever(*, vector_store, embedder)[source]#
Bases:
RetrieverDense similarity search: the base retriever every other one over-fetches from.
Holds its collaborators without owning their lifecycles: the caller opens
vector_store(async with MilvusVectorStore(...) as vector_store:) and this retriever never opens or closes it.embedderis used only for itsembed()method — never run as a pipeline step, never cached, never batched — so a single query embeds as one call.async with MilvusVectorStore(url=MILVUS_URI) as vector_store: retriever = VectorRetriever( vector_store=vector_store, embedder=Model2VecEmbedder(model=EMBEDDING_MODEL), ) documents = await retriever.retrieve("What is AgrospAI?", k=5)
- Parameters:
vector_store (VectorStore) – The collection to search. Opened by the caller.
embedder (Embedder) – Embeds the query text with the same model the collection was indexed with.
Modules
The |
|
Lexical retrieval through the SDK's |
|
Pluggable ranking fusion strategies. |
|
Composable hybrid retrieval with replaceable ranking fusion. |
|
Retrieval that prefers documents in the language of the question. |
|
Reranking: scoring documents against a query. |
|
|
|
Database-independent exact source context for structural retrieval hits. |
|
|