Technical field guide

Index-time decisions are expensive to change; query-time decisions are expensive to run

Index time turns source content into retrieval units, representations, and an index, and changing any of it means reprocessing documents or rebuilding part of that index. Query time retrieves candidates and reranks them, and those settings land directly on latency, cost, recall, and precision. A control loop closes the stack: change one lever, measure it against labeled queries from your own corpus, then keep or roll back.

This guide explains what each control measures, gives an implementation range or model example, and shows the downstream trade-off. The builder then translates your choices into JSON or Markdown that tells a developer or AI what to implement and what must be calibrated first.

Learn first. Configure second.

Build a measurable vector search stack

Choose one decision at each stage. Every option names the real control, its unit, a starting value, and the consequence. The generated contract gives an AI or developer explicit decisions, compatibility checks, and calibration guardrails.

Ranges are starting points, not universal targets. Validate every choice on labeled queries from your own corpus.

System lifecycle

Three parts of the system behind a search

Ingest & Index builds searchable data. Retrieve & Rank runs for each request. Evaluate & Improve measures both phases and tunes the next version. Select a card to see its decisions, terms, and output.

Starting profiles

Choose the miss you can least afford

Directional effect

How the current choices push each trade-off

Qualitative, not measured
RecallNear baselineHow often relevant items enter the candidate set.
PrecisionNear baselineHow much of the returned set is relevant.
CostNear baselineEmbedding, storage, model, and compute load.
LatencyNear baselineQuery time, including retrieval and reranking.
1SegmentWhat is the smallest useful retrieval unit?Structure-aware · Medium · 400–800 tokens · Light · 10%

Chunking is a deterministic split, a structure-aware split, or a model-assisted semantic split. Size and overlap are separate numeric controls.

Boundary method

Choose how the system decides where one chunk ends and the next begins.

Selected valueheading > paragraph > sentence > tokenboundary priority
What it means
Keep sections, paragraphs, lists, tables, or code blocks intact until the hard token limit forces a split.
Use it when
Documents have useful headings or layout. This is the default for most knowledge bases.
Trade-off
Requires better parsing and produces variable-size chunks.
Target chunk size

The number is tokenizer tokens, not words or characters. The hard maximum must stay below the embedding model input limit.

Selected value400-800tokens per chunk
What it means
A practical baseline that usually preserves a short section while remaining focused.
Use it when
General RAG over articles, policies, notes, or product documentation.
Trade-off
May still split long procedures or mix two small topics.
Chunk overlap

Measure overlap as both a percentage and token count. Do not use overlap to repair poor boundaries.

Selected value10% or 40-80 tokens for a medium chunk% plus derived tokens
What it means
Repeat a small boundary window. Calculate tokens from the selected target chunk size.
Use it when
Fixed-size or forced splits may divide a sentence, table explanation, or procedure.
Trade-off
Adds about 10% more embedded text and can create duplicate hits.
2RepresentWhat signal should represent each chunk?Hosted small · OpenAI 3-small · Hybrid dense + sparse

An embedding model sets vector dimensions, input limit, language coverage, hosting boundary, and the similarity behavior that every downstream index must match.

Embedding model profile

These are representative types and current examples. Benchmark the exact model on your domain before adopting it.

Selected valuetext-embedding-3-small · 1,536 dimensions · 8,192-token inputmodel, vector dimensions, max input tokens
What it means
A hosted dense model optimized for lower cost and throughput. The dimensions parameter can shorten stored vectors.
Use it when
You want a simple managed baseline and can send text to a hosted API.
Trade-off
External processing boundary and lower benchmark quality than the larger profile.
Retrieval signal

Dense, sparse, and multi-vector representations solve different matching problems.

Selected valuedense top-k + BM25 k1=1.2/b=0.75 → RRF k=60parallel retrieval legs
What it means
Search a dense vector index and a tokenized BM25 inverted index, then combine ranks with 1/(60 + rank).
Use it when
The corpus contains names, SKUs, error codes, dates, or domain terms alongside natural-language questions.
Trade-off
Two indexes and a fusion step add operational and query cost.
3IndexHow much recall can the nearest-neighbor index trade for speed?HNSW balanced · 16 links / build effort 64 · Balanced · search effort 100

