AI Agents  

Implementing Agentic AI with C# Using Azure OpenAI: A Practical, Tool-Driven Approach

Most examples of Generative AI stop at simple prompt–response chatbots. However, real enterprise systems require tool execution, orchestration, configuration management, and controlled behavior.

In this article, we move from theory to implementation and demonstrate how to build an agent-like AI system in C# using Azure OpenAI, where the AI can:

  • Accept user input

  • Decide what to do

  • Call real C# methods (tools)

  • Return structured, meaningful results

  • Remain secure, configurable, and production-ready

All examples in this article are based on actual working C# code, not pseudo-logic.

Solution Overview

The implementation consists of four major parts:

  1. Utility Layer

    • Azure OpenAI client setup

    • Configuration loading

    • Tool execution methods

  2. Tool Functions

    • Calculator tool

    • Weather tool

  3. Vector Model (Enterprise Ready)

    • Prepared for semantic search and memory

  4. Chat Orchestration

    • Chat loop with system control

    • Message history handling

This design closely aligns with enterprise AI agent architecture.

1. Centralized Utility Layer (Enterprise Best Practice)

In enterprise systems, AI configuration must never be hardcoded. Your Utility class correctly centralizes:

  • Azure OpenAI configuration

  • Client creation

  • Tool execution logic

Azure OpenAI Configuration Loading

public static void GetAzureOpenAIConfig(
    out string endpoint,
    out string key,
    out string deploymentName,
    out string EmbedDeploymentName)
{
    IConfiguration config = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .Build();

    deploymentName = config["ai:azure:deploymentname"]!;
    endpoint = config["ai:azure:endpoint"]!;
    key = config["ai:azure:key"]!;
    EmbedDeploymentName = config["ai:azure:EmbeddingDeployName"]!;
}

Why this matters architecturally

  • Environment-specific configuration (Dev / QA / Prod)

  • Secure secret handling

  • Cloud-native design

  • Zero code change during deployment

2. Azure OpenAI Client Creation

public static AzureOpenAIClient GetAzureOpenAIClient()
{
    string endpoint, key, deploymentName, EmbedDeplomentName;
    GetAzureOpenAIConfig(out endpoint, out key, out deploymentName, out EmbedDeplomentName);

    AzureKeyCredential cred = new AzureKeyCredential(key!);
    return new AzureOpenAIClient(new Uri(endpoint!), cred);
}

This method ensures:

  • Reusable client

  • Centralized credential management

  • Clean dependency separation

This is exactly how enterprise AI services should be instantiated.

3. Implementing AI Tools (Agent Capabilities)

Calculator Tool – Deterministic Execution

public static string ExecuteCalculationTool(BinaryData functionArguments)
{
    Console.WriteLine("Executing Calculator");

    var argsDoc = JsonDocument.Parse(functionArguments);
    string expression = argsDoc.RootElement.GetProperty("expression").GetString()!;

    object rawResult = new DataTable().Compute(expression, null);

    double result = rawResult switch
    {
        double d => d,
        int i => i,
        decimal dec => (double)dec,
        _ => 0.0
    };

    var toolResult = new { apiName = "CalculatorAPI", expression, result };
    return JsonSerializer.Serialize(toolResult);
}

Why this is important

  • AI does not calculate — C# does

  • Prevents hallucinations

  • Ensures deterministic, auditable results

  • Perfect example of agent tool execution

Weather Tool – External Capability Simulation

public static string ExecuteWeatherTool(BinaryData functionArguments)
{
    Console.WriteLine("Executing Weather Method");

    var args = JsonDocument.Parse(functionArguments);
    string city = args.RootElement.GetProperty("city").GetString() ?? "Noida";
    string unit = args.RootElement.TryGetProperty("unit", out var unitel)
        ? unitel.GetString() ?? "celcius"
        : "Farenheit";

    var result = new
    {
        city,
        unit,
        temperature = 13,
        description = $"The weather in {city} is 13 degrees {unit}, extreme hot."
    };

    return JsonSerializer.Serialize(result);
}

🔹 In real projects, this can call:

  • Weather APIs

  • Internal services

  • Microservices

  • Databases

This is how AI agents interact with the real world.

4. Vector Model for Future Memory & Search

public class CloudServiceModel
{
    [VectorStoreKey]
    public string Key { get; set; } = string.Empty;

    [VectorStoreData]
    public string Name { get; set; } = string.Empty;

    [VectorStoreData]
    public string Description { get; set; } = string.Empty;

    [VectorStoreVector(
        Dimensions: 3072,
        DistanceFunction = DistanceFunction.CosineSimilarity)]
    public ReadOnlyMemory<float> Vector { get; set; }
}

Architectural significance

  • Ready for semantic search

  • Enterprise memory support

  • Compatible with Azure AI Search

  • Scalable knowledge base design

This is forward-looking agent architecture.

5. Chat Orchestration Layer (Agent Controller)

Utility.GetAzureOpenAIConfig(out endpoint, out key, out deploymentName, out string embed);

var azureOpenAIClient = Utility.GetAzureOpenAIClient();
ChatClient chatClient = azureOpenAIClient.GetChatClient(deploymentName);

List<ChatMessage> chatHistory = new();
chatHistory.Add(new SystemChatMessage(
    "You are a helpful assistant. keep answers short"));

Controlled System Prompt

The system message:

  • Defines AI behavior

  • Prevents verbose or unsafe output

  • Acts as AI governance layer

Interactive Chat Loop

while (true)
{
    Console.Write("Q. ");
    string userInput = Console.ReadLine()!;

    chatHistory.Add(new UserChatMessage(userInput));

    var response = await chatClient.CompleteChatAsync(chatHistory.ToArray());

    Console.WriteLine($"AI Reply. {response.Value.Content[0].Text}");
}

What this demonstrates

  • Persistent conversation memory

  • Controlled AI output

  • Simple but extensible orchestration

  • Ready for tool-calling extension

Application Configuration (appsettings.json)

{
  "ai": {
    "azure": {
      "endpoint": "https://xyz.azure.com/",
      "key": "sdfsfsfsfsfsfsfs",
      "deploymentname": "gpt-4o-mini"
    }
  }
}

✔ Supports:

  • Secure deployments

  • Multiple environments

  • DevOps pipelines

How This Becomes a Full Agent

Your current implementation already has 80% of an AI agent.

To make it fully agentic:

  1. Add function calling support

  2. Let the model decide which tool to call

  3. Execute the tool

  4. Feed the result back to the model

Your ExecuteCalculationTool and ExecuteWeatherTool are perfect agent tools.

Why This Design Works for Enterprises

  • ✔ Strong separation of concerns

  • ✔ Deterministic tool execution

  • ✔ Secure configuration handling

  • ✔ Extensible for memory and search

  • ✔ Production-ready C# patterns

This is not a demo chatbot — this is an enterprise AI foundation.

Conclusion

This article demonstrated a real, working implementation of agent-style AI using C# and Azure OpenAI.

Instead of relying purely on LLM responses, we:

  • Delegated calculations to C#

  • Controlled AI behavior

  • Prepared for vector memory

  • Designed for scale and governance

For organizations building serious Generative AI systems, this approach offers the right balance of intelligence, control, and architecture.