Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Semantic Code Search

Natural language code discovery for fast_code_search, enabling developers to find code using conceptual queries instead of exact keywords.

Quick Start

1. Generate Configuration

cargo run --bin fast_code_search_semantic -- --init

This creates fast_code_search_semantic.toml with default settings.

2. Configure Paths to Index

Edit fast_code_search_semantic.toml:

[indexer]
paths = [
    "/path/to/your/codebase",  # Unix/Linux/Mac
    # "C:\\code\\my-project",  # Windows example
]

# Optional: Enable persistent index
# Unix/Linux/Mac:
index_path = "/var/lib/fast_code_search_semantic/index"
# Windows:
# index_path = "C:\\ProgramData\\fast_code_search_semantic\\index"

3. Start the Server

cargo run --bin fast_code_search_semantic -- --config fast_code_search_semantic.toml

The server starts on:

  • gRPC: port 50052
  • Web UI: http://localhost:8081

4. Search Your Code

Web UI (easiest):

  • Open http://localhost:8081 in your browser
  • Enter natural language queries like “authentication logic” or “database connection”

REST API:

curl "http://localhost:8081/api/search?q=authentication&max=10"

gRPC (using example client):

cargo run --example semantic_grpc_client "authentication logic"

Features

Natural Language Queries

Ask questions in plain English:

  • “authentication and login flow”
  • “error handling patterns”
  • “database connection setup”
  • “API endpoint definitions”
  • “configuration file loading”

Symbol-Aware Chunking

Automatically identifies and indexes:

  • Functions and methods
  • Classes and structs
  • Modules and namespaces

Query Caching

  • LRU cache for query embeddings
  • Near-instant responses for repeated queries
  • 100 query capacity (configurable)

Index Persistence

  • Save index to disk after indexing
  • Load pre-built index on startup
  • No re-indexing needed on restart

Dual API Access

REST API (/api/...):

  • /api/search?q={query}&max={limit} - Search with natural language
  • /api/stats - Get server statistics
  • /api/health - Health check

gRPC (port 50052):

  • Search - Streaming search results
  • GetStats - Server statistics
  • ReloadIndex - Dynamic index reloading

Web Interface

Modern, responsive UI with:

  • Natural language query input
  • Example queries for quick start
  • Syntax-highlighted results
  • Relevance scoring visualization
  • Real-time server statistics

Architecture

Semantic search runs as a completely independent binary:

  • Traditional: fast_code_search_server (exact/regex search)
  • Semantic: fast_code_search_semantic (natural language)

Both share:

  • Symbol extraction (tree-sitter)
  • Infrastructure (logging, config)
  • Code organization patterns

Current Implementation

Embedding Model: TF-IDF-based vector representation (default)

  • Fast and lightweight
  • No external dependencies
  • Works out of the box

ML Embeddings (optional, via --features ml-models):

  • CodeBERT/UniXcoder models via ONNX Runtime
  • Higher quality semantic understanding
  • Requires model download (~500MB)
  • Optional SHA256 verification via FCS_MODEL_SHA256 or FCS_MODEL_SHA256_<MODEL>
  • See “Building with ML Models” section for setup

Vector Index: HNSW (Hierarchical Navigable Small World)

  • Fast approximate nearest neighbor search (O(log n) complexity)
  • Cosine similarity scoring
  • Configurable accuracy/speed tradeoff
  • Optimized for large codebases (10K+ code chunks)

Performance

Current performance (TF-IDF model with HNSW):

  • Query latency: 5-50ms (depending on index size and HNSW parameters)
  • Index loading: ~1-2s for 10,000 chunks
  • Memory overhead: ~3x indexed code size (includes embeddings and HNSW graph)

Configuration Reference

Server Settings

[server]
# gRPC server address
address = "0.0.0.0:50052"

# Web UI server address
web_address = "0.0.0.0:8081"

# Enable/disable Web UI
enable_web_ui = true

Indexer Settings

[indexer]
# Paths to index
paths = [
    "/path/to/code",
]

# Patterns to exclude
exclude_patterns = [
    "**/node_modules/**",
    "**/target/**",
    "**/.git/**",
    "**/dist/**",
]

# Code chunking parameters
chunk_size = 50          # Lines per chunk
chunk_overlap = 5        # Overlap between chunks

# Optional: Persistent index
index_path = "/var/lib/fast_code_search_semantic/index"

# HNSW vector index configuration
[indexer.hnsw]
m = 16                   # Bi-directional links per element (4-64, default: 16)
                         # Higher = better accuracy but more memory
ef_construction = 200    # Construction quality (100-400, default: 200)
                         # Higher = better index quality but slower indexing
ef_search = 100          # Search quality (50-200, default: 100)
                         # Higher = better accuracy but slower search

HNSW Parameter Tuning Guide:

  • For small codebases (<10K chunks): Use defaults (m=16, ef_construction=200, ef_search=100)
  • For large codebases (>100K chunks):
    • Increase m to 24-32 for better accuracy
    • Increase ef_construction to 300-400 for better index quality
    • Tune ef_search at query time: 50 for speed, 200 for accuracy
  • For memory-constrained systems: Reduce m to 8-12
  • For maximum speed: Reduce ef_search to 50-75

Examples

Web UI

Visit http://localhost:8081 and try:

  • “authentication and login”
  • “error handling”
  • “database queries”

REST API

# Search
curl "http://localhost:8081/api/search?q=authentication&max=5" | jq

# Stats
curl "http://localhost:8081/api/stats" | jq

# Health check
curl "http://localhost:8081/api/health"

gRPC Client

# Use the example client
cargo run --example semantic_grpc_client "login logic"