Exact search compares every eligible vector and provides the recall baseline. HNSW means Hierarchical Navigable Small World. It stores vectors in a layered graph so a query can follow promising links instead of scanning every vector. The m setting controls stored links per node, ef_construction controls index-build effort, and ef_search controls work for each query.

Index build profile

HNSW examples use pgvector's documented defaults as a baseline. Other engines expose similar controls with different limits.

Selected valuem=16, ef_construction=64neighbors per layer, build candidate list
What it means
pgvector's documented defaults. m shapes graph connectivity and memory; ef_construction shapes build effort and index recall.
Use it when
You need a strong general ANN baseline before tuning.
Trade-off
Approximate results can miss exact neighbors and require recall measurement against flat search.
HNSW query-time effort

ef_search is the dynamic candidate list used for each query. It changes query recall and latency without rebuilding the index.

Selected value100HNSW search candidates
What it means
A moderate search expansion to test against the default.
Use it when
You want a higher-recall query baseline without rebuilding the index.
Trade-off
More distance calculations increase query latency.
4RetrieveHow wide should the candidate net be before ranking?Medium · 50 per leg · Calibrate on labeled queries

Candidate count controls the ceiling for reranking. Filters and thresholds can remove results before the expensive stage, but each can also remove the only relevant item.

Candidates per retrieval leg

For hybrid search, this count applies to each dense and sparse leg before fusion.

Selected value50candidates per leg
What it means
A practical two-stage retrieval baseline for medium corpora.
Use it when
You use hybrid fusion or a reranker and need room for reordering.
Trade-off
Adds fusion and reranker work compared with a narrow pool.
Similarity threshold policy

A raw cosine or distance score is not a portable probability. Calibrate thresholds separately for each model, corpus, and query type.

Selected valuechosen from a precision-recall curvemodel-specific similarity or distance score
What it means
Sweep candidate thresholds on judged queries and choose the point that satisfies the product's miss-versus-noise cost.
Use it when
The product needs a no-answer state or must block weak matches.
Trade-off
Requires maintained labels and recalibration after model, corpus, or chunking changes.
5RankHow much extra work should refine the candidate order?Fast cross-encoder · Rerank 4 Fast · 10 results

Fusion combines retrieval lists. Reranking uses query-document interaction to improve order after retrieval, so it mainly improves precision within the candidate set.

Second-stage ranker

Apply expensive rankers only to the retrieved candidate pool, not the full corpus.

Selected valuecohere rerank-v4.0-fastquery-document scoring model
What it means
Scores the query together with each candidate document and returns a new relevance order.
Use it when
You need better precision with lower latency and higher throughput than a quality-first reranker.
Trade-off
Adds an external model call and cost proportional to candidate text.
Final results kept

This is the result count after reranking and before context packing or display.

Selected value10final chunks
What it means
A balanced evidence set for RAG and search-result pages.
Use it when
Answers may need several sources or corroborating passages.
Trade-off
Consumes more context and requires deduplication or diversity checks.
6EvaluateWhich failure should the system optimize first?Grounded Q&A

A labeled query set turns every upstream choice into a measurable comparison. Choose the primary metric before tuning the stack.

Primary evaluation objective

Targets below are starting gates. Establish the current baseline, then set a product-specific improvement and latency budget.

Selected valueRecall@20 ≥ 0.90 · nDCG@10 ≥ 0.75 · citation coverage ≥ 0.95illustrative acceptance gate
What it means
Recall checks whether supporting evidence entered the pool; nDCG rewards correct order; citation coverage checks whether claims point to retrieved evidence.
Use it when
An LLM answers from retrieved context and must cite or ground its claims.
Trade-off
Requires both passage relevance labels and answer-level review.

Decision output

Copy the decision contract

An AI can implement resolved choices and stop on fields marked for calibration or correction.

Implementation statusrequires calibration2 fields must be measured or supplied.
Resolve before implementation
  • Replace CALIBRATE with a threshold measured on labeled queries. Similarity scores are model, metric, and corpus specific.
  • Replace REQUIRED_LABELED_QUERY_SET with the versioned evaluation dataset used to approve this configuration.

