Azure AI Agents Persistent SDK for .NET. Low-level SDK for creating and managing AI agents with threads, messages, runs, and tools. Use for agent CRUD, conversation threads, streaming responses, function calling, file search, and code interpreter. Triggers: "PersistentAgentsClient", "persistent agents", "agent threads", "agent runs", "streaming agents", "function calling agents .NET".
Documentation
Azure.AI.Agents.Persistent (.NET)
Low-level SDK for creating and managing persistent AI agents with threads, messages, runs, and tools.
MODEL_DEPLOYMENT_NAME=gpt-4o-mini # Required: model deployment name
AZURE_BING_CONNECTION_ID=<bing-connection-resource-id> # Required: Bing connection resource ID
AZURE_AI_SEARCH_CONNECTION_ID=<search-connection-resource-id> # Required: Azure AI Search connection resource ID
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
using Azure.AI.Agents.Persistent;using Azure.Identity;var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>var credential = new DefaultAzureCredential( DefaultAzureCredential.DefaultEnvironmentVariableName);// Or use a specific credential directly in production:// See https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes// var credential = new ManagedIdentityCredential();PersistentAgentsClient client = new(projectEndpoint, credential);
PersistentAgentsClient├── Administration → Agent CRUD operations├── Threads → Thread management├── Messages → Message operations├── Runs → Run execution and streaming├── Files → File upload/download└── VectorStores → Vector store management
var modelDeploymentName = Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");PersistentAgent agent = await client.Administration.CreateAgentAsync( model: modelDeploymentName, name: "Math Tutor", instructions: "You are a personal math tutor. Write and run code to answer math questions.", tools: [new CodeInterpreterToolDefinition()]);
// Create threadPersistentAgentThread thread = await client.Threads.CreateThreadAsync();// Create messageawait client.Messages.CreateMessageAsync( thread.Id, MessageRole.User, "I need to solve the equation `3x + 11 = 14`. Can you help me?");
// Create runThreadRun run = await client.Runs.CreateRunAsync( thread.Id, agent.Id, additionalInstructions: "Please address the user as Jane Doe.");// Poll for completiondo{ await Task.Delay(TimeSpan.FromMilliseconds(500)); run = await client.Runs.GetRunAsync(thread.Id, run.Id);}while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);// Retrieve messagesawait foreach (PersistentThreadMessage message in client.Messages.GetMessagesAsync( threadId: thread.Id, order: ListSortOrder.Ascending)){ Console.Write($"{message.Role}: "); foreach (MessageContent content in message.ContentItems) { if (content is MessageTextContent textContent) Console.WriteLine(textContent.Text); }}
AsyncCollectionResult<StreamingUpdate> stream = client.Runs.CreateRunStreamingAsync( thread.Id, agent.Id);await foreach (StreamingUpdate update in stream){ if (update.UpdateKind == StreamingUpdateReason.RunCreated) { Console.WriteLine("--- Run started! ---"); } else if (update is MessageContentUpdate contentUpdate) { Console.Write(contentUpdate.Text); } else if (update.UpdateKind == StreamingUpdateReason.RunCompleted) { Console.WriteLine("\n--- Run completed! ---"); }}
// Define function toolFunctionToolDefinition weatherTool = new( name: "getCurrentWeather", description: "Gets the current weather at a location.", parameters: BinaryData.FromObjectAsJson(new { Type = "object", Properties = new { Location = new { Type = "string", Description = "City and state, e.g. San Francisco, CA" }, Unit = new { Type = "string", Enum = new[] { "c", "f" } } }, Required = new[] { "location" } }, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }));// Create agent with functionPersistentAgent agent = await client.Administration.CreateAgentAsync( model: modelDeploymentName, name: "Weather Bot", instructions: "You are a weather bot.", tools: [weatherTool]);// Handle function calls during pollingdo{ await Task.Delay(500); run = await client.Runs.GetRunAsync(thread.Id, run.Id); if (run.Status == RunStatus.RequiresAction && run.RequiredAction is SubmitToolOutputsAction submitAction) { List<ToolOutput> outputs = []; foreach (RequiredToolCall toolCall in submitAction.ToolCalls) { if (toolCall is RequiredFunctionToolCall funcCall) { // Execute function and get result string result = ExecuteFunction(funcCall.Name, funcCall.Arguments); outputs.Add(new ToolOutput(toolCall, result)); } } run = await client.Runs.SubmitToolOutputsToRunAsync(run, outputs, toolApprovals: null); }}while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);