Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
<PackageVersion Include="CommunityToolkit.VectorData.AzureAISearch" Version="1.0.0" />
<PackageVersion Include="CommunityToolkit.VectorData.AzureDocumentDB" Version="1.0.0" />
<PackageVersion Include="CommunityToolkit.VectorData.AzureCosmosDB" Version="1.0.0" />
<PackageVersion Include="CommunityToolkit.VectorData.Chroma" Version="1.0.1-preview" />
<PackageVersion Include="CommunityToolkit.VectorData.InMemory" Version="1.0.1" />
<PackageVersion Include="CommunityToolkit.VectorData.PgVector" Version="1.0.0" />
<PackageVersion Include="CommunityToolkit.VectorData.Qdrant" Version="1.0.0" />
Expand Down
1 change: 1 addition & 0 deletions dotnet/samples/Concepts/Concepts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<PackageReference Include="Grpc.Net.ClientFactory" />
<PackageReference Include="CommunityToolkit.VectorData.AzureAISearch" />
<PackageReference Include="CommunityToolkit.VectorData.AzureDocumentDB" />
<PackageReference Include="CommunityToolkit.VectorData.Chroma" />
<PackageReference Include="CommunityToolkit.VectorData.InMemory" />
<PackageReference Include="CommunityToolkit.VectorData.Qdrant" />
<PackageReference Include="CommunityToolkit.VectorData.PgVector" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) Microsoft. All rights reserved.

using ChromaDB.Client;
using Docker.DotNet;

namespace Memory.VectorStoreFixtures;

/// <summary>
/// Fixture to use for creating a Chroma container before tests and delete it after tests.
/// </summary>
public class VectorStoreChromaContainerFixture : IAsyncLifetime
{
private DockerClient? _dockerClient;
private string? _chromaContainerId;

public async Task InitializeAsync()
{
}

public async Task ManualInitializeAsync()
{
if (this._chromaContainerId == null)
{
// Connect to docker and start the docker container.
using var dockerClientConfiguration = new DockerClientConfiguration();
this._dockerClient = dockerClientConfiguration.CreateClient();
this._chromaContainerId = await VectorStoreInfra.SetupChromaContainerAsync(this._dockerClient);

// Delay until the Chroma server is ready.
var chromaClient = new ChromaClient("http://localhost:8000");
var succeeded = false;
var attemptCount = 0;
while (!succeeded && attemptCount++ < 10)
{
try
{
await chromaClient.ListCollectionsAsync();
succeeded = true;
}
catch (Exception)
{
await Task.Delay(1000);
}
}
}
}

public async Task DisposeAsync()
{
if (this._dockerClient != null && this._chromaContainerId != null)
{
// Delete docker container.
await VectorStoreInfra.DeleteContainerAsync(this._dockerClient, this._chromaContainerId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,46 @@ namespace Memory.VectorStoreFixtures;
/// </summary>
internal static class VectorStoreInfra
{
/// <summary>
/// Setup the chroma container by pulling the image and running it.
/// </summary>
/// <param name="client">The docker client to create the container with.</param>
/// <returns>The id of the container.</returns>
public static async Task<string> SetupChromaContainerAsync(DockerClient client)
{
await client.Images.CreateImageAsync(
new ImagesCreateParameters
{
FromImage = "chromadb/chroma",
Tag = "latest",
},
null,
new Progress<JSONMessage>());

var container = await client.Containers.CreateContainerAsync(new CreateContainerParameters()
{
Image = "chromadb/chroma",
HostConfig = new HostConfig()
{
PortBindings = new Dictionary<string, IList<PortBinding>>
{
{"8000", new List<PortBinding> {new() {HostPort = "8000" } }},
},
PublishAllPorts = true
},
ExposedPorts = new Dictionary<string, EmptyStruct>
{
{ "8000", default },
},
});

await client.Containers.StartContainerAsync(
container.ID,
new ContainerStartParameters());

return container.ID;
}

/// <summary>
/// Setup the postgres pgvector container by pulling the image and running it.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Memory;
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Redis"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_InMemory"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Postgres"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Chroma"/></para>
///
/// To run this sample, you need an already existing Azure AI Search instance.
/// To set your secrets use:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft. All rights reserved.

using Azure.AI.OpenAI;
using Azure.Identity;
using ChromaDB.Client;
using CommunityToolkit.VectorData.Chroma;
using Memory.VectorStoreFixtures;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;

namespace Memory;

/// <summary>
/// An example showing how to use common code, that can work with any vector database, with a Chroma database.
/// The common code is in the <see cref="VectorStore_VectorSearch_MultiStore_Common"/> class.
/// The common code ingests data into the vector store and then searches over that data.
/// This example is part of a set of examples each showing a different vector database.
///
/// For other databases, see the following classes:
/// <para><see cref="VectorStore_VectorSearch_MultiStore_AzureAISearch"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Qdrant"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Redis"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_InMemory"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Postgres"/></para>
///
/// To run this sample, you need a local instance of Docker running, since the associated fixture will try and start a Chroma container in the local docker instance.
/// </summary>
public class VectorStore_VectorSearch_MultiStore_Chroma(ITestOutputHelper output, VectorStoreChromaContainerFixture chromaFixture) : BaseTest(output), IClassFixture<VectorStoreChromaContainerFixture>
{
[Fact]
public async Task ExampleWithDIAsync()
{
// Use the kernel for DI purposes.
var kernelBuilder = Kernel
.CreateBuilder();

// Register an embedding generation service with the DI container.
kernelBuilder.AddAzureOpenAIEmbeddingGenerator(
deploymentName: TestConfiguration.AzureOpenAIEmbeddings.DeploymentName,
endpoint: TestConfiguration.AzureOpenAIEmbeddings.Endpoint,
credential: new AzureCliCredential(),
dimensions: 1536);

// Initialize the Chroma docker container via the fixtures and register the Chroma VectorStore.
await chromaFixture.ManualInitializeAsync();
kernelBuilder.Services.AddChromaVectorStore("http://localhost:8000");

// Register the test output helper common processor with the DI container.
kernelBuilder.Services.AddSingleton<ITestOutputHelper>(this.Output);
kernelBuilder.Services.AddTransient<VectorStore_VectorSearch_MultiStore_Common>();

// Build the kernel.
var kernel = kernelBuilder.Build();

// Build a common processor object using the DI container.
var processor = kernel.GetRequiredService<VectorStore_VectorSearch_MultiStore_Common>();

// Run the process and pass a key generator function to it, to generate unique record keys.
// The key generator function is required, since different vector stores may require different key types.
// E.g. Chroma supports Guid and string keys, but others may not support Guid.
await processor.IngestDataAndSearchAsync("skglossaryWithDI", () => Guid.NewGuid());
}

[Fact]
public async Task ExampleWithoutDIAsync()
{
// Create an embedding generation service.
var embeddingGenerator = new AzureOpenAIClient(new Uri(TestConfiguration.AzureOpenAIEmbeddings.Endpoint), new AzureCliCredential())
.GetEmbeddingClient(TestConfiguration.AzureOpenAIEmbeddings.DeploymentName)
.AsIEmbeddingGenerator(1536);

// Initialize the Chroma docker container via the fixtures and construct the Chroma VectorStore.
await chromaFixture.ManualInitializeAsync();
var chromaClient = new ChromaClient("http://localhost:8000");
var vectorStore = new ChromaVectorStore(chromaClient, ownsClient: true);

// Create the common processor that works for any vector store.
var processor = new VectorStore_VectorSearch_MultiStore_Common(vectorStore, embeddingGenerator, this.Output);

// Run the process and pass a key generator function to it, to generate unique record keys.
// The key generator function is required, since different vector stores may require different key types.
// E.g. Chroma supports Guid and string keys, but others may not support Guid.
await processor.IngestDataAndSearchAsync("skglossaryWithoutDI", () => Guid.NewGuid());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Memory;
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Redis"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_InMemory"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Postgres"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Chroma"/></para>
/// </summary>
/// <param name="vectorStore">The vector store to ingest data into.</param>
/// <param name="embeddingGenerator">The service to use for generating embeddings.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Memory;
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Redis"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Qdrant"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Postgres"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Chroma"/></para>
/// </summary>
public class VectorStore_VectorSearch_MultiStore_InMemory(ITestOutputHelper output) : BaseTest(output)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Memory;
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Qdrant"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Redis"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_InMemory"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Chroma"/></para>
///
/// To run this sample, you need a local instance of Docker running, since the associated fixture will try and start a Postgres container in the local docker instance.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Memory;
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Redis"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_InMemory"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Postgres"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Chroma"/></para>
///
/// To run this sample, you need a local instance of Docker running, since the associated fixture will try and start a Qdrant container in the local docker instance.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Memory;
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Qdrant"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_InMemory"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Postgres"/></para>
/// <para><see cref="VectorStore_VectorSearch_MultiStore_Chroma"/></para>
///
/// Redis supports two record storage types: Json and HashSet.
/// Note the use of the <see cref="RedisStorageType"/> enum to specify the preferred storage type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal sealed class ApplicationConfig
private readonly RagConfig _ragConfig = new();
private readonly AzureAISearchConfig _azureAISearchConfig = new();
private readonly CosmosConfig _azureDocumentDBConfig = new();
private readonly ChromaConfig _chromaConfig = new();
private readonly CosmosConfig _cosmosNoSqlConfig = new();
private readonly QdrantConfig _qdrantConfig = new();
private readonly RedisConfig _redisConfig = new();
Expand Down Expand Up @@ -45,6 +46,9 @@ public ApplicationConfig(ConfigurationManager configurationManager)
configurationManager
.GetRequiredSection($"VectorStores:{CosmosConfig.DocumentDBConfigSectionName}")
.Bind(this._azureDocumentDBConfig);
configurationManager
.GetRequiredSection($"VectorStores:{ChromaConfig.ConfigSectionName}")
.Bind(this._chromaConfig);
configurationManager
.GetRequiredSection($"VectorStores:{CosmosConfig.NoSqlConfigSectionName}")
.Bind(this._cosmosNoSqlConfig);
Expand Down Expand Up @@ -73,6 +77,8 @@ public ApplicationConfig(ConfigurationManager configurationManager)

public CosmosConfig AzureDocumentDBConfig => this._azureDocumentDBConfig;

public ChromaConfig ChromaConfig => this._chromaConfig;

public CosmosConfig CosmosNoSqlConfig => this._cosmosNoSqlConfig;

public QdrantConfig QdrantConfig => this._qdrantConfig;
Expand Down
16 changes: 16 additions & 0 deletions dotnet/samples/Demos/VectorStoreRAG/Options/ChromaConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.

using System.ComponentModel.DataAnnotations;

namespace VectorStoreRAG.Options;

/// <summary>
/// Chroma service settings.
/// </summary>
internal sealed class ChromaConfig
{
public const string ConfigSectionName = "Chroma";

[Required]
public string ConnectionString { get; set; } = string.Empty;
}
6 changes: 6 additions & 0 deletions dotnet/samples/Demos/VectorStoreRAG/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
appConfig.AzureDocumentDBConfig.ConnectionString,
appConfig.AzureDocumentDBConfig.DatabaseName);
break;
case "Chroma":
kernelBuilder.Services.AddChromaCollection<string, TextSnippet<string>>(
appConfig.RagConfig.CollectionName,
appConfig.ChromaConfig.ConnectionString);
break;
case "CosmosNoSql":
kernelBuilder.Services.AddCosmosCollection<string, TextSnippet<string>>(
appConfig.RagConfig.CollectionName,
Expand Down Expand Up @@ -121,6 +126,7 @@
{
case "AzureAISearch":
case "AzureDocumentDB":
case "Chroma":
case "CosmosNoSql":
case "InMemory":
case "Redis":
Expand Down
17 changes: 17 additions & 0 deletions dotnet/samples/Demos/VectorStoreRAG/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The sample can be configured in various ways:
1. You can choose your preferred vector store by setting the `Rag:VectorStoreType` configuration setting in the `appsettings.json` file to one of the following values:
1. AzureAISearch
1. AzureDocumentDB
1. Chroma
1. CosmosNoSql
1. InMemory
1. Qdrant
Expand Down Expand Up @@ -130,6 +131,22 @@ dotnet user-secrets set "VectorStores:CosmosNoSql:ConnectionString" "<yourconnec
dotnet user-secrets set "VectorStores:CosmosNoSql:DatabaseName" "<yourdbname>"
```

### Chroma

If you want to use Chroma as your vector store, you will need to have an instance of Chroma available.

You can use the following command to start a Chroma instance in docker, and this will work with the default configured settings:

```cli
docker run -d --name chroma -p 8000:8000 chromadb/chroma:latest
```

If you want to use a different instance of Chroma, you can update the appsettings.json file or add the following secret to reconfigure:

```cli
dotnet user-secrets set "VectorStores:Chroma:ConnectionString" "<yourchromaconnectionstring>"
```

### Qdrant

If you want to use Qdrant as your vector store, you will need to have an instance of Qdrant available.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<PackageReference Include="CommunityToolkit.VectorData.AzureAISearch" />
<PackageReference Include="CommunityToolkit.VectorData.AzureDocumentDB" />
<PackageReference Include="CommunityToolkit.VectorData.AzureCosmosDB" />
<PackageReference Include="CommunityToolkit.VectorData.Chroma" />
<PackageReference Include="CommunityToolkit.VectorData.InMemory" />
<PackageReference Include="CommunityToolkit.VectorData.Qdrant" />
<PackageReference Include="CommunityToolkit.VectorData.Redis" />
Expand Down
3 changes: 3 additions & 0 deletions dotnet/samples/Demos/VectorStoreRAG/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
"ConnectionString": "",
"DatabaseName": ""
},
"Chroma": {
"ConnectionString": "http://localhost:8000"
},
"CosmosNoSql": {
"ConnectionString": "",
"DatabaseName": ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public static void Initialize(IConfigurationRoot configRoot)
public static PostgresConfig Postgres => LoadSection<PostgresConfig>();
public static RedisConfig Redis => LoadSection<RedisConfig>();
public static JiraConfig Jira => LoadSection<JiraConfig>();
public static ChromaConfig Chroma => LoadSection<ChromaConfig>();
public static MongoDBConfig MongoDB => LoadSection<MongoDBConfig>();
public static ChatGPTRetrievalPluginConfig ChatGPTRetrievalPlugin => LoadSection<ChatGPTRetrievalPluginConfig>();
public static MsGraphConfiguration MSGraph => LoadSection<MsGraphConfiguration>();
Expand Down Expand Up @@ -219,11 +218,6 @@ public class JiraConfig
public string Domain { get; set; }
}

public class ChromaConfig
{
public string Endpoint { get; set; }
}

public class MongoDBConfig
{
public string ConnectionString { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion dotnet/src/VectorData/Chroma/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Microsoft.SemanticKernel.Connectors.Chroma and the MemoryStore abstraction has been deprecated. Please use the new Microsoft.Extensions.VectorData abstractions with the Chroma implementation that can be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma)
Microsoft.SemanticKernel.Connectors.Chroma and the MemoryStore abstraction have been deprecated. Please use the new Microsoft.Extensions.VectorData abstractions with the Chroma implementation that can be found in the [CommunityToolkit/AI repository](https://github.com/CommunityToolkit/AI/tree/main/MEVD/src/Chroma), published as [CommunityToolkit.VectorData.Chroma](https://www.nuget.org/packages/CommunityToolkit.VectorData.Chroma).
6 changes: 0 additions & 6 deletions dotnet/test/VectorData/Chroma.UnitTests/.editorconfig

This file was deleted.

Loading