DEV Community

Ziya Abbas
Ziya Abbas

Posted on

Building Your First AI Agent with .NET and Azure AI Foundry

If you're a .NET developer looking to break into AI engineering, agents are the single best place to start. They're the point where "calling an LLM API" turns into "building a system that reasons, uses tools, and takes action" β€” and Azure AI Foundry Agent Service, paired with .NET, makes this surprisingly approachable.

In this post, I'll walk through exactly how to stand up your first agent end-to-end β€” from the Azure side setup to the actual C# code β€” and share the full walkthrough in video form as well.

πŸŽ₯ Watch the full hands-on video here: https://youtu.be/mrsEsculrNg


Why Agents, and Why Now

Most of us started our AI journey with a simple chat completion call β€” send a prompt, get text back. That's fine for Q&A, but it falls apart the moment you need the model to do something: run code, search documents, call an API, or hold a multi-turn conversation with real state.

That's exactly the gap Foundry Agent Service closes. An agent in Foundry is:

  • Durable β€” it lives as a resource in your Foundry project, not in your app's memory
  • Tool-aware β€” it can invoke built-in tools (like a code interpreter) or your own custom functions
  • Stateful β€” conversations persist and carry context across turns

And the best part for us .NET folks: the entire thing is callable from clean, typed C# β€” no wrestling with raw REST payloads.

What You'll Need

Before writing any code, set up the Azure side:

  1. An Azure AI Foundry project with a chat model deployed (e.g., gpt-4o-mini)
  2. The Foundry User RBAC role assigned to your account at the resource/resource-group scope β€” this is the single most common blocker people hit (a silent 403 when calling the SDK), so don't skip it
  3. az login run locally, so your code can authenticate without hardcoding any keys

If you've worked with Cognitive Services roles before, note that agent management needs this separate Foundry-specific role β€” that trips up a lot of people coming from plain Azure OpenAI usage.

Setting Up the .NET Project

dotnet new console -n FoundryAgentLab -f net10.0
cd FoundryAgentLab
dotnet add package Azure.AI.Projects
dotnet add package Azure.Identity
Enter fullscreen mode Exit fullscreen mode

Set your environment variables:

export PROJECT_ENDPOINT="https://<your-resource>.services.ai.azure.com/api/projects/<your-project>"
export MODEL_DEPLOYMENT_NAME="gpt-4o-mini"
export AGENT_NAME="my-dotnet-agent"
Enter fullscreen mode Exit fullscreen mode

Creating the Agent

using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;

string projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("Missing environment variable 'PROJECT_ENDPOINT'");
string modelDeploymentName = Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME")
    ?? throw new InvalidOperationException("Missing environment variable 'MODEL_DEPLOYMENT_NAME'");
string agentName = Environment.GetEnvironmentVariable("AGENT_NAME")
    ?? throw new InvalidOperationException("Missing environment variable 'AGENT_NAME'");

AIProjectClient projectClient = new(new Uri(projectEndpoint), new AzureCliCredential());

AgentDefinition agentDefinition = new PromptAgentDefinition(modelDeploymentName)
{
    Instructions = "You are a helpful .NET/Azure tutor that answers general questions",
};

AgentVersion newAgentVersion = projectClient.Agents.CreateAgentVersion(
    agentName,
    options: new(agentDefinition));

Console.WriteLine($"Agent created β€” Id: {newAgentVersion.Id}, Version: {newAgentVersion.Version}");
Enter fullscreen mode Exit fullscreen mode

A few things worth calling out here:

  • AIProjectClient is your single entry point into the project β€” agents, conversations, and responses all hang off it.
  • PromptAgentDefinition is a declarative agent β€” you describe its model and instructions, and Foundry handles the execution plumbing.
  • Notice the agent has a version. Every time you update it, Foundry keeps a version history β€” helpful when you're iterating on prompts and want to roll back.

Talking to the Agent

Creating the agent is half the story β€” now let's have an actual conversation with it, with context retained across turns:

using OpenAI.Responses;

// Create a conversation to maintain context across turns
ProjectConversation conversation = projectClient.OpenAI.Conversations.CreateProjectConversation();

// A responses client pre-bound to this agent and this conversation
ProjectResponsesClient responsesClient = projectClient.OpenAI.GetProjectResponsesClientForAgent(
    defaultAgent: agentName,
    defaultConversationId: conversation.Id);

ResponseResult response = responsesClient.CreateResponse("What is the size of France in square miles?");
Console.WriteLine(response.GetOutputText());

// Follow-up β€” same conversation, so context carries over
response = responsesClient.CreateResponse("And what is the capital city?");
Console.WriteLine(response.GetOutputText());
Enter fullscreen mode Exit fullscreen mode

Run it, and you'll see the second answer correctly reference "it" back to France β€” no manual history management, no prompt-stuffing. That's the conversation object doing its job.

What Makes This "Agentic" Rather Than Just "A Chat Call"

It's a fair question β€” at this scale, it looks a lot like calling any chat API. The distinction shows up once you scale this pattern up:

  • Attach built-in tools (code interpreter, file search, Bing grounding) and the model decides on its own when to invoke them
  • Attach your own function tools, and the agent calls into your application code mid-conversation
  • The agent persists as a named, versioned resource your whole team can reference β€” not a prompt buried in someone's script

This lab is deliberately the smallest possible slice of that β€” enough to get something real running today, with room to grow into tool-calling and multi-agent patterns next.

Wrapping Up

If you're a .NET developer eyeing a move toward AI engineering, this is a genuinely good on-ramp β€” the SDK is clean, the concepts map well onto things you already know (clients, DI-friendly patterns, typed models), and Foundry handles the infrastructure you'd otherwise have to hand-roll.

I go through this entire setup β€” including the Azure Portal steps, the RBAC gotcha, and debugging a couple of real errors β€” in the video below. If you're following along in Hindi/Hinglish, this one's for you:

πŸŽ₯ https://youtu.be/mrsEsculrNg

If you found this useful, a like/subscribe on the channel genuinely helps β€” and drop a comment if you get stuck anywhere, I read all of them.

Happy coding! πŸš€

Top comments (1)

Collapse
 
alexshev profile image
Alex Shev

This is a good entry point for .NET developers because it moves past β€œsend prompt, get answer” into tools and action boundaries. The next useful layer is usually observability: what the agent tried, what tool returned, and where a human can inspect the trace.