Causly Lab

Causly Lab

Ideas, builds and systems for a more autonomous future.

Get insights in your inbox

High-signal content on AI, automation and building systems.

Have an idea?

Suggest a topic or request a deep dive.

A clearer tomorrow built together

- Causly

Lab

How Should an AI Agent Recover From Failure?

AI agents will fail. The real engineering problem is what happens next. This technical dive explores how AI agent infrastructure can detect failures, diagnose what went wrong, retry intelligently, preserve state, roll back unsafe changes, verify recovery, and escalate to a human when automation should stop.

September 12, 2026
Series — 2: What Can an AI Agent Actually Do With Its Own Environment?
  1. 1.How Should an AI Agent Recover From Failure?

How Should an AI Agent Recover From Failure?

AI agents are getting better at doing things.

They can write code, use APIs, operate browsers, query databases, deploy applications, modify files, and work through multi-step tasks without someone manually telling them what to do at every step.

But there is a problem hiding underneath all of that autonomy:

What happens when something goes wrong?

Imagine an AI coding agent is asked to build a small web application.

  • It creates the project.
  • Installs dependencies.
  • Writes the API.
  • Builds the frontend.
  • Runs the tests.
  • The build fails.
  • That part is normal.

The interesting question is what happens next.

Does the agent:

“Try the same command again”?

  • Does it read the error and change its approach?
  • Does it know which files changed before the failure?
  • Can it roll back a bad change?
  • Can it restore its previous state?
  • Can it run a smaller test to isolate the problem?
  • Can it recognize that the current approach is fundamentally wrong?

And, perhaps most importantly:

Can the infrastructure tell when the agent should stop trying?

This is where AI agent infrastructure becomes much more interesting than simply giving an LLM access to tools.

A capable model can generate another action. A reliable agent environment needs to make sure that action happens safely, observably, and recoverably.

In the previous article, we looked at what happens when an AI agent gets stuck.

Now we're going one layer deeper.

Instead of asking:

Why did the agent fail?

we're asking:

What should the infrastructure actually do after the failure?


The Core Idea: Failure Should Be a State Transition

A naive agent loop looks something like this:

Think → Act → Fail → Try Again

That's not really recovery.

It's repetition.

A more useful system looks like this:

Execute
   ↓
Observe
   ↓
Detect failure
   ↓
Capture evidence
   ↓
Classify failure
   ↓
Choose recovery strategy
   ↓
Recover / Replan / Rollback
   ↓
Verify
   ↓
Continue

And if recovery doesn't work:

Recovery failed
      ↓
Can we safely try another strategy?
      ↓
      Yes
      ↓
New recovery attempt

      No
      ↓
Escalate / Stop

This distinction matters.

Retrying is an action. Recovery is a system.


1. First, Detect That Something Actually Went Wrong

The first challenge is surprisingly easy to underestimate.

Not every failure produces an obvious error.

Some failures are explicit:

npm install → exit code 1

Others are much more subtle:

API call → HTTP 200

but the response contains incorrect data.

Or:

Agent → creates file

but the file does not satisfy the task requirements.

Or:

Tests → pass

but the application still doesn't behave correctly. So failure detection cannot depend entirely on exceptions.

A useful AI agent environment needs several signals.

Explicit execution signals

These are the easiest:

  • process exit codes
  • HTTP status codes
  • exceptions
  • timeouts
  • missing files
  • permission errors
  • dependency failures
  • failed builds
  • failed tests

For example:

result = subprocess.run(
    command,
    capture_output=True,
    text=True
)

if result.returncode != 0:
    failure = {
        "type": "process_failure",
        "exit_code": result.returncode,
        "stderr": result.stderr
    }

But that's only the first layer.

Verification signals

The infrastructure should also ask:

Did the action actually achieve what it was supposed to achieve?

For example:

def verify_build():
    result = run("npm run build")
    return result.returncode == 0

Or for an API task:

response = call_api()

assert response.status_code == 200
assert "customer_id" in response.json()

The important distinction is:

Execution success does not necessarily mean task success.

An agent can successfully execute a command and still fail the actual objective.


2. Capture Evidence Before Trying to Fix Anything

Once a failure occurs, the worst thing an infrastructure layer can do is immediately overwrite the evidence.

Suppose an agent runs:

npm run build

and receives:

Module not found: Can't resolve './Button'

That error is valuable.

The recovery system should capture the execution context before another action changes the environment.

A useful execution record could look like:

{
  "run_id": "run_8f31",
  "step_id": "step_17",
  "action": "npm run build",
  "started_at": "2026-09-12T12:41:02Z",
  "duration_ms": 4312,
  "exit_code": 1,
  "stdout": "...",
  "stderr": "Module not found: Can't resolve './Button'",
  "workspace_revision": "a91f42",
  "files_changed": [
    "src/app/page.tsx",
    "src/components/Header.tsx"
  ]
}

Now the agent has something much more useful than:

“The build failed.”

It has evidence.


Logs Are Not the Same as Traces

For AI agent infrastructure, it's useful to separate the two.

Logs

Logs answer:

What happened?

For example:

12:41:02 npm install
12:41:07 dependency installation complete
12:41:09 npm run build
12:41:13 build failed

Traces

Traces answer:

How did we get here?

A trace can connect:

Task
 ↓
Agent decision
 ↓
Tool call
 ↓
Shell command
 ↓
File modifications
 ↓
Build
 ↓
Failure

That relationship becomes extremely valuable when an agent has performed dozens or hundreds of actions. The infrastructure shouldn't just preserve the final error.

It should preserve the execution history that produced it.


3. Give Every Execution a Trace

A practical agent runtime can assign an identifier to every task and every step.

task_id
   ↓
run_id
   ↓
step_id
   ↓
tool_call_id

For example:

{
  "task_id": "task_102",
  "run_id": "run_8f31",
  "step_id": "step_17",
  "tool_call_id": "tool_884",
  "tool": "shell",
  "command": "npm run build"
}

This creates a chain of evidence.

The recovery controller can then answer questions such as:

  • What was the last successful step?
  • What changed after the last checkpoint?
  • Which tool produced the failure?
  • Which files were modified?
  • Has this exact error happened before?
  • Has the agent already tried this strategy?
  • How much recovery budget has been consumed?

This is where observability stops being a debugging feature and becomes part of the agent's runtime architecture.


4. Classify the Failure Before Choosing the Recovery

Once we know that something failed, the next question is:

What kind of failure is this?

A simple taxonomy is useful.

Failure typeExampleTypical response
TransientNetwork timeoutRetry
DependencyPackage unavailableRetry/change dependency
EnvironmentMissing environment variableRepair environment
SyntaxInvalid Python/TypeScriptFix code
TestUnit test failureDiagnose + modify
StateCorrupted workspaceRestore checkpoint
ToolAPI unavailableChange tool/path
PlanningWrong implementation strategyReplan
SemanticOutput technically valid but wrongVerify + rethink
PermissionOperation not allowedEscalate or change scope
SafetyRisky irreversible actionStop/escalate

The important part is that different failures require different recovery strategies.

A network timeout and a fundamentally broken architecture are both “errors,” but retrying both makes no sense.


5. Retry Is Useful — Until It Isn't

Retrying is one of the oldest reliability techniques in computing.

If a request fails because of a temporary network problem:

Request
  ↓
Timeout
  ↓
Retry

makes perfect sense.

But this:

Compilation error
  ↓
Retry
  ↓
Compilation error
  ↓
Retry
  ↓
Compilation error

is just burning time.

AI agents make this problem even more interesting because an LLM can repeatedly produce slightly different versions of the same failed action.

So the recovery layer needs retry policies and retry budgets.


A Retry Policy

A basic policy might look like:

class RetryPolicy:
    max_attempts = 3
    base_delay = 2

    def should_retry(self, failure):
        return failure.type in {
            "network_timeout",
            "temporary_service_error"
        }

The infrastructure can also use backoff:

delay = base_delay * (2 ** attempt)

So:

Attempt 1 → immediate
Attempt 2 → wait 2s
Attempt 3 → wait 4s

But an AI agent needs something more than ordinary infrastructure retries.

It needs a strategy budget.

For example:

Recovery budget
----------------
Same strategy:      2 attempts
Alternative strategy: 2 attempts
Rollback:           1 attempt
Human escalation:   after budget exhausted

That prevents the agent from endlessly hammering the same failed path.


6. The Important Part: Change the Strategy

This is where AI agent recovery starts becoming genuinely different from traditional retry logic.

Imagine an agent needs to install a package.

It runs:

pip install package-x

and receives:

Could not find a matching distribution

Blind retry:

pip install package-x

is pointless.

A better recovery process is:

Failure
  ↓
Diagnose
  ↓
Is the failure transient?
  ↓
No
  ↓
Is the dependency name/version wrong?
  ↓
Yes
  ↓
Inspect environment
  ↓
Search available versions
  ↓
Choose compatible version
  ↓
Retry installation

The agent isn't merely retrying.

It is changing the strategy based on evidence.

Research on agentic systems has explored related ideas such as reflection, feedback-driven improvement, and replanning. Reflexion, for example, stores textual feedback from failed trials and uses that information in subsequent attempts rather than simply repeating the original behavior.

More recent work has also specifically examined tool failures and dynamic replanning, showing that failures in tools can cause substantial degradation and that recovery is a distinct challenge from simply executing the original task.

The infrastructure implication is straightforward:

A recovery controller should treat a failed strategy as information.

Not as an instruction to repeat itself.


7. Recovery Needs a Verification Loop

Suppose the agent changes the code after a build failure.

How does it know the recovery worked?

It doesn't.

Not until something verifies it.

A robust loop therefore looks like:

Failure
  ↓
Diagnose
  ↓
Modify
  ↓
Execute
  ↓
Verify
  ↓
Success?
 ├── Yes → Continue
 └── No  → Diagnose again

This creates a closed loop.

For a coding agent:

def recover():
    diagnose()
    apply_fix()

    if run_tests():
        return "recovered"

    return "recovery_failed"

The verification step can involve:

  • unit tests
  • integration tests
  • build checks
  • type checking
  • linting
  • API responses
  • file existence
  • schema validation
  • browser checks
  • task-specific assertions

The exact verifier depends on the environment.

But the principle is the same:

Never assume a recovery succeeded just because the recovery action completed.


8. Persistent State: The Agent Should Not Have to Start From Zero

Imagine an agent has spent 30 minutes building an application.

It has:

  • created 40 files
  • installed dependencies
  • configured the database
  • implemented authentication
  • written tests
  • fixed three earlier errors

Then the environment crashes.

If the agent's only state was inside the model's active context, a huge amount of useful information may disappear.

This is why persistent agent state matters.

A runtime can store things like:

{
  "task": "Build customer dashboard",
  "goal": "Create a working dashboard with authentication",
  "completed_steps": [
    "project_initialized",
    "database_configured",
    "auth_implemented"
  ],
  "current_step": "dashboard_ui",
  "known_failures": [
    "chart_library_import_error"
  ],
  "last_checkpoint": "checkpoint_12"
}

The model's context can change.

The runtime state should not disappear with it.


9. Checkpoints Turn Recovery Into Something Concrete

A checkpoint is basically a known-good state.

For a coding environment, that might include:

Workspace files
+
Git revision
+
Dependency state
+
Configuration
+
Agent state
+
Execution metadata

For example:

Checkpoint 10
----------------
Git commit: 91af2e
Tests: PASS
Build: PASS
Agent state: valid

Then the agent makes several changes:

Checkpoint 10
    ↓
Change A
    ↓
Change B
    ↓
Change C
    ↓
Build fails

Instead of trying to manually undo everything:

Rollback → Checkpoint 10

Now the agent has a known-good starting point.


10. Rollback Is Not the Same as Retry

This distinction matters.

A retry says:

“Run the operation again.”

A rollback says:

“Return the environment to a previous known-good state.”

For example:

Known good
    ↓
Agent changes 12 files
    ↓
System becomes unstable
    ↓
Rollback
    ↓
Known good
    ↓
Try different strategy

This becomes especially important for autonomous AI agents because they can modify many things very quickly.

The more powerful the agent becomes, the more important rollback becomes.


11. But Checkpoints Need Boundaries

You don't necessarily want to snapshot the entire environment after every single action.

That could become expensive and noisy.

A better approach is to checkpoint at meaningful boundaries.

For example:

Task started
     ↓
Checkpoint
     ↓
Feature completed
     ↓
Tests pass
     ↓
Checkpoint
     ↓
Deployment preparation
     ↓
Checkpoint

The exact policy is an engineering decision.

One possible rule is:

Create a checkpoint after a meaningful unit of work reaches a verified state.

This gives recovery a stable foundation without turning every tool call into a snapshot operation.


12. Isolated Execution Makes Recovery Safer

Now consider something more dangerous.

The agent is asked to modify a production-like environment.

If it breaks something, rollback may not be enough.

Some operations are irreversible.

That's why autonomous agents should ideally operate inside isolated environments.

For example:

                User Task
                    ↓
            Agent Controller
                    ↓
             Isolated Runtime
              /     |      \
           Files   Tools   Network
                    ↓
                Verification
                    ↓
              Approved Output

The isolated runtime might be:

  • a container
  • a virtual machine
  • a sandbox
  • a temporary workspace
  • a branch
  • an ephemeral development environment

The exact implementation depends on the product.

The architectural principle is more important:

Give the agent enough power to complete the task, but enough isolation that failure doesn't automatically become damage.


13. Recovery Controller: The Missing Layer

At this point, we have several components:

  • execution
  • logs
  • traces
  • failure detection
  • diagnosis
  • retries
  • state
  • checkpoints
  • rollback
  • verification
  • isolation

But something needs to coordinate them.

That's the job of the recovery controller.

A simplified architecture could look like this:

This is the core architecture proposed in this article.

The agent decides what it wants to accomplish.

The runtime executes actions.

The recovery controller decides what should happen when execution doesn't go according to plan.

That separation is important.


14. The Agent Should Not Control Everything

One tempting architecture is:

LLM
 ↓
Everything

The model decides:

  • what to execute
  • whether it failed
  • whether to retry
  • whether rollback is necessary
  • whether the action is safe
  • whether to continue

That creates a dangerous dependency.

The same component that caused the failure is also deciding whether the failure matters.

A stronger architecture separates responsibilities.

Agent
 ↓
Proposes action
 ↓
Runtime
 ↓
Executes action
 ↓
Verifier
 ↓
Checks result
 ↓
Recovery Controller
 ↓
Determines recovery path

The agent still participates in diagnosis and planning.

But infrastructure owns the boundaries.

This is particularly important for autonomous AI agents operating with real tools.


15. A Practical Recovery State Machine

A recovery system can be represented as a state machine.

This gives us something much more useful than a generic “retry loop.”

Every transition has a reason.

Every recovery path has a boundary.

And every failure can eventually reach a controlled stopping point.


16. Example: An AI Coding Agent Breaks Its Own Application

Let's make this concrete.

The user says:

Build a dashboard that displays customer revenue by month.

The agent creates:

app/
├── api/
├── components/
├── dashboard/
└── database/

It writes the code.

The initial tests pass.

A checkpoint is created.

Then the agent decides to replace the chart library.

It changes:

package.json
dashboard/page.tsx
components/RevenueChart.tsx

The build fails:

Module not found: Can't resolve 'chart-library'

Step 1: Detect

The runtime sees:

exit_code = 1

Step 2: Capture evidence

It stores:

stderr
command
workspace revision
changed files
trace
agent step

Step 3: Classify

The recovery controller identifies:

Failure = dependency/import failure

Not:

network timeout

Not:

system crash

Step 4: Diagnose

The agent inspects:

package.json
node_modules
import statement
lockfile

It discovers that the package was never installed.

Step 5: Repair

It installs the correct dependency.

Step 6: Verify

It runs:

npm run build
npm test

Both pass.

Step 7: Checkpoint

The new state becomes:

Checkpoint 14
Build: PASS
Tests: PASS

The agent continues.

Notice what happened.

The infrastructure didn't simply say:

“Try again.”

It turned:

Failure

into:

Evidence
→ Diagnosis
→ Repair
→ Verification
→ New known-good state

That's recovery.


17. What If the Fix Makes Things Worse?

This is where checkpoints become extremely valuable.

Imagine the agent tries to fix the dependency issue but changes five additional files.

The build still fails.

Worse, now there are multiple errors.

The recovery controller compares the current state with the previous checkpoint.

If the new state is clearly worse, it can do:

Current state
    ↓
Recovery unsuccessful
    ↓
Rollback
    ↓
Checkpoint 13
    ↓
New strategy

The agent can then try a different approach.

This is much safer than allowing every failed recovery attempt to accumulate changes forever.


18. Recovery Needs Memory

There's another failure mode that isn't obvious at first.

Suppose the agent tries:

Strategy A

It fails.

Then:

Strategy B

It fails.

Then the model's context changes.

Later, it accidentally tries:

Strategy A

again.

Without persistent recovery state, the system may repeat old mistakes.

So the runtime should preserve information like:

{
  "failed_strategies": [
    {
      "strategy": "Install package-x v1",
      "reason": "Version incompatible with runtime"
    },
    {
      "strategy": "Use package-y",
      "reason": "API does not support required feature"
    }
  ]
}

This doesn't mean storing every piece of agent conversation forever.

It means preserving operationally useful state.

The distinction is important.

The agent doesn't need a giant transcript.

It needs enough state to avoid repeating known failures.


19. Recovery Can Fail Too

This is the part many architectures leave out.

What happens when the recovery mechanism itself fails?

For example:

Application breaks
      ↓
Agent attempts repair
      ↓
Repair breaks dependency tree
      ↓
Rollback starts
      ↓
Rollback fails

Now we have:

Failure
  ↓
Recovery failure
  ↓
Recovery of recovery

You don't want an infinite recursion of increasingly desperate automation.

So the recovery system needs failure boundaries.

A useful policy is:

Normal execution
      ↓
Recovery attempt
      ↓
Alternative recovery
      ↓
Rollback
      ↓
Human escalation

At some point:

The system should stop trying to be autonomous.

That is not a weakness.

It's a reliability feature.


20. Human Escalation Should Carry Context

“Human intervention required” is not enough.

If the system escalates, the human should receive the evidence needed to make a decision.

For example:

TASK
Build customer dashboard

CURRENT STATE
Build failing

FAILURE
Missing database migration

WHAT WAS TRIED
1. Regenerated migration
2. Re-ran migration
3. Restored previous schema

RESULT
Still failing

LAST KNOWN GOOD CHECKPOINT
checkpoint_21

RECOMMENDATION
Rollback to checkpoint_21 and review migration manually

That's a useful escalation.

Compare that with:

Something went wrong.
Please fix it.

The second one just transfers the debugging problem to the human.

The first one gives the human a decision.


21. A Better Escalation Model

The recovery controller can therefore classify failures into three broad categories.

Recover automatically

Examples:

  • transient network failure
  • dependency installation issue
  • temporary tool failure
  • known deterministic error

Recover with replanning

Examples:

  • implementation strategy doesn't work
  • API doesn't support the assumed operation
  • generated code repeatedly fails verification
  • current approach violates a discovered constraint

Escalate

Examples:

  • irreversible operation
  • ambiguous user intent
  • missing credentials
  • permission boundary
  • repeated recovery failure
  • unknown failure
  • safety-sensitive action

This creates a useful principle:

Autonomy should increase when confidence is high and decrease when uncertainty increases.


22. The Complete Recovery Architecture

Putting everything together, the infrastructure starts to look like this:

There are several important boundaries here.

The agent

Responsible for:

  • reasoning
  • planning
  • choosing actions
  • interpreting evidence
  • proposing recovery strategies

The execution controller

Responsible for:

  • running actions
  • enforcing permissions
  • collecting results
  • enforcing execution limits

The isolated environment

Responsible for:

  • containing changes
  • limiting blast radius
  • providing reproducible execution

The verifier

Responsible for:

  • determining whether the result actually works

The recovery controller

Responsible for:

  • classifying failure
  • selecting recovery strategy
  • enforcing retry budgets
  • deciding when to rollback
  • deciding when to escalate

The state/checkpoint layer

Responsible for:

  • persistent state
  • known-good states
  • recovery history
  • previous failed strategies

That's a real infrastructure problem.

Not just a better prompt.


23. What Should the Recovery Controller Actually Store?

A minimal recovery record might look like this:

from dataclasses import dataclass
from typing import Optional


@dataclass
class RecoveryRecord:
    task_id: str
    run_id: str
    step_id: str

    failure_type: str
    error_message: str

    attempt_count: int
    recovery_attempts: int

    last_checkpoint: Optional[str]

    strategy_used: str
    strategies_failed: list[str]

    verification_status: str

And the controller could expose something conceptually similar to:

class RecoveryController:

    def handle_failure(self, failure, state):

        evidence = self.collect_evidence(failure)

        diagnosis = self.classify(
            failure=failure,
            evidence=evidence,
            state=state
        )

        if diagnosis.is_transient:
            return self.retry()

        if diagnosis.requires_replan:
            return self.replan()

        if diagnosis.requires_rollback:
            return self.rollback()

        if diagnosis.is_recoverable:
            return self.repair()

        return self.escalate()

This isn't a complete production implementation.

It's an architectural pattern.

The important thing is that recovery becomes an explicit subsystem instead of an accidental behavior of the model.


24. What Existing Research Tells Us — And What It Doesn't

There is already meaningful research around agent reflection, planning, replanning, and failure handling.

For example, Reflexion explored using feedback from unsuccessful trials and maintaining reflective memory for subsequent attempts.

Planning research such as PlanBench explicitly evaluates whether language models can reason about plan execution and replan when unexpected events alter the environment.

More recent work such as ToolMaze focuses specifically on failures in tool-integrated reasoning and dynamic replanning. Its results reinforce an important point: tool failure and recovery are not simply the same problem as ordinary task execution.

There is also emerging work proposing integrated self-healing frameworks for LLM-based agents, combining failure detection, diagnosis, and adaptive recovery. These systems are useful evidence that recovery is becoming an explicit research problem, although proposed frameworks should not automatically be treated as established production practice.

But research papers don't give us a universal production architecture.

That's where engineering judgment comes in.


25. What Is Established vs. What Are We Proposing?

This distinction is important.

Established engineering patterns

These are not new ideas:

  • structured logging
  • distributed tracing
  • retries
  • exponential backoff
  • checkpoints
  • snapshots
  • rollback
  • isolated execution
  • automated testing
  • state persistence
  • human escalation

These patterns already exist across reliable software systems.

Research-backed agent techniques

Examples include:

  • reflection from task feedback
  • memory across trials
  • replanning after unexpected events
  • tool-failure recovery
  • execution-aware agent evaluation

These have been explored in academic agent research.

Proposed Causly architecture

The architecture in this article — particularly the separation between:

Agent
Execution Runtime
Verification
Recovery Controller
Checkpoint Store
Human Escalation

is a proposed architecture for Causly's exploration.

It should be treated as a design hypothesis, not as an established industry standard.

That's an important distinction.


26. The Interesting Experiment for Causly

This architecture also gives us something we can actually test.

Instead of asking:

“Can an AI agent build an application?”

we can ask something more useful:

Can an AI agent recover from controlled failures without human intervention?

We could create a controlled environment where the agent is deliberately exposed to failures.

For example:

Experiment A
Network timeout

Experiment B
Broken dependency

Experiment C
Compilation error

Experiment D
Failed test

Experiment E
Corrupted state

Experiment F
Wrong API assumption

Experiment G
Bad implementation strategy

Then compare different recovery mechanisms.

Baseline

Agent → Failure → Retry

