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:
- Serializes nodes using
_node_to_text(lines 180–188 inembeddings.py) to convert graph nodes into searchable text representations. - Hashes the serialized text to detect content changes and avoid redundant API calls.
- Batches embedding requests via
provider.embed(texts)for efficient throughput. - Persists vectors using
_encode_vectorto store binary-encoded embeddings alongside the content hash and provider identity in the SQLiteembeddingstable.
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_similarityand 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_toolorembed_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.pyfile for provider implementations andtools/query.pyfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →