From 1a5a9297a8523c3ea6253ea952bfb30f89adf13c Mon Sep 17 00:00:00 2001 From: Laurianti Date: Fri, 9 Oct 2026 23:29:30 +0200 Subject: [PATCH 1/2] Add C# documentation for the Chroma vector store connector --- .../chroma-connector.md | 221 +++++++++++++++++- .../out-of-the-box-connectors/index.md | 2 +- 2 files changed, 219 insertions(+), 4 deletions(-) diff --git a/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md b/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md index a8ae0cdc..38ada7f7 100644 --- a/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md +++ b/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md @@ -5,20 +5,235 @@ zone_pivot_groups: programming-languages author: eavanvalkenburg ms.topic: article ms.author: edvan -ms.date: 02/26/2025 +ms.date: 10/09/2026 ms.service: semantic-kernel --- + + # Using the Chroma connector (Preview) +::: zone pivot="programming-language-csharp" + +> [!WARNING] +> The Chroma Vector Store functionality is in preview, and improvements that require breaking changes may still occur in limited circumstances before release. + +::: zone-end +::: zone pivot="programming-language-python" + +> [!WARNING] +> The Semantic Kernel Vector Store functionality is in preview, and improvements that require breaking changes may still occur in limited circumstances before release. + +::: zone-end +::: zone pivot="programming-language-java" + > [!WARNING] > The Semantic Kernel Vector Store functionality is in preview, and improvements that require breaking changes may still occur in limited circumstances before release. +::: zone-end + ::: zone pivot="programming-language-csharp" -## Not supported +## Overview -Not supported. +The Chroma Vector Store connector can be used to access and manage data in Chroma and Chroma Cloud. The connector has the following characteristics. + +| Feature Area | Support | +| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| Collection maps to | Chroma collection | +| Supported key property types | | +| Supported data property types | | +| Supported vector property types | | +| Supported index types | Hnsw | +| Supported distance functions | | +| Supported filter clauses | | +| Supports multiple vectors in a record | No | +| IsIndexed supported? | Not needed, every data property can be used in filters | +| IsFullTextIndexed supported? | Yes | +| StorageName supported? | Yes | +| HybridSearch supported? | Yes, on Chroma Cloud only. See [Hybrid search](#hybrid-search). | + +## Limitations + +Notable Chroma connector functionality limitations. + +- Chroma metadata has no null values. A data property with a null value is not stored, and is read back as null. +- Chroma does not store empty arrays and lists, so they are read back as null. +- Array and list data properties need Chroma 1.5.0 or later. +- `GetAsync` with a filter does not support ordering. +- On Chroma Cloud, `top` and `Skip` of a vector search can add up to at most 300, the default quota of Chroma Cloud. Beyond that, Chroma Cloud returns a quota error. + +## Getting started + +Add the Chroma Vector Store connector NuGet package to your project. + +```dotnetcli +dotnet add package CommunityToolkit.VectorData.Chroma --prerelease +``` + +You can add the vector store to the dependency injection container available on the `KernelBuilder` or to the `IServiceCollection` dependency injection container using extension methods provided by the connector package. + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel; + +// Using Kernel Builder. +var kernelBuilder = Kernel + .CreateBuilder(); +kernelBuilder.Services + .AddChromaVectorStore("http://localhost:8000"); +``` + +```csharp +using Microsoft.Extensions.DependencyInjection; + +// Using IServiceCollection with ASP.NET Core. +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddChromaVectorStore("http://localhost:8000"); +``` + +The string is a connection string. To connect to Chroma Cloud, it also contains an API key, and the tenant and the database shown in the Chroma Cloud dashboard. + +```csharp +using Microsoft.Extensions.DependencyInjection; + +// Using IServiceCollection with ASP.NET Core. +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddChromaVectorStore("Endpoint=https://api.trychroma.com;Token=;Tenant=;Database="); +``` + +Extension methods that take no parameters are also provided. These require an instance of the `ChromaDB.Client.ChromaClient` class to be separately registered with the dependency injection container. + +```csharp +using ChromaDB.Client; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel; + +// Using Kernel Builder. +var kernelBuilder = Kernel.CreateBuilder(); +kernelBuilder.Services.AddSingleton(sp => new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"))); +kernelBuilder.Services.AddChromaVectorStore(); +``` + +```csharp +using ChromaDB.Client; +using Microsoft.Extensions.DependencyInjection; + +// Using IServiceCollection with ASP.NET Core. +var builder = WebApplication.CreateBuilder(args); +builder.Services.AddSingleton(sp => new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"))); +builder.Services.AddChromaVectorStore(); +``` + +You can construct a Chroma Vector Store instance directly. + +```csharp +using ChromaDB.Client; +using CommunityToolkit.VectorData.Chroma; + +var vectorStore = new ChromaVectorStore( + new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000")), + ownsClient: true); +``` + +It is possible to construct a direct reference to a named collection. + +```csharp +using ChromaDB.Client; +using CommunityToolkit.VectorData.Chroma; + +var collection = new ChromaCollection( + new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000")), + "skhotels", + ownsClient: true); +``` + +## Data mapping + +The Chroma connector provides a default mapper when mapping data from the data model to storage. +Chroma stores each record as an id, an embedding, metadata and a document. +The default mapper uses the model annotations or record definition to determine the type of each property and to do this mapping. + +- The data model property annotated as a key will be mapped to the Chroma record id. +- The data model properties annotated as data will be mapped to the Chroma record metadata. +- The data model property annotated as a vector will be mapped to the Chroma record embedding. +- If exactly one `string` data property has `IsFullTextIndexed` set, it will also be mapped to the Chroma record document. `string.Contains` filters on this property search the document. On Chroma Cloud, a text longer than 8,182 bytes is stored in the document only, since Chroma Cloud does not accept longer metadata values. + +### Property name override + +For data properties, you can provide override field names to use in storage that is different to the property names on the data model. This is not supported for keys, since a key is stored as the Chroma record id, or for vectors, since a Chroma record has a single unnamed embedding. + +The property name override is done by setting the `StorageName` option via the data model attributes or record definition. + +Here is an example of a data model with `StorageName` set on its attributes and how that will be represented in Chroma. + +```csharp +using Microsoft.Extensions.VectorData; + +public class Hotel +{ + [VectorStoreKey] + public string HotelId { get; set; } + + [VectorStoreData(StorageName = "hotel_name")] + public string HotelName { get; set; } + + [VectorStoreData(IsFullTextIndexed = true, StorageName = "hotel_description")] + public string Description { get; set; } + + [VectorStoreVector(4, DistanceFunction = DistanceFunction.CosineSimilarity, IndexKind = IndexKind.Hnsw)] + public ReadOnlyMemory? DescriptionEmbedding { get; set; } +} +``` + +```json +{ + "ids": ["h1"], + "embeddings": [[0.9, 0.1, 0.1, 0.1]], + "metadatas": [{ "hotel_name": "Hotel Happy", "hotel_description": "A place where everyone can be happy." }], + "documents": ["A place where everyone can be happy."] +} +``` + +## Hybrid search + +On Chroma Cloud, the connector supports [hybrid search](../hybrid-search.md). It combines a vector search with a BM25 search of the keywords in a full-text indexed `string` property, and fuses the two rankings with reciprocal rank fusion. + +When the connector creates a collection on Chroma Cloud, it also creates a BM25 index for each full-text indexed `string` property. A Chroma server outside Chroma Cloud has no BM25 indexes. There, `GetService` does not return the collection as `IKeywordHybridSearchable`, and `HybridSearchAsync` throws. + +```csharp +using ChromaDB.Client; +using CommunityToolkit.VectorData.Chroma; +using Microsoft.Extensions.VectorData; + +var vectorStore = new ChromaVectorStore( + new ChromaClient(ChromaConfigurationOptions.FromConnectionString( + "Endpoint=https://api.trychroma.com;Token=;Tenant=;Database=")), + ownsClient: true); +var collection = vectorStore.GetCollection("skhotels"); +await collection.EnsureCollectionExistsAsync(); + +// This snippet assumes searchVector is already provided, having been created using the embedding model of your choice. +var hybridSearchCollection = (IKeywordHybridSearchable)collection; +var searchResult = hybridSearchCollection.HybridSearchAsync(searchVector, ["happy", "place"], top: 3); + +await foreach (var result in searchResult) +{ + Console.WriteLine($"{result.Record.HotelName}: {result.Score}"); +} +``` ::: zone-end ::: zone pivot="programming-language-python" diff --git a/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/index.md b/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/index.md index 58068a46..eb0786c2 100644 --- a/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/index.md +++ b/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/index.md @@ -39,7 +39,7 @@ Semantic Kernel provides a number of out-of-the-box Vector Store integrations ma | [Cosmos DB No SQL](./azure-cosmosdb-nosql-connector.md) | ✅ | ✅ | Microsoft | | [Couchbase](./couchbase-connector.md) | ✅ | ✅ | Couchbase | | [Elasticsearch](./elasticsearch-connector.md) | ✅ | ✅ | Elastic | -| Chroma | Planned | | | +| [Chroma](./chroma-connector.md) | ✅ | ❌ | Microsoft | | [In-Memory](./inmemory-connector.md) | ✅ | N/A | Microsoft | | Milvus | Planned | | | | [MongoDB](./mongodb-connector.md) | ✅ | ✅ | Microsoft | From 63e1e01c37b18e3d8f1167cdb2cfab2229110583 Mon Sep 17 00:00:00 2001 From: Laurianti Date: Fri, 9 Oct 2026 23:56:25 +0200 Subject: [PATCH 2/2] Fix subject-verb agreement in the property name override --- .../out-of-the-box-connectors/chroma-connector.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md b/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md index 38ada7f7..a6114abb 100644 --- a/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md +++ b/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/chroma-connector.md @@ -173,7 +173,7 @@ The default mapper uses the model annotations or record definition to determine ### Property name override -For data properties, you can provide override field names to use in storage that is different to the property names on the data model. This is not supported for keys, since a key is stored as the Chroma record id, or for vectors, since a Chroma record has a single unnamed embedding. +For data properties, you can provide override field names to use in storage that are different from the property names on the data model. This is not supported for keys, since a key is stored as the Chroma record id, or for vectors, since a Chroma record has a single unnamed embedding. The property name override is done by setting the `StorageName` option via the data model attributes or record definition.