-
Notifications
You must be signed in to change notification settings - Fork 2.1k
.NET: Add Cosmos NoSQL vector memory sample #7552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Saurish (nos-redacted)
wants to merge
6
commits into
microsoft:main
Choose a base branch
from
nos-redacted:rank4-cosmos-nosql-memory-sample
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
6f8c73c
.NET: Add Cosmos NoSQL vector memory sample
nosxredacted-hash 862b907
Address Cosmos memory sample review feedback
nosxredacted-hash e08d31d
Merge branch 'main' into rank4-cosmos-nosql-memory-sample
nos-redacted bd8fde9
Merge branch 'main' into rank4-cosmos-nosql-memory-sample
nos-redacted c7b9225
Merge branch 'main' into rank4-cosmos-nosql-memory-sample
nos-redacted c45fd57
Merge branch 'main' into rank4-cosmos-nosql-memory-sample
nos-redacted File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...Memory_Step08_MemoryUsingCosmosNoSql/AgentWithMemory_Step08_MemoryUsingCosmosNoSql.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFrameworks>net10.0</TargetFrameworks> | ||
|
|
||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Azure.Identity" /> | ||
| <PackageReference Include="CommunityToolkit.VectorData.CosmosNoSql" /> | ||
| <PackageReference Include="Microsoft.Azure.Cosmos" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Foundry\Microsoft.Agents.AI.Foundry.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
92 changes: 92 additions & 0 deletions
92
...amples/02-agents/AgentWithMemory/AgentWithMemory_Step08_MemoryUsingCosmosNoSql/Program.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
|
|
||
| // This sample shows how to persist chat history in Azure Cosmos DB for NoSQL using the ChatHistoryMemoryProvider. | ||
| // The agent can then use chat history from prior conversations to inform responses in new conversations. | ||
|
|
||
| using System.Text.Json; | ||
| using Azure.AI.Projects; | ||
| using Azure.Identity; | ||
| using CommunityToolkit.VectorData.CosmosNoSql; | ||
| using Microsoft.Agents.AI; | ||
| using Microsoft.Azure.Cosmos; | ||
| using Microsoft.Extensions.AI; | ||
| using Microsoft.Extensions.VectorData; | ||
|
|
||
| var endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."); | ||
| var deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini"; | ||
| var embeddingDeploymentName = Environment.GetEnvironmentVariable("FOUNDRY_EMBEDDING_MODEL") ?? "text-embedding-3-large"; | ||
| var embeddingDimensions = 3072; | ||
| if (Environment.GetEnvironmentVariable("FOUNDRY_EMBEDDING_DIMENSIONS") is string embeddingDimensionsValue && | ||
| (!int.TryParse(embeddingDimensionsValue, out embeddingDimensions) || embeddingDimensions <= 0)) | ||
| { | ||
| throw new InvalidOperationException("FOUNDRY_EMBEDDING_DIMENSIONS must be a positive integer."); | ||
| } | ||
| var cosmosEndpoint = Environment.GetEnvironmentVariable("COSMOS_ENDPOINT") ?? throw new InvalidOperationException("COSMOS_ENDPOINT is not set."); | ||
|
nos-redacted marked this conversation as resolved.
|
||
| var cosmosDatabaseName = Environment.GetEnvironmentVariable("COSMOS_DATABASE_NAME") ?? "agent-memory"; | ||
|
|
||
| // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. | ||
| // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid | ||
| // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. | ||
| DefaultAzureCredential credential = new(); | ||
| AIProjectClient aiProjectClient = new(new Uri(endpoint), credential); | ||
|
|
||
| using CosmosClient cosmosClient = new( | ||
| cosmosEndpoint, | ||
| credential, | ||
| new CosmosClientOptions | ||
| { | ||
| UseSystemTextJsonSerializerWithOptions = JsonSerializerOptions.Default, | ||
| }); | ||
|
|
||
| DatabaseResponse databaseResponse = await cosmosClient.CreateDatabaseIfNotExistsAsync(cosmosDatabaseName); | ||
|
|
||
| VectorStore vectorStore = new CosmosNoSqlVectorStore( | ||
| databaseResponse.Database, | ||
| new CosmosNoSqlVectorStoreOptions | ||
| { | ||
| JsonSerializerOptions = JsonSerializerOptions.Default, | ||
| EmbeddingGenerator = aiProjectClient | ||
| .GetProjectOpenAIClient() | ||
| .GetEmbeddingClient(embeddingDeploymentName) | ||
| .AsIEmbeddingGenerator(), | ||
| }); | ||
|
|
||
| var userId = $"sample-{Guid.NewGuid():N}"; | ||
|
|
||
| // Create the agent and add the ChatHistoryMemoryProvider to store chat messages in Cosmos DB. | ||
| AIAgent agent = aiProjectClient | ||
| .AsAIAgent(new ChatClientAgentOptions | ||
| { | ||
| ChatOptions = new() { ModelId = deploymentName, Instructions = "You are good at telling jokes." }, | ||
| Name = "Joker", | ||
| AIContextProviders = [new ChatHistoryMemoryProvider( | ||
| vectorStore, | ||
| collectionName: "chathistory", | ||
| vectorDimensions: embeddingDimensions, | ||
| // Callback to configure the initial state of the ChatHistoryMemoryProvider. | ||
| // The ChatHistoryMemoryProvider stores its state in the AgentSession and this callback | ||
| // will be called whenever the ChatHistoryMemoryProvider cannot find existing state in the session, | ||
| // typically the first time it is used with a new session. | ||
| _ => new ChatHistoryMemoryProvider.State( | ||
| // Configure the scope values under which chat messages will be stored. | ||
| // In this case, we are using a per-run user ID and a unique session ID for each new session. | ||
| storageScope: new() { UserId = userId, SessionId = Guid.NewGuid().ToString("N") }, | ||
| // Configure the scope which would be used to search for relevant prior messages. | ||
| // In this case, we are searching for any messages for the user across all sessions. | ||
| searchScope: new() { UserId = userId }))] | ||
| }); | ||
|
|
||
| // Start a new session for the agent conversation. | ||
| AgentSession session = await agent.CreateSessionAsync(); | ||
|
|
||
| // Run the agent with the session that stores conversation history in Cosmos DB. | ||
| Console.WriteLine("First session:"); | ||
| Console.WriteLine(await agent.RunAsync("I like jokes about Pirates. Tell me a joke about a pirate.", session)); | ||
|
|
||
| // Start a second session. Since we configured the search scope to be across all sessions for the user, | ||
| // the agent should remember that the user likes pirate jokes. | ||
| AgentSession session2 = await agent.CreateSessionAsync(); | ||
|
|
||
| // Run the agent with the second session. | ||
| Console.WriteLine("Second session (recalling prior chat history from Cosmos DB):"); | ||
| Console.WriteLine(await agent.RunAsync("Tell me a joke that I might like.", session2)); | ||
41 changes: 41 additions & 0 deletions
41
...-agents/AgentWithMemory/AgentWithMemory_Step08_MemoryUsingCosmosNoSql/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # Agent with Memory Using Azure Cosmos DB for NoSQL | ||
|
|
||
| This sample uses `ChatHistoryMemoryProvider` with `CosmosNoSqlVectorStore` to persist chat history in Azure Cosmos DB for NoSQL and recall relevant messages in a new agent session. | ||
|
|
||
| ## Features Demonstrated | ||
|
|
||
| - Authenticating to Microsoft Foundry and Azure Cosmos DB with `DefaultAzureCredential` | ||
| - Storing chat messages in an Azure Cosmos DB vector store | ||
| - Creating the configured database and chat-history container when they do not exist | ||
| - Recalling relevant chat history across agent sessions | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| 1. [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) | ||
| 2. A Microsoft Foundry project with: | ||
| - A chat model deployment (the default is `gpt-5.4-mini`) | ||
| - A `text-embedding-3-large` deployment with 3,072 dimensions | ||
| 3. An Azure Cosmos DB for NoSQL account with [vector search enabled](https://learn.microsoft.com/azure/cosmos-db/nosql/vector-search) | ||
| 4. An Azure identity that can create the configured database and container and read and write items | ||
| 5. Azure CLI authentication (`az login`) | ||
|
|
||
| ## Configuration | ||
|
|
||
| Set the following environment variables: | ||
|
|
||
| | Variable | Description | Default | | ||
| |---|---|---| | ||
| | `FOUNDRY_PROJECT_ENDPOINT` | Microsoft Foundry project endpoint | *(required)* | | ||
| | `COSMOS_ENDPOINT` | Azure Cosmos DB account endpoint | *(required)* | | ||
| | `FOUNDRY_MODEL` | Chat model deployment name | `gpt-5.4-mini` | | ||
| | `FOUNDRY_EMBEDDING_MODEL` | Embedding model deployment name | `text-embedding-3-large` | | ||
| | `FOUNDRY_EMBEDDING_DIMENSIONS` | Number of dimensions produced by the embedding deployment | `3072` | | ||
| | `COSMOS_DATABASE_NAME` | Database used to store agent memory | `agent-memory` | | ||
|
|
||
| ## Run the Sample | ||
|
|
||
| ```bash | ||
| dotnet run | ||
| ``` | ||
|
|
||
| The first session stores the user's preference for pirate jokes. The second session uses a different `AgentSession` but the same per-run user search scope, allowing the agent to retrieve that preference from Azure Cosmos DB without recalling data from earlier sample runs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.