{
  "schema_version": "rosslabs.vector-search-decision.v2",
  "profile_name": "balanced-rag",
  "implementation_status": "requires_calibration",
  "unresolved_fields": [
    {
      "path": "query.retrieval.similarity_threshold",
      "placeholder": "CALIBRATE",
      "resolution": "Sweep scores on labeled queries and choose the threshold that meets the product precision-recall target."
    },
    {
      "path": "evaluation.dataset_id",
      "placeholder": "REQUIRED_LABELED_QUERY_SET",
      "resolution": "Create and version a representative query-to-relevant-result dataset before approving the stack."
    }
  ],
  "assumptions": [
    "Numeric values are explicit starting points, not measured predictions.",
    "Chunk size uses the embedding model tokenizer, not words or characters.",
    "All quality targets require a labeled query and relevance set from the target corpus."
  ],
  "indexing": {
    "segmentation": {
      "strategy": "structure_aware",
      "boundary_order": [
        "heading",
        "paragraph",
        "sentence",
        "token"
      ],
      "target_tokens": 600,
      "range_tokens": [
        400,
        800
      ],
      "overlap_percent": 10,
      "overlap_tokens": 60
    },
    "representation": {
      "provider": "openai",
      "model": "text-embedding-3-small",
      "dimensions": 1536,
      "max_input_tokens": 8192,
      "hosting": "managed",
      "distance_metric": "cosine",
      "normalize_vectors": true,
      "signals": [
        "dense",
        "sparse"
      ]
    },
    "nearest_neighbor_index": {
      "engine": "pgvector",
      "algorithm": "hnsw",
      "approximate": true,
      "storage_type": "vector",
      "distance_metric": "cosine",
      "query_operator": "<=>",
      "standard_vector_max_dimensions": 2000,
      "m": 16,
      "ef_construction": 64,
      "ef_search": 100
    }
  },
  "query": {
    "retrieval": {
      "candidate_k_per_leg": 50,
      "similarity_threshold": "CALIBRATE",
      "calibration_metric": "precision_recall_curve",
      "recalibrate_on_model_change": true,
      "sparse_retriever": {
        "engine": "lucene_compatible",
        "method": "bm25",
        "index": "inverted",
        "analyzer": "language_specific_with_keyword_subfields",
        "k1": 1.2,
        "b": 0.75,
        "parameter_status": "starting_heuristic",
        "candidate_k_source": "query.retrieval.candidate_k_per_leg"
      },
      "fusion": {
        "method": "rrf",
        "rrf_k": 60,
        "dense_weight": 1,
        "sparse_weight": 1,
        "parameter_status": "starting_heuristic",
        "tune_on_labeled_queries": true
      }
    },
    "reranking": {
      "provider": "cohere",
      "model": "rerank-v4.0-fast",
      "method": "cross_encoder",
      "final_k": 10
    }
  },
  "evaluation": {
    "dataset_id": "REQUIRED_LABELED_QUERY_SET",
    "primary_metrics": [
      "recall@20",
      "ndcg@10"
    ],
    "example_targets": {
      "recall@20": 0.9,
      "ndcg@10": 0.75,
      "citation_coverage": 0.95
    },
    "guardrail_metrics": [
      "citation_coverage",
      "p95_retrieval_latency_ms",
      "cost_per_query"
    ],
    "target_policy": "Replace examples after measuring the baseline"
  },
  "warnings": [
    "Replace CALIBRATE with a threshold measured on labeled queries. Similarity scores are model, metric, and corpus specific.",
    "Replace REQUIRED_LABELED_QUERY_SET with the versioned evaluation dataset used to approve this configuration."
  ],
  "sources": [
    "https://developers.openai.com/api/docs/guides/embeddings",
    "https://help.openai.com/en/articles/6824809-embeddings-faq",
    "https://github.com/pgvector/pgvector#hnsw",
    "https://huggingface.co/BAAI/bge-m3",
    "https://docs.cohere.com/v2/docs/rerank",
    "https://docs.unstructured.io/concepts/chunking",
    "https://qdrant.tech/documentation/advanced-tutorials/reranking-hybrid-search/"
  ]
}
Primary sources and claim boundaries

Product names and documented defaults were checked on 2026-08-10. Heuristic ranges are labeled as starting points.