Microsoft Agent Framework Middleware Created: 23 Feb 2026 Updated: 23 Feb 2026

Result Overrides

Result override middleware intercepts the AgentResponse returned by an agent and modifies its content before the response reaches the caller. Unlike termination middleware (which skips the agent entirely), result override middleware always calls the agent and then transforms what comes back.

Why Result Overrides?

  1. Content transformation — Reformat, translate, or clean up the text in every reply.
  2. Response enrichment — Append disclaimers, timestamps, citation links, or confidence scores.
  3. Conditional replacement — Replace the entire response when a business rule is triggered (e.g., the agent returned an empty answer).

The Override Pattern

The shape of a result override middleware function is identical to any other AgentRunMiddleware. The difference is in what happens inside:

async Task<AgentResponse> ResultOverrideMiddleware(
IEnumerable<ChatMessage> messages,
AgentSession? session,
AgentRunOptions? options,
AIAgent innerAgent,
CancellationToken cancellationToken)
{
// 1. Always call the real agent.
AgentResponse response = await innerAgent
.RunAsync(messages, session, options, cancellationToken);

// 2. Transform the messages.
List<ChatMessage> modified = response.Messages
.Select(msg =>
{
if (msg.Role == ChatRole.Assistant && msg.Text is not null)
return new ChatMessage(ChatRole.Assistant,
msg.Text + "\n\n_Disclaimer: This information is AI-generated._");
return msg;
})
.ToList();

// 3. Return a new AgentResponse with the modified list.
return new AgentResponse(modified);
}

The key constructor is AgentResponse(IList<ChatMessage>): supply the transformed message list and the framework wraps it in a proper response object.

Demo: Disclaimer Middleware

The full demo is in Lesson7/Demo1_ResultOverrides.cs.

Step 1 – Build the base agent

AIAgent baseAgent = new OpenAIClient(apiKey)
.GetChatClient("gpt-4o-mini")
.AsIChatClient()
.AsAIAgent(
instructions: "You are a helpful weather assistant.",
name: "WeatherAssistant");

Step 2 – Register the override middleware

AIAgent agentWithOverride = baseAgent
.AsBuilder()
.Use(runFunc: ResultOverrideMiddleware, runStreamingFunc: null)
.Build();

Step 3 – Call the agent normally

AgentResponse response = await agentWithOverride.RunAsync("What's the weather in Seattle?");
Console.WriteLine(response.Text);
// Output ends with:
// _Disclaimer: This information is AI-generated._

The caller sees the modified response. The middleware is completely transparent — no changes are needed at the call site.

Comparison: Termination vs. Result Override

PatternCalls innerAgent?What is returned?Typical use
Termination (Lesson 6)NoSynthetic response constructed by middlewareBlock forbidden input before the LLM is called
Result Override (Lesson 7)YesAgent response transformed by middlewareEnrich, format, or conditionally replace output

Common Override Scenarios

ScenarioWhat the middleware modifies
Append disclaimerConcatenate fixed text to msg.Text
Add timestamp headerPrepend $"[{DateTime.UtcNow:u}]\n" to each assistant message
Translate to another languageCall a translation API on msg.Text and replace the content
Fallback on empty replyCheck if msg.Text is empty; return a default message if so
Redact PIIRun a regex substitution on msg.Text before returning

Key Types

Type / MemberPackageRole
AgentResponse(IList<ChatMessage>)Microsoft.Agents.AIConstruct the modified response to return
AgentResponse.MessagesMicrosoft.Agents.AIThe list of messages produced by the agent run
AIAgent.AsBuilder().Use().Build()Microsoft.Agents.AIRegister middleware on an existing agent
ChatMessage(ChatRole, string)Microsoft.Extensions.AICreate a replacement or enriched message

Required Packages

<PackageReference Include="Microsoft.Agents.AI" Version="1.0.0-rc1" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="10.3.0" />

Reference

Microsoft Agent Framework – Middleware: Result Overrides


Share this lesson: