Microsoft released the stable harness for Agent Framework on July 22, and it quietly solves the thing that makes ad-hoc agent scripts useless in production: if the process dies, you lose the run. The harness persists chat history after every model call, so a crashed agent can be inspected and resumed mid-task instead of restarted from zero.

What the harness actually bundles

A harness is the runtime that turns a model into an agent — tool calling, memory, planning, context management, approvals. Agent Framework now ships one, in both languages: HarnessAgent in .NET and create_harness_agent in Python. Internally it's still just a chat-client agent (Agent in Python, ChatClientAgent in .NET) with a curated set of framework features enabled by default:

  • Function invocation — the tool-calling loop, with a configurable iteration limit.
  • Per-service-call history persistence — chat history saved after every model call for crash recovery and mid-run inspection.
  • Compaction — context-window management so long tool loops don't overflow.
  • Todo and agent-mode providers — a persistent todo list plus plan/execute mode tracking.
  • File memory — durable session notes and artifacts that survive across turns.
  • Skills — progressive discovery and loading of packaged domain expertise.
  • Web search — the inference service's built-in search tool, when the provider has one.
  • Tool approval — "don't ask again" standing rules plus heuristic auto-approval for safe calls.
  • Telemetry — built-in OpenTelemetry.

You supply the chat client, instructions, and tools. Everything else has a sensible default, and each piece is individually removable.

The whole pipeline collapses into a single call. In .NET:

IChatClient chatClient =
    new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
        .GetProjectOpenAIClient()
        .GetResponsesClient()
        .AsIChatClient(deploymentName);

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    ChatOptions = new ChatOptions
    {
        Instructions = "You are a helpful research assistant. Plan your work, then execute it.",
        Tools = [/* your custom AIFunction tools */],
    },
});

AgentRunResponse response = await agent.RunAsync("Research the outlook for renewable energy stocks.");

The equivalent in Python is create_harness_agent(client, agent_instructions=..., tools=[]). The demo agent reads FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL from the environment, defaulting the model to gpt-5.4.

Why the persistence matters

I've been burned by long agent runs more times than I can count — a 20-minute research loop that dies on an API error and loses all its intermediate tool results. That's the norm for most agent scripts today. Per-service-call history persistence is the feature that changes the calculus: run crashes, you inspect where it stopped and resume from there, because the state was durable the whole time.

That, plus plan/execute mode, is what makes a "personal-finance claw" style agent feasible as an actual product rather than a demo. The todo list gives you a checkpoint trail; mode tracking tells you whether the agent was planning or already acting when it stopped. From that you can build real retry and recovery semantics.

What's still gated

The release explicitly holds back four features as opt-in alpha. You can use them, but you get a warning on opt-in, and the team wants customer feedback before stabilizing:

  • Background agents — delegate sub-tasks to other agents concurrently.
  • File access — read/write file tools scoped to a working directory.
  • Looping — auto re-invoke the agent until a completion condition is met.
  • Shell tooling — run shell commands from the alpha-stage tools package.

That's the honest catch: file access and shell tooling are exactly the tools a production data-processing or automation agent needs, and they're not stable yet. For research-style agents — plan, search, summarize — the core harness is enough. For agents that touch the filesystem or run commands, you're signing up for alpha behavior and a warning from the framework until they're promoted.

When I'd reach for it

If you're on .NET or Python and already using Agent Framework, this replaces a pile of hand-rolled scaffolding. The chat-client agent is still the right starting point for something simple or fully custom; the harness is for when you want the whole "claw" experience out of the box and don't want to maintain the loop, compaction, and persistence yourself.

My take: the crash-recovery default is the headline. Agents that can resume are agents you can trust to run unattended — and that's the difference between a script and a service.

Documentation is on Microsoft Learn, with .NET and Python samples under samples/02-agents/Harness in the repo.

Sources: