How to Set Up Semantic Search with Vector Embeddings in code-review-graph

To set up semantic search with vector embeddings in code-review-graph, configure an embedding provider (local or cloud), run embed_graph_tool to vectorize your code knowledge graph, and query using semantic_search_nodes_tool or the Python semantic_search API.

The code-review-graph repository ships a production-ready semantic search pipeline that transforms your code knowledge graph into searchable vector embeddings. This system uses a pluggable provider architecture to support both offline local models and cloud-based APIs, storing dense vectors in SQLite with optimized cosine-similarity retrieval. Whether you need privacy-preserving local inference or high-performance cloud embeddings, the setup follows a consistent three-step workflow: provider configuration, index building, and semantic querying.

Prerequisites and Installation

Install the package with the optional embeddings extra to include sentence-transformers and vector dependencies:

pip install "code-review-graph[embeddings]"

This installs the base library plus all requirements for local embedding generation. Cloud providers (OpenAI, Google Gemini, MiniMax) require only API key configuration and no additional packages.

Step 1 — Configure an Embedding Provider

The system uses the abstract EmbeddingProvider base class defined in code_review_graph/embeddings.py, with concrete implementations for local and cloud inference. Choose one provider based on your privacy and latency requirements.

Local Provider (Offline, Fast)

The local provider uses sentence-transformers models and runs entirely on your hardware. No API keys or network calls are required.

Optional Windows optimization: To prevent threading deadlocks on Windows, pre-warm the model on the main thread before parallel operations:

from code_review_graph.embeddings import prewarm_local_embeddings

prewarm_local_embeddings()  # Uses CRG_EMBEDDING_MODEL env var or default model

If CRG_EMBEDDING_MODEL is unset, the system defaults to a lightweight multilingual model suitable for code semantics.

OpenAI-Compatible Provider (Cloud)

For higher-quality embeddings or GPU acceleration, configure an OpenAI-compatible endpoint by setting three environment variables:

export CRG_OPENAI_API_KEY=sk-your-key-here
export CRG_OPENAI_BASE_URL=https://api.openai.com/v1
export CRG_OPENAI_MODEL=text-embedding-3-small

This pattern supports OpenAI, Azure OpenAI, and LiteLLM proxy endpoints. The same configuration structure applies to Google Gemini (GOOGLE_API_KEY) and MiniMax (MINIMAX_API_KEY) providers.

Security note: On first use, the library warns that source code will be transmitted to external APIs. Set CRG_ACCEPT_CLOUD_EMBEDDINGS=1 to acknowledge and suppress this warning.

Step 2 — Build the Vector Index

Generate embeddings for every node in your knowledge graph using the CLI tool or Python API. The CLI approach is fastest for initial setup:


# Use default local provider

crg embed_graph_tool

# Or specify a cloud provider explicitly

crg embed_graph_tool --provider openai --model text-embedding-3-small

Under the hood, embed_graph_tool (defined in code_review_graph/main.py) invokes embed_graph → EmbeddingStore.embed_nodes, which performs the following operations:

  1. Serializes nodes using _node_to_text (lines 180–188 in embeddings.py) to convert graph nodes into searchable text representations.
  2. Hashes the serialized text to detect content changes and avoid redundant API calls.
  3. Batches embedding requests via provider.embed(texts) for efficient throughput.
  4. Persists vectors using _encode_vector to store binary-encoded embeddings alongside the content hash and provider identity in the SQLite embeddings table.

The provider name (provider.name) is stored with each vector, ensuring that switching models or providers automatically invalidates stale embeddings and triggers re-processing.

Step 3 — Query the Semantic Index

Search your vectorized codebase using natural language queries:

crg semantic_search_nodes_tool "create user session" --limit 10

The semantic_search_nodes_tool (implemented in code_review_graph/tools/query.py) executes the following logic:

  • Generates a query vector via provider.embed_query.
  • Retrieves all stored vectors for the active provider using SELECT qualified_name, vector FROM embeddings WHERE provider = ?.
  • Computes cosine similarity via _cosine_similarity and ranks results by semantic relevance.
  • Returns the top-N matches with similarity scores.

If no embeddings exist for the configured provider or the vector store is unavailable, the system gracefully degrades to the built-in FTS5 keyword search (graph.search_nodes) without raising errors.

Python API Implementation

For programmatic access or custom pipelines, use the EmbeddingStore and semantic_search functions directly:

from pathlib import Path
from code_review_graph.embeddings import EmbeddingStore, get_provider, semantic_search
from code_review_graph.graph import GraphStore, embed_all_nodes

# 1. Load existing graph database

graph = GraphStore(Path("graph.db"))

# 2. Initialize embedding store with local provider

store = EmbeddingStore(
    db_path=Path("embeddings.db"),
    provider="local",           # Options: "local", "openai", "google", "minimax"

    model="all-MiniLM-L6-v2",   # Optional; overrides env var defaults

)

# 3. Generate embeddings for all nodes (idempotent with hash checking)

embed_all_nodes(graph, store)

# 4. Execute semantic query

results = semantic_search(
    query="authentication token validation",
    graph_store=graph,
    embedding_store=store,
    limit=5,
)

for hit in results:
    print(f"{hit['qualified_name']}: {hit['similarity_score']:.3f}")

The EmbeddingStore class handles vector encoding/decoding, schema management (_EMBEDDINGS_SCHEMA), and similarity computation, while semantic_search orchestrates the query embedding and result ranking.

Summary

  • Install with pip install "code-review-graph[embeddings]" to include local embedding dependencies.
  • Configure your provider via environment variables for cloud APIs or use the zero-config local provider.
  • Index your graph once using crg embed_graph_tool or embed_all_nodes(); the system hashes content to avoid redundant work when re-indexing.
  • Query via CLI (semantic_search_nodes_tool) or Python API (semantic_search), with automatic fallback to FTS5 keyword search if vectors are unavailable.
  • Monitor the embeddings.py file for provider implementations and tools/query.py for search orchestration logic.

Frequently Asked Questions

How do I switch from local embeddings to OpenAI without re-indexing everything?

You must re-index when switching providers. The EmbeddingStore schema includes the provider name in each row (see _EMBEDDINGS_SCHEMA in embeddings.py), and refresh_embeddings checks this field to invalidate stale vectors. Run crg embed_graph_tool --provider openai to generate new embeddings for the new backend.

What happens if I search before building the vector index?

The semantic_search_nodes_tool automatically falls back to FTS5 keyword search via graph.search_nodes if no embeddings exist for the configured provider. This ensures the CLI remains functional during initial setup, though results will use lexical rather than semantic matching until you run embed_graph_tool.

Why am I seeing Windows deadlock errors with local embeddings?

Local embedding generation uses sentence-transformers multi-threading that can deadlock on Windows if the model isn't loaded on the main thread first. Call prewarm_local_embeddings() from code_review_graph/embeddings.py before any parallel operations to load the transformer model into memory safely.

Can I use different embedding models for different parts of the codebase?

No, the current EmbeddingStore implementation assumes a single active provider per database file. The provider parameter in EmbeddingStore.__init__ sets the backend for all operations, and the SQLite schema filters queries by provider name. To use multiple models simultaneously, maintain separate embeddings.db files for each model configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →