Build an AI Agent in C#: Understanding Agent Harness with Microsoft Agent Framework

AI applications are moving beyond simple question-and-answer chatbots.

A modern AI application may need to search the web, call APIs, work with files, remember previous information, execute tools, follow a multi-step plan, ask for human approval, and continue working until a task is completed.

At that point, simply sending a prompt to a language model is no longer enough.

This is where an AI agent harness becomes useful.

Microsoft's Agent Framework now provides a harness that can wrap an IChatClient and add capabilities such as tool invocation, conversation history, planning, context management, memory, approvals, and other agent features. Microsoft recently demonstrated this approach in a C# series focused on building an agent incrementally from a simple model connection into a more capable and observable application.

In this article, we'll look at what an AI agent harness is, how it differs from a simple chatbot, how to create one in C#, and why it can be useful when building real-world .NET AI applications.

Note: Microsoft Agent Framework and its harness capabilities are evolving. Always check the current Microsoft documentation and package versions before using specific APIs in production.


What Is an AI Agent?

Before understanding an agent harness, it helps to understand what makes an application an AI agent.

A basic chatbot generally follows a simple flow:

User
  ↓
Prompt
  ↓
AI Model
  ↓
Response

For example:

User: What is ASP.NET Core?
AI: ASP.NET Core is a cross-platform framework...

An agent can follow a more complex process:

User
  ↓
AI Agent
  ↓
Plan the task
  ↓
Choose a tool
  ↓
Execute the tool
  ↓
Read the result
  ↓
Decide what to do next
  ↓
Repeat if necessary
  ↓
Final response

For example, a user might ask:

"Analyze these sales files and prepare a summary."

An agent may need to:

  1. Find the files.

  2. Read the data.

  3. Analyze the numbers.

  4. Identify important changes.

  5. Create a report.

  6. Ask for approval before performing certain actions.

  7. Return the final result.

The language model provides the reasoning capability, but something needs to coordinate the entire process.

That coordinating layer is where an agent harness comes in.


What Is an Agent Harness?

An agent harness is the runtime scaffolding around a language model that helps it perform multi-step work.

Microsoft describes the harness as a runtime layer that can drive model and tool calls, maintain conversation state and context, apply approval policies, and help an agent continue through a multi-step task.

Instead of building every piece yourself, you can start with an existing IChatClient and create a harness agent.

The basic C# concept is:

AIAgent agent = chatClient.AsHarnessAgent();

The important idea is that the harness does not replace the underlying model.

It sits around the model and provides the machinery needed to turn a model interaction into an agent workflow.


Chatbot vs AI Agent

The difference becomes easier to understand with an example.


Traditional chatbot

var response = await chatClient.GetResponseAsync(
    "Explain dependency injection in ASP.NET Core.");

The model receives a prompt and generates a response.


Agent

An agent may receive:

"Review my project and tell me which dependencies need updating."

The agent may then:

1. Inspect project files
2. Identify dependencies
3. Check available information
4. Analyze versions
5. Prepare a summary

The application therefore needs more than model inference.

It needs orchestration.


Creating Your First Harness Agent in C#

Microsoft's current Agent Framework documentation shows that a harness agent can be created from an existing IChatClient.

A basic example looks like this:

using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

AIAgent agent = chatClient.AsHarnessAgent();

AgentResponse response =
    await agent.RunAsync("Explain how dependency injection works in ASP.NET Core.");

Console.WriteLine(response.Text);

The exact IChatClient implementation depends on the model provider you're using.

The important part is:

chatClient.AsHarnessAgent();

This converts the chat client into a harness-based agent.


Adding Instructions

A real application normally needs instructions that define the agent's role.

For example:

AIAgent agent = chatClient.AsHarnessAgent(
    new HarnessAgentOptions
    {
        Name = "dotnet-assistant",
        HarnessInstructions =
            "Work carefully through multi-step development tasks.",
        ChatOptions = new ChatOptions
        {
            Instructions =
                """
                You are a .NET development assistant.
                Prefer practical C# examples.
                Explain assumptions before making changes.
                """
        }
    });

This separates two different ideas.

Harness instructions can control how the agent operates.

Chat instructions describe what the agent should do from a domain perspective.

This separation becomes increasingly useful as an agent grows.


Giving the Agent Tools

One of the biggest differences between a chatbot and an agent is the ability to use tools.

Suppose we have a simple C# function:

[Description("Gets the current stock quantity for a product.")]
public static int GetStockQuantity(
    [Description("The product ID.")] int productId)
{
    return 125;
}

We can expose the function as an AI tool:

AIFunction stockTool =
    AIFunctionFactory.Create(
        GetStockQuantity,
        "get_stock_quantity");

Then provide it to the agent:

AIAgent agent = chatClient.AsHarnessAgent(
    new HarnessAgentOptions
    {
        ChatOptions = new ChatOptions
        {
            Instructions =
                "Use the stock tool when the user asks about inventory.",
            Tools = [stockTool]
        }
    });

Now the model doesn't need to guess the inventory.

It can request the appropriate tool.

The general flow becomes:

User
 ↓
Agent
 ↓
Model decides a tool is required
 ↓
Tool executes
 ↓
Tool result returns to model
 ↓
Agent generates response

Microsoft's current Agent Framework documentation describes function invocation as one of the capabilities provided by the harness.


Why Tool Calling Matters

Consider an inventory application.

A user asks:

"How many units of product 1001 are currently available?"

A language model doesn't have access to your PostgreSQL database simply because it knows C#.

Your application needs to provide a controlled tool such as:

GetStockQuantity(1001)

The model decides when the tool is appropriate, while your application controls what the tool actually does.

This creates a useful separation:

AI Model
Reasoning
    ↓
Tool Selection
    ↓
Application Code
    ↓
Database / API / Service

The model should not directly receive unrestricted database credentials.

The application should expose narrowly defined operations.


Planning and Multi-Step Tasks

Real-world tasks often require multiple steps.

For example:

"Analyze this month's sales and identify the three products with the largest decline."

An agent may need to:

1. Read sales data
2. Calculate totals
3. Compare periods
4. Sort products
5. Identify the largest declines
6. Prepare an explanation

A harness can provide planning and todo capabilities so the agent can keep track of the work.

Microsoft's current Agent Harness documentation describes planning/execution modes and todo state as part of the harness capabilities.

This is different from simply asking a model to "think step by step."

The application has an actual runtime responsible for managing the work.


Maintaining Conversation State

An agent often needs more than one interaction.

For example:

User:
Analyze my sales data.

Agent:
I found the sales file.

User:
Now compare it with last month.

Agent:
...

The agent needs to preserve relevant state between turns.

Agent Framework uses sessions and context providers for this purpose.

A typical application can maintain an AgentSession while the conversation continues.

Conceptually:

var session = await agent.CreateSessionAsync();

var response1 =
    await agent.RunAsync(
        "Analyze this month's sales.",
        session);

var response2 =
    await agent.RunAsync(
        "Now compare them with last month.",
        session);

The exact APIs can evolve with the framework, but the important architectural concept is persistent agent state.

Microsoft's Agent Framework documentation recommends keeping an AgentSession for interactive multi-step harness tasks so state such as history, plan, and todos can persist across turns.


Context Compaction

Long-running agents can accumulate a large amount of conversation history.

For example:

User message
↓
Tool call
↓
Tool result
↓
Model response
↓
Another tool call
↓
Another result
↓
...

Eventually, sending the entire history to the model can become inefficient or exceed context limits.

A harness can provide context compaction capabilities to reduce unnecessary context while preserving useful information.

This is important for agents that perform long-running tasks.

Without context management, an agent can become increasingly expensive and less reliable as its history grows.


File Access

Agents often need to work with files.

Examples include:

  • CSV files

  • JSON files

  • Markdown documents

  • Reports

  • Source code

  • Configuration files

However, unrestricted filesystem access is dangerous.

An application should establish a clear boundary.

For example:

var workingDirectory =
    Path.Combine(
        AppContext.BaseDirectory,
        "working");

A file access provider can then be configured around that approved directory.

The idea is simple:

Agent
  ↓
Approved File Store
  ↓
Specific Directory

rather than:

Agent
  ↓
Entire Operating System

Microsoft's recent C# agent-harness example specifically demonstrates restricting file access to an approved working directory rather than giving the agent arbitrary filesystem access.


Human Approval for Sensitive Actions

Not every tool should execute automatically.

Imagine an agent that can:

  • Read a database

  • Create a report

  • Delete a file

  • Send an email

  • Modify a record

  • Execute a command

These actions don't have the same risk level.

A useful agent architecture separates them.

For example:

ActionExampleApproval
ReadRead reportUsually automatic
AnalyzeCalculate totalsUsually automatic
CreateGenerate reportDepends
ModifyUpdate databaseOften appropriate
DeleteDelete filesStrong approval
External side effectSend emailOften appropriate

The goal isn't to ask the user for permission for every operation.

The goal is to put human control around meaningful side effects.

Microsoft's current Agent Framework material demonstrates approval handling as part of the harness approach.


Memory in AI Agents

Memory is another important capability.

