Skip to main content

Command Palette

Search for a command to run...

AI Agent Middleware

Middleware in the Agent Framework offers a powerful mechanism to intercept, adjust, and improve agent interactions.

Updated
4 min read
AI Agent Middleware

Agent Middleware

Agent middleware can be used to handle cross-cutting concerns like logging, security, error handling, and transforming results.

There are three main types of middleware that can be defined:

  • Agent Run middleware – intercepts all agent executions

  • Function calling middleware – intercepts all function calls made by the agent

  • IChatClient middleware – intercepts calls to an IChatClient implementation

Let’s explore an example by creating and using a simple agent run middleware.


Defining the author agent

To begin, let’s define a simple author agent that will be responsible for writing horror stories.

var azureOpenAIClient = new AzureOpenAIClient(endpoint, new AzureKeyCredential(apiKey))
    .GetChatClient(deploymentName);

var authorAgent = azureOpenAIClient.AsIChatClient()
    .AsBuilder()
    .BuildAIAgent(
        instructions: "You are an author that writes horror stories.",
        name: "Author");

Next, let’s add our middleware, which will format the agent’s response with a stylish horror-themed header and footer.

async Task<AgentRunResponse> HorrorAtmosphereMiddleware(
        IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
{
    Console.Write("The author retreats into the shadows");
    for (int i = 0; i < 3; i++)
    {
        await Task.Delay(800, cancellationToken).ConfigureAwait(false);
        Console.Write(".");
    }
    Console.WriteLine("\n");

    var response = await innerAgent.RunAsync(messages, thread, options, cancellationToken).ConfigureAwait(false);

    foreach (var message in response.Messages)
    {
        if (message.Contents != null)
        {
            foreach (var content in message.Contents)
            {
                if (content is TextContent textContent)
                {
                    textContent.Text = $"================================================\n" +
                                     $"           HORROR STORY ARCHIVE\n" +
                                     $"================================================\n\n" +
                                     $"{textContent.Text}\n\n" +
                                     $"================================================\n" +
                                     $"Author: {innerAgent.Name}\n" +
                                     $"Date: {DateTime.Now:MMMM dd, yyyy 'at' HH:mm}\n" +
                                     $"================================================";
                }
            }
        }
    }

    return response;
}

Agent run and function calling middleware types can be registered on an agent by using the agent builder along with an existing agent instance.

 var updatedAgent = authorAgent
     .AsBuilder()
         .Use(HorrorAtmosphereMiddleware, null)
     .Build();

 var authorResponse = await updatedAgent.RunAsync("Tell me a short horror story about vampires.");
 Console.WriteLine($"{authorResponse}");

Executing the agent yields the following output:

The author retreats into the shadows...

\================================================ HORROR STORY ARCHIVE

The moon hung high over the abandoned village of Eldersblood, casting eerie shadows that danced among the crumbling stone houses. Legend had it, the village had been cursed by a dark Hemlock witch centuries ago, drawing the attention of a clan of vampires who sought refuge from the sun's scalding rays. Though no one had set foot in Eldersblood for decades, whispers of its sinister past lingered in the air like a promise of dread.

One night, a curious traveler named Elara, drawn by the thrill of the unknown, ventured into the ghostly village. With each cautious step, the wooden boards beneath her feet creaked and moaned as if warning her of an impending doom. The chilling wind wrapped around her like a cold finger, and the distant howl of wolves sent shivers racing down her spine.

As Elara explored, she stumbled upon an ancient tavern, its door slightly ajar, as if inviting her in. Inside, the air thickened with an unsettling chill, and cobwebs adorned the corners like tattered curtains. The flicker of her lantern revealed a table set for a feast, the plates gleaming, untouched, as shadows began to stretch across the room.

Suddenly, the door slammed shut, plunging her into darkness. Panic coursed through her veins as she fumbled for the handle, but it was locked tight. A raspy voice echoed from the shadows, "Welcome, dear traveler. You've found your way to our humble domain."

A figure emerged from the darkness, cloaked in a tattered black robe. Its face was pale as death, eyes gleaming like two obsidian stones. Behind it, more figures began to materialize, their features hidden, but their hunger palpable.

"Stay for dinner," the figure hissed, revealing elongated fangs glistening under the dim flicker of light. "We rarely have guests in Eldersblood."

Elara's heart raced. She backed away, her instincts screaming for her to flee, but the ground seemed to grow roots beneath her feet. The vampires circled closer, their predatory gazes locking onto her.

With a sudden rush of adrenaline, Elara lunged for the window, clawing at the grime-covered glass, but it was too late. The air crackled with dark energy as the vampires closed in, filling the air with a deep, rumbling laughter.

"Dinner is served!" they declared in unison, their fangs bared, eyes sparkling with wicked delight.

The moon outside bore witness as Elara was swallowed by shadows, her screams swallowed whole by the night. Eldersblood remained silent, the village locked in its cursed slumber, waiting patiently for the next curious soul to wander into its grasp.

\================================================ Author: Author Date: October 23, 2025 at 13:05

I hope you enjoyed this chilling tale - and that it didn’t send too many shivers down your spine. More importantly, I hope you learned something along the way. Until the next story… sleep well, if you can.

The Azure Behind the Madness

Part 10 of 15

Explore the world of Microsoft Azure - from AI and cloud architecture to data and DevOps. The Azure Behind the Madness brings insights, stories, and hands-on guidance for building intelligent, scalable solutions in the cloud.

Up next

Azure Costs Out of Control? Here’s How to Take Back Control

I highlight some of the most common pitfalls I’ve observed when working with Azure and how to avoid them.