This sample demonstrates how to build a Blazor web application that uses the Microsoft Agent Framework with AG-UI (Agent Gateway User Interface) to create a distributed AI agent architecture. The sample showcases how to separate the AI agent backend from the frontend, enabling better scalability and maintainability.
This application consists of three main components orchestrated using .NET Aspire:
- Agent Backend Service (
MAF-AIWebChatApp-AG-UI-Agents) - Hosts the AI agent and exposes it via AG-UI endpoints - Blazor Frontend (
MAF-AIWebChatApp-AG-UI.Web) - Interactive web UI that connects to the remote agent - Aspire App Host (
MAF-AIWebChatApp-AG-UI.AppHost) - Orchestrates the distributed application
┌─────────────────────┐
│ Blazor Web App │
│ (Frontend Client) │
│ │
│ - Chat UI │
│ - Local Tools │
│ - Vector Search │
└──────────┬──────────┘
│
│ HTTP/HTTPS
│ AG-UI Protocol
│
┌──────────▼──────────┐
│ Agent Backend │
│ (Remote Service) │
│ │
│ - AI Agent │
│ - Azure OpenAI │
│ - Agent Logic │
└─────────────────────┘
This sample demonstrates the AG-UI feature of Microsoft Agent Framework, which allows:
- Remote Agent Execution: The AI agent runs as a separate backend service, not embedded in the frontend
- AGUIChatClient: A specialized chat client that communicates with remote agents over HTTP
- Distributed Architecture: Frontend and backend can scale independently
- Tool Distribution: Frontend can provide its own tools (like search) while the backend handles AI reasoning
The application includes:
- PDF Document Ingestion: Automatically processes PDF files from
wwwroot/Datadirectory - Vector Store: Uses SQLite with vector embeddings for semantic search
- Search Function: AI agent can search through ingested documents to provide contextual answers
- Citation Support: Responses include citations with filename and page numbers
Built with .NET Aspire for:
- Service discovery and communication
- Automatic Azure OpenAI provisioning (in publish mode)
- Health checks and observability
- Development and production configurations
- .NET 10 SDK or later
- Access to Azure OpenAI with:
gpt-5-minimodel deploymenttext-embedding-3-smallmodel deployment
- Visual Studio 2022 or Visual Studio Code with C# extensions
You need to provide Azure OpenAI credentials. Choose one of the following methods:
Navigate to the AppHost project directory and set user secrets:
cd MAF-AIWebChatApp-AG-UI.AppHost
# Set Azure OpenAI connection string
dotnet user-secrets set "ConnectionStrings:openai" "Endpoint=https://YOUR-RESOURCE.openai.azure.com/;Key=YOUR-API-KEY"Set the following environment variable:
$env:ConnectionStrings__openai = "Endpoint=https://YOUR-RESOURCE.openai.azure.com/;Key=YOUR-API-KEY"When using builder.ExecutionContext.IsPublishMode, the AppHost automatically provisions Azure OpenAI resources. See Aspire Azure provisioning documentation for details.
Place PDF files you want to search in:
MAF-AIWebChatApp-AG-UI.Web/wwwroot/Data/
The sample includes two example PDFs:
Example_Emergency_Survival_Kit.pdfExample_GPS_Watch.pdf
Important: Ensure any content you ingest is trusted, as it may be reflected back to users or could be a source of prompt injection risk.
- Open
MAF-AIWebChatApp-AG-UI.slnx - Set MAF-AIWebChatApp-AG-UI.AppHost as the startup project
- Press
F5to run
cd MAF-AIWebChatApp-AG-UI.AppHost
dotnet runThe Aspire dashboard will open, showing:
- aichatweb-agents - The agent backend service
- aichatweb-app - The Blazor web frontend
Navigate to the aichatweb-app endpoint to access the chat interface.
The agent backend service that hosts the AI agent:
// Register AI Agent with AG-UI endpoint
builder.AddAIAgent("ChatAgent", (sp, key) =>
{
var chatClient = sp.GetRequiredService<IChatClient>();
var aiAgent = chatClient.CreateAIAgent(
name: key,
instructions: "You are a useful agent that helps users with short and funny answers.",
description: "An AI agent that helps users with short and funny answers."
)
.AsBuilder()
.UseOpenTelemetry(configure: c =>
c.EnableSensitiveData = builder.Environment.IsDevelopment())
.Build();
return aiAgent;
});
// Map AG-UI endpoint
var aiAgent = app.Services.GetKeyedService<AIAgent>("ChatAgent");
app.MapAGUI("/", aiAgent);Key Points:
- Hosts the AI agent as a web service
- Exposes AG-UI endpoints via
app.MapAGUI() - Configures Azure OpenAI chat client with function invocation support
- Enables OpenTelemetry for observability
The Blazor frontend that connects to the remote agent:
// Create AGUIChatClient to communicate with remote agent
var agentService = sp.GetRequiredService<AgentsService>();
AGUIChatClient chatClient = new(agentService.HttpClient, "https+http://aichatweb-agents");
// Create AI Agent with frontend tools
var searchFunctions = sp.GetRequiredService<SearchFunctions>();
AITool[] frontendTools = [AIFunctionFactory.Create(searchFunctions.SearchAsync)];
var aiAgent = chatClient.CreateAIAgent(
name: "ChatAgent",
instructions: "You are a useful agent that helps users with short and funny answers.",
description: "An AI agent that helps users with short and funny answers.",
tools: frontendTools
)
.AsBuilder()
.UseOpenTelemetry(configure: c =>
c.EnableSensitiveData = builder.Environment.IsDevelopment())
.Build();Key Points:
- Uses
AGUIChatClientto connect to the remote agent backend - Provides local tools (search functionality) that the remote agent can invoke
- Implements vector search over ingested PDF documents
- Interactive Blazor Server UI with streaming responses
The frontend provides a search tool that the AI agent can use:
[Description("Searches for information using a phrase or keyword")]
public async Task<IEnumerable<string>> SearchAsync(
[Description("The phrase to search for.")] string searchPhrase,
[Description("If possible, specify the filename to search that file only.")] string? filenameFilter = null)
{
// Perform semantic search over ingested chunks
var results = await _semanticSearch.SearchAsync(searchPhrase, filenameFilter, maxResults: 5);
// Return formatted results as XML
return results.Select(result =>
$"<result filename=\"{result.DocumentId}\" page_number=\"{result.PageNumber}\">{result.Text}</result>");
}How It Works:
- User asks a question in the chat UI
- The frontend sends the message to the remote agent via AGUIChatClient
- The remote agent processes the request and may call the frontend's search tool
- Frontend executes semantic search against vector store
- Results are sent back to the remote agent
- Agent formulates a response with citations
- Response is streamed back to the frontend UI
The AG-UI feature enables a distributed agent architecture where:
- Backend Service: Hosts the AI agent logic and LLM integration
- Frontend Client: Provides UI and local tools/data access
- Communication: HTTP-based protocol for agent invocation and tool calling
- Separation of Concerns: UI logic separate from AI agent logic
- Scalability: Backend agent service can scale independently
- Security: Keep sensitive API keys and credentials in backend only
- Tool Distribution: Frontend can provide tools that access local data or user context
MapAGUI(): Used in the backend to expose an agent via HTTP endpointsAGUIChatClient: Used in the frontend to connect to a remote agent exposed via MapAGUI
- Microsoft Agent Framework: AI agent orchestration and management
- AG-UI Integration: Remote agent communication protocol
- Microsoft.Extensions.AI: AI service abstractions for .NET
- .NET Aspire: Cloud-native application orchestration
- Blazor Server: Interactive web UI with streaming support
- Azure OpenAI: LLM and embedding models
<PackageReference Include="Microsoft.Agents.AI" Version="1.0.0-preview.251114.1" />
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="1.0.0-preview.251114.1" />
<PackageReference Include="Microsoft.Agents.AI.Hosting.AGUI.AspNetCore" Version="1.0.0-preview.251114.1" />
<PackageReference Include="Microsoft.Extensions.AI" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="10.0.0-preview.1.25560.10" />
<PackageReference Include="Aspire.Azure.AI.OpenAI" Version="13.0.0-preview.1.25560.3" /><PackageReference Include="Microsoft.Agents.AI" Version="1.0.0-preview.251114.1" />
<PackageReference Include="Microsoft.Agents.AI.AGUI" Version="1.0.0-preview.251114.1" />
<PackageReference Include="Microsoft.Agents.AI.Hosting" Version="1.0.0-preview.251114.1" />
<PackageReference Include="Microsoft.Extensions.AI" Version="10.0.0" />
<PackageReference Include="ElBruno.Connectors.SqliteVec" Version="0.5.1-preview" />
<PackageReference Include="PdfPig" Version="0.1.13-alpha-20251115-aef0a" />- Microsoft Agent Framework Documentation
- AG-UI Integration Guide
- .NET Aspire Documentation
- Microsoft.Extensions.AI
"Unable to connect to agent service"
- Ensure both projects are running (check Aspire dashboard)
- Verify the service URL in
AgentsServicematches the Aspire service name - Check that the agent backend is listening on the correct port
"No search results found"
- Verify PDF files are in
wwwroot/Datadirectory - Check that the vector store was created (look for
vector-store.dbin output directory) - Ensure the embedding model is correctly configured
"OpenAI API errors"
- Verify your Azure OpenAI connection string is correct
- Ensure both model deployments (
gpt-5-miniandtext-embedding-3-small) exist - Check your Azure OpenAI quota and rate limits
"Build errors with Microsoft.Agents.AI packages"
- Ensure you're using .NET 10 SDK or later
- Clear NuGet cache:
dotnet nuget locals all --clear - Restore packages:
dotnet restore
This sample is part of the Generative AI for Beginners - .NET Edition course.
For more Agent Framework samples, see: