How to make an AI agent reliable: a step-by-step plan from measurement to autonomous work
To make an AI agent reliable, start with measurement: keep a log of failures and count how many steps the agent completes without a breakdown and how long recovery takes. Then strengthen the harness in order of impact: feedback loops, cheap rollback, memory in files, one task at a time, and a separate executor and verifier — and only after that let the agent run in an autonomous loop with a stop condition.
Why an agent is unreliable even if the model is strong
An agent's reliability is a property of the whole system, not of the model. A long task consists of dozens of steps, and errors accumulate: if 95% of steps are correct, about 60% of runs get through a chain of ten without a single error (0.95^10 ≈ 0.60), and fewer than 10% get through fifty. You cannot raise the model's accuracy, but you can catch an error at the same step and make it cheap. That is what the harness does: instructions, tools, environment, state and feedback around the model.
Below is a plan that leads from "vibe-based" work to measurable reliability and then to autonomous work. The steps follow the order of return: each next one builds on the previous.
Step 1. Stop evaluating by feeling
One engineer is sure that a new prompt changed everything, another sees no difference, and nobody has measured anything. Start with a failure log: each time the agent gets stuck, breaks something or reports a broken feature as done, write one line.
| date | task | what happened | subsystem |
|-------|------------------|--------------------------------|----------------|
| 10.10 | cart discounts | "done", did not run e2e | feedback |
| 10.10 | payment webhook | could not start the database | environment |
| 11.10 | API refactoring | repeated a rejected solution | state |
The "subsystem" column is the key. After a week it becomes clear where the bottleneck is, and you fix that rather than everything at once. Counting reliability by successful runs is a mistake: it is the log of breakdowns that shows where the agent falls down.
Step 2. Introduce two metrics: MTBF and MTTR
Reliability is two numbers. MTBF (mean time between failures) for an agent is how many steps it goes through before getting stuck. MTTR (mean time to recovery) is how long it takes to return to a working state after a breakdown. Availability grows both from the first number increasing and from the second decreasing.
Chasing an agent that never makes mistakes is an endless race. Reducing MTTR can usually be done in a day. So start with the second number.
Step 3. Make a mistake cheap
Autonomy is acceptable not when the agent has stopped making mistakes, but when the cost of a mistake has dropped almost to zero. For this you need three things:
- Small clean commits — any change can be rolled back with one command.
- Isolation — the agent works in a separate branch or working copy, for example via
git worktree, and in a sandbox without access to production. - An environment reset script — the database, dependencies and services return to the initial state with one command.
git worktree add ../shop-agent -b agent/discount
cd ../shop-agent
make reset # recreate the database, apply migrations, load fixtures
Time with a stopwatch how long a full return to a working state takes. That is your MTTR. At the same time, limit the blast radius: a cap on the size of one task's diff and a ban on editing files outside its scope.
Step 4. Close the feedback loop
Without checks the agent is its own only judge, and it sincerely considers the work done. Give it commands with which it checks itself, and make them mandatory.
- Fail-fast: a check fails on the first error with a clear message instead of printing a hundred lines of noise.
- Fast checks after every edit: linter and type checking through an agent hook.
- Redundancy: a second, independent check of the same property — an E2E scenario on top of unit tests. Green unit tests do not prove that the feature works for the user.
Write the "done" criterion as a verifiable condition: "the E2E checkout scenario with a promo code passes", not "discount implemented".
Step 5. Move memory into files
The agent does not remember the previous session. Everything needed to continue the work must live in the repository: the goal, what was done and how it was verified, decisions with reasons, dead ends, the next step. A good sign: a new session, given only the repository and the word "continue", immediately starts useful work.
A long compressed dialogue history creates a feeling of continuity but loses the most valuable thing — the reasons for rejected decisions. A deliberate session reset with a full written state is usually cheaper.
Step 6. One task at a time
Little's law: the number of tasks in progress equals the arrival rate multiplied by the time a task spends in the system. With fixed throughput, parallel tasks do not speed up the work, they only stretch each one. For an agent this is even stricter: three features mean three domain models in one context window.
- Keep WIP=1: one feature until it has a verified result.
- Cut tasks to size: one verifiable user capability, 1–3 files, a check that runs in under a minute.
- Create a
BACKLOG.md— a valve for "while we're at it". If the agent notices a neighboring problem, it adds one line to the backlog instead of making an unauthorized edit.
Step 7. Separate the executor and the verifier
An agent's self-assessment is a weak brake: the same session that wrote the code tends to consider it correct. Let a separate sub-agent or a separate session evaluate the result, receiving only the requirement, the diff and the check results — without the executor's reasoning. The verifier's verdict relies on machine checks, not on "looks fine".
Step 8. Let the agent run in an autonomous loop
The harness makes one run reliable; the loop makes a series of runs autonomous. A loop built on a poor harness only multiplies mistakes faster, so this step comes last. The simplest loop can be described in three lines:
Goal: the e2e payment scenario with a promo code passes
Check: make lint && make test && make e2e
Stop: goal reached OR 15 attempts OR 2 hours → call a human
Choose the loop type according to the task. If the work has a finish line, you need a goal-based loop: memory of progress, an independent verifier and a step budget. If there is no end (a morning CI check, triage of new errors), use a scheduled loop. A common mistake is running a task that has an end on a schedule: each run starts it from scratch.
Rules of safe autonomy
- The stop condition must be machine-checkable only, plus a limit on attempts and budget.
- Escalation: list in advance what the loop must not be trusted with (production migrations, money, data deletion).
- If a task is stuck and progress does not really grow, that is a signal to hand it to a human, not to keep spinning.
- Read the diffs. The speed of the loop must not exceed your speed of reading, otherwise you stop understanding your own codebase.
Common mistakes on this path
Starting by rewriting the instructions
The most popular response to an agent failure is to add a rule to AGENTS.md. A couple of months later the file has grown to hundreds of lines, and the important rules get lost in it. If the failure log shows that the agent did not run the checks, fix the feedback: a check command and a hook, not one more paragraph of text.
Fixing everything at once
You want to improve all five harness subsystems at the same time. But then it is unclear what actually helped. Rate each subsystem from 1 to 5, spend half an hour on the weakest one, and run the same set of five typical tasks before and after. The difference in the failure log will show whether there was an effect.
Confusing "tests are green" with "the feature works"
The agent can write a test that checks its own implementation rather than the requirement. Such a test is always green. The protection is a user-level check (an E2E scenario), written before the implementation or by an independent verifier, plus a rule that the agent does not edit a test to make it pass.
Turning off checks for speed
Slow checks tempt you to skip them "just this once". Better split them: fast linting and type checking after every edit, and the full test suite and E2E before saying "done". This keeps the feedback loop short and out of the way.
Treating ablation as the first step
You can switch off harness subsystems one by one and watch how much quality drops. This is a useful check, but it is expensive and not the first one: first the failure log points to the bottleneck, and ablation only confirms the hypothesis. A zero drop when a component is removed does not mean the component is useless — the chosen set of tasks may simply not have exercised it.
The maturity ladder
| Level | What the agent can do | What must be in place |
|---|---|---|
| 0 | Answers one-off requests | Nothing |
| 1 | Brings a task to a verified result under supervision | Failure log, check commands, plan file |
| 2 | Retries until the goal is reached on its own | Cheap rollback, isolation, stop condition |
| 3 | Works for hours without supervision | Independent verifier, escalation, scheduled automation |
Summary
To make an AI agent reliable: measure, find the weak subsystem through the failure log, make mistakes cheap, close the feedback loop, move memory into files, keep one task at a time and separate the executor from the verifier. Only after that does an autonomous loop with a machine-checkable stop condition become safe. Each step of this plan is covered in practice in the harness engineering course.
FAQ
Will switching to a newer model help?
Sometimes a little, but instability usually remains: errors accumulate on long tasks for any model. Feedback loops and cheap rollback give a bigger and more predictable effect.
How many steps should an agent complete without errors?
There is no universal norm. The trend matters more: if after a harness change the MTBF grows and the MTTR falls on the same set of tasks, you are moving in the right direction.
Can I run several agents in parallel?
Yes, if each one works in its own isolated working copy on its own task. Splitting tasks within one agent and one session is not advisable, because it stretches each of them.
How do I know when the agent should call a human?
When the stop condition is not reached within the allotted budget, when the check results do not improve over several attempts in a row, or when the task touches something marked in advance as requiring escalation.
This topic is covered in depth with practice in the course “Harness Engineering: Engineering Reliability for AI Agents”.
- What Is Harness Engineering? Why AI Coding Agents Fail Because of the Environment
- Error Accumulation in AI Agents: Why 95% Per-Step Accuracy Fails by Step 10
- AI Agent Reliability Metrics: MTBF, MTTR, Blast Radius and Little's Law
- Autonomous AI Coding Agent for Hours: Loop Engineering and Stop Conditions