# Or use grpcurl
grpcurl -plaintext -d '{"query":"authentication","max_results":10}' \
  localhost:50052 semantic_search.SemanticCodeSearch/Search

Development

Running Tests

# All semantic search tests
cargo test --lib semantic

# Specific module
cargo test --lib semantic::cache

Building

# Debug build
cargo build --bin fast_code_search_semantic

# Release build
cargo build --release --bin fast_code_search_semantic

Building with ML Models (Optional)

To use ML-based embeddings (CodeBERT/UniXcoder) instead of TF-IDF, build with the ml-models feature:

cargo build --release --bin fast_code_search_semantic --features ml-models

Windows-Specific Setup

On Windows, the ml-models feature requires additional setup due to CRT (C Runtime) linking conflicts between the ort (ONNX Runtime) and tokenizers crates. The solution is to use dynamic loading.

⚠️ Version Compatibility: This project uses ort 2.0.0-rc.10 which requires ONNX Runtime 1.18.x - 1.22.x. Do NOT use ONNX Runtime 1.23+ (incompatible).

  1. Build with the feature (ort uses load-dynamic internally):

    cargo build --release --bin fast_code_search_semantic --features ml-models
    
  2. Download ONNX Runtime 1.22.0 (recommended version):

    • Go to ONNX Runtime v1.22.0 Release
    • Download onnxruntime-win-x64-1.22.0.zip
    • Extract to the project’s onnxruntime/ folder:
      fast_code_search/
      └── onnxruntime/
          └── onnxruntime-win-x64-1.22.0/
              └── lib/
                  └── onnxruntime.dll
      
  3. Run using the launcher script (recommended - sets ORT_DYLIB_PATH automatically):

    # PowerShell (recommended)
    .\scripts\run_semantic_server.ps1
    
    # Or with custom config
    .\scripts\run_semantic_server.ps1 -ConfigFile .\my_config.toml
    
    # Command Prompt alternative
    scripts\run_semantic_server.bat
    
  4. Or set the environment variable manually:

    # PowerShell (per-session)
    $env:ORT_DYLIB_PATH = "C:\path\to\onnxruntime.dll"
    .\target\release\fast_code_search_semantic.exe --config fast_code_search_semantic.toml
    
    # Or permanently via System Settings
    [Environment]::SetEnvironmentVariable("ORT_DYLIB_PATH", "C:\path\to\onnxruntime.dll", "User")
    

Why is this needed? The ort crate links against the dynamic C runtime (/MD), while tokenizers (via esaxx-rs) uses the static runtime (/MT). These are incompatible at link time on Windows. Using load-dynamic avoids static linking entirely by loading onnxruntime.dll at runtime.

Linux/macOS Setup

On Unix systems, the build typically works without additional setup:

cargo build --release --bin fast_code_search_semantic --features ml-models

If you encounter issues, you can still use the dynamic loading approach by setting:

export ORT_DYLIB_PATH=/path/to/libonnxruntime.so  # Linux
export ORT_DYLIB_PATH=/path/to/libonnxruntime.dylib  # macOS

Linting

cargo clippy --bin fast_code_search_semantic
cargo fmt --check

Roadmap

Phase 4 (Complete) ✅

  • Enhanced Web UI with natural language interface
  • Example queries and suggestions
  • Improved result visualization

Phase 5 (Complete) ✅

  • HNSW Vector Index: Fast O(log n) approximate nearest neighbor search
  • Configurable accuracy/speed tradeoff
  • Optimized for large codebases (10K+ chunks)

Future Enhancements

  • ML Embeddings: Available now via --features ml-models (CodeBERT/UniXcoder via ONNX Runtime)
  • GPU Support: Faster embedding generation with CUDA/Metal
  • Multi-language: Support for more programming languages
  • Query expansion: Automatic synonym and context expansion

Troubleshooting

Server doesn’t start

Check if ports are available:

lsof -i :50052  # gRPC
lsof -i :8081   # Web UI

No results found

  1. Check if files are indexed:

    curl http://localhost:8081/api/stats
    
  2. Verify paths in config are correct

  3. Check exclude patterns aren’t too broad

Slow queries

  1. Enable index persistence to avoid re-indexing
  2. Reduce max_results parameter
  3. Consider upgrading to ML embeddings for better accuracy

ML Models won’t build (Windows)

Symptom: Linker errors mentioning RuntimeLibrary mismatch or LIBCMT vs MSVCRT

Solution: This is expected. The ort crate in this project uses load-dynamic to avoid CRT conflicts. Follow the “Windows-Specific Setup” section in Development > Building with ML Models.

ML Models runtime error: “Cannot find ONNX Runtime library”

Solution: Set the ORT_DYLIB_PATH environment variable to point to the ONNX Runtime library:

# Windows
$env:ORT_DYLIB_PATH = "C:\path\to\onnxruntime.dll"

# Linux
export ORT_DYLIB_PATH=/path/to/libonnxruntime.so

# macOS
export ORT_DYLIB_PATH=/path/to/libonnxruntime.dylib

ML Models runtime error: “ort X.X is not compatible with ONNX Runtime binary”

Symptom: Error like expected version >= '1.23.x', but got '1.22.0' or similar version mismatch.

Solution: This project uses ort 2.0.0-rc.10 which requires ONNX Runtime 1.18.x - 1.22.x.

  • If you have ONNX Runtime 1.23+, downgrade to v1.22.0
  • If you have ONNX Runtime older than 1.18, upgrade to v1.22.0

On Windows, use the bundled launcher scripts which point to the correct version:

.\scripts\run_semantic_server.ps1

License

Same as fast_code_search (see main README)