How to Use Voyage Embeddings with code-review-graph for Semantic Search
Set the VOYAGE_API_KEY environment variable and call get_provider(provider="voyage") to initialize a VoyageEmbeddingProvider that generates code-optimized vectors for semantic search.
The code-review-graph repository abstracts embedding generation behind a pluggable EmbeddingProvider hierarchy, allowing you to swap in Voyage AI's code-specific models for high-quality semantic search across your codebase. By configuring a few environment variables, you can leverage Voyage's voyage-code-3 model (or custom variants) to embed code fragments and execute cosine-similarity retrieval against a local SQLite store.
Prerequisites and Configuration
The Voyage provider activates automatically when it detects the required API credentials in your environment.
Required Environment Variables
Export your Voyage AI API key before importing the library:
export VOYAGE_API_KEY="your-voyage-api-key-here"
As implemented in code_review_graph/embeddings.py at lines 972‑1000, the get_provider() factory inspects the environment and instantiates VoyageEmbeddingProvider only when VOYAGE_API_KEY is present.
Optional Configuration Parameters
Fine-tune the provider by setting these variables before initialization:
CRG_VOYAGE_MODEL– Defaults tovoyage-code-3; override to use a different Voyage model.CRG_VOYAGE_BASE_URL– Custom API endpoint (default: Voyage's standard URL).CRG_VOYAGE_OUTPUT_DIMENSION– Reduce vector dimensions for storage efficiency.CRG_VOYAGE_OUTPUT_DTYPE– Specify floating-point precision.CRG_VOYAGE_BATCH_SIZE– Control the number of texts sent per API call.CRG_VOYAGE_MIN_INTERVAL_SEC– Minimum seconds between requests for rate-limit compliance.
The constructor reads these values at lines 62‑84 and stores them for subsequent API interactions.
Initializing the Voyage Embedding Provider
Import the factory function and request the Voyage backend explicitly:
import os
os.environ["VOYAGE_API_KEY"] = "your-key-here"
from code_review_graph.embeddings import get_provider
# Returns VoyageEmbeddingProvider instance
voyage = get_provider(provider="voyage")
assert voyage is not None, "VOYAGE_API_KEY must be set"
If you omit the provider argument, get_provider() auto-selects based on available environment variables, but explicit selection ensures predictable behavior when multiple keys are present.
Generating Embeddings for Code
The provider implements two primary methods for vector generation: embed() for batch processing and embed_query() for single search terms.
Batch Processing with Rate Limiting
Pass a list of code strings to embed() to receive a list of dense vectors:
code_fragments = [
"def calculate_sum(a, b): return a + b",
"class UserManager: def get_user(self, id): ...",
"import pandas as pd; df = pd.read_csv('data.csv')",
]
# Returns list of float vectors
vectors = voyage.embed(code_fragments)
According to the source code at lines 666‑676, the provider enforces a minimum interval between calls using CRG_VOYAGE_MIN_INTERVAL_SEC to respect API rate limits.
API Payload Construction and Retry Logic
For each batch, the provider constructs a JSON payload containing model, input, input_type, output_dimension, and output_dtype, then POSTs to <BASE_URL>/embeddings as shown at lines 777‑815.
If the API returns transient HTTP errors (429 or 5xx) or network issues occur, the retry mechanism at lines 942‑998 attempts the request up to three times with exponential back-off.
Response Validation
Before returning vectors, the provider validates the API response at lines 848‑873. It checks that returned data contains either a full permutation of integer indices or a one-to-one list of embeddings, raising a clear RuntimeError if the response structure is malformed.
Performing Semantic Search
Once embeddings are generated, the semantic search pipeline stores vectors and computes similarity scores.
Vector Storage Schema
The system persists embeddings in a local SQLite database. The schema defined at lines 1040‑1045 creates an embeddings table that maps code node identifiers to their corresponding vectors.
Similarity Retrieval
The search module fetches the query vector via provider.embed_query(query), then computes cosine similarity against stored vectors using the _cosine_similarity function at lines 1060‑1063.
from code_review_graph.search import SemanticSearcher
# Initialize searcher with the Voyage provider
searcher = SemanticSearcher(provider=voyage)
# Search for semantically similar code
query = "function to add two numbers"
results = searcher.search(query, top_k=5)
for node, score in results:
print(f"{score:.4f} | {node.file_path}:{node.line_number} → {node.qualified_name}")
CLI Usage
For command-line workflows, prefix the crg command with the environment variable:
VOYAGE_API_KEY=your-key-here crg search --provider voyage "find all database connection handlers"
The CLI documentation in docs/USAGE.md at line 90 confirms that VOYAGE_API_KEY is mandatory for Voyage support, while CRG_VOYAGE_MODEL remains optional.
Summary
- Authentication: Export
VOYAGE_API_KEYto enable the Voyage provider; optionally configureCRG_VOYAGE_MODELand otherCRG_VOYAGE_*variables. - Instantiation: Call
get_provider(provider="voyage")fromcode_review_graph/embeddings.pyto receive aVoyageEmbeddingProviderinstance. - Embedding: Use
embed()for batches andembed_query()for search terms; the provider handles rate limiting (lines 666‑676) and automatic retries with exponential back-off (lines 942‑998). - Storage: Vectors are stored in SQLite (schema at lines 1040‑1045) and retrieved via cosine similarity (lines 1060‑1063).
- Interfaces: Works with both the Python API (
SemanticSearcher) and the CLI (crg search --provider voyage).
Frequently Asked Questions
What is the default Voyage model used by code-review-graph?
The default model is voyage-code-3, optimized for code understanding tasks. You can override this by setting the CRG_VOYAGE_MODEL environment variable before initializing the provider, as documented in docs/USAGE.md at line 90.
How does the provider handle Voyage API rate limits?
The VoyageEmbeddingProvider enforces a configurable minimum interval between API calls using CRG_VOYAGE_MIN_INTERVAL_SEC (implementation at lines 666‑676). Additionally, it implements retry logic with exponential back-off for HTTP 429 and 5xx errors (lines 942‑998).
Can I use Voyage embeddings with the existing SQLite vector store?
Yes. The semantic search pipeline stores Voyage-generated vectors in the same SQLite embeddings table (schema defined at lines 1040‑1045) used by other providers. The cosine similarity calculation at lines 1060‑1063 is provider-agnostic and works with any embedding dimension supported by Voyage.
What happens if the Voyage API returns malformed data?
The provider validates API responses at lines 848‑873, checking that returned indices and embeddings form a complete one-to-one mapping. If the response structure is invalid or indices are missing, it raises a descriptive RuntimeError rather than returning corrupt vectors.
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 →