ai newsMo., 26. Okt.
EilmeldungOpenAI launches GPT-6.1 Terra, a cheaper model for everyday computer work

Harness engineering: the skill that took over from prompt engineering

In 2024 the skill everyone talked about was prompting: find the right words and the model does the right thing. In 2025 it was context: hand the model the right files and docs, and the exact wording matters less. In 2026, when an agent fails, it is rarely the wording or the context that let it down

dev.toMontag 20:17 · 26.10.6 Min. Lesezeit
Bild: dev.to

Posted on Oct 26 • Originally published at mahmadmanzoor.com

In 2024 the skill everyone talked about was prompting: find the right words and the model does the right thing. In 2025 it was context: hand the model the right files and docs, and the exact wording matters less. In 2026, when an agent fails, it is rarely the wording or the context that let it down.

What fails now is the layer around the model: which tools it is handed, who checks its work, what it remembers between sessions, what it is allowed to touch, and whether anyone can see afterwards what it actually did. That layer has a name: the harness.

None of these shifts threw the previous one away. Good context work still includes a clear prompt, and harness work still includes choosing the context. The harness adds what wording and context cannot give you on their own: limits on tools, permissions, checks, memory, records, routing between models, and a way for every mistake to become a rule.

Each layer still matters. The outer one is where things break first now.

This post walks through the harness I actually run for this site and for client work, piece by piece. None of it is exotic. Most of it is a few files in the repo.

Everything outside the green box is code and config you write.

Every tool an agent can call is a permission, whether you think of it that way or not. A tool that runs SQL can delete rows. A tool that fetches URLs can be pointed at whatever a web page tells it to fetch.

So the first habit is subtraction. When I gave an agent access to production data, it got a small MCP server with a handful of read-only queries, not a database connection. The details are in the read-only MCP server post. The same thinking applies to agents inside a product: each tool does one narrow thing, validates its input, and returns errors the model can act on.

Give the agent the questions, not the database.

Tools decide what the agent can do. Permissions decide what it may do without asking. I sort actions into three answers and write them down, instead of clicking approve on whatever comes up.

In Claude Code that lives in.claude/settings.json. Reads and checks are allowed, anything that leaves the machine asks first, and secrets and destructive commands are denied outright. Each agent also works in its own git worktree, so a bad edit stays on its own branch ( more on worktrees ).

{ "permissions": { "allow": [ "Bash(npm run lint)", "Bash(npm run typecheck)", "Bash(npm run build)" ], "ask": [ "Bash(npm install:*)", "Bash(git push:*)" ], "deny": [ "Read(./.env*)", "Bash(git push --force:*)", "Bash(rm -rf:*)" ] } } Enter fullscreen mode Exit fullscreen mode Instructions and memory: what carries over A model starts every session knowing nothing about your project. The harness decides what it knows before the first message: a CLAUDE.md with the commands, conventions and hard rules, skills for repeatable jobs, and a small memory folder for things learned along the way.

A fresh session knows nothing. The harness decides what it knows first.

The rule I keep relearning is that instructions only work if they are short and specific. "Write clean code" changes nothing. "Client work is described with screenshots only, never a repo link" changes behaviour on the first try. I wrote more about this in agent instructions that actually change behaviour.

This is the part I would build first if I were starting again. An agent saying "everything works now" tells you what it meant to do. The harness should make it show what happened: typecheck, lint, build, a bundle budget, and screenshots for anything visual.

The fast checks run before the agent is allowed to stop.

The fast checks run in a Stop hook, so the agent cannot end its turn while they are red. The slow ones run in CI. The full setup is in make coding agents prove their work. For LLM features inside a product, the equivalent is an eval set that runs before anyone touches the prompt ( evals before prompts ).

Not every step needs the biggest model. My global instructions tell the main session to pick a model per subagent: a small, fast one for copy edits, screenshots and data gathering, a mid-size one for normal build and fix work, and the large one only for architecture, security and hard reviews. The main session plans, reviews and merges.

When work goes to subagents, always set the model by how hard the task is: - haiku: copy-only edits, mechanical changes, screenshots, data gathering. - sonnet: normal build and fix work (UI, small logic, tests). - opus: complex work only: architecture, security, hard merges, deep reviews. Enter fullscreen mode Exit fullscreen mode This is a harness decision, not a prompt trick, and it is the single biggest lever on cost I have found. More detail in matching the model to the task.

When something goes wrong a day later, "the agent did it" is not an answer. I want the transcript, the commands it ran, the diff, and the report it wrote. Claude Code keeps session transcripts on disk, every change goes through a branch and a pull request, and every agent report follows the same format: files changed, command output pasted, and a section for what it did not check.

For agents inside a product, the same idea means logging each tool call with its input, output and timing, and keeping a trace per request. You cannot fix a loop you cannot see.

The last piece ties the others together. When an agent makes a mistake, correcting that one output is the smallest possible fix. The better fix changes the harness so the next run cannot repeat it quietly: a new line in CLAUDE.md, a hook, a denied command, a test, or a new case in the eval set.

Every mistake should leave the harness a little stricter.

Over a few weeks this compounds. The harness for this site started as a single instructions file. It now holds naming rules for client work, a budget script, a Stop hook, model routing and a handful of skills, and nearly every one of those exists because something went wrong once.

A short CLAUDE.md: commands, conventions, and the few things that must never happen.

Typecheck, lint and build in a Stop hook; slower checks in CI; evals for LLM features.

Read-only by default, ask before anything leaves the machine, deny secrets and destructive commands.

Small models for mechanical work, the large one for decisions.

A line, a hook, a test or an eval case, so it does not happen twice.

None of this makes the model smarter. It makes the system around it predictable, which in my experience is what decides whether an agent is useful at work or just impressive in a demo.

This post was prompted by an article on X by chuplung about harness engineering, which is worth reading for a broader take on the same idea.

Harness Engineering (chuplung on X): The article that prompted this post: why the layer around the model is now the main engineering work.

Claude Code settings and permissions: allow, ask and deny rules in.claude/settings.json.

Originally published on my site. More posts and projects at mahmadmanzoor.com.

Quelle: dev.to (dev.to). Original öffnen