Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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".
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 43% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 67% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 82% | 0% |
Low-level SDK for creating and managing persistent AI agents with threads, messages, runs, and tools.
bashdotnet add package Azure.AI.Agents.Persistent --prerelease dotnet add package Azure.Identity
Current Versions: Stable v1.1.0, Preview v1.2.0-beta.8
bashPROJECT_ENDPOINT=https://<resource>.services.ai.azure.com/api/projects/<project> # Required: Azure AI project endpoint 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
csharpusing 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 managementcsharpvar 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()] );
csharp// Create thread PersistentAgentThread thread = await client.Threads.CreateThreadAsync(); // Create message await client.Messages.CreateMessageAsync( thread.Id, MessageRole.User, "I need to solve the equation `3x + 11 = 14`. Can you help me?" );
csharp// Create run ThreadRun run = await client.Runs.CreateRunAsync( thread.Id, agent.Id, additionalInstructions: "Please address the user as Jane Doe." ); // Poll for completion do { 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 messages await 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); } }
csharpAsyncCollectionResult<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! ---"); } }
csharp// Define function tool FunctionToolDefinition 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 function PersistentAgent agent = await client.Administration.CreateAgentAsync( model: modelDeploymentName, name: "Weather Bot", instructions: "You are a weather bot.", tools: [weatherTool] ); // Handle function calls during polling do { 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);
csharp// Upload file PersistentAgentFileInfo file = await client.Files.UploadFileAsync( filePath: "document.txt", purpose: PersistentAgentFilePurpose.Agents ); // Create vector store PersistentAgentsVectorStore vectorStore = await client.VectorStores.CreateVectorStoreAsync( fileIds: [file.Id], name: "my_vector_store" ); // Create file search resource FileSearchToolResource fileSearchResource = new(); fileSearchResource.VectorStoreIds.Add(vectorStore.Id); // Create agent with file search PersistentAgent agent = await client.Administration.CreateAgentAsync( model: modelDeploymentName, name: "Document Assistant", instructions: "You help users find information in documents.", tools: [new FileSearchToolDefinition()], toolResources: new ToolResources { FileSearch = fileSearchResource } );
csharpvar bingConnectionId = Environment.GetEnvironmentVariable("AZURE_BING_CONNECTION_ID"); BingGroundingToolDefinition bingTool = new( new BingGroundingSearchToolParameters( [new BingGroundingSearchConfiguration(bingConnectionId)] ) ); PersistentAgent agent = await client.Administration.CreateAgentAsync( model: modelDeploymentName, name: "Search Agent", instructions: "Use Bing to answer questions about current events.", tools: [bingTool] );
csharpAzureAISearchToolResource searchResource = new( connectionId: searchConnectionId, indexName: "my_index", topK: 5, filter: "category eq 'documentation'", queryType: AzureAISearchQueryType.Simple ); PersistentAgent agent = await client.Administration.CreateAgentAsync( model: modelDeploymentName, name: "Search Agent", instructions: "Search the documentation index to answer questions.", tools: [new AzureAISearchToolDefinition()], toolResources: new ToolResources { AzureAISearch = searchResource } );
csharpawait client.Threads.DeleteThreadAsync(thread.Id); await client.Administration.DeleteAgentAsync(agent.Id); await client.VectorStores.DeleteVectorStoreAsync(vectorStore.Id); await client.Files.DeleteFileAsync(file.Id);
| Tool | Class | Purpose | |------|-------|---------| | Code Interpreter | CodeInterpreterToolDefinition | Execute Python code, generate visualizations | | File Search | FileSearchToolDefinition | Search uploaded files via vector stores | | Function Calling | FunctionToolDefinition | Call custom functions | | Bing Grounding | BingGroundingToolDefinition | Web search via Bing | | Azure AI Search | AzureAISearchToolDefinition | Search Azure AI Search indexes | | OpenAPI | OpenApiToolDefinition | Call external APIs via OpenAPI spec | | Azure Functions | AzureFunctionToolDefinition | Invoke Azure Functions | | MCP | MCPToolDefinition | Model Context Protocol tools | | SharePoint | SharepointToolDefinition | Access SharePoint content | | Microsoft Fabric | MicrosoftFabricToolDefinition | Access Fabric data |
| Update Type | Description | |-------------|-------------| | StreamingUpdateReason.RunCreated | Run started | | StreamingUpdateReason.RunInProgress | Run processing | | StreamingUpdateReason.RunCompleted | Run finished | | StreamingUpdateReason.RunFailed | Run errored | | MessageContentUpdate | Text content chunk | | RunStepUpdate | Step status change |
| Type | Purpose | |------|---------| | PersistentAgentsClient | Main entry point | | PersistentAgent | Agent with model, instructions, tools | | PersistentAgentThread | Conversation thread | | PersistentThreadMessage | Message in thread | | ThreadRun | Execution of agent against thread | | RunStatus | Queued, InProgress, RequiresAction, Completed, Failed | | ToolResources | Combined tool resources | | ToolOutput | Function call response |
using statements or explicit disposalRequiresAction, Failed, Cancelledcsharpusing Azure; try { var agent = await client.Administration.CreateAgentAsync(...); } catch (RequestFailedException ex) when (ex.Status == 404) { Console.WriteLine("Resource not found"); } catch (RequestFailedException ex) { Console.WriteLine($"Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}"); }
| SDK | Purpose | Install | |-----|---------|---------| | Azure.AI.Agents.Persistent | Low-level agents (this SDK) | dotnet add package Azure.AI.Agents.Persistent | | Azure.AI.Projects | High-level project client | dotnet add package Azure.AI.Projects |
| Resource | URL | |----------|-----| | NuGet Package | https://www.nuget.org/packages/Azure.AI.Agents.Persistent | | API Reference | https://learn.microsoft.com/dotnet/api/azure.ai.agents.persistent | | GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent | | Samples | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Agents.Persistent/samples |
Other measured skills in the registry, with their headline benchmark lift.