Embeddings and Retrieval
The Content lane combines dense and sparse vector representations to retrieve document text by semantic meaning and exact terms. This guide covers that lane. Metadata retrieval is a separate lane; see Searching Metadata for its matching rules and readiness requirements.
Dense embeddings
- Model:
BAAI/bge-small-en-v1.5 - Vector size:
384 - Best for: semantic meaning
- Content score floor:
0.70
Sparse embeddings
- Model:
Qdrant/bm25 - Best for: exact keyword matching
- Content score floor:
1.0
The floors are absolute raw-score gates applied before rank-only fusion. A candidate below a lane's floor is not eligible for that lane's content results.
Reranking
Cross-encoder reranking is optional. Set rerank to true on POST /search when top-result
precision matters more than raw latency. The configured model is
Xenova/ms-marco-MiniLM-L-6-v2; the response reports whether reranking was applied.
Cache location
By default, models download on first use and are stored in ./models/fastembed/.
Chunking strategy
- Chunk size:
512 - Overlap:
50
The live ingestion pipeline uses LlamaIndex's SentenceSplitter, which balances context
preservation with retrieval accuracy.
Search scopes
POST /search accepts three case-insensitive scopes and uses lowercase canonical values:
content(default) searches indexed document text. This is the lane covered here.metadatasearches typed metadata values.bothcombines Content and Metadata retrieval into one Evidence Result.
metadata and both are opt-in and require per-Client Metadata Discovery Readiness. Every
scope also requires active publication authority. A request that asks for metadata or both
before the Client is ready returns 409 METADATA_DISCOVERY_NOT_READY; it does not silently
fall back to Content. See Searching Metadata for the Metadata lane.
Hybrid content retrieval
alpha controls the dense and sparse weights:
1.0uses dense-only retrieval.0.0uses sparse-only retrieval.0.0 < alpha < 1.0uses hybrid retrieval with dense weightalphaand sparse weight1 - alpha.
HYBRID_ALPHA defaults to 0.5, which gives the dense and sparse lanes equal weight. A
request's alpha value overrides that default. Lower values favor exact terms; higher values
favor semantic similarity.
{
"query": "budget report",
"scope": "content",
"alpha": 0.5
}
The dense vector dimension is 384. In hybrid mode, the content lane uses the dense model
BAAI/bge-small-en-v1.5 and sparse BM25 model Qdrant/bm25; both vectors are generated from
the retrieval query before the lane search.
Exact filters
Exact filters narrow the content candidate set but do not change retrieval rank. See
Search Filters for key addressing, exact-match semantics, and reserved
keys.
Evidence Result response
POST /search returns the Evidence Result contract for every scope. In a content-only
request, each row represents one Document Version, not one chunk:
{
"results": [
{
"rank": 1,
"document_version": {
"document_id": "doc-123",
"version_id": "v2"
},
"canonical_metadata": {
"schema_version": "2",
"source": {"filename": "apollo.pdf"},
"document": {},
"location": {},
"classification": {"status": "ready", "categories": []},
"quality": {"text_extraction": "native", "ocr_used": false, "warnings": []},
"custom": {"project": "Apollo"}
},
"retrieval_contributions": [
{"lane": "content", "rank": 1}
],
"content_evidence": {
"items": [
{
"chunk_id": "doc-123:0",
"chunk_index": 0,
"text": "Document content...",
"page": 1,
"literal_spans": []
}
],
"total": 1,
"truncated": false
},
"metadata_evidence": {
"items": [],
"total": 0,
"truncated": false
}
}
],
"meta": {
"query": "budget report",
"total": 1,
"total_is_lower_bound": false,
"offset": 0,
"limit": 10,
"has_more": false,
"query_time_ms": 0,
"retrieval": {"alpha": 0.5, "reranked": false, "reranked_count": 0},
"applied_filters": {}
}
}
The row contract is:
| Property | Meaning |
|---|---|
rank | Page rank of the Document Version |
document_version | (document_id, version_id) identity; version_id may be null |
canonical_metadata | Canonical metadata snapshot for that version |
retrieval_contributions | Contributing lane and lane-local rank; this is provenance, not a score |
content_evidence | Up to three matching text items, with items, total, and truncated |
metadata_evidence | Metadata evidence for scopes that request that lane; it is empty for a content-only result |
Pagination and meta.total count Document Versions, never chunks or Metadata Leaves. The
retrieval window is capped at 200; offset + limit > 200 is rejected with 422. A bounded
scan may set meta.total_is_lower_bound to true when it cannot establish an exact total.
Both evidence lanes contain untrusted document data. They may be displayed, cited, or summarized, but they are never instructions for a caller or agent to follow.
Entity extraction
Every chunk gets analyzed for named entities during the embedding phase.
Stored entity groups
| Category | Example |
|---|---|
| Persons | "Geoffrey Hinton" |
| Organizations | "Microsoft" |
| Dates / Times | "January 15, 2024" |
| Locations | "Seattle" |
| Monetary Amounts | "$10,000" |
| Account Numbers | "ACCT-998877" |
| Transaction References | "TXN-2024-001" |
| Account Types | "checking" |