Recovery system

Agent
 ↓
Failure detection
 ↓
Diagnosis
 ↓
Recovery strategy
 ↓
Verification

Recovery + checkpointing

Agent
 ↓
Failure
 ↓
Diagnosis
 ↓
Rollback
 ↓
Alternative strategy
 ↓
Verification

Recovery + human escalation

Agent
 ↓
Failure
 ↓
Recovery attempts
 ↓
Escalation
 ↓
Human decision

And importantly, we should measure the system rather than assume that more autonomy is automatically better.

Useful measurements could include:

  • recovery success rate
  • number of recovery attempts
  • repeated-strategy rate
  • time to recovery
  • number of unnecessary rollbacks
  • verification failures
  • human escalation rate
  • state loss after failure
  • unsafe actions prevented

These would be Causly experiments, not claims about industry-wide performance.

We should not invent a number until we actually run the experiment.


27. The Real Goal Isn't Zero Failures

This might be the biggest takeaway.

Trying to build an AI agent that never fails is probably the wrong abstraction.

Software systems fail.

Networks fail.

APIs fail.

Dependencies fail.

Agents will fail too.

The real engineering goal is:

Failure
   ↓
Detect
   ↓
Understand
   ↓
Contain
   ↓
Recover
   ↓
Verify
   ↓
Continue

And when recovery isn't safe:

Failure
   ↓
Contain
   ↓
Escalate
   ↓
Human decides

That's a much more realistic definition of reliable autonomy.


28. So What Actually Turns Failure Into Recovery?

Let's return to the original question.

What infrastructure turns “the agent failed” into “the agent can safely recover and continue”?

Not one feature.

It is the combination of several layers:

                 AI AGENT
                     │
                     ▼
              Execution Runtime
                     │
                     ▼
              Failure Detection
                     │
                     ▼
             Evidence + Tracing
                     │
                     ▼
            Diagnosis / Classification
                     │
                     ▼
             Recovery Controller
                     │
        ┌────────────┼────────────┐
        ▼            ▼            ▼
      Retry        Replan       Rollback
        │            │            │
        └────────────┼────────────┘
                     ▼
                 Verification
                     │
               ┌─────┴─────┐
               ▼           ▼
            Success     Failure
               │           │
               ▼           ▼
            Continue    Escalate

The model is only one part of that system.

The surrounding infrastructure determines whether failure becomes:

infinite retry

or:

controlled recovery

That difference is going to matter more as AI agents move from generating text to actually changing software, systems, data, and infrastructure.


Final Takeaway

The most useful way to think about an AI agent environment is not:

“Where does the agent run?”

It's:

“What happens when the agent is wrong?”

A good environment should assume failure.

It should preserve evidence.

It should know what changed.

It should maintain known-good states.

It should limit retries.

It should allow the agent to change strategy.

It should verify every recovery.

It should isolate dangerous operations.

And when the system reaches a point where automation is no longer trustworthy, it should stop and ask for help.

That's the foundation of recoverable autonomy.

An autonomous AI agent doesn't become reliable because it stops failing.

It becomes reliable when its environment knows what to do after it fails.


References & Further Reading

  1. Reflexion: Language Agents with Verbal Reinforcement Learning — Shinn et al. Research on using feedback and episodic reflective memory to improve subsequent agent trials.

  2. PlanBench: An Extensible Benchmark for Evaluating Large Language Models on Planning and Reasoning about Plans Includes evaluation of plan execution and replanning after unexpected events.

  3. When Tools Fail: Benchmarking Dynamic Replanning and Anomaly Recovery in LLM Agents Research specifically examining tool failures, anomaly recovery, and dynamic replanning in tool-integrated agents.

  4. A Self-Healing Framework for Reliable LLM-Based Autonomous Agents An emerging framework exploring integrated failure detection, reliability assessment, and adaptive recovery for LLM agents.


The broader question we're exploring is simple:

If AI agents are going to work for us, what infrastructure do they need to work reliably?

Not just how agents think.

Not just how they use tools.

But what happens when things inevitably go wrong.