Vector Stores API¶
ai4rag talks to vector databases through direct clients selected by a typed configuration object. A config carries the connection details for a single backend, and get_vector_store instantiates the matching store — the backend is chosen entirely from config.provider, so no separate type string is needed. Three backends are supported today:
| Backend | Config | Provider | Store | Hybrid search |
|---|---|---|---|---|
| Milvus (remote server only) | MilvusConfig | "milvus" | MilvusVectorStore | ✅ server-side dense + BM25 |
| Milvus Lite (embedded, local file only) | MilvusLiteConfig | "milvus_lite" | MilvusVectorStore | ✅ embedded dense + BM25 |
| PostgreSQL + pgvector | PGVectorConfig | "pgvector" | PGVectorStore | ✅ dense + full-text |
MilvusConfig and MilvusLiteConfig both construct a MilvusVectorStore, but they are separate, mutually-exclusive config classes rather than two modes of one config:
Why MilvusConfig and MilvusLiteConfig are separate — and why that matters
MilvusConfig.uri is validated to be an http(s):// URL and raises ValueError for anything else (a bare host, a local file path, an empty string). This is a deliberate safety fix: previously, a mistyped or unreachable MILVUS_URI could be silently interpreted as a local file path, creating an unintended local Milvus Lite database instead of failing — dangerous in production, where it could mask a misconfigured deployment. That silent fallback is no longer possible: a bad MILVUS_URI now fails loudly at construction time.
To use the embedded engine, opt in explicitly with MilvusLiteConfig(db_path="./ai4rag.db") (or MilvusLiteConfig() for the default path, DEFAULT_MILVUS_LITE_DB_PATH = "./ai4rag_milvus_lite.db"). MilvusLiteConfig validates the inverse — it rejects http(s):// values in db_path, since those belong in MilvusConfig.
Milvus Lite limitations
Milvus Lite is intended for local development, tests, and small-scale workloads, not production. It computes BM25 statistics segment-locally rather than corpus-wide, so hybrid-search ranking fidelity (and any benchmark/HPO scores measured against it) may not transfer exactly to a production Milvus server; and it serializes writes, so only one process should open a given .db file at a time. For production or large corpora, use a remote Milvus server (MilvusConfig), Zilliz Cloud, or pgvector.
Every config is a frozen dataclass exposing a from_env() classmethod, so connection details (and secrets) can be sourced from environment variables and never embedded in generated artefacts.
Base Vector Store¶
base_vector_store ¶
Classes¶
BaseVectorStore ¶
BaseVectorStore(embedding_model: BaseEmbeddingModel, config: BaseVectorStoreConfig, distance_metric: str, collection_name: str | None = None)
Bases: ABC
Abstract class defining interface for VectorStore in the ai4rag experiment. Single instance defines 1 collection/index that can be used to store or retrieve data.
Parameters:
-
embedding_model(BaseEmbeddingModel) –Model used to embed documents and queries.
-
config(BaseVectorStoreConfig) –Backend-specific connection parameters.
-
distance_metric(str) –Metric used to measure similarity between vectors.
-
collection_name(str | None, default:None) –Existing collection to reuse; must start with the
ai4ragprefix. WhenNone, a new compliant name is generated (see :func:ai4rag.rag.vector_store.utils.resolve_collection_name).
Source code in ai4rag/rag/vector_store/base_vector_store.py
Attributes¶
collection_name property ¶
The resolved collection name — reused when supplied, otherwise generated.
Guaranteed to start with :data:~ai4rag.rag.vector_store.utils.COLLECTION_NAME_PREFIX and to be a valid, length-bounded identifier usable as both a backend collection name and a physical SQL table name.
Methods:¶
search abstractmethod ¶
Search for the chunks relevant to the query. The method used will be simple similarity search.
Parameters:
-
query(str) –Question / query for which the similarity search will be executed.
-
k(int) –Number of chunks to be returned as a result of similarity search
-
**kwargs(Any, default:{}) –Backend-specific search options (e.g. metadata filters or hybrid search parameters). Ignored by backends that do not support them.
Returns:
-
list[AI4RAGChunk]–List of chunks with content and metadata.
Source code in ai4rag/rag/vector_store/base_vector_store.py
add_documents abstractmethod ¶
Add documents to the collection.
Parameters:
-
documents(Sequence[AI4RAGChunk]) –Chunks to add to the collection.
Source code in ai4rag/rag/vector_store/base_vector_store.py
close ¶
Release backend resources held by this store (connections, clients).
A no-op by default. Concrete stores that hold a real connection or client (e.g. :class:~ai4rag.rag.vector_store.pgvector.PGVectorStore, :class:~ai4rag.rag.vector_store.milvus.MilvusVectorStore) override this to release it; callers should call close() (or use the store as a context manager) once they are done searching or indexing, since the store performs no automatic cleanup on garbage collection. Idempotent: safe to call more than once.
Source code in ai4rag/rag/vector_store/base_vector_store.py
Functions:¶
Configuration¶
config ¶
Classes¶
BaseVectorStoreConfig dataclass ¶
Bases: ABC
Base config shared by every vector store backend.
Attributes:
-
provider(str) –Backend discriminator (
"milvus","milvus_lite", or"pgvector") used by :func:ai4rag.rag.vector_store.get_vector_store.get_vector_storeto select the concrete store class.
Methods:¶
MilvusConfig dataclass ¶
MilvusConfig(*, provider: str = 'milvus', uri: str, token: str | None = None, server_cert: str | None = None)
Bases: BaseVectorStoreConfig
Connection parameters for a remote Milvus server.
This config targets a running Milvus (or Zilliz Cloud) instance reached over gRPC. For an embedded, local, zero-server database use :class:MilvusLiteConfig instead — the two are deliberately separate so that a mistyped or unreachable server uri fails loudly rather than silently spinning up a throwaway local database (a dangerous surprise in production).
To enforce that, uri must be an http:// or https:// URL; anything else (a bare host, a file path, an empty string) is rejected at construction. TLS is driven by the scheme: https:// opens a secure gRPC channel, http:// stays plaintext. When a remote endpoint presents a certificate signed by a self-signed or private CA, pass the CA/server certificate as PEM text via server_cert; :class:~ai4rag.rag.vector_store.milvus.MilvusVectorStore materializes it to a temporary file for pymilvus to verify against. Endpoints with publicly trusted certificates need no server_cert.
Parameters:
-
uri(str) –Milvus server endpoint. Must start with
http://(plaintext) orhttps://(TLS), e.g.https://host:19530. -
token(str | None, default:None) –Authentication token (
"user:password").Nonefor unauthenticated. -
server_cert(str | None, default:None) –PEM-encoded server/CA certificate used to verify a TLS connection. Required only for self-signed or private-CA endpoints; leave
Nonewhen the server uses a publicly trusted certificate. -
provider(str, default:"milvus") –Name of the provider used in the system.
Attributes:
-
env_vars(ClassVar[tuple[tuple[str, str], ...]]) –(name, description)pairs for the environment variables consulted by :meth:from_env. Exposed for documentation and notebook generation.
Raises:
-
ValueError–If
uriis not anhttp://orhttps://URL.
Methods:¶
__post_init__ ¶
Reject any uri that is not an explicit Milvus server URL.
Guards against the footgun where an incorrect uri (a typo, a bare hostname, or a stray path) is silently interpreted by MilvusClient as a local Milvus Lite database file, creating a throwaway store instead of connecting to the intended server. Local, embedded use must go through :class:MilvusLiteConfig.
Source code in ai4rag/rag/vector_store/config.py
from_env classmethod ¶
Build config from MILVUS_* environment variables.
Reads MILVUS_URI (required), plus the optional MILVUS_TOKEN and MILVUS_SERVER_CERT. MILVUS_SERVER_CERT holds the PEM certificate text itself, not a filesystem path.
Returns:
-
MilvusConfig–Config populated from the
MILVUS_*environment variables.
Raises:
-
KeyError–If the required
MILVUS_URIvariable is not set. -
ValueError–If
MILVUS_URIis not anhttp:///https://URL.
Source code in ai4rag/rag/vector_store/config.py
MilvusLiteConfig dataclass ¶
Bases: BaseVectorStoreConfig
Connection parameters for an embedded, local Milvus Lite database.
Milvus Lite is the zero-server Milvus engine bundled with pymilvus[milvus-lite]; it stores everything in a single local file and is the recommended lightweight option for local development, tests, and small-scale workloads (prototyping, up to roughly one million vectors) — not production serving. For a remote server use :class:MilvusConfig.
Choosing the embedded engine is explicit: it happens only when this config is used (provider "milvus_lite"), never as a silent fallback from a misconfigured :class:MilvusConfig.
Parameters:
-
db_path(str, default::data:`DEFAULT_MILVUS_LITE_DB_PATH`) –Local filesystem path to the Milvus Lite database file. Created on first use; a relative path resolves against the current working directory.
-
provider(str, default:"milvus_lite") –Name of the provider used in the system.
Attributes:
-
env_vars(ClassVar[tuple[tuple[str, str], ...]]) –(name, description)pairs for the environment variables consulted by :meth:from_env. Exposed for documentation and notebook generation.
Raises:
-
ValueError–If
db_pathis empty/blank, or looks like a server URL (http:///https://).
Methods:¶
__post_init__ ¶
Reject a db_path that is blank or is actually a server URL.
The symmetric guard to :meth:MilvusConfig.__post_init__: a value like https://host:19530 is a server endpoint, not a local database file, and belongs in :class:MilvusConfig. An empty or whitespace-only path is rejected here too, rather than being handed to MilvusClient where it would surface as an opaque, hard-to-trace pymilvus error.
Source code in ai4rag/rag/vector_store/config.py
from_env classmethod ¶
Build config from the MILVUS_LITE_DB_PATH environment variable.
An unset variable falls back to :data:DEFAULT_MILVUS_LITE_DB_PATH.
Returns:
-
MilvusLiteConfig–Config populated from
MILVUS_LITE_DB_PATH(or the default path).
Source code in ai4rag/rag/vector_store/config.py
PGVectorConfig dataclass ¶
PGVectorConfig(*, provider: str = 'pgvector', host: str = 'localhost', port: int = 5432, dbname: str = 'postgres', user: str = 'postgres', password: str | None = None, pool_max_size: int = 10)
Bases: BaseVectorStoreConfig
Connection parameters for a PostgreSQL + pgvector instance.
Parameters:
-
host(str, default:'localhost') –PostgreSQL host address.
-
port(int, default:5432) –PostgreSQL port.
-
dbname(str, default:'postgres') –Database name.
-
user(str, default:'postgres') –Database user.
-
password(str | None, default:None) –Database password.
Nonefor trust/peer auth. -
pool_max_size(int, default:10) –Maximum number of concurrent connections the store's connection pool will open. The pool starts lean and grows lazily on demand, so this is a ceiling, not an eagerly-held count; it should be set to at least the maximum number of concurrent
search()/add_documents()calls the caller will issue against this store, or those calls will queue for a slot and can eventually time out. -
provider(str, default:"pgvector") –Name of the provider used in the system.
Attributes:
-
env_vars(ClassVar[tuple[tuple[str, str], ...]]) –(name, description)pairs for the environment variables consulted by :meth:from_env. Exposed for documentation and notebook generation.
Methods:¶
from_env classmethod ¶
Build config from PGVECTOR_* environment variables.
Reads PGVECTOR_HOST, PGVECTOR_PORT, PGVECTOR_DB, PGVECTOR_USER and PGVECTOR_PASSWORD. Unset variables fall back to the local-PostgreSQL defaults; PGVECTOR_PASSWORD defaults to None for trust/peer authentication.
Returns:
-
PGVectorConfig–Config populated from the
PGVECTOR_*environment variables.
Source code in ai4rag/rag/vector_store/config.py
Functions:¶
get_vector_store_config ¶
Build a vector store config for provider from environment variables.
Companion to :func:ai4rag.rag.vector_store.get_vector_store.get_vector_store: given only a provider discriminator, it selects the matching config class and populates it from that backend's *_ENV variables via from_env. Keeping connection details in the environment means secrets never have to be embedded in generated artefacts (e.g. pattern notebooks).
Parameters:
-
provider(str) –Backend discriminator, one of
"milvus","milvus_lite"or"pgvector".
Returns:
-
BaseVectorStoreConfig–A config instance of the class matching provider, populated from the environment.
Raises:
-
ValueError–If provider names an unsupported backend.
-
KeyError–If a variable required by the selected backend's
from_envis unset (e.g.MILVUS_URIfor Milvus).
Examples:
>>> config = get_vector_store_config("milvus") # reads MILVUS_URI, ...
>>> store = get_vector_store(embedding_model, config, collection_name="ai4rag_docs")
Source code in ai4rag/rag/vector_store/config.py
get_vector_store_env_vars ¶
Return the environment variables consulted by provider's from_env.
Parameters:
-
provider(str) –Backend discriminator, one of
"milvus","milvus_lite"or"pgvector".
Returns:
-
tuple[tuple[str, str], ...]–(name, description)pairs, in the order they should be presented to a user. Descriptions note whether each variable is required or optional.
Raises:
-
ValueError–If provider names an unsupported backend.
Source code in ai4rag/rag/vector_store/config.py
Store Selection¶
get_vector_store ¶
Classes¶
Functions:¶
get_vector_store ¶
get_vector_store(embedding_model: BaseEmbeddingModel, config: BaseVectorStoreConfig, collection_name: str | None = None) -> BaseVectorStore
Get vector store of desired type with chosen settings.
The backend is selected by config.provider, so the vector store type is fully determined by which config class is passed in — no separate type string is required.
Parameters:
-
embedding_model(BaseEmbeddingModel) –Embedding model used for embeddings creation.
-
config(MilvusConfig | MilvusLiteConfig | PGVectorConfig) –Connection config for the chosen backend. :class:
MilvusConfigtargets a remote Milvus server; :class:MilvusLiteConfigselects the embedded, local Milvus Lite engine. -
collection_name(str | None, default:None) –Name of an existing collection to reuse. When omitted, a new name is generated following the ai4rag naming convention (see :func:
ai4rag.rag.vector_store.utils.generate_collection_name).
Returns:
-
BaseVectorStore–Instance of the vector store.
Raises:
-
TypeError–If
configis not the config class matching itsprovider(e.g. aprovider="milvus"config that is not a :class:MilvusConfig). -
ValueError–If
config.providernames an unsupported backend.
Source code in ai4rag/rag/vector_store/get_vector_store.py
Milvus¶
milvus ¶
Classes¶
MilvusVectorStore ¶
MilvusVectorStore(embedding_model: BaseEmbeddingModel, config: MilvusConfig | MilvusLiteConfig, distance_metric: str = 'cosine', collection_name: str | None = None)
Bases: BaseVectorStore
Vector store backed by Milvus via pymilvus (remote server or Milvus Lite).
A single store class serves both deployment styles, selected by the config type: :class:~ai4rag.rag.vector_store.config.MilvusConfig connects to a remote server, while :class:~ai4rag.rag.vector_store.config.MilvusLiteConfig opens the embedded, local Milvus Lite engine. Both support pure vector search and hybrid search (dense + BM25 sparse) with RRF or weighted reranking, using Milvus native server-side fusion.
Parameters:
-
embedding_model(BaseEmbeddingModel) –Model used to embed documents and queries.
-
config(MilvusConfig | MilvusLiteConfig) –Connection parameters. A :class:
MilvusConfigconnects to a remote server (TLS via anhttps://URI;config.server_certsupplies a self-signed CA certificate, materialized to a temporary file and passed toMilvusClientasserver_pem_path). A :class:MilvusLiteConfigopens the embedded engine backed by its localdb_path. -
distance_metric(str, default:'cosine') –Distance metric for vector similarity (default
"cosine"). -
collection_name(str | None, default:None) –Existing collection to reuse; must start with the
ai4ragprefix. When omitted, a new compliant name is generated (see :func:ai4rag.rag.vector_store.utils.resolve_collection_name).
The MilvusClient is built according to the config type: a :class:MilvusLiteConfig opens the embedded engine at its local db_path; a :class:MilvusConfig connects to a remote server and, when config.server_cert is set, materializes its PEM text to a temporary file (see :func:_materialize_server_cert) passed as server_pem_path for TLS verification. The target collection — with its dense, sparse/BM25, and JSON fields — is created only when it does not already exist.
Parameters:
-
embedding_model(BaseEmbeddingModel) –Model used to embed documents and queries.
-
config(MilvusConfig | MilvusLiteConfig) –Connection parameters for a remote Milvus server or the embedded Milvus Lite engine.
-
distance_metric(str, default:"cosine") –Distance metric used for dense vector similarity.
-
collection_name(str | None, default:None) –Existing collection to reuse; must start with the
ai4ragprefix. When omitted, a new compliant name is generated.
Source code in ai4rag/rag/vector_store/milvus.py
Methods:¶
search ¶
search(query: str, k: int = 5, include_scores: bool = False, search_mode: str = 'vector', ranker_strategy: str | None = None, ranker_k: int | None = None, ranker_alpha: float | None = None, **kwargs) -> list[AI4RAGChunk] | list[tuple[AI4RAGChunk, float]]
Search for chunks relevant to query.
Parameters:
-
query(str) –Search query text.
-
k(int, default:5) –Number of results to return.
-
include_scores(bool, default:False) –Whether to include similarity scores in the results.
-
search_mode(str, default:"vector") –"vector"for dense-only search or"hybrid"for dense + BM25 sparse search. -
ranker_strategy(str | None, default:None) –Hybrid ranker:
"rrf","weighted", or"normalized". -
ranker_k(int | None, default:None) –RRF smoothing constant (
k). -
ranker_alpha(float | None, default:None) –Weighted blend factor (
0= keyword,1= vector). -
**kwargs(Any, default:{}) –Accepted for interface compatibility; ignored by this backend.
Returns:
-
list[AI4RAGChunk] | list[tuple[AI4RAGChunk, float]]–Matched chunks, optionally paired with their scores.
Source code in ai4rag/rag/vector_store/milvus.py
add_documents ¶
Embed, deduplicate, and upsert chunks into Milvus.
Duplicate chunk_id values within documents are skipped (first occurrence wins) and logged. Rows are upserted in batches.
Parameters:
-
documents(list[AI4RAGChunk]) –Chunks to be embedded and stored.
-
**kwargs(Any, default:{}) –Optional overrides.
batch_size(int) sets the upsert batch size (default :attr:_BATCH_SIZE).
Source code in ai4rag/rag/vector_store/milvus.py
clean_collection ¶
close ¶
Close the underlying Milvus client connection.
The temporary TLS certificate file (when one was materialized) is intentionally not removed here: pymilvus can reconnect an idle channel from a background thread and re-read server_pem_path after close(), so the file is kept for the process lifetime and cleaned at interpreter exit by :func:_cleanup_server_certs.
Source code in ai4rag/rag/vector_store/milvus.py
Functions:¶
PGVector¶
pgvector ¶
Classes¶
PGVectorStore ¶
PGVectorStore(embedding_model: BaseEmbeddingModel, config: PGVectorConfig, distance_metric: str = 'cosine', collection_name: str | None = None)
Bases: BaseVectorStore
Vector store backed by PostgreSQL with the pgvector extension.
Supports pure vector search and hybrid search (dense vector + tsvector full-text) with RRF or weighted reranking via in-memory fusion.
Driven by asyncpg rather than psycopg: asyncpg speaks the Postgres wire protocol itself instead of wrapping the libpq C library, so it ships as a normal self-contained wheel with no system libpq dependency and none of psycopg[binary]'s bundled-OpenSSL conflicts. Every public method here stays synchronous (matching :class:BaseVectorStore and every other backend) by dispatching onto one dedicated background event loop — see :meth:_run — so callers never need to know asyncpg is involved.
Parameters:
-
embedding_model(BaseEmbeddingModel) –Model used to embed documents and queries.
-
config(PGVectorConfig) –Connection parameters for the PostgreSQL server.
-
distance_metric(str, default:'cosine') –Distance metric (default
"cosine"). One of"cosine","l2","l1","inner_product". -
collection_name(str | None, default:None) –Existing collection to reuse; must start with the
ai4ragprefix. The name is used verbatim as the PostgreSQL table name. When omitted, a new compliant name is generated (see :func:ai4rag.rag.vector_store.utils.resolve_collection_name).
Resolves the distance metric to its pgvector operator and index opclass. The connection pool and backing table are created lazily on the first DB access (see :meth:_ensure_db) so that :meth:add_documents can embed documents — the slow step — before any idle connection is opened. HNSW and GIN indexes are deferred further, to the first search (see :meth:_ensure_indexes), avoiding per-row HNSW maintenance during bulk inserts.
Parameters:
-
embedding_model(BaseEmbeddingModel) –Model used to embed documents and queries.
-
config(PGVectorConfig) –Connection parameters for the PostgreSQL server.
-
distance_metric(str, default:"cosine") –Distance metric. One of
"cosine","l2","l1","inner_product". -
collection_name(str | None, default:None) –Existing collection to reuse; must start with the
ai4ragprefix and is used verbatim as the table name. When omitted, a new compliant name is generated.
Raises:
-
ValueError–If
distance_metricis not one of the supported metrics.
Source code in ai4rag/rag/vector_store/pgvector.py
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | |
Methods:¶
search ¶
search(query: str, k: int, include_scores: bool = False, search_mode: str = 'vector', ranker_strategy: str | None = None, ranker_k: int | None = None, ranker_alpha: float | None = None, **kwargs) -> list[AI4RAGChunk] | list[tuple[AI4RAGChunk, float]]
Search for chunks relevant to query.
Parameters:
-
query(str) –Search query text.
-
k(int) –Number of results to return.
-
include_scores(bool, default:False) –Whether to include similarity scores.
-
search_mode(str, default:"vector") –"vector"for dense-only search or"hybrid"for dense + full-text search. -
ranker_strategy(str | None, default:None) –Hybrid ranker:
"rrf","weighted", or"normalized". -
ranker_k(int | None, default:None) –RRF smoothing constant (
k). -
ranker_alpha(float | None, default:None) –Weighted blend factor (
0= keyword,1= vector). -
**kwargs(Any, default:{}) –Accepted for interface compatibility; ignored by this backend.
Returns:
-
list[AI4RAGChunk] | list[tuple[AI4RAGChunk, float]]–Matched chunks, optionally paired with their scores.
Source code in ai4rag/rag/vector_store/pgvector.py
add_documents ¶
Embed, deduplicate, and upsert chunks into PGVector.
Duplicate chunk_id values within documents are skipped (first occurrence wins) and logged. Rows are upserted in batches, each with a one-shot retry on a dropped connection.
Parameters:
-
documents(list[AI4RAGChunk]) –Chunks to be embedded and stored.
-
**kwargs(Any, default:{}) –Optional overrides.
batch_size(int) sets the insert batch size (default :attr:_BATCH_SIZE).
Source code in ai4rag/rag/vector_store/pgvector.py
clean_collection ¶
close ¶
Close the connection pool and stop the store's background event loop.
Idempotent: a second call sees :attr:_db already None and returns immediately, rather than dispatching onto a loop that has already stopped — which would hang forever waiting for a callback the stopped loop can never run.
Safe to call while another thread is mid-:meth:_run: :attr:_db is cleared up front (under :attr:_inflight) so no new call can start, but the loop and pool are only stopped once every call that already started has finished — see :meth:_run. A call that started before this method clears :attr:_db still completes normally; one that starts after gets a clear RuntimeError instead of racing the teardown.
Source code in ai4rag/rag/vector_store/pgvector.py
Functions:¶
Hybrid Search Reranking¶
Milvus fuses dense and sparse results server-side, while PGVector combines dense similarity with PostgreSQL full-text search in memory using the reranker below.
reranker ¶
Classes¶
WeightedInMemoryAggregator ¶
Combines vector and keyword search scores using reranking strategies.
Methods:¶
weighted_rerank staticmethod ¶
weighted_rerank(vector_scores: dict[str, float], keyword_scores: dict[str, float], alpha: float = 0.5) -> dict[str, float]
Weighted average of normalized vector and keyword scores.
Parameters:
-
vector_scores(dict[str, float]) –Scores from vector search keyed by chunk id.
-
keyword_scores(dict[str, float]) –Scores from keyword search keyed by chunk id.
-
alpha(float, default:0.5) –Blend factor:
0= keyword only,1= vector only.
Returns:
-
dict[str, float]–Combined scores keyed by chunk id.
Source code in ai4rag/rag/vector_store/reranker.py
rrf_rerank staticmethod ¶
rrf_rerank(vector_scores: dict[str, float], keyword_scores: dict[str, float], k: float = 60.0) -> dict[str, float]
Reciprocal Rank Fusion of vector and keyword search results.
Parameters:
-
vector_scores(dict[str, float]) –Scores from vector search keyed by chunk id.
-
keyword_scores(dict[str, float]) –Scores from keyword search keyed by chunk id.
-
k(float, default:60.0) –RRF smoothing constant (default
60.0).
Returns:
-
dict[str, float]–Fused RRF scores keyed by chunk id.
Source code in ai4rag/rag/vector_store/reranker.py
combine_search_results staticmethod ¶
combine_search_results(vector_scores: dict[str, float], keyword_scores: dict[str, float], reranker_type: str = 'rrf', reranker_params: dict[str, Any] | None = None) -> dict[str, float]
Dispatch to the appropriate reranking strategy.
Parameters:
-
vector_scores(dict[str, float]) –Scores from vector search keyed by chunk id.
-
keyword_scores(dict[str, float]) –Scores from keyword search keyed by chunk id.
-
reranker_type(str, default:'rrf') –"rrf","weighted", or"normalized"(falls through to RRF). -
reranker_params(dict[str, Any] | None, default:None) –Strategy-specific params:
{"k": float}for RRF,{"alpha": float}for weighted.
Returns:
-
dict[str, float]–Combined scores keyed by chunk id, produced by the selected strategy.
Source code in ai4rag/rag/vector_store/reranker.py
Collection Naming & Search Utilities¶
Collections follow the ai4rag_<timestamp>_<suffix> convention and are capped at 63 characters. Pass an existing name via collection_name to reuse a collection.
utils ¶
Functions:¶
generate_collection_name ¶
Generate a unique vector store collection name.
Follows the convention <prefix>_<UTC timestamp>_<8 random chars>, e.g. ai4rag_20260728153000_zxcvbnml.
Returns:
-
str–A unique, convention-following collection name.
Source code in ai4rag/rag/vector_store/utils.py
resolve_collection_name ¶
Resolve, validate, and sanitize a vector store collection name.
Single entry point every backend uses to turn the optional caller-supplied collection_name into the concrete name it will create or reuse. It enforces the invariants that keep ai4rag stores safe and portable:
- Auto-generation — when
collection_nameisNonea fresh, convention-following name is generated (see :func:generate_collection_name). - Namespace guard — a caller-supplied name must start with :data:
COLLECTION_NAME_PREFIX. This is the isolation boundary guaranteeing ai4rag only ever touches its own tables/collections; a non-compliant name is rejected rather than silently coerced, so mistakes surface immediately. - Identifier safety — the name is sanitized into a valid identifier (see :func:
sanitize_collection_name) and bounded to :data:_MAX_COLLECTION_NAME_LENGTH, so it is usable verbatim as a backend collection and as a physical SQL table name.
Parameters:
-
collection_name(str | None) –Existing collection name to reuse, or
Noneto generate a new one.
Returns:
-
str–The resolved, sanitized collection name.
Raises:
-
ValueError–If
collection_namedoes not start with :data:COLLECTION_NAME_PREFIX, or if it exceeds :data:_MAX_COLLECTION_NAME_LENGTHcharacters.
Source code in ai4rag/rag/vector_store/utils.py
sanitize_collection_name ¶
Coerce a name into a valid identifier for every supported backend.
Replaces non-alphanumeric characters (except underscores) with underscores, so the result is usable verbatim as both a backend collection name and a physical SQL table name.
Parameters:
-
name(str) –Raw collection name to sanitize.
Returns:
-
str–The sanitized, identifier-safe collection name.
Source code in ai4rag/rag/vector_store/utils.py
validate_search_params ¶
validate_search_params(search_mode: str, ranker_strategy: str | None, ranker_k: int | None, ranker_alpha: float | None) -> None
Validate the search mode and hybrid ranker parameter combination.
Backend-agnostic guard shared by every hybrid-capable vector store (e.g. Milvus, PGVector): it enforces that ranker parameters are only supplied for a hybrid search and that each is paired with its matching strategy, before any backend-specific query is issued.
Parameters:
-
search_mode(str) –How the search should be conducted.
"vector"for dense embedding search only, or"hybrid"for both sparse & dense (hybrid) search. -
ranker_strategy(str | None) –Reranking strategy (function) used with hybrid search. One of
"rrf","weighted", or"normalized". Must be unset for non-hybrid search. -
ranker_k(int | None) –The smoothing constant in Reciprocal Rank Fusion (RRF). Valid only with
ranker_strategy="rrf". -
ranker_alpha(float | None) –Weighting coefficient that determines how much the system trusts semantic (vector) search versus lexical (keyword/BM25) search. Valid only with
ranker_strategy="weighted".
Raises:
-
ValueError–If
search_modeis unknown, if any ranker parameter is supplied for a non-hybrid search, ifranker_strategyis missing or invalid for a hybrid search, or ifranker_k/ranker_alphaare paired with the wrong strategy.