diff --git a/README.md b/README.md index 5946a7f..dcaf5fb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Website: [chromadotnet.org](https://chromadotnet.org) | [VectorStore_VectorSearch_MultiStore_Chroma](./samples/Concepts/Memory/VectorStore_VectorSearch_MultiStore_Chroma.cs) | Ingests a glossary into Chroma and searches it, with and without a filter. It goes through the common vector store sample code, with and without dependency injection. Adapted from [VectorStore_VectorSearch_MultiStore_Qdrant](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Memory/VectorStore_VectorSearch_MultiStore_Qdrant.cs). | | [VectorStore_DynamicDataModel_Interop_Chroma](./samples/Concepts/Memory/VectorStore_DynamicDataModel_Interop_Chroma.cs) | Writes records as dictionaries described by a record definition, then reads them back as a .NET data model. It also does the reverse. Adapted from [VectorStore_DynamicDataModel_Interop](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Memory/VectorStore_DynamicDataModel_Interop.cs). | | [VectorStore_VectorSearch_Paging_Chroma](./samples/Concepts/Memory/VectorStore_VectorSearch_Paging_Chroma.cs) | Uses `Top` and `Skip` to page through vector search results over 1,000 records. Needs no model. Adapted from [VectorStore_VectorSearch_Paging](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Memory/VectorStore_VectorSearch_Paging.cs), but with the Euclidean distance. Chroma searches with an approximate index, and with the cosine distance that index can miss some of the made-up vectors in the sample. | -| [VectorStore_HybridSearch_Simple_Chroma](./samples/Concepts/Memory/VectorStore_HybridSearch_Simple_Chroma.cs) | Searches a glossary on Chroma Cloud with a vector and keywords, with and without a filter. The vector store creates the collection with a BM25 index for the full-text indexed property. Adapted from [VectorStore_HybridSearch_Simple_AzureAISearch](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Memory/VectorStore_HybridSearch_Simple_AzureAISearch.cs). | +| [VectorStore_HybridSearch_Simple_Chroma](./samples/Concepts/Memory/VectorStore_HybridSearch_Simple_Chroma.cs) | Searches a glossary on Chroma Cloud with a vector and keywords, with and without a filter. On Chroma Cloud, the collection gets a BM25 index for the full-text indexed property when it is created. Adapted from [VectorStore_HybridSearch_Simple_AzureAISearch](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Memory/VectorStore_HybridSearch_Simple_AzureAISearch.cs). | | [ChatCompletion_Rag_Chroma](./samples/Concepts/Agents/ChatCompletion_Rag_Chroma.cs) | A `ChatCompletionAgent` that answers through a `TextSearchProvider`, from documents that a `TextSearchStore` keeps in Chroma. It also covers citations and a search namespace. Adapted from [ChatCompletion_Rag](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/Agents/ChatCompletion_Rag.cs). | | [ChatCompletion_Rag_Chroma_Ollama](./samples/Concepts/Agents/ChatCompletion_Rag_Chroma_Ollama.cs) | The same sample with models that run locally in Ollama. | | [Step5_Search_With_Chroma](./samples/GettingStartedWithTextSearch/Step5_Search_With_Chroma.cs) | Searches records that have their own data model in Chroma, through `VectorStoreTextSearch`. It then either passes the results to the model in a Handlebars prompt, or gives the model the search as a function to call. Adapted from [Step4_Search_With_VectorStore](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithTextSearch/Step4_Search_With_VectorStore.cs). | diff --git a/samples/Concepts/Agents/ChatCompletion_Rag_Chroma.cs b/samples/Concepts/Agents/ChatCompletion_Rag_Chroma.cs index 0824eb2..b4ce517 100644 --- a/samples/Concepts/Agents/ChatCompletion_Rag_Chroma.cs +++ b/samples/Concepts/Agents/ChatCompletion_Rag_Chroma.cs @@ -51,6 +51,7 @@ public async Task UseChatCompletionAgentWithBasicRag() using var httpClient = new HttpClient(); using var vectorStore = new ChromaVectorStore( new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), + ownsClient: true, new() { EmbeddingGenerator = embeddingGenerator }); // Create a store that uses a built in schema for storing text documents @@ -114,6 +115,7 @@ public async Task RagWithCitationsAndFiltering() using var httpClient = new HttpClient(); using var vectorStore = new ChromaVectorStore( new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), + ownsClient: true, new() { EmbeddingGenerator = embeddingGenerator }); // Create a store that uses a built in schema for storing text documents diff --git a/samples/Concepts/Agents/ChatCompletion_Rag_Chroma_Ollama.cs b/samples/Concepts/Agents/ChatCompletion_Rag_Chroma_Ollama.cs index 630461b..c5e88f4 100644 --- a/samples/Concepts/Agents/ChatCompletion_Rag_Chroma_Ollama.cs +++ b/samples/Concepts/Agents/ChatCompletion_Rag_Chroma_Ollama.cs @@ -48,6 +48,7 @@ public async Task UseChatCompletionAgentWithBasicRag() using var httpClient = new HttpClient(); using var vectorStore = new ChromaVectorStore( new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), + ownsClient: true, new() { EmbeddingGenerator = embeddingGenerator }); // Create a store that uses a built in schema for storing text documents @@ -113,6 +114,7 @@ public async Task RagWithCitationsAndFiltering() using var httpClient = new HttpClient(); using var vectorStore = new ChromaVectorStore( new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), + ownsClient: true, new() { EmbeddingGenerator = embeddingGenerator }); // Create a store that uses a built in schema for storing text documents diff --git a/samples/Concepts/Concepts.csproj b/samples/Concepts/Concepts.csproj index c3cab83..40e7b5b 100644 --- a/samples/Concepts/Concepts.csproj +++ b/samples/Concepts/Concepts.csproj @@ -16,7 +16,7 @@ - + diff --git a/samples/Concepts/Memory/VectorStore_DynamicDataModel_Interop_Chroma.cs b/samples/Concepts/Memory/VectorStore_DynamicDataModel_Interop_Chroma.cs index cf40fd2..d39e150 100644 --- a/samples/Concepts/Memory/VectorStore_DynamicDataModel_Interop_Chroma.cs +++ b/samples/Concepts/Memory/VectorStore_DynamicDataModel_Interop_Chroma.cs @@ -49,7 +49,7 @@ public async Task UpsertWithDynamicRetrieveWithCustomAsync() // Initiate the docker container and construct the vector store. await chromaFixture.ManualInitializeAsync(); using var httpClient = new HttpClient(); - using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient)); + using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), ownsClient: true); // Get and create collection if it doesn't exist using the dynamic data model and record definition that defines the schema. var dynamicDataModelCollection = vectorStore.GetDynamicCollection("skglossary", s_definition); @@ -87,7 +87,7 @@ public async Task UpsertWithCustomRetrieveWithDynamicAsync() // Initiate the docker container and construct the vector store. await chromaFixture.ManualInitializeAsync(); using var httpClient = new HttpClient(); - using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient)); + using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), ownsClient: true); // Get and create collection if it doesn't exist using the custom data model. var customDataModelCollection = vectorStore.GetCollection("skglossary"); diff --git a/samples/Concepts/Memory/VectorStore_HybridSearch_Simple_Chroma.cs b/samples/Concepts/Memory/VectorStore_HybridSearch_Simple_Chroma.cs index 6c31dab..07f6f79 100644 --- a/samples/Concepts/Memory/VectorStore_HybridSearch_Simple_Chroma.cs +++ b/samples/Concepts/Memory/VectorStore_HybridSearch_Simple_Chroma.cs @@ -14,7 +14,7 @@ namespace Memory; /// /// The example shows the following steps: /// 1. Create an embedding generator. -/// 2. Create a Chroma Vector Store that creates a BM25 index for the full-text indexed properties of its collections. +/// 2. Create a Chroma Vector Store: on Chroma Cloud, its collections get a BM25 index for each full-text indexed property. /// 3. Ingest some data into the vector store. /// 4. Do a hybrid search on the vector store with various text+keyword and filtering options. /// @@ -30,7 +30,7 @@ public async Task IngestDataAndUseHybridSearch() .GetEmbeddingClient(TestConfiguration.AzureOpenAIEmbeddings.DeploymentName) .AsIEmbeddingGenerator(1536); - // Construct the Chroma VectorStore, which creates the collections with a BM25 index for each full-text indexed property. + // Construct the Chroma VectorStore. On Chroma Cloud, creating a collection creates a BM25 index for each full-text indexed property, which the hybrid search uses. using var httpClient = new HttpClient(); var chromaClient = new ChromaClient( new ChromaConfigurationOptions( @@ -39,7 +39,7 @@ public async Task IngestDataAndUseHybridSearch() database: TestConfiguration.Chroma.Database, chromaToken: TestConfiguration.Chroma.ApiKey), httpClient); - using var vectorStore = new ChromaVectorStore(chromaClient, new() { CreateBm25Indexes = true }); + using var vectorStore = new ChromaVectorStore(chromaClient, ownsClient: true); // Get and create collection if it doesn't exist. var collection = vectorStore.GetCollection("skglossary"); diff --git a/samples/Concepts/Memory/VectorStore_VectorSearch_MultiStore_Chroma.cs b/samples/Concepts/Memory/VectorStore_VectorSearch_MultiStore_Chroma.cs index 4b25594..f3e9877 100644 --- a/samples/Concepts/Memory/VectorStore_VectorSearch_MultiStore_Chroma.cs +++ b/samples/Concepts/Memory/VectorStore_VectorSearch_MultiStore_Chroma.cs @@ -67,7 +67,7 @@ public async Task ExampleWithoutDIAsync() await chromaFixture.ManualInitializeAsync(); using var httpClient = new HttpClient(); var chromaClient = new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient); - using var vectorStore = new ChromaVectorStore(chromaClient); + using 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); diff --git a/samples/Concepts/Memory/VectorStore_VectorSearch_Paging_Chroma.cs b/samples/Concepts/Memory/VectorStore_VectorSearch_Paging_Chroma.cs index 0c54608..5f62dfb 100644 --- a/samples/Concepts/Memory/VectorStore_VectorSearch_Paging_Chroma.cs +++ b/samples/Concepts/Memory/VectorStore_VectorSearch_Paging_Chroma.cs @@ -25,7 +25,7 @@ public async Task VectorSearchWithPagingAsync() // Initiate the docker container and construct the Chroma vector store. await chromaFixture.ManualInitializeAsync(); using var httpClient = new HttpClient(); - using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient)); + using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient), ownsClient: true); // Get and create collection if it doesn't exist. // Chroma supports string and Guid keys. diff --git a/samples/GettingStartedWithTextSearch/ChromaVectorStoreFixtureBase.cs b/samples/GettingStartedWithTextSearch/ChromaVectorStoreFixtureBase.cs index a5437e1..cc7d275 100644 --- a/samples/GettingStartedWithTextSearch/ChromaVectorStoreFixtureBase.cs +++ b/samples/GettingStartedWithTextSearch/ChromaVectorStoreFixtureBase.cs @@ -64,6 +64,7 @@ public async Task InitializeAsync() await this._chromaContainer.StartAsync(); this.ChromaVectorStore = new ChromaVectorStore( new ChromaClient(new ChromaConfigurationOptions(this._chromaContainer.GetConnectionString()), this._httpClient), + ownsClient: true, new() { EmbeddingGenerator = this.EmbeddingGenerator }); this.VectorStoreRecordCollection = await this.InitializeRecordCollectionAsync(); diff --git a/samples/GettingStartedWithTextSearch/GettingStartedWithTextSearch.csproj b/samples/GettingStartedWithTextSearch/GettingStartedWithTextSearch.csproj index 0b9208b..ae4d376 100644 --- a/samples/GettingStartedWithTextSearch/GettingStartedWithTextSearch.csproj +++ b/samples/GettingStartedWithTextSearch/GettingStartedWithTextSearch.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/test/ChromaDB.SemanticKernel.Sample.Tests/ChatCompletionRagTests.cs b/test/ChromaDB.SemanticKernel.Sample.Tests/ChatCompletionRagTests.cs index b27c2e4..5e6604d 100644 --- a/test/ChromaDB.SemanticKernel.Sample.Tests/ChatCompletionRagTests.cs +++ b/test/ChromaDB.SemanticKernel.Sample.Tests/ChatCompletionRagTests.cs @@ -57,7 +57,7 @@ public async Task Only_the_documents_of_the_search_namespace_reach_the_model_wit } private ChromaVectorStore CreateVectorStore(HttpClient httpClient) - => new(new ChromaClient(new ChromaConfigurationOptions(fixture.Endpoint), httpClient), new() { EmbeddingGenerator = new WordEmbeddingGenerator(EmbeddingDimensions) }); + => new(new ChromaClient(new ChromaConfigurationOptions(fixture.Endpoint), httpClient), ownsClient: true, new() { EmbeddingGenerator = new WordEmbeddingGenerator(EmbeddingDimensions) }); private static (ChatCompletionAgent Agent, RecordingChatClient Model) CreateAgent() { diff --git a/test/ChromaDB.SemanticKernel.Sample.Tests/ChromaDB.SemanticKernel.Sample.Tests.csproj b/test/ChromaDB.SemanticKernel.Sample.Tests/ChromaDB.SemanticKernel.Sample.Tests.csproj index 563f7f2..2a4ebc0 100644 --- a/test/ChromaDB.SemanticKernel.Sample.Tests/ChromaDB.SemanticKernel.Sample.Tests.csproj +++ b/test/ChromaDB.SemanticKernel.Sample.Tests/ChromaDB.SemanticKernel.Sample.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/ChromaDB.SemanticKernel.Sample.Tests/DataModelAndPagingTests.cs b/test/ChromaDB.SemanticKernel.Sample.Tests/DataModelAndPagingTests.cs index 5bcbbcb..ff7a185 100644 --- a/test/ChromaDB.SemanticKernel.Sample.Tests/DataModelAndPagingTests.cs +++ b/test/ChromaDB.SemanticKernel.Sample.Tests/DataModelAndPagingTests.cs @@ -105,7 +105,7 @@ public async Task The_pages_go_through_every_record_once_in_the_order_of_the_dis } private ChromaVectorStore CreateVectorStore(HttpClient httpClient) - => new(new ChromaClient(new ChromaConfigurationOptions(fixture.Endpoint), httpClient)); + => new(new ChromaClient(new ChromaConfigurationOptions(fixture.Endpoint), httpClient), ownsClient: true); private sealed class Glossary { diff --git a/test/ChromaDB.SemanticKernel.Sample.Tests/MultiStoreTests.cs b/test/ChromaDB.SemanticKernel.Sample.Tests/MultiStoreTests.cs index 304f197..c40a5c3 100644 --- a/test/ChromaDB.SemanticKernel.Sample.Tests/MultiStoreTests.cs +++ b/test/ChromaDB.SemanticKernel.Sample.Tests/MultiStoreTests.cs @@ -37,7 +37,7 @@ public async Task Without_DI_each_search_finds_its_glossary_entry() { var output = new RecordingOutput(testOutput); using var httpClient = new HttpClient(); - using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions(fixture.Endpoint), httpClient)); + using var vectorStore = new ChromaVectorStore(new ChromaClient(new ChromaConfigurationOptions(fixture.Endpoint), httpClient), ownsClient: true); var processor = new VectorStore_VectorSearch_MultiStore_Common(vectorStore, new WordEmbeddingGenerator(EmbeddingDimensions), output); await processor.IngestDataAndSearchAsync("skglossaryWithoutDI", () => Guid.NewGuid());