Skip to content

Vector Search

The Vector Search module wraps IVectorIndex<T> as a composable effect, providing similarity search over embedding vectors. The default InMemoryVectorIndex<T> uses brute-force search for development; swap in Supabase pgvector or another backend for production.

Quick Start

[Runtime]
[Uses(typeof(VectorModule<Document>))]
public sealed partial class AppRuntime;
from results in VectorModule<Document>.searchAsync<AppRuntime>(
    queryEmbedding, new VectorSearchOptions(Limit: 10, MinSimilarity: 0.7))
select results.Items;

Generic module

VectorModule<T> is generic — reference it with a concrete type argument in [Uses].

Interface

public interface IVectorIndex<T> where T : class
{
    Task<VectorSearchResult<T>> SearchAsync(
        ReadOnlyMemory<float> queryEmbedding, VectorSearchOptions? options = null);
    Task UpsertAsync(string id, T document, ReadOnlyMemory<float> embedding);
    Task UpsertManyAsync(IReadOnlyList<VectorDocument<T>> items);
    Task RemoveAsync(string id);
    Task ClearAsync();
}

Key Types

Type Description
VectorSearchResult<T> Items (list of hits) + TotalCount
VectorHit<T> Id, Document, Similarity (0–1), optional Embedding
VectorSearchOptions Limit, MinSimilarity, Metric, Filters, IncludeEmbeddings
VectorDocument<T> Id, Document, Embedding — for batch upsert
DistanceMetric Cosine (default), Euclidean, InnerProduct

Implementations

Implementation Use Case
InMemoryVectorIndex<T> Development & tests ([DevelopmentOnly], brute-force, ConcurrentDictionary)
Supabase pgvector Production — services.AddSupabaseVectorIndex<AppRuntime, Document>()

Combine vector search with full-text search:

from textResults in SearchModule<Document>.searchAsync<RT>(
    new SearchOptions(Query: query, Limit: 20))
from vectorResults in VectorModule<Document>.searchAsync<RT>(embedding,
    new VectorSearchOptions(Limit: 20, MinSimilarity: 0.6))
select MergeResults(textResults, vectorResults);