# How to Configure Custom Embedding Providers and Models in code-review-graph

> Learn how to configure custom embedding providers and models in code-review-graph. Easily switch between local and cloud-based models like OpenAI and Google for your vector embeddings.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: how-to-guide
- Published: 2026-08-07

---

**The `code-review-graph` library abstracts vector embeddings behind the `EmbeddingProvider` interface, allowing you to switch between local Sentence-Transformers models and cloud providers like OpenAI, Google, MiniMax, or Voyage via environment variables or explicit arguments to `get_provider()`.**

The `code-review-graph` repository provides a flexible embedding backend system that supports both offline local inference and cloud-based API providers. To configure custom embedding providers and models in code-review-graph, you interact with the factory function `get_provider()` defined in [`code_review_graph/embeddings.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/embeddings.py) and the `EmbeddingStore` class that handles persistence. This architecture lets you optimize for latency, cost, or accuracy by swapping the underlying embedding model without changing your graph analysis code.

## Supported Embedding Providers

The system implements five concrete providers behind the abstract `EmbeddingProvider` interface (defined at lines 47-66 in [`embeddings.py`](https://github.com/tirth8205/code-review-graph/blob/main/embeddings.py)). Each provider class handles authentication, model selection, and dimensionality differently.

### Local Sentence-Transformers

The **`LocalEmbeddingProvider`** requires no API keys and runs entirely offline. By default, it loads `all-MiniLM-L6-v2` (defined as `LOCAL_DEFAULT_MODEL` at lines 78-85), but you can override this via the `CRG_EMBEDDING_MODEL` environment variable or the `model` constructor argument. The provider name follows the format `local:<model>` for database partitioning.

### OpenAI-Compatible APIs

The **`OpenAIEmbeddingProvider`** supports any OpenAI-compatible endpoint, including local LLM servers. It requires `CRG_OPENAI_API_KEY` and `CRG_OPENAI_BASE_URL` environment variables. The model defaults to the value of `CRG_OPENAI_MODEL` but can be overridden via the `model` parameter in `get_provider()`. Dimensions default to 1536 unless specified via `CRG_OPENAI_DIMENSION`. The provider name format is `openai:<model>@<host_key>` (lines 20-27).

### Google Gemini

The **`GoogleEmbeddingProvider`** requires a `GOOGLE_API_KEY` environment variable. While it defaults to `gemini-embedding-001`, you can specify alternative Gemini models via the `model` argument when calling `get_provider()`. The naming convention follows `google:<model>` (lines 70-71).

### MiniMax

The **`MiniMaxEmbeddingProvider`** requires `MINIMAX_API_KEY` and uses a fixed model `embo-01` with 1536 dimensions. Unlike other providers, MiniMax does not support custom model selection. The provider identifier follows `minimax:<model>` (lines 74-76).

### Voyage AI

The **`VoyageEmbeddingProvider`** offers fine-grained control via multiple environment variables: `VOYAGE_API_KEY` (required), `CRG_VOYAGE_MODEL` (defaults to `voyage-code-3`), `CRG_VOYAGE_OUTPUT_DIMENSION` (defaults to 1024), `CRG_VOYAGE_OUTPUT_DTYPE`, and rate-limiting controls `CRG_VOYAGE_BATCH_SIZE` and `CRG_VOYAGE_MIN_INTERVAL_SEC`. The provider name includes dimension and dtype metadata: `voyage:<model>:dim<dim>:<dtype>@<host_key>` (lines 20-23).

## Provider Selection Logic

The **`get_provider()`** factory function (lines 72-99 in [`embeddings.py`](https://github.com/tirth8205/code-review-graph/blob/main/embeddings.py)) determines which backend to instantiate using the following priority order:

1. **Explicit request** – When you pass `provider="openai"` (or any valid provider key) and optionally `model="text-embedding-3-large"` to `get_provider()`, the factory returns that specific implementation.

2. **Implicit OpenAI default** – If `CRG_OPENAI_API_KEY` and `CRG_OPENAI_BASE_URL` are present in the environment and no `provider` argument is supplied, the function automatically selects the OpenAI provider (lines 11-15).

3. **Fallback to local** – When no cloud credentials are detected, `get_provider()` returns a `LocalEmbeddingProvider` instance.

4. **Validation** – Unknown provider names raise `ValueError` against the `_VALID_PROVIDERS` list (lines 69-70).

## Configuring Custom Models

Each provider supports different mechanisms for model customization:

- **Local**: Set `CRG_EMBEDDING_MODEL` to any HuggingFace model name (e.g., `sentence-transformers/all-MiniLM-L12-v2`) or pass `model` directly to `LocalEmbeddingProvider`.

- **OpenAI**: Override via `CRG_OPENAI_MODEL` environment variable or the `model` parameter in `get_provider()`. Force specific dimensions with `CRG_OPENAI_DIMENSION`.

- **Google**: Pass the `model` argument to `GoogleEmbeddingProvider` to override the default Gemini model.

- **Voyage**: Use `CRG_VOYAGE_MODEL` to change from the default `voyage-code-3`, and `CRG_VOYAGE_OUTPUT_DIMENSION` to adjust vector size.

All cloud providers issue a **one-time stderr warning** before making API calls unless the base URL points to localhost or you set `CRG_ACCEPT_CLOUD_EMBEDDINGS=1` (see `_warn_cloud_egress` at lines 43-52).

## Database Partitioning and Storage

The `EmbeddingStore` class uses the provider's `name` property as a partition key in the SQLite `embeddings` table (`provider` column, lines 44-45). This ensures that changing the provider or model creates a new namespace, preventing dimension mismatches. For example, switching from `local:all-MiniLM-L6-v2` to `openai:text-embedding-3-large@default` creates separate storage partitions automatically.

## Complete Configuration Examples

### Using an Explicit Provider in EmbeddingStore

```python
from code_review_graph.embeddings import EmbeddingStore

# Use OpenAI embeddings with a custom model

store = EmbeddingStore(
    db_path="my_graph.db",
    provider="openai",
    model="text-embedding-3-large",
)

# store.embed_nodes([...]) now calls OpenAI with the specified model

```

### Switching to a Local Sentence-Transformers Model

```python
import os
os.environ["CRG_EMBEDDING_MODEL"] = "sentence-transformers/all-MiniLM-L12-v2"

from code_review_graph.embeddings import EmbeddingStore

# No provider argument defaults to local with the custom model

store = EmbeddingStore(db_path="local.db")

```

### Configuring MiniMax

```bash
export MINIMAX_API_KEY="my-minimax-key"

```

```python
from code_review_graph.embeddings import EmbeddingStore

# MiniMax uses fixed model embo-01; no model argument needed

store = EmbeddingStore(db_path="mm.db", provider="minimax")

```

### Custom Google Gemini Model

```python
import os
os.environ["GOOGLE_API_KEY"] = "my-google-key"

from code_review_graph.embeddings import EmbeddingStore

store = EmbeddingStore(
    db_path="gcloud.db",
    provider="google",
    model="gemini-embedding-002"
)

```

### Direct Provider Access for Ad-Hoc Embedding

```python
from code_review_graph.embeddings import get_provider

provider = get_provider(provider="voyage", model="voyage-code-2")
vectors = provider.embed(["def foo(): pass", "class Bar: ..."])

```

## Summary

- The **`EmbeddingProvider`** interface in [`code_review_graph/embeddings.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/embeddings.py) abstracts all embedding backends behind a unified API.
- Use **`get_provider()`** to instantiate providers explicitly, or rely on environment variable auto-detection for OpenAI and local fallbacks.
- Configure models via provider-specific environment variables (`CRG_EMBEDDING_MODEL`, `CRG_OPENAI_MODEL`, `CRG_VOYAGE_MODEL`) or constructor arguments.
- Each provider generates a unique namespace string (e.g., `openai:text-embedding-3-large@default`) that partitions the SQLite database to prevent vector dimension conflicts.
- Cloud providers require explicit opt-in via `CRG_ACCEPT_CLOUD_EMBEDDINGS=1` to suppress security warnings about data egress.

