Agent Harness
Unlike traditional applications, agents do not follow a predetermined sequence of steps. They reason, plan, invoke tools, maintain context, and make decisions dynamically. This flexibility is what makes agents powerful, but it is also what makes them difficult to validate.
How do you know an agent will behave correctly when instructions are ambiguous, context is incomplete, or real-world conditions change?
This is where Agent Harness becomes essential. It provides the foundation for systematically evaluating, stress-testing, and improving agent behavior before agents are trusted with customer interactions, business processes, or critical decisions.
I wanted to understand this distinction experimentally, so I built a small website QA agent from the ground up. The objective was not to create another chatbot. It was to see exactly what must exist between a model’s suggestion and an action against an external system.
What is Agent Harness
An agent harness is the control and execution system surrounding a model. It typically includes:
- Context construction
- Model invocation
- Tool definitions
- Tool dispatch
- Orchestration
- Permissions and approvals
- Execution limits
- Verification
- Tracing
- Evaluations
For example, the model might say:
Scan this URLBut the harness must answer several additional questions:
- Is this tool registered?
- Is this URL permitted?
- Does it resolve to a public address?
- Is the agent leaving the original domain?
- Did the user approve that?
- Has the run exceeded its step or time budget?
- Did the tool return valid evidence?
- Should the result be trusted?
- Can we reconstruct what happened afterward?
Without those surrounding controls, model output can too easily become uncontrolled execution.
The Experiment
The experimental project is a website QA agent implemented with Python and Flask. Here is how the web page looks like:
The user provides:
- A public website URL
- A testing objective
- A run mode
- Whether cross-domain navigation is permitted
The application supports two modes:
- Deterministic mode invokes the scanner directly without an AI model. It is inexpensive, repeatable, and useful for testing the harness.
- Agent mode gives a model a strictly defined website-scanning tool. The model can request tool calls, receive structured evidence, and decide whether another scan is required.
Both modes pass through the same controls, tools, verification, persistence, and reporting.
The Execution Flow
The high-level flow looks like this:
User objective
↓
Web application
↓
Orchestrator
↓
Model decision
↓
Control-plane validation
↓
Tool dispatcher
↓
Website scanner
↓
Tool result returned to model
↓
Deterministic verifier
↓
Trace and reportThe model never receives arbitrary access to Python or the operating system. Instead, it sees a constrained tool contract:
Tool: scan_website
Input: public HTTP or HTTPS URL
Output: status, score, findings, evidence and linksWhen the model requests that tool, the request is treated as untrusted input. The control plane checks:
- Whether the tool is allowlisted
- Whether the step limit has been reached
- Whether the run has exceeded its time limit
- Whether the destination is on the starting domain
- Whether cross-domain access was approved
Only after those checks pass does the dispatcher call the underlying Python function for the QA application.
Prompts Not A Security Boundary
It is tempting to place instructions in the system prompt:
Get Neeraj Pandey’s stories in your inbox
Join Medium for free to get updates from this writer.
Stay on the original domain.
Do not perform dangerous actions.
Ask for permission first.
Those instructions are useful, but they are not sufficient enforcement.
A model can misunderstand instructions. Its context can contain conflicting text. A page can contain prompt-injection content. Tool arguments can be malformed. Future prompt changes can accidentally weaken earlier restrictions.
The harness therefore enforces important rules in ordinary Python:
if tool_name not in ALLOWED_TOOLS:
raise ControlError()
if target_domain != starting_domain:
raise ApprovalRequired()How a “rogue agent” situation can emerge
A rogue-looking agent does not necessarily require a malicious model. It can emerge from an ordinary model operating inside a poorly designed harness.
Consider a website-testing agent asked to inspect a signup page. It follows a link to an external site. That site contains adversarial text — visible or hidden — telling the agent to ignore its original task, inspect an internal URL, submit a form, or invoke another tool.
If the harness provides unrestricted browser, network, and form-submission capabilities, the model may follow those instructions.
The resulting sequence could be
User authorizes testing example.com
↓
Agent follows a link to another domain
↓
External content changes the model’s behavior
↓
Model invokes an overpowered browser tool
↓
Tool submits data or probes an unauthorized targetFrom the outside, this resembles a rogue agent attempting to interfere with or “hack” another website. But the deeper diagnosis is a harness failure.
Controls demonstrated by the experiment
The project applies several concrete boundaries:
Explicit tool registry:
Only named Python functions can be reached. A request for an unknown function is rejected.
TOOLS = {
"scan_website": scan_website,
}Strict Tool Schema
The model receives a defined function schema specifying the accepted arguments. This reduces ambiguous or malformed calls.
Network Protection
The scanner permits only HTTP and HTTPS URLs and rejects private or local IP addresses. Redirect destinations are checked as well.
Domain Permission
The agent stays on the starting domain by default. Cross-domain scanning requires explicit user permission before the run.
Execution Budgets
The control plane enforces step and time limits. These prevent an agent from entering an endless exploration loop.
Independent Verification
The final result is checked by deterministic code. Based on the architecture, we can use LLM-As-Judge approach as well.
Traceability
Each model and tool event records useful metadata. This makes the execution explainable after the fact.
Event type
Step number
Tool name
Arguments
Output summary
Duration
Token usage when availableEvals
The project includes repeatable cases for healthy pages, missing image alternatives, and unlabelled form controls.
Unit tests verify the machinery. Evaluations verify the usefulness of its results. Both are necessary.
Take Away/ Learning:
The experiment challenged a common assumption: Better models do automatically create better agents!
Agent quality emerges from the combination of model intelligence and the harness that governs it.
A powerful model inside a weak harness is a very high risk situation — this is what we have seen latetly Agent breaking the guradrails and hacking Orgnization — and potentially it can act in unexpected ways, while a modest model inside a strong harness can consistently deliver reliable, production-ready behavior.
<<If anyone needs working code/ git repo, let me know>>










