
Agent = Model + Harness: Do not put an F1 engine into a brakeless bus
- luandnh
- Ai tools , System design
- July 5, 2026
Table of Contents
At the end of last year, I created a bot that ran in the background to automatically read menus from partner restaurants sent in PDF/Excel format, then parsed them into a Go struct to load into the Menu Service database.
The logic was very simple: read the file -> put it into a prompt -> call the GPT-4 API -> receive JSON -> parse it into a struct -> save. I was confident and tried running it. The first 3 days ran smoothly. On the 4th day, a restaurant sent a 15-page PDF menu, scanned blurry and with a disorganized structure.
The result: The bot fell into an infinite loop. The model kept returning JSON with missing validation fields, my Go code returned an error, and then the prompt called the model again to “fix it”. The model fixed it but made another mistake. It repeated this process for 2 hours until I discovered and killed the process. I opened the OpenRouter dashboard: nearly $40 in API costs had vanished in just one morning.
It was then that I realized a truth: No matter how good a model is, if it’s not controlled within a framework (harness), it will eventually waste money or destroy the system.
Last week, LangChain posted a great blog article called “The Anatomy of an Agent Harness”. It dissected exactly this “control framework”. This article is what I’ve learned after reading it, directly related to my painful experiences working with “hot” agents like Hermes Agent, OpenClaw, and Pi.
Agent = Model + Harness. If you’re not a Model, you’re a Harness
There’s a extremely common misconception: just stuffing a cool prompt into a powerful LLM (like GPT-4 or Claude 3.5 Sonnet) and you have an AI Agent.
Not so. The raw LLM is actually extremely powerless. In essence, it only takes in a sequence of tokens (text, images, speech) and outputs another sequence of tokens. It’s completely stateless.
- It doesn’t know how to store temporary files.
- It doesn’t know how to install libraries or run a compiler to test code.
- It doesn’t know how to automatically rollback git when the code has syntax errors.
- It doesn’t know how to automatically free up memory when the conversation gets too long (context rot).
To turn this “text generation engine” into a real work engine, you need a system wrapped around it. That system is called Harness.
User -> Harness (Sandbox, Filesystem, Memory, Tools) -> Model (LLM) -> Output
The standard formula is: Agent = Model + Harness.
If you’re writing code, configuring systems, creating Docker sandboxes, or writing tools to wrap around LLMs - you’re doing Harness Engineering.
For my fellow backend devs, there’s a way to compare that’s extremely easy to visualize:
- Model is like an
http.HandlerFuncin Go: It receives a request (input prompt) and returns a response (completion text). It’s completely stateless and only handles a single logical task. - Harness is like the entire Web Framework & Infrastructure wrapped around it: It includes the Gin router for routing, middleware for auth checking, database connection pools, loggers for tracing, Docker containers for isolated running, rate limiters to prevent spam, and systemd for automatic restarts when crashing.
You can’t throw a bare handler into production without a framework wrapped around it. Agents are the same.
Dissecting 5 Components of a Practical Harness
A modern Agent Harness is not just a Python script calling an API. To run complex tasks on a real codebase (like Claude Code or Hermes Agent), a Harness must have the following components:
1. Filesystem & Git (Storage Infrastructure)
A model can only operate on what is within its context window. However, the context window is expensive and prone to drift. The filesystem serves as “physical RAM” for the agent to store specs, record work logs (journals), or store intermediate code files.
When combined with Git, the filesystem becomes a time machine. If the agent accidentally writes bad code that breaks the project (a common occurrence), the Harness can automatically run git checkout -- . to restore the previous state.
2. Sandbox & Verification Loop (Execution Environment and Self-Correction)
For an agent to write and run code autonomously, it needs a sandbox (typically a Docker container or isolated VM). Running AI code on a real machine without a sandbox is the quickest way to lose data.
The Harness provides the agent with tools like Bash, compilers (Go, Node), and most importantly, Verification Tools (such as test runners, linters). When the agent modifies code, the Harness automatically triggers go test ./... or staticcheck. If the tests fail, the Harness sends the error back to the model for self-debugging. This is called the self-verification loop, which makes the difference between an automated agent and a regular chatbot.
3. Mitigating Context Rot (Memory Degradation)
When an agent works for an extended period in a session, the context window becomes full. This phenomenon is called Context Rot: the model starts to “forget,” loses the initial spec, repeats old errors, and degrades its reasoning ability.
A robust Harness addresses this issue with three mechanisms:
- Compaction (Summarization): Automatically condenses old messages, summarizes them, and frees up context space.
- Tool Output Offloading (Output Truncation): If the agent runs a bash command that returns 10,000 lines of log, the Harness truncates the middle part, writes the full log to disk, and only loads the head/tail into the model’s context with a file path for the model to read if needed.
- Skills (Lazy Loading Tools): Instead of loading descriptions of 100 tools into the prompt at the beginning of the session (diluting context), the Harness displays a summary list (progressive disclosure). When the model actually needs to use a specific skill, the Harness loads the tool’s details into the context.
4. Ralph Loops (Long-Horizon Execution)
When performing large tasks that take several hours, models often tend to “get satisfied” and stop early (early stopping) after completing only half of the task.
The Harness applies a pattern called Ralph Loop: it blocks the model’s exit signal, checks the target state in the filesystem, and if not completed, it “kicks” the model by clearing the old context (to lighten the load) and injecting a new prompt: “This is the current state on disk, you’ve only completed 50% of the task, please continue.”
3 Typical Examples of Harness: Hermes Agent, OpenClaw, and Pi
To better visualize, let’s put these three popular names on the scale to see what roles they play in this Harness picture.
graph TD
Human["HUMAN INTERFACE
(Zalo, Telegram, Discord, WebUI - Managed by OpenClaw)"]
Harness["AGENT HARNESS
(Context, Sandbox, Memory, Tools - Managed by Hermes/Pi)"]
Model["RAW MODEL
(Claude 3.7, GPT-5 - Stateless LLM)"]
Human -->|"Message routing and auth"| Harness
Harness -->|"Structured completion API"| Model
1. Hermes Agent: Internal Harness & Sandbox Operator
Hermes is a monster in terms of Harness Engineering that I’m using to write this article itself.
- How it manages Context: When I call tools that run terminals with extremely long output, Hermes doesn’t cram all that text into the chat. It saves it to a local log file as cache and only shows a preview.
- How it manages Skill: Instead of stuffing all tools into the system prompt, Hermes has a
skill_manageandskill_viewsystem. When I need to write a blog, it loads theblog-writer-v2skill into the context. - How it manages Memory: It uses a local SQLite database (
session_search) running FTS5 to store the history of previous work sessions. When I ask “how did I optimize the menu service structure last week?”, it will query the database to retrieve the context instead of making me copy-paste again.
2. OpenClaw: External Harness & Messaging Gateway
If Hermes is the skeleton and muscles running inside the sandbox, then OpenClaw is the skin and nervous system connecting to the outside world.
- Routing (Multi-agent routing): OpenClaw acts as a self-hosted gateway. It connects chat applications like Telegram, Zalo, Discord with coding agents running in the background.
- Session Management (Session & Workspace Isolation): When you send a message to the bot via Zalo, OpenClaw will identify your chat ID, map it to a separate workspace folder on the VPS, restore the corresponding Hermes Agent session, and forward the message. It ensures that conversations from different group chats do not mix up data.
- Security: OpenClaw plays the role of a “security gate”. It does not allow raw terminal commands (raw CLI execution) to be sent directly to the customer’s Zalo/Telegram, preventing the exposure of API keys or sensitive folder structures.
3. Pi (pi-agent-harness): Minimalist Terminal Harness
In contrast to the grandeur of Hermes or the gateway functionality of OpenClaw, Pi is a minimalist harness project written in TypeScript that runs entirely on the terminal.
- Pi’s philosophy is to keep the core extremely small. It only provides a skeleton for programmers to define skills, write prompt templates, and set up workspaces.
- Pi is extremely suitable for quick, lightweight automation tasks on a local personal computer without needing to set up a complex sandbox system or multi-channel gateway.
The Future: When Models and Harnesses Unite
Currently, AI developers are training models in a harness-in-the-loop style.
The Claude 3.7 model or the latest GPT-5 didn’t magically learn how to write patch files or use terminal commands. They were post-trained in simulated environments equipped with tools like Claude Code or OpenAI Codex. This allows the model to work seamlessly with the tools in the harness.
However, this also leads to a side-effect: the model becomes overfitting to the tool structure of that particular company. For example, if you change the format of the file editing tool of OpenAI Codex from the traditional apply_patch to a different structure, the model’s performance may plummet because it’s not accustomed to it.
Nevertheless, the Terminal Bench 2.0 ranking (which benchmarks the ability of agents to self-debug and run terminals) has revealed an interesting fact: The same model (e.g., Claude 3.5 Opus), but when run on different optimized harnesses, the score can differ from 30th place to 5th place.
This means that: The model is only a necessary condition. The harness is the sufficient condition to optimize the performance and cost of the Agent for your specific problem.
Bottom line: Don’t Blame the Model
Next time, if your AI agent writes code that doesn’t follow conventions, gets stuck in an infinite loop, or overflows the context leading to a system crash, don’t rush to call the LLM stupid or hastily switch to a more expensive model.
Stop and ask yourself: Have I built a good Harness for it?
Have you configured a safe sandbox? Do you have a linter that automatically blocks faulty code? Do you have a mechanism to truncate logs to prevent context rot? Have you stored the project specs in local markdown files as guidelines for it?
If not, get started with Harness Engineering. An F1 engine is very powerful, but it needs a sturdy chassis and safe brakes to reach the finish line.
What about you? Are you building a harness for your bot using your own scripts, or are you using available solutions like Hermes Agent, OpenClaw, and Pi? Share your experience in the comments! 🦞


