Continuing with the Microsoft Agent Framework – Practical Examples 06–10 for Real-World Development

A few weeks ago, I published an article titled
Getting Started with the Microsoft Agent Framework and Azure OpenAI – My First Five .NET 9 Samples,
where I walked through the foundational building blocks of the Agent Framework—basic agents, tool invocation, streaming output, and structured responses.

This article is the direct continuation of that series.

While my current work focuses on much more advanced multi-agent systems—where layered knowledge processing, document pipelines, and context-routing play a crucial role—I still believe that the best way to understand a new technology is through clear, minimal, practical samples.

So in this follow-up, I want to share the next set of examples that helped me understand the deeper capabilities of the framework.
These are Examples 06–10, and they focus on persistence, custom storage, observability, dependency injection, and MCP tool hosting.

Let’s dive in.


Example 06 — Persistent Threads: Saving & Restoring Long-Running Conversations

One of the major strengths of the Microsoft Agent Framework is the ability to maintain conversational state across messages, sessions, and even application restarts.
This is critical if you’re building:

  • personal assistants
  • developer copilots
  • chat interfaces
  • multi-step reasoning chains
  • or anything that needs user-specific memory

In Example 06, the agent:

  1. Starts a new conversation thread
  2. Answers a developer-related question
  3. Serializes the thread using thread.Serialize()
  4. Saves the serialized state to disk (or any storage)
  5. Reloads it later
  6. Resumes the conversation with full continuity

Why this matters:

  • Enables long-lived, multi-turn conversations
  • You can manage per-user memory in your own storage
  • Perfect for web apps, bots, and multi-agent orchestration
  • Unlocks real “assistant-like” behavior

This is the first step toward user-level persistent AI.


Example 07 — Custom (3rd-Party) Storage for Agent Threads

Example 07 builds directly on top of Example 06, but introduces a powerful idea: Instead of storing conversation state in local files, you can store it in any external system.

Since the thread state is simply a JsonElement, you can write it to:

  • SQL Server
  • Azure Blob Storage
  • Redis
  • Cosmos DB
  • PostgreSQL
  • Key-Value stores

This means you can scale conversations across:

  • multiple servers
  • containers
  • cloud environments
  • distributed systems

Why this example is an important milestone:

  • It demonstrates full storage abstraction
  • Opens the door to multi-tenant agent systems
  • Lets you resume threads anywhere, even on a different machine
  • Ideal for production environments
  • You control where and how memory is stored

If Example 06 introduces persistence, Example 07 introduces architecture.


Example 08 — Observability with OpenTelemetry & Application Insights

No real AI application is complete without proper telemetry and observability.

Example 08 shows exactly how to do this:

  • Set up a full TracerProvider
  • Emit traces to the console
  • Optionally export them to Azure Application Insights
  • Enable OpenTelemetry within the Agent Framework using .UseOpenTelemetry()
  • Trace:
    • request execution
    • streaming updates
    • agent reasoning paths (as spans)
    • custom activities

You can also wrap agent calls inside your own spans:

using (var span = activitySource.StartActivity("Warmup"))
{
    span?.SetTag("app.step", "before-first-call");
}

Why this example matters:

  • Helps diagnose performance issues
  • Lets you inspect prompt flow, latency, errors
  • Enables distributed tracing in multi-agent systems
  • Essential for any production agent-based application
  • Works perfectly with Azure Monitor dashboards and workbooks

Observability is not optional—especially once your solution grows beyond a toy demo.


Example 09 — Dependency Injection & Hosting Agents Inside .NET Applications

Example 09 shows how to move beyond standalone console scripts and integrate agents into a real .NET application.

Here, the agent is:

  • registered using dependency injection
  • created as a singleton
  • supplied with its own ChatClientAgentOptions
  • resolved inside a BackgroundService
  • used inside a persistent AgentThread

This pattern is crucial for ASP.NET, Worker Services, microservices, Blazor, and MAUI apps.

You see how easy it becomes to:

  • reuse the same agent instance
  • maintain a persistent conversation thread
  • stream responses to the console
  • gracefully shut down when the user exits

If you want to build anything that lives longer than a simple script, you must understand this pattern.


Example 10 — Hosting an Agent as an MCP Tool (Model Context Protocol)

This is the most advanced example in this series—and honestly one of the most exciting ones.

In Example 10, we turn a .NET application into a fully functional MCP server.

This means:

Your agent becomes a tool that any MCP-compatible client (like VS Code, Cursor, Copilot Studio, or any future MCP client) can interact with.

The example demonstrates:

Creating a persistent agent via Azure Foundry

Using PersistentAgentsClient to ensure the agent has durable memory on the cloud side.

Registering the agent in DI

So tools can easily access it.

Implementing multiple MCP tools

Including:

  • an ultra-simple EchoTool
  • the more advanced DeveloperAssistantTool that delegates to your AI agent

Running the MCP server over STDIO

This enables integration with:

  • MCP Inspector
  • IDE extensions
  • Copilot-style clients

Testing it live

With:

npx @modelcontextprotocol/inspector dotnet run

Why this is a huge step forward:

  • Enables cross-tool, cross-editor interoperability
  • Lets you build your own Copilot for developers, analysts, or domain experts
  • Decouples tools from agents
  • Works with persistent state
  • Matches where the entire AI ecosystem is heading

This is the future of agent-based development—and Example 10 gives you the foundations to start experimenting today.


Conclusion

This article continued where the previous one ended, moving from the basics (Examples 01–05) to more advanced, real-world-ready features (Examples 06–10).

Together, these examples form a practical learning path:

  • Persistent state
  • Custom storage
  • Observability
  • Application-level integration
  • MCP tooling

These concepts are essential if you aim to build robust, production-grade agent systems using .NET, Azure OpenAI, and the Microsoft Agent Framework.

[Source code]

That’s all folks!

Cheers!
Gašper Rupnik

{End.}

Leave a comment

Website Powered by WordPress.com.

Up ↑