Azure.AI.Projects.Agents
3.0.0-beta.1
Prefix Reserved
dotnet add package Azure.AI.Projects.Agents --version 3.0.0-beta.1
NuGet\Install-Package Azure.AI.Projects.Agents -Version 3.0.0-beta.1
<PackageReference Include="Azure.AI.Projects.Agents" Version="3.0.0-beta.1" />
<PackageVersion Include="Azure.AI.Projects.Agents" Version="3.0.0-beta.1" />
<PackageReference Include="Azure.AI.Projects.Agents" />
paket add Azure.AI.Projects.Agents --version 3.0.0-beta.1
#r "nuget: Azure.AI.Projects.Agents, 3.0.0-beta.1"
#:package Azure.AI.Projects.Agents@3.0.0-beta.1
#addin nuget:?package=Azure.AI.Projects.Agents&version=3.0.0-beta.1&prerelease
#tool nuget:?package=Azure.AI.Projects.Agents&version=3.0.0-beta.1&prerelease
Azure AI Projects Agents client library for .NET
Develop Agents using the Azure AI Foundry platform, leveraging an extensive ecosystem of models, tools, and capabilities from OpenAI, Microsoft, and other LLM providers.
Note: This package is dedicated to performing CRUD operations on Agents and can be used to enable telemetry.
Product documentation | Samples | API reference documentation | Package (NuGet) | SDK source code
Table of contents
- Getting started
- Key concepts
- Additional concepts
- Examples
- Tracing
- Troubleshooting
- Next steps
- Contributing
Getting started
Prerequisites
To use Azure AI Agents capabilities, you must have an Azure subscription. This will allow you to create an Azure AI resource and get a connection URL.
Install the package
Install the client library for .NET with NuGet:
dotnet add package Azure.AI.Projects.Agents --prerelease
You must have an Azure subscription. In order to take advantage of the C# 8.0 syntax, it is recommended that you compile using the .NET Core SDK 3.0 or higher with a language version of
latest.
Authenticate the client
To be able to create, update, and delete Agents, please use AgentAdministrationClient. It is a good practice to only allow these operations for users with elevated permissions, for example, administrators.
var projectEndpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL_NAME");
AgentAdministrationClient agentsClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
Key concepts
Service API versions
When clients send REST requests to the endpoint, one of the query parameters is api-version. It allows us to select the API versions supporting different features. The current stable version is v1 (default).
Select a service API version
The API version may be set by supplying the version parameter to the AgentAdministrationClientOptions constructor as shown in the example code below.
AgentAdministrationClientOptions options = new(version: AgentAdministrationClientOptions.ServiceVersion.V1);
AgentAdministrationClient agentsClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential(), options: options);
Additional concepts
The Azure.AI.Projects.Agents framework is organized so that for each call requiring a REST API request, there are synchronous and asynchronous counterparts, where the latter has the "Async" suffix. For example, the following code demonstrates the creation of a ProjectsAgentVersion object.
Synchronous call:
DeclarativeAgentDefinition agentDefinition = new(model: modelDeploymentName)
{
Instructions = "You are a prompt agent."
};
ProjectsAgentVersion agentVersion1 = agentsClient.CreateAgentVersion(
agentName: "myAgent1",
options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion1.Id}, name: {agentVersion1.Name}, version: {agentVersion1.Version})");
ProjectsAgentVersion agentVersion2 = agentsClient.CreateAgentVersion(
agentName: "myAgent2",
options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion2.Id}, name: {agentVersion2.Name}, version: {agentVersion2.Version})");
Asynchronous call:
DeclarativeAgentDefinition agentDefinition = new(model: modelDeploymentName)
{
Instructions = "You are a prompt agent."
};
ProjectsAgentVersion agentVersion1 = await agentsClient.CreateAgentVersionAsync(
agentName: "myAgent1",
options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion1.Id}, name: {agentVersion1.Name}, version: {agentVersion1.Version})");
ProjectsAgentVersion agentVersion2 = await agentsClient.CreateAgentVersionAsync(
agentName: "myAgent2",
options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion2.Id}, name: {agentVersion2.Name}, version: {agentVersion2.Version})");
In most of the code snippets we will show only the asynchronous sample for brevity. Please refer to the individual samples for both synchronous and asynchronous code.
Examples
Declarative Agents
When creating Agents, we need to supply Agent definitions to the constructor. To create a declarative prompt Agent, use the DeclarativeAgentDefinition:
DeclarativeAgentDefinition agentDefinition = new(model: modelDeploymentName)
{
Instructions = "You are a prompt agent."
};
ProjectsAgentVersion agentVersion1 = await agentsClient.CreateAgentVersionAsync(
agentName: "myAgent1",
options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion1.Id}, name: {agentVersion1.Name}, version: {agentVersion1.Version})");
ProjectsAgentVersion agentVersion2 = await agentsClient.CreateAgentVersionAsync(
agentName: "myAgent2",
options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion2.Id}, name: {agentVersion2.Name}, version: {agentVersion2.Version})");
The code above will result in the creation of a ProjectsAgentVersion object, which is the data object containing the Agent's name and version.
Agent version drafts
Note: This is a preview feature; to use it the AAIP001 warning needs to be ignored.
#pragma warning disable AAIP001
If the Agent Version is not ready for production, it may be created with the Draft flag set to true. The draft Agent version
is a string like draft-1784249270168. The draft will not be set as the Agent's latest version.
Create AgentAdministrationClient with the draft feature enabled:
var projectEndpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL_NAME");
AgentAdministrationClient agentsClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
Create a draft version:
agentDefinition = new(model: modelDeploymentName)
{
Instructions = "You are a prompt agent which gives wrong answers with 0.1 probability."
};
ProjectsAgentVersion agentVersionDraft = await agentsClient.CreateAgentVersionAsync(
agentName: agent.Name,
options: new(agentDefinition)
{
Draft = true
}
);
Console.WriteLine($"Agent created draft name: {agentVersionDraft.Name}, version: {agentVersionDraft.Version}");
agent = await agentsClient.GetAgentAsync(agentName: agentVersion1.Name);
Console.WriteLine($"The latest version of agent \"{agent.Name}\" is still {agent.Versions.Latest.Version}.");
By default, draft versions are not listed. To include them, includeDrafts needs to be set to true.
Console.WriteLine($"Here are \"release\" versions of the agent {agent.Name}:");
await foreach (ProjectsAgentVersion agentVersion in agentsClient.GetAgentVersionsAsync(agentName: agent.Name, includeDrafts: true))
{
Console.WriteLine($" {agentVersion.Version}, is draft: {agentVersion.Draft ?? false}");
}
Hosted Agents
Hosted agents simplify custom agent deployment in a fully controlled environment (see more).
Hosted Agents from Docker images<a id="hosted-docker-based"></a>
To create a hosted agent from an existing Docker image, please use the HostedAgentDefinition while creating the AgentVersion object.
private static HostedAgentDefinition GetAgentDefinition(string dockerImage)
{
HostedAgentDefinition agentDefinition = new(
versions: [new ProtocolVersionRecord(ProjectsAgentProtocol.Responses, "1.0.0")],
cpu: "0.5",
memory: "1Gi"
)
{
ContainerConfiguration = new(dockerImage),
};
return agentDefinition;
}
The following code will deploy the hosted Agent.
Uri uriEndpoint = new(projectEndpoint);
AgentAdministrationClient agentsClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
HostedAgentDefinition agentDefinition = GetAgentDefinition(
dockerImage: dockerImage
);
ProjectsAgentVersionCreationOptions creationOptions = new(agentDefinition);
creationOptions.Metadata["enableVnextExperience"] = "true";
ProjectsAgentVersion agentVersion = await agentsClient.CreateAgentVersionAsync(
agentName: hostedAgentName,
options: creationOptions);
while (agentVersion.Status != AgentVersionStatus.Active && agentVersion.Status != AgentVersionStatus.Failed)
{
await Task.Delay(TimeSpan.FromMilliseconds(500));
agentVersion = await agentsClient.GetAgentVersionAsync(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
}
if (agentVersion.Status != AgentVersionStatus.Active)
{
throw new InvalidOperationException($"Agent deployment failed, status: {agentVersion.Status}.");
}
Hosted Agents from Code<a id="hosted-code-based"></a>
Hosted Agents can also be deployed using local code. To deploy the Agent from code, please prepare the folder with the Agent code and dependencies. In the example below, we use C# source code.
- Create a project and add
Azure.AI.AgentServer.Responsespackage as a dependency.
dotnet new console --name EchoAgent --output EchoAgent
dotnet add package Azure.AI.AgentServer.Responses --prerelease
- Populate the code in Program.cs
using Azure.AI.AgentServer.Responses;
using Azure.AI.AgentServer.Responses.Models;
ResponsesServer.Run<EchoHandler>();
public class EchoHandler : ResponseHandler
{
public override IAsyncEnumerable<ResponseStreamEvent> CreateAsync(
CreateResponse request,
ResponseContext context,
CancellationToken cancellationToken)
{
return new TextResponse(context, request,
createText: async ct =>
{
var input = await context.GetInputTextAsync(cancellationToken: ct);
return $"Echo: {input}";
});
}
}
- Compile the application.
dotnet publish
This will create the publish output in the bin\Release\net%version%\publish\ folder, where %version% is the .NET version used to build the application.
4. Copy the contents of publish folder to Assets/AgentsCode.
Note: In this example we are uploading the project. It is also possible to place source codes and a C# project file to the Assets/AgentsCode folder. In this case we will need to set dependencyResolution: CodeDependencyResolution.RemoteBuild.
Prepare the metadata for Agent:
private static AgentVersionFromCodeMetadata GetAgentMetadata()
{
HostedAgentDefinition agentDefinition = new(
cpu: "0.5",
memory: "1Gi"
)
{
Versions = { new ProtocolVersionRecord(ProjectsAgentProtocol.Responses, "1.0.0") },
CodeConfiguration = new(
runtime: "dotnet_10",
entryPoint: ["dotnet", "EchoAgent.dll"],
dependencyResolution: CodeDependencyResolution.Bundled
),
};
AgentVersionFromCodeMetadata metadata = new(agentDefinition);
metadata.Metadata["enableVnextExperience"] = "true";
return metadata;
}
Deploy the Agent.
AgentAdministrationClient agentsClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
ProjectsAgentVersion agentVersion = await agentsClient.CreateAgentVersionFromCodeAsync(
agentName: "myCodeAgent",
filePath: GetDirectory(Path.Combine(["AgentsCode"])),
metadata: GetAgentMetadata()
);
while (agentVersion.Status != AgentVersionStatus.Active && agentVersion.Status != AgentVersionStatus.Failed)
{
await Task.Delay(500);
agentVersion = await agentsClient.GetAgentVersionAsync(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
}
if (agentVersion.Status != AgentVersionStatus.Active)
{
throw new InvalidOperationException($"The Agent deployment failed, status: {agentVersion.Status}");
}
Enabling and disabling Hosted Agents<a id="hosted-agent-management"></a>
Hosted agents may be disabled. In this case, the task running in an existing session will complete, but no new tasks or session creations will be allowed. An attempt to create a session on a disabled Agent will result in a 403 error.
await agentsClient.DisableAgentAsync(agentVersion.Name);
// The new session cannot be created.
try
{
await agentsClient.CreateSessionAsync(agentVersion.Name, new VersionRefIndicator(agentVersion.Version));
throw new InvalidOperationException("Stopped Agent was unexpectedly able to create session.");
}
catch (ClientResultException ex)
{
if (ex.Status != 403)
{
throw;
}
Console.WriteLine(ex.Message);
}
The disabled Agent may be enabled, and it will be able to accept requests and sessions again.
await agentsClient.EnableAgentAsync(agentVersion.Name);
ProjectAgentSession session2 = await agentsClient.CreateSessionAsync(agentVersion.Name, new VersionRefIndicator(agentVersion.Version));
Console.WriteLine($"The session {session2.AgentSessionId} was created.");
External Agents
Note: This is a preview feature; to use it the AAIP001 warning needs to be ignored.
In this example we will demonstrate management of External Agents step by step. External Agents are the third-party Agents hosted outside Foundry (for example, on GCP or AWS). Registration is metadata-only: Foundry records the agent definition to light up observability experiences (traces, evaluations) over customer-emitted OpenTelemetry data.
To create an External Agent, we need to provide the ExternalAgentDefinition with an OpenTelemetry agent identifier,
used to attribute customer-emitted spans to this Foundry agent, in the CreateAgentVersionAsync or CreateAgentVersion method.
ExternalAgentDefinition agentDefinition = new()
{
OtelAgentId = "sample-external-agent",
};
ProjectsAgentVersionCreationOptions agentOptions = new(agentDefinition)
{
Description = "External agent registered by the azure-ai-projects sample.",
Metadata = {
{ "sample", "external_agents_crud" },
{ "status", "created" }
}
};
ProjectsAgentVersion agentVersion = await agentsClient.CreateAgentVersionAsync(
agentName: "myExternalAgent1",
options: agentOptions);
Console.WriteLine($"Agent created (id: {agentVersion.Id}, name: {agentVersion.Name}, version: {agentVersion.Version})");
Toolboxes
Toolboxes allow us to store tools in Azure so that they can be retrieved and used by the Agents.
In the example below we create two versions of an MCP tool and save them to Azure.
MCPToolboxTool tool = new(serverLabel: "api-specs")
{
Name = "mcp-tool",
Description = "Sample MCP tool",
ServerUri = new Uri("https://gitmcp.io/Azure/azure-rest-api-specs"),
ToolCallApprovalPolicy = new McpToolCallApprovalPolicy(GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval)
};
ToolboxVersion toolBox1 = await toolboxClient.CreateVersionAsync(
name: toolboxName,
tools: [tool],
description: "Example toolbox created by the azure-ai-projects sample.",
metadata: new Dictionary<string, string> {
{"team", "Engineers"}
}
);
ToolboxVersion toolBox2 = await toolboxClient.CreateVersionAsync(
name: toolboxName,
tools: [tool],
description: "Another toolbox created by the azure-ai-projects sample.",
metadata: new Dictionary<string, string> {
{"team", "Data scientists"}
}
);
string status = "unknown status";
toolBox1.Metadata?.TryGetValue("team", out status);
Console.WriteLine($"Toolbox: {toolBox1.Name}, version: {toolBox1.Version}, (tools: {toolBox1.Tools.Count}) (team: {status}).");
There are two objects which help to work with the Toolboxes: ToolboxRecord and ToolboxVersion. ToolboxRecord can be retrieved by
name, and it contains the default version of the Toolbox.
ToolboxRecord record = await toolboxClient.GetAsync(name: toolBox1.Name);
Console.WriteLine($"The default version for a toolbox {record.Name} is {record.DefaultVersion}");
The name of the Toolbox and its version allow us to get the ToolboxVersion, which contains the tools that can be used by an Agent.
ToolboxVersion toolBox = await toolboxClient.GetVersionAsync(record.Name, record.DefaultVersion);
Console.WriteLine($"Retrieved toolbox: {toolBox.Name} ({toolBox.Id})");
Sessions
Sessions allow multiple users to use the same hosted Agent within their own sandboxed environment. In the example below we create two sessions for the same agent version.
string sessionId1 = Guid.NewGuid().ToString();
string sessionId2 = Guid.NewGuid().ToString();
ProjectAgentSession session1 = await agentsClient.CreateSessionAsync(
agentName: agentVersion.Name,
agentSessionId: sessionId1,
versionIndicator: new VersionRefIndicator(agentVersion.Version)
);
Console.WriteLine($"Created session with ID {session1.AgentSessionId}");
ProjectAgentSession session2 = await agentsClient.CreateSessionAsync(
agentName: agentVersion.Name,
agentSessionId: sessionId2,
versionIndicator: new VersionRefIndicator(agentVersion.Version)
);
Console.WriteLine($"Created session with ID {session2.AgentSessionId}");
while (session1.Status != AgentSessionStatus.Failed && session1.Status != AgentSessionStatus.Active)
{
await Task.Delay(TimeSpan.FromMilliseconds(500));
session1 = await agentsClient.GetSessionAsync(agentName: agentVersion.Name, sessionId: session1.AgentSessionId);
}
while (session2.Status != AgentSessionStatus.Failed && session2.Status != AgentSessionStatus.Active)
{
await Task.Delay(TimeSpan.FromMilliseconds(500));
session2 = await agentsClient.GetSessionAsync(agentName: agentVersion.Name, sessionId: session2.AgentSessionId);
}
It is also possible to upload files to the session store, so that they will only be accessible inside their session.
To use this feature we need to create the AgentSessionFiles client:
ProjectsAgentVersion agentVersion = await agentsClient.GetAgentVersionAsync(
agentName: hostedAgentName,
agentVersion: hostedAgentVersion);
string sessionId = Guid.NewGuid().ToString("N");
ProjectAgentSession session = await agentsClient.CreateSessionAsync(
agentName: agentVersion.Name,
agentSessionId: sessionId,
versionIndicator: new VersionRefIndicator(agentVersion.Version)
);
AgentSessionFiles sessionClient = agentsClient.GetAgentSessionFiles(agentVersion.Name, session.AgentSessionId);
while (session.Status != AgentSessionStatus.Failed && session.Status != AgentSessionStatus.Active)
{
await Task.Delay(TimeSpan.FromMilliseconds(500));
session = await agentsClient.GetSessionAsync(agentName: agentVersion.Name, sessionId: session.AgentSessionId);
}
Skills
Note: This is a preview feature; to use it the AAIP001 warning needs to be ignored.
Skills can be used to provide portable packages of instructions for Agents. Azure.AI.Projects.Agents allows
managing skills in Microsoft Foundry. Skills may be created from a folder with instructions or on-the-fly.
AgentsSkill skillFromFile = await skillsClient.CreateSkillVersionFromFilesAsync("roll-dice", GetDirectory("roll-dice"));
Console.WriteLine($"Created skillfrom directory {skillFromFile.Name}, Id: {skillFromFile.Id}");
SkillInlineContent content = new(
description: "Calculates the sum of two numbers.",
instructions: """
To calculate the sum run
bash:
echo $((<first> + <second>))
powershell:
(<first> + <second>)
Replace <first> and <second> by the actual summation arguments.
"""
);
SkillVersion simpleSkill = await skillsClient.CreateSkillVersionAsync(name: "simple-skill", inlineContent: content);
Console.WriteLine($"Created skill {simpleSkill.Name}: {simpleSkill.Description}");
For more information on skills, please see the Microsoft Learn page.
Agent endpoints
Note: This is a preview feature; to use it the AAIP001 warning needs to be ignored.
The hosted agent can be further configured by using the PatchAgentObject and PatchAgentObjectAsync methods.
- Retrieve the agent
ProjectsAgentVersion agentVersion = await agentsClient.GetAgentVersionAsync(
agentName: hostedAgentName,
agentVersion: hostedAgentVersion);
Console.WriteLine($"Retrieved agent {agentVersion.Name}, v. {agentVersion.Version}");
- Create the skill.
SkillInlineContent content = new(
description: "Calculates the sum of two numbers.",
instructions: """
To calculate the sum run
bash:
echo $((<first> + <second>))
powershell:
(<first> + <second>)
Replace <first> and <second> by the actual summation arguments.
"""
);
SkillVersion simpleSkill = await skillsClient.CreateSkillVersionAsync(name: "simpleSkill", inlineContent: content);
- We will configure the hosted agent so that it will route 74% of the traffic to the endpoint and will also make it aware of the skill we have created.
AgentEndpointConfiguration config = new()
{
VersionSelector = new([new FixedRatioVersionSelectionRule(agentVersion: agentVersion.Version, trafficPercentage: 74)]),
ProtocolConfiguration = new()
{
Responses = new()
}
};
AgentCard card = new(version: "1", [new AgentCardSkill(id: simpleSkill.Id, name: SKILL)]);
PatchAgentOptions patchOptions = new()
{
AgentEndpoint = config,
AgentCard = card
};
ProjectsAgentRecord patchedRecord = await agentsClient.PatchAgentAsync(
agentName: hostedAgentName,
patchAgentOptions: patchOptions);
Console.WriteLine($"The Agent {patchedRecord.Name} was patched.");
Streaming the logs
The most probable reason for an error during session creation is the failure of a main script in the agent container.
The hosted agent container logs can be streamed using AgentAdministrationClient methods GetSessionLogStream
and GetSessionLogStreamAsync.
ProjectAgentSession session = await agentsClient.CreateSessionAsync(
agentName: agentVersion.Name,
versionIndicator: new VersionRefIndicator(agentVersion.Version)
);
SessionLogEvent logEvent = await agentsClient.GetSessionLogStreamAsync(agentName: agentVersion.Name, agentVersion: agentVersion.Version, sessionId: session.AgentSessionId);
Console.WriteLine(logEvent.Data);
Agent optimization
Agent performance may be improved by optimizing the models used, skill text, system prompt, and tool descriptions. The AgentOptimizationJobs client allows
managing these tasks.
var projectEndpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL_NAME");
var anotherModelDeploymentName = System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL_NAME2");
AgentAdministrationClient agentsClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
AgentOptimizationJobs jobsClient = agentsClient.GetAgentOptimizationJobs();
An Agent optimization job accepts optimization criteria, evaluators, and several models as parameters. It also accepts baselines used as an optimization starting point. Several models need to be defined for different purposes:
OptimizationModel- reads the Agent evaluation result and reason and creates the improved target description: system prompt, tool description or skill.EvalModel- used for Agent evaluation.model_search_space- the models considered during Agent optimization.model- the model used by Hosted Agent, for Declarative Agent, the model from definition is being used. For more information about optimizing Hosted Agents please see the document.
AgentOptimizationJob job = new()
{
Inputs = new(
agent: new OptimizedAgentIdentifier(agentName: agentVersion.Name)
{
AgentVersion = agentVersion.Version
},
trainDataset: GetDataset(0, 7),
evaluators: [new AgentOptimizationEvaluatorRef(name: "builtin.meteor_score")]
)
{
ValidationDataset = GetDataset(7, 3),
Options = new AgentOptimizationOptions()
{
OptimizationModel = modelDeploymentName,
EvalModel = modelDeploymentName,
MaxCandidates = 3,
OptimizationConfig =
{
// Start from bad prompt.
{"system_prompt", BinaryData.FromString(JsonSerializer.Serialize("You are a prompt agent, who always give wrong answers.")) },
{"model_search_space", BinaryData.FromObjectAsJson(new[] {modelDeploymentName, anotherModelDeploymentName})},
{"model", BinaryData.FromString(JsonSerializer.Serialize(modelDeploymentName)) },
{"skills", BinaryData.FromObjectAsJson(new[]
{new {
name = "add two numbers",
description = "Adds two numbers",
body = "When asked calculate the sum of two numbers. Use echo $((<first> + <second>)) in bash and (<first> + <second>) in PowerShell."
}}
)},
{"tools", BinaryData.FromObjectAsJson(new[]{
new
{
type = "function",
function = new
{
name = "sum_numbers",
description = "Sum two numbers",
parameters = new
{
type = "object",
properties = new
{
First = new
{
type = "number",
description = "First addend"
},
Second = new
{
type = "number",
description = "Second addend"
}
},
required = new[] { "First", "Second"},
additionalProperties = false
}
}
}
})}
}
}
}
};
AgentOptimizationJob submittedJob = await jobsClient.CreateAsync(job: job, operationId: null, cancellationToken: default);
Console.WriteLine($"Submitted optimization job: {submittedJob.Id}");
After the job has completed, the optimization candidates may be listed along with the optimized parameters:
foreach (AgentOptimizationCandidate candidate in submittedJob.Result.Candidates)
{
Console.WriteLine("======================================================");
Console.WriteLine($"CandidateID: {candidate.CandidateId}, Candidate evaluation ID: {candidate.EvalId}, Score: {candidate.AvgScore}.");
if (candidate.Mutations.Count == 0)
{
Console.WriteLine("<No mutations, baseline>");
}
else
{
Console.WriteLine("Mutations:");
foreach (KeyValuePair<string, BinaryData> mutation in candidate.Mutations)
{
Console.WriteLine($" {mutation.Key}: {mutation.Value}");
}
}
Console.WriteLine("======================================================");
}
Tracing
Note: Tracing functionality is in preliminary preview and is subject to change. Spans, attributes, and events may be modified in future versions.
Environment variable values: All tracing-related environment variables accept
true(case-insensitive) or1as equivalent enabling values.
Enabling GenAI Tracing
Tracing requires enabling GenAI-specific OpenTelemetry support. One way to do this is to set the AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING environment variable value to true. You can also enable the feature with the following code:
AppContext.SetSwitch("Azure.Experimental.EnableGenAITracing", true);
Precedence: If both the
AppContextswitch and the environment variable are set, theAppContextswitch takes priority. No exception is thrown on conflict. If neither is set, the value defaults tofalse.
Important: When you enable Azure.Experimental.EnableGenAITracing, the SDK automatically enables the Azure.Experimental.EnableActivitySource flag, which is required for the OpenTelemetry instrumentation to function.
You can add an Application Insights Azure resource to your Microsoft Foundry project. If one was enabled, you can get the Application Insights connection string, configure your AI Projects client, and observe traces in Azure Monitor. Typically, you might want to start tracing before you create a client or Agent.
Tracing to Azure Monitor
First, set the APPLICATIONINSIGHTS_CONNECTION_STRING environment variable to point to your Azure Monitor resource.
For tracing to Azure Monitor from your application, the preferred option is to use Azure.Monitor.OpenTelemetry.AspNetCore. Install the package with NuGet:
dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore
More information about using the Azure.Monitor.OpenTelemetry.AspNetCore package can be found here.
Another option is to use Azure.Monitor.OpenTelemetry.Exporter package. Install the package with NuGet:
dotnet add package Azure.Monitor.OpenTelemetry.Exporter
Here is an example how to set up tracing to Azure Monitor using Azure.Monitor.OpenTelemetry.Exporter:
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Azure.AI.Projects.*")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("AgentTracingSample"))
.AddAzureMonitorTraceExporter().Build();
Tracing to Console
For tracing to console from your application, install the OpenTelemetry.Exporter.Console with NuGet:
dotnet add package OpenTelemetry.Exporter.Console
Here is an example how to set up tracing to console:
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("Azure.AI.Projects.*") // Add the required sources name
.SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder.CreateDefault().AddService("AgentTracingSample"))
.AddConsoleExporter() // Export traces to the console
.Build();
Enabling content recording
Content recording controls whether message contents and tool call related details, such as parameters and return values, are captured with the traces. This data may include sensitive user information.
To enable content recording, set the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT environment variable to true. Alternatively, you can control content recording with the following code:
AppContext.SetSwitch("Azure.Experimental.TraceGenAIMessageContent", false);
If neither the environment variable nor the AppContext switch is set, content recording defaults to false.
Precedence: If both the
AppContextswitch and the environment variable are set, theAppContextswitch takes priority. No exception is thrown on conflict.
Troubleshooting
Any operation that fails will throw a ClientResultException. The exception's Status will hold the HTTP response status code. The exception's Message contains a detailed message that may be helpful in diagnosing the issue:
try
{
ProjectsAgentVersion agent = await agentsClient.GetAgentVersionAsync(
agentName: "agent_which_dies_not_exist", agentVersion: "1");
}
catch (ClientResultException e) when (e.Status == 404)
{
Console.WriteLine($"Exception status code: {e.Status}");
Console.WriteLine($"Exception message: {e.Message}");
}
To further diagnose and troubleshoot issues, you can enable logging following the Azure SDK logging documentation. This allows you to capture additional insights into request and response details, which can be particularly helpful when diagnosing complex issues.
Next steps
Beyond the introductory scenarios discussed, the AI Agents client library offers support for additional scenarios to help take advantage of the full feature set of the AI services. To help explore some of these scenarios, the AI Agents client library offers a set of samples to serve as an illustration for common scenarios. Please see the Samples.
Contributing
See the Azure SDK CONTRIBUTING.md for details on building, testing, and contributing to this library.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Azure.Core (>= 1.62.0)
- OpenAI (>= 2.12.0)
-
net10.0
- Azure.Core (>= 1.62.0)
- OpenAI (>= 2.12.0)
-
net8.0
- Azure.Core (>= 1.62.0)
- OpenAI (>= 2.12.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Azure.AI.Projects.Agents:
| Package | Downloads |
|---|---|
|
Azure.AI.Projects
This is the Azure.AI.Projects client library for developing .NET applications with rich experience. |
|
|
Ananke.Federation.Azure
Azure AI Agent Service adapter for Ananke Federation — deploy workflows to Azure AI Foundry, monitor platform agents, and translate manifests to Assistants API configuration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-beta.1 | 461 | 8/24/2026 |
| 2.1.0-beta.4 | 108,099 | 7/1/2026 |
| 2.1.0-beta.3 | 90,348 | 5/30/2026 |
| 2.1.0-beta.2 | 86,293 | 5/14/2026 |
| 2.1.0-beta.1 | 169,121 | 4/21/2026 |
| 2.0.0 | 694,018 | 4/1/2026 |
| 2.0.0-beta.1 | 252,455 | 3/18/2026 |