# How to Use Semantic Vector Search for Code Retrieval in Code-Graph-RAG

> Learn to use semantic vector search for code retrieval with Code-Graph-RAG. Embed queries, search vectors, and resolve code matches efficiently.

- Repository: [Vitali Avagyan/code-graph-rag](https://github.com/vitali87/code-graph-rag)
- Tags: how-to-guide
- Published: 2026-08-13

---

**Code-Graph-RAG enables intent-based code retrieval by embedding natural language queries using UniXcoder, performing nearest-neighbor search against a vector store (Qdrant or Milvus), and resolving matches to full function metadata via Cypher queries.**

The `vitali87/code-graph-rag` repository implements a **semantic vector search** pipeline that retrieves code based on meaning rather than exact keywords. This approach converts both user queries and codebase elements into dense vector embeddings, allowing developers to find functions and classes using natural language descriptions.

## How Semantic Vector Search Works in Code-Graph-RAG

The semantic search pipeline operates through three integrated stages defined in the source code.

### Stage 1: Embedding Natural Language Queries

The process begins in [`codebase_rag/embedder.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/embedder.py), where the `embed_code()` function converts text queries into dense vectors. By default, the system uses the **UniXcoder** model, though any OpenAI-compatible provider can be configured. The function caches embeddings for reuse (lines 80-89), ensuring efficient repeated queries against the same codebase.

### Stage 2: Vector Store Retrieval

The embedded query passes to [`codebase_rag/vector_store.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/vector_store.py), where `search_embeddings()` (lines 90-95) abstracts the underlying vector database. The system supports **Qdrant** by default, with optional **Milvus** support. If a `project` filter is provided, the helper `_filter_by_project()` (lines 23-32) narrows results to specific repository prefixes, ensuring cross-project isolation.

### Stage 3: Resolving Matches to Metadata

Vector store returns contain only node IDs and similarity scores. The system converts these to full metadata through `build_nodes_by_ids_query` in [`codebase_rag/cypher_queries.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/cypher_queries.py). The ingestor—a `QueryProtocol` implementation—executes this Cypher query against the graph database (Memgraph), returning qualified names, types, and attributes. Finally, `semantic_code_search()` in [`codebase_rag/tools/semantic_search.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/tools/semantic_search.py) (lines 30-85) wraps these as `SemanticSearchResult` objects.

## Prerequisites and Dependency Gating

Semantic search requires the **semantic extra** package set. The guard function `has_semantic_dependencies()` in [`codebase_rag/utils/dependencies.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/dependencies.py) checks for `torch`, `transformers`, and a vector-store client at runtime. If dependencies are missing, `semantic_code_search()` logs warning `ex.SEMANTIC_EXTRA` and returns an empty list (lines 36-39) rather than failing.

## Implementation Examples

### Direct API Usage

```python
from codebase_rag.tools.semantic_search import semantic_code_search
from codebase_rag.services import QueryProtocol

results = semantic_code_search(
    ingestor=ingestor,  # QueryProtocol implementation

    query="function that parses JSON",
    top_k=5,
    project="my_python_project"
)

for r in results:
    print(f"{r['qualified_name']} (type: {r['type']}, score: {r['score']})")

```

The function returns a list of dictionaries containing `node_id`, `qualified_name`, `name`, `type`, and `score`.

### Command-Line Interface

```bash

# Start interactive mode

cgr start --repo-path /path/to/repo

# Inside the REPL

> semantic search "read a configuration file"

```

The CLI creates the tool via `create_semantic_search_tool()` (lines 58-86) and forwards queries through the same pipeline.

### SDK Integration

```python
from cgr import embed_code, semantic_search

# Debug embedding generation

embedding = embed_code("def load_config(path): ...")

# Search against running daemon

matches = semantic_search("load configuration file")

```

## Summary

- **Three-stage pipeline**: Query embedding (`embed_code`), vector retrieval (`search_embeddings`), and metadata resolution (`build_nodes_by_ids_query`)
- **Configurable backends**: Supports UniXcoder embeddings with Qdrant or Milvus vector stores
- **Project isolation**: Optional `_filter_by_project` ensures repository-scoped results
- **Dependency gating**: `has_semantic_dependencies()` prevents runtime errors when optional packages are missing
- **Multiple interfaces**: Available via direct Python API, CLI REPL, or high-level SDK

## Frequently Asked Questions

### What embedding model does Code-Graph-RAG use for semantic search?

By default, the system uses the **UniXcoder** model through the `embed_code()` function in [`codebase_rag/embedder.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/embedder.py). The architecture supports OpenAI-compatible providers, allowing you to configure alternative embedding models by adjusting the provider settings in the embedder configuration.

### How does the project filter work in semantic vector search?

When you pass the `project` parameter to `semantic_code_search()`, it propagates through to `_filter_by_project()` in [`codebase_rag/vector_store.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/vector_store.py). This helper applies a prefix filter to node IDs, ensuring the vector store only returns results belonging to the specified repository, which is critical for multi-project deployments.

### Can I use a different vector store backend with Code-Graph-RAG?

Yes. While Qdrant is the default, the `search_embeddings()` interface in [`codebase_rag/vector_store.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/vector_store.py) abstracts the backend implementation. You can configure Milvus by setting the appropriate environment variables or configuration flags, and the generic interface will route calls accordingly.

### What happens if semantic dependencies are not installed?

The system calls `has_semantic_dependencies()` from [`codebase_rag/utils/dependencies.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/utils/dependencies.py) at runtime. If `torch`, `transformers`, or the vector client are missing, `semantic_code_search()` logs warning code `ex.SEMANTIC_EXTRA` and returns an empty list rather than raising an exception, allowing the system to degrade gracefully.