An agent harness is the complete software infrastructure wrapped around a large language model that lets it act rather than merely respond. A raw LLM does one thing: given text, it predicts more text. The harness is everything else — the orchestration loop that calls the model, executes the tools it asks for, feeds the results back, manages context and memory, enforces guardrails, and decides when the task is finished. Put most simply: the model is the engine; the harness is the car built around it. In 2025–2026 the term became load-bearing because the leading agentic coding tools — Anthropic’s Claude Code, OpenClaw, and Zhipu’s ZCode (shipped July 2026 for GLM-5.2) — are all, precisely, harnesses.
The core idea: the loop is the agent
A single call to a model returns one response. Autonomy comes from wrapping that call in a loop that keeps going until a goal is met.
flowchart LR
classDef default fill:#ffffff,stroke:#4338CA,stroke-width:2px,color:#0F172A
classDef system fill:#4338CA,stroke:#4338CA,stroke-width:2px,color:#ffffff
classDef step fill:#EEF0F7,stroke:#6366F1,stroke-width:2px,color:#0F172A
classDef done fill:#0D9488,stroke:#0D9488,stroke-width:2px,color:#ffffff
T([Task]):::step --> M[Call model\nplan next action]:::system
M --> Q{Tool call\nrequested?}:::system
Q -- Yes --> X[Execute tool\nshell / edit / API]:::step
X --> OB[Observe result\nappend to context]:::step
OB --> M
Q -- No --> S([Stop\nreturn answer]):::done
The loop that calls the model, handles its tool calls, and decides when to stop is the harness. Everything sophisticated — retries, planning, sub-agents — is an elaboration of this loop.
What a harness provides
A production harness is far more than a while loop. Its responsibilities include:
| Responsibility | What it does |
|---|---|
| Tool execution | Runs shell commands, edits files, drives browsers, queries APIs on the model’s behalf |
| Orchestration loop | Iterative observe → decide → act cycles until a stop condition |
| Context management | Decides what goes into the finite context window — compaction, summarization, retrieval |
| Memory & state | Persists facts, files, and progress across turns (and sometimes across sessions) |
| Guardrails | Turn budgets, permission prompts, sandboxing, scoped credentials, policy checks |
| Error handling | Catches tool failures and feeds them back so the model can recover instead of crashing |
| Observability | Logs every step for debugging, evaluation, and audit |
Harness vs. scaffold vs. agent
These words are often blurred; getting them right matters.
- Scaffolding is the prompt-level structure the model is steered by: the system prompt, tool descriptions, and required output format. Like construction scaffolding, it is meant to be removed as the building nears completion — as models get better, scaffolding should shrink.
- Harness is the full runtime — the scaffold plus the loop, tool execution, memory, guardrails, and observability.
- Agent = model + harness: the model doing the reasoning, wrapped in the harness that lets it take action in a loop.
flowchart TB
classDef default fill:#ffffff,stroke:#4338CA,stroke-width:2px,color:#0F172A
classDef system fill:#4338CA,stroke:#4338CA,stroke-width:2px,color:#ffffff
classDef mid fill:#EEF0F7,stroke:#6366F1,stroke-width:2px,color:#0F172A
classDef accent fill:#0D9488,stroke:#0D9488,stroke-width:2px,color:#ffffff
subgraph AGENT[AI Agent]
direction TB
subgraph HARNESS[Harness · the runtime]
direction TB
SCAF[Scaffold\nsystem prompt · tool specs · output format]:::mid
LOOP[Loop · tools · memory · guardrails · logs]:::accent
end
MODEL[LLM\nreasoning core]:::system
end
MODEL --- HARNESS
Why the harness matters as much as the model
The harness is not plumbing to be ignored — it materially determines how capable an agent is. On the SWE-bench software-engineering benchmark, a basic scaffold scores around 23%, while an optimized ~250-turn harness running the same model reaches 45%+. Half of the observed capability, in other words, comes from the harness, not the weights.
This has two consequences that shaped the 2025–2026 agent landscape:
- Model–harness coupling. Claude Code’s model was trained with the specific harness it runs in — the model learned to use its own tools and loop. A frontier model dropped into a foreign harness often underperforms, which is why labs increasingly ship model and harness together (Anthropic → Claude Code, Zhipu → ZCode for GLM-5.2).
- Harness engineering as a discipline. Building good harnesses — memory design, MCP tool integration, permissions, sandboxing, observability, and multi-agent orchestration — has become a specialization in its own right, sometimes called harness engineering.
In practice
When you use an agentic coding tool, you are using a harness: it holds your repository in context, decides which files to read, runs your tests, reads the failures, and edits code in a loop — pausing for permission on risky actions. Models like GLM-5.2 expose exactly the primitives a harness needs — function calling, structured output, MCP, streaming, and a long context window — so that the same model can be driven by Claude Code, ZCode, or a custom in-house harness. Understanding the harness is understanding where an agentic AI system’s real behavior — its reliability, its guardrails, and its limits — actually lives.
A minimal agent harness: the plan → act → observe loop
# The harness is the loop, not the model. This ~30-line core is the
# scaffolding that turns a chat model into an autonomous agent.
import json
from openai import OpenAI
client = OpenAI() # any OpenAI-compatible model endpoint
# 1) TOOLS: what the agent is allowed to do in the world.
def read_file(path: str) -> str:
with open(path) as f:
return f.read()
TOOLS_IMPL = {"read_file": read_file}
TOOL_SCHEMAS = [{
"type": "function",
"function": {
"name": "read_file",
"description": "Read a UTF-8 text file and return its contents.",
"parameters": {
"type": "object",
"properties": {"path": {"type": "string"}},
"required": ["path"],
},
},
}]
def run_agent(task: str, model: str = "gpt-5.5", max_turns: int = 25) -> str:
# 2) SCAFFOLDING: system prompt + tool descriptions + stop condition.
messages = [
{"role": "system", "content": "You are an autonomous engineer. "
"Use tools to gather facts before answering. Stop when done."},
{"role": "user", "content": task},
]
# 3) THE LOOP: call model -> run tools -> feed results back -> repeat.
for _turn in range(max_turns): # turn budget = a guardrail
reply = client.chat.completions.create(
model=model, messages=messages, tools=TOOL_SCHEMAS,
).choices[0].message
messages.append(reply)
if not reply.tool_calls: # model chose to stop -> we stop
return reply.content
for call in reply.tool_calls: # 4) EXECUTE + OBSERVE
args = json.loads(call.function.arguments)
try:
result = TOOLS_IMPL[call.function.name](**args)
except Exception as e: # error handling is the harness's job
result = f"ERROR: {e}"
messages.append({
"role": "tool", "tool_call_id": call.id, "content": str(result),
})
return "Stopped: turn budget exhausted." # bounded, never runs forever
Ready to build?
Leverage AI technologies to build your product stack
Superteams can help you build, deploy and launch AI application stacks using open source technologies — from architecture through to production.
Talk to Superteams