{"id":54278,"date":"2024-10-29T11:05:00","date_gmt":"2024-10-29T18:05:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=54278"},"modified":"2024-10-30T10:39:13","modified_gmt":"2024-10-30T17:39:13","slug":"introducing-microsoft-extensions-vector-data","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/introducing-microsoft-extensions-vector-data\/","title":{"rendered":"Introducing Microsoft.Extensions.VectorData Preview"},"content":{"rendered":"<p>We are excited to introduce the Microsoft.Extensions.VectorData.Abstractions library, now available in preview.<\/p>\n<p>Just as the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/introducing-microsoft-extensions-ai-preview\/\">Microsoft.Extensions.AI libraries<\/a> offer a unified layer for working with AI services, this package provides the .NET ecosystem with abstractions that help integrate vector stores into .NET applications and libraries.<\/p>\n<h2>Why vector stores?<\/h2>\n<p>Vector databases are important for tasks like search and grounding Generative AI responses.<\/p>\n<p>Similar to how relational databases and document databases are optimized for structured and semi-structured data, vector databases are built to efficiently store, index, and manage data represented as embedding vectors. As a result, the indexing algorithms used by vector databases are optimized to efficiently retrieve data that can be used downstream in your applications.<\/p>\n<h2>What is Microsoft.Extensions.VectorData?<\/h2>\n<p>Microsoft.Extensions.VectorData is a set of core .NET libraries developed in collaboration with Semantic Kernel and the broader .NET ecosystem. These libraries provide a unified layer of C# abstractions for interacting with vector stores.<\/p>\n<p>The abstractions in Microsoft.Extensions.VectorData provide library authors and developers with the following functionality:<\/p>\n<ul>\n<li>Perform Create-Read-Update-Delete (CRUD) operations on vector stores<\/li>\n<li>Use vector and text search on vector stores.<\/li>\n<\/ul>\n<h2>How to get started?<\/h2>\n<p>The easiest way to get started with Microsoft.Extensions.VectorData abstractions is by using any of the <a href=\"https:\/\/learn.microsoft.com\/semantic-kernel\/concepts\/vector-store-connectors\/out-of-the-box-connectors\/\">Semantic Kernel vector store connectors<\/a>.<\/p>\n<p>In this example, I\u2019ll be using the in-memory vector store implementation.<\/p>\n<p>To compliment this sample and make it feel more real, we\u2019ll also be using the Ollama reference implementation in Microsoft.Extensions.AI. However, any of the other implementations that support embedding generation work as well.<\/p>\n<h3>Create application and add NuGet packages<\/h3>\n<ol>\n<li>\n<p>Create a C# console application.<\/p>\n<\/li>\n<li>\n<p>Install the following NuGet packages<\/p>\n<ul>\n<li><a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.SemanticKernel.Connectors.InMemory\">Microsoft.SemanticKernel.Connectors.InMemory<\/a><\/li>\n<li><a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.Extensions.VectorData.Abstractions\/\">Microsoft.Extensions.VectorData.Abstractions<\/a><\/li>\n<li><a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.Extensions.AI.Ollama\">Microsoft.Extensions.AI.Ollama<\/a><\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Add the following <code>using<\/code> statements to your application.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"language-csharp\">using System.Collections.ObjectModel;\nusing Microsoft.Extensions.AI;\nusing Microsoft.Extensions.VectorData;\nusing Microsoft.SemanticKernel;\nusing Microsoft.SemanticKernel.Connectors.InMemory;<\/code><\/pre>\n<h3>Store data<\/h3>\n<p>The scenario used by this sample performs semantic search over a collection of movies.<\/p>\n<h4>Define data models<\/h4>\n<p>Start by defining a class to represent your movie data.<\/p>\n<pre><code class=\"language-csharp\">public class Movie\n{\n    [VectorStoreRecordKey]\n    public int Key {get;set;}\n\n    [VectorStoreRecordData] \n    public string Title {get;set;}\n\n    [VectorStoreRecordData]\n    public string Description {get;set;}\n\n    [VectorStoreRecordVector(384, DistanceFunction.CosineSimilarity)]\n    public ReadOnlyMemory&lt;float&gt; Vector {get;set;}\n}<\/code><\/pre>\n<p>By using attributes like <code>VectoStoreRecordKey<\/code>, <code>VectorStoreRecordVector<\/code>, and <code>VectorStoreRecordData<\/code>, you can annotate your data models to make it easier for vector store implementations to map POCO objects to their underlying data models. See the <a href=\"https:\/\/learn.microsoft.com\/semantic-kernel\/concepts\/vector-store-connectors\/defining-your-data-model#attributes\">Semantic Kernel Vector Store Data Model learn page<\/a> for more information on the options supported by each attribute.<\/p>\n<h4>Create vector store and movie collection<\/h4>\n<p>Now that you&#8217;ve defined your data models, create a vector store with a collection to store movie data.<\/p>\n<pre><code class=\"language-csharp\">var movieData = new List&lt;Movie&gt;()\n{\n    new Movie\n        {\n            Key=0, \n            Title=\"Lion King\", \n            Description=\"The Lion King is a classic Disney animated film that tells the story of a young lion named Simba who embarks on a journey to reclaim his throne as the king of the Pride Lands after the tragic death of his father.\"\n        },\n    new Movie\n        {\n            Key=1,\n            Title=\"Inception\", \n            Description=\"Inception is a science fiction film directed by Christopher Nolan that follows a group of thieves who enter the dreams of their targets to steal information.\"\n        },\n    new Movie\n        {\n            Key=2,\n            Title=\"The Matrix\", \n            Description=\"The Matrix is a science fiction film directed by the Wachowskis that follows a computer hacker named Neo who discovers that the world he lives in is a simulated reality created by machines.\"\n        },\n    new Movie\n        {\n            Key=3,\n            Title=\"Shrek\", \n            Description=\"Shrek is an animated film that tells the story of an ogre named Shrek who embarks on a quest to rescue Princess Fiona from a dragon and bring her back to the kingdom of Duloc.\"\n        }\n};\n\nvar vectorStore = new InMemoryVectorStore();\n\nvar movies = vectorStore.GetCollection&lt;int, Movie&gt;(\"movies\");\n\nawait movies.CreateCollectionIfNotExistsAsync();<\/code><\/pre>\n<h4>Create embedding generator<\/h4>\n<p>To generate embeddings, use one of the models hosted in provided by Ollama. In this sample, the model used is <em>all-minilm<\/em>, but any would work.<\/p>\n<ol>\n<li>Install <a href=\"https:\/\/ollama.com\/download\">Ollama<\/a>.<\/li>\n<li><a href=\"https:\/\/ollama.com\/library\/all-minilm\">Download the all-minilm model<\/a>.<\/li>\n<li>\n<p>Configure an <code>OllamaEmbeddingGenerator<\/code> in your application:<\/p>\n<pre><code class=\"language-csharp\">IEmbeddingGenerator&lt;string,Embedding&lt;float&gt;&gt; generator = \n    new OllamaEmbeddingGenerator(new Uri(\"http:\/\/localhost:11434\/\"), \"all-minilm\");<\/code><\/pre>\n<\/li>\n<\/ol>\n<h4>Generate embeddings<\/h4>\n<p>Now that you have an embedding generator, use it to generate embeddings for your movie data store them in your vector store.<\/p>\n<pre><code class=\"language-csharp\">foreach(var movie in movieData)\n{\n    movie.Vector = await generator.GenerateEmbeddingVectorAsync(movie.Description);\n    await movies.UpsertAsync(movie);\n}<\/code><\/pre>\n<h3>Query data<\/h3>\n<p>Now that you have data in your data store, you can query it.<\/p>\n<h4>Generate query embedding<\/h4>\n<p>Generate an embedding for the query &#8220;A family friendly movie&#8221;.<\/p>\n<pre><code class=\"language-csharp\">var query = \"A family friendly movie\";\nvar queryEmbedding = await generator.GenerateEmbeddingVectorAsync(query);<\/code><\/pre>\n<h4>Query your data store<\/h4>\n<p>Now that you have an embedding for your query, you can use it to search your data store for relevant results.<\/p>\n<pre><code class=\"language-csharp\">var searchOptions = new VectorSearchOptions()\n{\n    Top = 1,\n    VectorPropertyName = \"Vector\"\n};\n\nvar results = await movies.VectorizedSearchAsync(queryEmbedding, searchOptions);\n\nawait foreach(var result in results.Results)\n{\n    Console.WriteLine($\"Title: {result.Record.Title}\");\n    Console.WriteLine($\"Description: {result.Record.Description}\");\n    Console.WriteLine($\"Score: {result.Score}\");\n    Console.WriteLine();\n}<\/code><\/pre>\n<p>The result should look as follows:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2024\/10\/output-vectordata-query.png\" alt=\"Console output displaying Lion King as a query result\" \/><\/p>\n<h3>Continue learning<\/h3>\n<p>For detailed documentation on using the abstractions see the <a href=\"https:\/\/learn.microsoft.com\/semantic-kernel\/concepts\/vector-store-connectors\">Semantic Kernel Vector Store Learn Site<\/a>.<\/p>\n<p>Learn more from the following samples:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/microsoft\/semantic-kernel\/tree\/main\/dotnet\/samples\/Demos\/VectorStoreRAG\">RAG Sample<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/semantic-kernel\/concepts\/vector-store-connectors\/code-samples\">Microsoft.Extensions.VectorData core concepts<\/a>.<\/li>\n<\/ul>\n<h2>What&#8217;s next for Microsoft.Extensions.VectorData?<\/h2>\n<p>Similar to Microsoft.Extensions.AI, we plan to:<\/p>\n<ul>\n<li>Continue collaborating with Semantic Kernel to build on top of the abstractions as well as Microsoft.Extensions.VectorData to bring more streamlined experiences in RAG scenarios. Check out the <a href=\"https:\/\/devblogs.microsoft.com\/semantic-kernel\/microsoft-extensions-vectordata-abstractions-now-available\/\">Semantic Kernel blog<\/a> to learn more.<\/li>\n<li>Work with vector store partners in the ecosystem that offer client SDKs, library authors, and developers across the .NET ecosystem on Microsoft.Extensions.VectorData adoption.<\/li>\n<\/ul>\n<p>We\u2019re excited for you to start building using Microsoft.Extensions.VectorData.<\/p>\n<p>Try it out and give us feedback!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We are excited to introduce the Microsoft.Extensions.VectorData.Abstractions package available in preview today. This new package provides a unified abstraction layer that enables you to integrate vector stores into your .NET applications.<\/p>\n","protected":false},"author":26108,"featured_media":54302,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7781],"tags":[4,568,7885,7806],"class_list":["post-54278","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-ai","tag-net","tag-ai","tag-microsoft-extensions-ai","tag-vectordb"],"acf":[],"blog_post_summary":"<p>We are excited to introduce the Microsoft.Extensions.VectorData.Abstractions package available in preview today. This new package provides a unified abstraction layer that enables you to integrate vector stores into your .NET applications.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/54278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/26108"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=54278"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/54278\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/54302"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=54278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=54278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=54278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}