## Frequently Asked Questions

### How do I switch from local embeddings to OpenAI without modifying code?

Set the environment variables `CRG_OPENAI_API_KEY` and `CRG_OPENAI_BASE_URL` before running your script. When `get_provider()` detects these variables and receives no explicit `provider` argument, it automatically selects the OpenAI provider instead of the local default.

### Can I use a custom HuggingFace model for local embeddings?

Yes. Either set `CRG_EMBEDDING_MODEL` to the HuggingFace model identifier (e.g., `BAAI/bge-large-en-v1.5`) or pass `model="BAAI/bge-large-en-v1.5"` directly to `LocalEmbeddingProvider`. The model will be downloaded on first use and cached locally.

### What happens if I change the embedding model after creating a database?

The system creates a new storage partition automatically. The `EmbeddingStore` uses the provider's `name` property (which includes the model identifier) as the `provider` column value in the SQLite table. Existing embeddings remain under the old namespace; new embeddings use the new namespace. You may need to re-embed existing nodes to maintain search consistency.

### How do I suppress the cloud embedding warning?

Set the environment variable `CRG_ACCEPT_CLOUD_EMBEDDINGS=1`. Alternatively, if your `CRG_OPENAI_BASE_URL` points to localhost (e.g., `http://localhost:11434/v1`), the warning is automatically suppressed because the data remains on-premise.