In Part 1, I argued that the harness is more important than the model, that the teams shipping reliable autonomous agents win by obsessing over the infrastructure around the LLM, not just the weights inside it.
That was the “why.” This post is the “what” and “how.”
We will deconstruct the anatomy of a production-grade agent harness, map out its execution lifecycle, and walk through a complete, working Python implementation you can run today. By the end, you will have a blueprint you can extend into your own projects.
An agent harness is more than an infinite while loop calling an API. In a production environment, a resilient harness consists of five distinct components working in unison:
An agent operating in the wild cannot be ephemeral. If a network request drops or a rate limit is hit, the agent must resume exactly where it left off. The State Controller maintains a durable, append-only conversation history, every prompt sent, every tool result received, so that each new step picks up with full context intact.
Models do not natively understand APIs, file systems, or shells. The Tool Registry translates between model intent and real-world system interfaces by maintaining a catalogue of declarative tool schemas, structured definitions the model reads to understand what a tool does and what parameters it expects. The registry also validates inputs before execution, rejecting malformed calls at the harness level and saving expensive API roundtrips.
A raw terminal is a liability. A robust harness isolates every tool call: commands run inside constrained environments (Docker containers, microVMs, or at minimum a subprocess with strict timeouts and blocked patterns) rather than directly on your host. In our implementation we use a subprocess with a blocklist and timeout, and we are honest about what a production sandbox looks like in Part 3.
Hooks intercept every tool call before and after execution, the same pattern HTTP frameworks use for authentication and logging middleware. Pre-execution hooks can block or rewrite a call (a linter catching bad syntax before wasting a compile cycle). Post-execution hooks can run tests and return pass/fail as feedback.
The harness is the last line of defense against runaway costs and infinite loops. Hard iteration caps guarantee a termination point regardless of what the model decides internally. Token budgets and timeout limits enforce financial boundaries.
Before reading the code, it helps to see how these five pillars interact during a single execution step:
The critical insight is in the bottom path: errors are not crashes. The harness intercepts them, formats them as structured feedback, appends them to the conversation history, and loops, giving the model the information it needs to self-correct on the next step.
Here is a fully working, minimal agent harness in Python. It uses the Anthropic API with real tool execution, a proper tool registry, lifecycle hooks, and boundary controls, but you can replace it with any other LLM provider or even your own local model. You can run this with pip install anthropic.
Before running, set your API key:
Looking at the code above, three behaviors stand out that elevate it beyond a simple API call:
1. The application never crashes on tool failure.
Any exception from read_file, write_file, or run_bash is caught inside _dispatch_tool and returned as a structured string with is_error=True. The model receives it as feedback, not as a Python traceback that kills the process. If the agent writes broken code and run_bash returns a SyntaxError, the harness feeds that error back and the model fixes it on the next step, without any human intervention.
2. Errors are formatted as instructions.
Setting is_error=True in the tool result is not cosmetic. The Anthropic API treats it as a signal that the model should analyze what went wrong and decide how to recover. This is the self-correction loop made concrete: the model is not told how to fix the error, but it is given the error precisely, and its next action should be a correction.
3. Termination is structurally guaranteed.
The while loop has a hard ceiling at max_iterations. No matter what logic the model follows internally, retrying the same broken approach five times, generating new subtasks, calling tools in unexpected orders, the harness guarantees a termination point. This is what makes agent systems safe to run unsupervised.
The implementation above is intentionally minimal. Here is where you would add more production pillars:
The sandbox in our implementation, subprocess calls with a blocklist and a timeout, is a good starting point for learning, but it is not what you would ship. A production harness needs genuine isolation: the agent’s code must not be able to read your SSH keys, saturate your CPU, or exfiltrate environment variables.
In Part 3 of this series, we will tackle Sandboxing & Execution Security in Harness Engineering. We will look at how to wrap agent tool calls in Docker containers, handle filesystem mounts safely, and build a security layer that lets your agent run with real permissions without putting your host at risk.
Thanks for reading The MLnotes Newsletter! This post is public so feel free to share it.

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.