Muokkaa

Agent Harness

An agent harness is the runtime scaffolding that turns a language model into an agent that can perform work. It drives model and tool calls, manages conversation state and context, applies approval policies, and can keep the agent progressing through a multi-step task.

Agent Framework provides an opinionated, batteries-included Harness for research, coding, data analysis, and other long-running work. You provide a chat client and customize only the capabilities your application needs.

Architecture

The Harness composes existing Agent Framework building blocks rather than defining a separate agent runtime:

  1. Chat client — connects the agent to a model.
  2. Chat pipeline — adds function invocation, message injection, per-service-call history persistence, and optional compaction.
  3. Agent and context providers — add session-scoped instructions, tools, memory, todo state, operating modes, and optional capabilities.
  4. Middleware and decorators — add approval handling, observability, and optional bounded looping.
  5. Application UX — streams responses, displays progress, and collects input such as tool approvals.

The resulting object remains a normal Agent Framework agent: a HarnessAgent that derives from AIAgent in .NET, or an Agent returned by create_harness_agent in Python. Its sessions use the same session and context provider abstractions as other agents.

Harness capability matrix

Capability Harness behavior Canonical guidance
Function invocation Enabled with a configurable per-request iteration limit. Function tools
Per-service-call history persistence Persists history after each model call in a tool-calling run. Sessions
Compaction Enabled when token limits or a custom strategy are supplied. Compaction
Todo tracking Enabled by default. Planning and todos
Agent modes Plan and execute modes are enabled by default. Planning and todos
File memory and file access Session file memory is enabled by default; shared file access is opt-in. Context providers
Tool approval Standing approvals and auto-approval rules are enabled by default. Tool approval
OpenTelemetry Agent observability is enabled by default. Observability
Web search Added by default where the selected chat client supports it. Web search
Agent Skills Enabled by default in .NET; opt-in through a provider or paths in Python. Agent Skills
Background agents Optional parallel delegation to named child agents. Background agents
Shell execution Composed from the shell package; the Python factory can wire it automatically. Shell tools
Looping Optional bounded re-invocation driven by evaluators or predicates. Agent looping

Background-agent delegation is separate from provider-managed background responses. Background agents run child agents on delegated tasks; background responses poll or resume one provider request by using a continuation token.

Create a harness agent

The Microsoft.Agents.AI.Harness package exposes HarnessAgent in the Microsoft.Agents.AI namespace. Create one from any IChatClient with AsHarnessAgent, or construct HarnessAgent directly:

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

AIAgent agent = chatClient.AsHarnessAgent();

AgentResponse response = await agent.RunAsync("Plan a weekend trip to Seattle.");
Console.WriteLine(response.Text);

Use HarnessAgentOptions to set harness-level operating guidance, agent-specific instructions, and feature options:

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    Name = "research-agent",
    HarnessInstructions = "Use tools deliberately and report verified results.",
    ChatOptions = new ChatOptions
    {
        Instructions = "You are a research assistant focused on academic sources.",
    },
    MaxContextWindowTokens = 128_000,
    MaxOutputTokens = 16_384,
});

HarnessAgent.DefaultInstructions supplies the default harness guidance. HarnessInstructions appears before ChatOptions.Instructions.

Customize the composition

Default capabilities have targeted options, including DisableTodoProvider, DisableAgentModeProvider, DisableFileMemory, DisableAgentSkillsProvider, DisableWebSearch, DisableToolAutoApproval, DisableOpenTelemetry, and DisableCompaction.

Add custom context providers with AIContextProviders. Opt in to file access with FileAccessStore, background delegation with BackgroundAgents, and looping with LoopEvaluators.

Create a harness agent

The create_harness_agent factory returns a fully configured Agent:

from agent_framework import create_harness_agent
from agent_framework.openai import OpenAIChatClient

agent = create_harness_agent(
    client=OpenAIChatClient(model="gpt-4o"),
)

session = agent.create_session()
response = await agent.run("Plan a weekend trip to Seattle.", session=session)
print(response.text)

Set harness-level and agent-specific instructions separately:

agent = create_harness_agent(
    client=client,
    name="research-agent",
    harness_instructions="Use tools deliberately and report verified results.",
    agent_instructions="You are a research assistant focused on academic sources.",
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
)

DEFAULT_HARNESS_INSTRUCTIONS supplies the default harness guidance. harness_instructions appears before agent_instructions.

Customize the composition

Disable defaults with options such as disable_todo, disable_mode, disable_file_memory, disable_web_search, disable_tool_auto_approval, and disable_compaction.

Replace built-in providers with todo_provider or mode_provider, and add providers with context_providers. Skills are opt-in through skills_provider or skills_paths; file access, background agents, shell tooling, and looping are also opt-in.

Note

create_harness_agent is released. Background agents, file access, and looping remain experimental, and shell tooling comes from the pre-release agent-framework-tools package.

Note

A packaged Go Harness isn't currently available. Compose the corresponding Go agent, context-provider, compaction, and middleware packages directly. See the Agent Framework Go repository for current support.

Sample terminal UX

The Harness doesn't prescribe an application interface. The repository includes sample terminal applications that stream output, display todos and the current mode, surface tool-approval prompts, and provide commands such as /todos, /mode, and /exit.

Important

These console projects are samples, not shipped framework components. Use them as runnable examples or as a starting point for your own terminal experience.

The .NET sample entry point is HarnessConsole.RunAgentAsync:

using Harness.Shared.Console;

await HarnessConsole.RunAgentAsync(
    agent,
    userPrompt: "Ask me anything to get started.");

Customize the sample with observers, tool formatters, command handlers, and HarnessConsoleOptions. See the .NET Harness samples.

The Python sample uses the Textual-based console package beside the Harness samples:

from console import run_agent_async

await run_agent_async(agent)

Customize the sample with observers, formatters, commands, and UI components. See the Python Harness samples.

The repository doesn't currently include a packaged Go Harness terminal sample.

Next steps

Go deeper