Repository navigation
Expand file tree
/
Copy pathProgram.cs
More file actions
83 lines (71 loc) · 4.58 KB
/
Copy pathProgram.cs
File metadata and controls
83 lines (71 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to persist chat history in Chroma using the ChatHistoryMemoryProvider.
// The agent can then use chat history from prior conversations to inform responses in new conversations.
using Azure.AI.OpenAI;
using Azure.AI.Projects;
using Azure.Identity;
using ChromaDB.Client;
using CommunityToolkit.VectorData.Chroma;
using Microsoft.Agents.AI;
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 chromaEndpoint = Environment.GetEnvironmentVariable("CHROMA_ENDPOINT") ?? "http://localhost:8000";
// 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);
// The project endpoint does not serve embeddings, so the embedding generator uses the endpoint of the
// Microsoft Foundry resource that hosts the project, with the same credential.
AzureOpenAIClient foundryResourceClient = new(new Uri(new Uri(endpoint).GetLeftPart(UriPartial.Authority)), credential);
using HttpClient httpClient = new();
using ChromaVectorStore vectorStore = new(
new ChromaClient(new ChromaConfigurationOptions(chromaEndpoint), httpClient),
ownsClient: true,
new ChromaVectorStoreOptions
{
EmbeddingGenerator = foundryResourceClient.GetEmbeddingClient(embeddingDeploymentName).AsIEmbeddingGenerator(),
});
var userId = $"sample-{Guid.NewGuid():N}";
// Create the agent and add the ChatHistoryMemoryProvider to store chat messages in Chroma.
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 Chroma.
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 Chroma):");
Console.WriteLine(await agent.RunAsync("Tell me a joke that I might like.", session2));