There are two different ideas that developers should distinguish.


Conversation history

This is information needed to continue the current interaction.


Long-term memory

This is information intentionally stored for future interactions.

For example:

User prefers:
- PostgreSQL
- Blazor
- ASP.NET Core

A production application needs an actual persistence mechanism for this information.

The model saying:

"I've remembered that."

doesn't prove that anything has been stored.

The application needs:

Memory request
 ↓
Storage
 ↓
Persistence result
 ↓
Future retrieval

This distinction becomes particularly important in production AI systems.


Skills: Keeping Instructions Manageable

As an agent becomes more capable, its system instructions can become very large.

Instead of putting everything into one enormous prompt, skills can package domain-specific instructions.

For example:

skills/
├── inventory/
├── reporting/
├── customer-support/
└── accounting/

The agent can discover or load the relevant skill when required.

This can make large agent systems easier to maintain.

Microsoft's recent Agent Framework harness series demonstrates skills as one of the ways to expand an agent without continuously increasing the size of its primary instructions.


Background Agents

Some tasks can be performed independently.

Suppose a user asks:

"Research Microsoft, Apple, and Nvidia and summarize their latest product announcements."

Instead of doing everything sequentially, an agent architecture can delegate separate research tasks.

Conceptually:

Main Agent
    │
    ├── Microsoft Research Agent
    │
    ├── Apple Research Agent
    │
    └── Nvidia Research Agent

The results can then be combined by the main agent.

Microsoft's Agent Framework harness includes support for background-agent delegation as a separate capability from provider-managed background responses.

This can be useful for workloads where independent tasks can run concurrently.


Code Execution and AI Agents

Some tasks are better solved by executing code than by asking a language model to perform calculations manually.

For example:

Calculate monthly revenue for 500,000 transactions.

A model can describe how to calculate it.

But a program can actually calculate it.

This leads to a useful architecture:

Model
 ↓
Determine calculation
 ↓
Generate/choose code
 ↓
Controlled execution environment
 ↓
Result
 ↓
Model explanation

The important word is controlled.

Code execution should not automatically mean unrestricted operating-system access.

Isolation, permissions, timeouts, resource limits, and approval policies remain important.


Observability for AI Agents

Traditional applications already use logging, metrics, and tracing.

Agents need observability too.

When an agent produces an unexpected result, developers may need to know:

What did the user ask?
        ↓
Which model was called?
        ↓
Which tools were selected?
        ↓
What arguments were passed?
        ↓
What did the tools return?
        ↓
How many model calls occurred?
        ↓
What was the final response?

Without this information, debugging an AI agent can be difficult.

The Microsoft Agent Framework harness includes OpenTelemetry instrumentation as one of its optional capabilities.

For production applications, observability should be treated as part of the architecture rather than an afterthought.


AI Agent Security Is Different from Chatbot Security

A chatbot that only generates text has a relatively limited action surface.

An agent can potentially:

Read
Write
Execute
Call APIs
Modify data
Send messages
Run background tasks

That changes the security model.

Developers should consider:

  • Least-privilege tool access

  • File-system boundaries

  • Authentication

  • Authorization

  • Input validation

  • Tool approval

  • Execution timeouts

  • Sandboxing

  • Audit logging

  • Sensitive-data handling

  • Rate limiting

The language model should not become an unrestricted administrator of your application.

A good architecture keeps the model inside clearly defined application boundaries.


A Simple Architecture for a .NET AI Agent

A practical architecture could look like this:

                    ┌──────────────────┐
                    │     User         │
                    └────────┬─────────┘
                             │
                             ▼
                    ┌──────────────────┐
                    │   ASP.NET Core   │
                    └────────┬─────────┘
                             │
                             ▼
                    ┌──────────────────┐
                    │  Agent Harness   │
                    └────────┬─────────┘
                             │
          ┌──────────────────┼──────────────────┐
          ▼                  ▼                  ▼
       Tools             Memory             Planning
          │                  │                  │
          ▼                  ▼                  ▼
      Database          Storage            Todo/Tasks
          │
          ▼
    External APIs

This architecture keeps responsibilities separated.

The model handles reasoning.

The harness coordinates the agent.

Your application owns the tools and business rules.

Your infrastructure controls data, permissions, storage, and external services.


When Should You Use an Agent Harness?

An agent harness makes more sense when the application needs multiple agent capabilities.

For example:


Simple chatbot

If your application only needs:

Prompt → Response

you may not need a full harness.


Tool-enabled assistant

If the application needs:

Prompt → Tool → Response

a harness becomes more useful.


Long-running agent

If the application needs:

Planning
Tools
Memory
Approvals
Multiple steps
Background tasks
Observability

a harness can significantly reduce the amount of orchestration code you need to build yourself.


When Should You Build Your Own Agent Runtime?

A framework isn't automatically the right answer for every project.

You may want a custom orchestration layer when:

  • The workflow is very specialized.

  • You need strict control over every model call.

  • The application has unusual execution requirements.

  • You have existing orchestration infrastructure.

  • You need a minimal runtime rather than a broad framework.

The advantage of a framework is speed and reusable infrastructure.

The advantage of building your own is complete control.

The right choice depends on the application.


Why This Matters for .NET Developers

For C# developers, one of the interesting aspects of the current Agent Framework approach is that the agent remains close to normal .NET development.

You can work with:

IChatClient
AIAgent
AIFunction
AgentSession
HarnessAgentOptions

and integrate these components with familiar .NET application architecture.

That means an existing ASP.NET Core application doesn't necessarily need to become a completely separate AI platform.

An agent can be another application capability.

For example:

ASP.NET Core
│
├── Authentication
├── Authorization
├── Business Services
├── Repository Layer
├── APIs
└── AI Agent
      ├── Tools
      ├── Memory
      ├── Planning
      └── Approvals

This is particularly relevant for enterprise applications where AI needs to work with existing business systems.


Final Thoughts

An AI agent is more than a language model that generates text.

Once an application needs to perform real work, it needs orchestration around the model.

That is the role of an agent harness.

With Microsoft's Agent Framework, C# developers can create a harness agent from an IChatClient and progressively add capabilities such as tools, planning, conversation state, memory, file access, approvals, skills, background agents, and observability.

The most important architectural lesson is that the model should not be given unrestricted control.

Your application should define:

  • What the agent can access

  • Which tools it can use

  • Which actions require approval

  • What information can be remembered

  • Where files can be accessed

  • How code can be executed

  • What should be logged

  • How the agent is evaluated

That separation makes an AI system easier to understand, test, secure, and maintain.

For .NET developers interested in building AI-powered applications, an agent harness is therefore worth understanding—not because every application needs one, but because it provides a structured way to move from a simple AI chat experience toward an application that can actually perform multi-step work.

As the Microsoft Agent Framework continues to evolve, the important skill for developers will not simply be learning another API. It will be understanding how to combine models, tools, application code, data, permissions, and human oversight into a reliable system.

That is where AI development starts to look much more like software engineering.


Frequently Asked Questions


What is an AI agent harness?

An AI agent harness is runtime infrastructure around a language model that helps an agent perform multi-step tasks using tools, planning, state, memory, approvals, and other capabilities.


What is Microsoft Agent Framework?

Microsoft Agent Framework is Microsoft's framework for building AI agents and agentic applications. Its current documentation provides capabilities for agents, tools, sessions, memory, workflows, hosting, and agent harnesses.


How do I create an agent harness in C#?

With an IChatClient, the current Agent Framework API provides the AsHarnessAgent() extension method:

AIAgent agent = chatClient.AsHarnessAgent();

You can then configure the agent using HarnessAgentOptions.


What can an AI agent do?

Depending on its configuration, an AI agent can call tools, work with files, maintain state, plan tasks, use memory, request approval, delegate work, and interact with external services.


Is an AI agent the same as a chatbot?

No. A chatbot can primarily generate conversational responses. An agent can use tools and follow a multi-step workflow to accomplish a task.


Can I use an agent harness with ASP.NET Core?

Yes. A harness can be integrated into a .NET application, including applications built with ASP.NET Core. The agent can be exposed through an API, web application, background service, or other application interface.


Should every AI application use an agent harness?

No. A simple question-and-answer application may not need one. A harness becomes more useful when the application needs tools, planning, memory, approvals, or long-running multi-step tasks.


Is an AI agent secure by default?

Security depends on how the application configures its tools, permissions, data access, execution environment, and approval policies. Developers should use least privilege, controlled tool access, appropriate isolation, and auditing for sensitive operations.


Can an AI agent access my database?

It can if the application exposes a database-related tool or service to the agent. The recommended approach is to expose controlled business operations rather than giving the language model unrestricted database credentials.


Why is observability important for AI agents?

Agent behavior can involve multiple model calls and tool executions. Tracing these operations helps developers understand what happened, diagnose failures, measure performance, and evaluate the quality of the agent's behavior.

Comments 0

contact.webp

SCHEDULE MEETING

Schedule A Custom 20 Min Consultation

Contact us today to schedule a free, 20-minute call to learn how DotNet Expert Solutions can help you revolutionize the way your company conducts business.

Schedule Meeting paperplane.webp