Skip to main content
Semantic search retrieves documents by meaning rather than exact keyword overlap. Documents and queries are converted into dense vector embeddings by the same model, and similarity is measured by cosine distance in the embedding space.

How it works

1

Indexing

Each document’s text is embedded using HuggingFaceEmbeddings (created via EmbedderHelper.create_embedder(config)). The resulting float vector and document metadata are stored in the target backend through the backend’s LangChain integration.
2

Query embedding

At search time, the same embedder model embeds the query string via EmbedderHelper.embed_query(embedder, query).
3

Nearest-neighbor retrieval

The LangChain retriever performs approximate nearest-neighbor search and returns the top-k most similar documents.
4

Optional generation

If rag.enabled: true, retrieved documents are formatted into a prompt using RAGHelper.format_prompt() and passed to a ChatGroq LLM for answer generation.

Pipeline implementation

The semantic search pipeline is implemented as two classes per backend: one for indexing and one for search.

Indexing pipeline

src/vectordb/langchain/semantic_search/indexing/chroma.py

Search pipeline

src/vectordb/langchain/semantic_search/search/chroma.py

Configuration

Embedding helper

The EmbedderHelper provides static methods for creating and using HuggingFace embedding models:
src/vectordb/langchain/utils/embeddings.py

RAG helper

The RAGHelper creates LLMs and formats prompts for answer generation:
src/vectordb/langchain/utils/rag.py

When to use it

  • Natural-language questions where query phrasing differs from document vocabulary
  • General-purpose RAG baseline before specializing with advanced features
  • Any corpus where exact keyword overlap between query and documents is unreliable

When not to use it

  • Strict compliance or legal workflows where exact terms must appear verbatim
  • Very small corpora where BM25 already saturates quality
  • Keyword-heavy technical workloads where semantic generalization is unhelpful

Tradeoffs

Settings to tune first

embeddings.model
string
The primary quality lever; the model determines how semantically meaningful similarity scores are.Common choices:
  • sentence-transformers/all-MiniLM-L6-v2: Fast, 384-dimensional
  • sentence-transformers/all-mpnet-base-v2: Higher quality, 768-dimensional
  • BAAI/bge-small-en-v1.5: Strong retrieval performance
search.top_k
integer
default:"10"
Controls the number of returned candidates; too small misses evidence, too large increases downstream cost.
dataloader.limit
integer
Corpus size for experiments; start small to validate pipeline, then scale up.

Common pitfalls

Mismatched embedding models: Using a different model for indexing and querying produces meaningless similarity scores.
Oversized chunks: Large text chunks blur the embedding signal. Shorter, focused chunks typically produce better retrieval.
Too small top_k: If relevant evidence is rarely in the top 3 results, increase top_k and apply reranking rather than only tuning the embedding model.

Backends supported

Chroma, Milvus, Pinecone, Qdrant, Weaviate.

Next steps

Add reranking

Add two-stage retrieval for better final-result precision

Hybrid search

Switch to hybrid indexing if queries mix natural language with domain keywords

Metadata filtering

Add metadata filtering if the corpus has reliable structured attributes

Components

Explore reusable components for query enhancement and compression