PAOVR 루프: 실제로 작업을 완료하는 실제 에이전트 루프

작성자

카테고리:

← 피드로
DEV Community · Eduard · 2026-09-11 개발(SW)

Plan → Act → Observe → Verify → Repair

Stop building agents that narrate completion. Start building systems that prove it.

In 2026 the conversation finally moved past “prompt engineering is dead.”

What replaced it is quieter, harder, and far more useful: loop engineering.

Most agents still fail the same way. They generate a confident final answer, declare victory, and leave the human to discover that half the work was invented, skipped, or never checked. We’ve all watched an agent burn five dollars in tokens just to confidently hallucinate a completely wrong API call or invent a tool result that never existed. The model is rarely the real problem anymore. The missing contract is.

This is a production-grade field guide to the PAOVR Loop — the only control pattern that consistently finishes real work: Plan → Act → Observe → Verify → Repair.

It is the synthesis of ReAct, Plan-and-Solve, modern harness design from Anthropic and OpenAI, and the hard lessons of teams that run agents in production instead of demos.

You will leave with:

  • A precise anatomy of the PAOVR Loop that survives long-horizon tasks
  • The actual prompts we use in production
  • JSON contracts and TypeScript interfaces that agents and runtimes can both consume
  • Real 2026 implementation stacks (Next.js, TypeScript, Supabase, Vercel)
  • Vector memory patterns that turn amnesiac agents into compounding workers
  • Failure patterns that still dominate and how to kill them
  • A one-week install plan you can run on your own stack

This is not theory. It is the difference between an agent that talks about finishing and one that proves it finished.

Table of Contents

  1. Why Most Agents Still Fail in 2026
  2. The Shift from Prompting to Loop Engineering
  3. The PAOVR Loop: Plan → Act → Observe → Verify → Repair
  4. Stage 1 — Plan: Stop Asking Agents to Think. Ask Them to Graph
  5. Stage 2 — Act: Atomic Execution with Tool Contracts
  6. Stage 3 — Observe: Grounding in Reality
  7. Stage 4 — Verify: The Step Almost Everyone Skips
  8. Stage 5 — Repair: Recovery Without Restarting from Zero
  9. JSON Contracts That Survive Production
  10. The Prompts We Actually Use in Production
  11. Context Engineering Inside the Loop
  12. Circuit Breakers, Budgets, and Stopping Conditions
  13. Failure Patterns I Keep Seeing in 2026
  14. How Real Production Systems Use This Loop
  15. A One-Week Install Plan
  16. Ship Checklist
  17. What to Do in the Next 15 Minutes
  18. Further Reading, People & Tools
  19. Frequently Asked Questions

1. Why Most Agents Still Fail in 2026

The failure mode shifted.

In 2023–2024 the model was often simply wrong.

In 2026 the model is usually competent at the atomic step. The system fails because there is no enforceable definition of “done.”

Typical symptoms:

  • The agent produces a beautiful plan and then freestyles the execution.
  • It marks a task complete because the last tool call returned something.
  • It never re-checks the original success criteria after the final action.
  • Context grows until the original goal is buried under tool noise.
  • When something breaks, the agent rewrites the entire plan instead of repairing the broken leaf.

The common root cause is the same: the loop has no Verify stage with teeth.

ReAct (Yao et al., 2022) taught us to interleave Thought → Action → Observation. That was necessary. It was not sufficient for long-horizon production work. Plan-and-Solve (Wang et al., 2023) added an explicit planning phase. Modern harnesses from Anthropic and OpenAI added budgets, worktrees, and skills. The missing piece that still separates demos from reliable systems is a hard Verify → Repair gate.

If your agent cannot answer the question “How do I know this is finished?” with evidence instead of narration, it is not finished.

2. The Shift from Prompting to Loop Engineering

Prompt engineering optimized the single turn.

Loop engineering optimizes the entire trajectory.

The people who ship reliable agents in 2026 talk about different things:

  • Boris Cherny (Claude Code, Anthropic): “I don’t prompt Claude anymore. I have loops running that prompt Claude.”
  • Addy Osmani and the broader community: loop engineering as a discipline.
  • Anthropic’s own guidance on the Agent SDK / Claude Code: gather context → take action → verify work → repeat.
  • Production teams: circuit breakers, maxTurns, cost thresholds, external verifiers.

The unit of design is no longer “the perfect system prompt.”

It is the control loop that keeps the model inside a contract until the contract is satisfied or the budget is exhausted.

This article is about that loop — specifically the PAOVR version of it.

3. The PAOVR Loop: Plan → Act → Observe → Verify → Repair

Here is the minimal reliable shape:

PLAN
  ↓
ACT (one atomic step)
  ↓
OBSERVE (real tool / environment feedback)
  ↓
VERIFY (against explicit done_when)
  ↓
  ├─ done → next task or finish
  └─ not done → REPAIR → back to ACT or re-plan only the affected subtree

Enter fullscreen mode Exit fullscreen mode

This is the PAOVR Loop.

Key design rules:

  1. One atomic action per Act. Prefer 1–3 tool calls maximum.
  2. Every task has a crisp done_when. If you cannot write it, the task is not ready.
  3. Verify is external or at least independent. The same model that generated the work should not be the only judge.
  4. Repair is local. Do not throw away the entire plan because one leaf failed.
  5. Hard stopping conditions always exist. Iteration limit, cost limit, repeated identical failure, context budget.

This is the pattern that survives when the task takes 40 steps instead of 4.

4. Stage 1 — Plan: Stop Asking Agents to Think. Ask Them to Graph

Planning is no longer “think step by step.”

It is the production of an executable graph.

What a good plan looks like

  • Goal stated as an observable outcome
  • Explicit assumptions
  • Clarifying questions only when the cost of being wrong is high
  • Tasks that are leaf-level (doable in 1–3 tool calls)
  • Dependencies declared
  • Every task has a done_when string that a later verifier can check
  • Risks listed

Planner prompt we actually use

Act as the Task Planner. You do not execute. You only produce an executable plan.

Rules:
1. Split the goal into atomic steps.
2. One step = one action or one tightly related group of tool calls (max 3).
3. Declare dependencies with task IDs.
4. Every step must have a crisp done_when that can be verified later.
5. If critical information is missing, list assumptions and clarifying_questions. Do not invent facts.
6. Output strict JSON only. No prose essay.

Return exactly this schema:
{
  "goal": "string",
  "assumptions": ["string"],
  "clarifying_questions": ["string"],
  "tasks": [
    {
      "id": "t1",
      "title": "string",
      "description": "string",
      "depends_on": ["t0"],
      "tool_hint": "none|search|code|browser|api|file",
      "done_when": "observable condition that proves completion"
    }
  ],
  "risks": ["string"]
}

Enter fullscreen mode Exit fullscreen mode

This planner is deliberately dumb about execution. That is the point. Separation of concerns is what keeps the system debuggable.

5. Stage 2 — Act: Atomic Execution with Tool Contracts

The Executor receives one task, the current plan state, and any previous observations. It is forbidden from jumping ahead.

Executor prompt

Act as the Executor Agent.
Take exactly one next task from the plan. Do not jump ahead. Do not invent missing data.

Inputs you will receive:
- plan JSON
- current_task_id
- previous tool results / observations (if any)

Method:
1. Re-read the done_when for the current task.
2. If you are blocked on missing data, request the cheapest tool or mark status blocked.
3. Perform the smallest useful action that moves the task forward.
4. Return structured output only:

## Action
(what you did)

## Evidence
(raw tool output or observation — never paraphrase away the truth)

## Status
done | partial | blocked

## Residual risks
(any new risks introduced)

## Next recommendation
(only if status is not done)

Enter fullscreen mode Exit fullscreen mode

The Executor never decides the overall goal is finished. That decision belongs to the outer loop after verification.

6. Stage 3 — Observe: Grounding in Reality

Observation is the only place the model is allowed to see the real world.

Rules that still matter in 2026:

  • Never let the model invent tool output. The runtime supplies it.
  • Prefer structured tool responses over free text when possible.
  • Keep the observation window small and high-signal. Context rot is real.
  • Log every observation with a timestamp and tool name. You will need it for debugging.

This is the stage that turns ReAct from a clever prompt into a reliable control system.

7. Stage 4 — Verify: The Step Almost Everyone Skips

Verification is the difference between an agent that claims success and one that demonstrates it.

What “done” actually means

A task is done only when its done_when is true and the evidence supports that claim.

The verifier should preferably be:

  • A separate model call with a different system prompt, or
  • An external checker (tests, linter, schema validator, SEO score, human review), or
  • A deterministic function when the domain allows it.

Verifier prompt

Act as the Verifier. You do not generate new work. You only judge whether the current task is complete.

You receive:
- original task (including done_when)
- action taken
- evidence / observation
- any claimed result

Rules:
1. Quote the done_when.
2. Decide: satisfied | not_satisfied | insufficient_evidence.
3. If not_satisfied, name the single cheapest next check or repair.
4. Never accept narration as proof. Require evidence.
5. Output strict JSON:

{
  "task_id": "...",
  "done_when": "...",
  "verdict": "satisfied|not_satisfied|insufficient_evidence",
  "evidence_summary": "one or two sentences",
  "missing": ["what is still required"],
  "recommended_repair": "smallest next action or null"
}

Enter fullscreen mode Exit fullscreen mode

This is the stage that prevents the polite lie.

8. Stage 5 — Repair: Recovery Without Restarting from Zero

When Verify returns not_satisfied, the system has two clean options:

  1. Local repair — re-run or adjust only the failed leaf.
  2. Subtree re-plan — only when dependencies themselves have changed.

Never throw away the entire plan because one step failed. That is how agents waste tokens and lose trust.

Repair rule that saves hours:

If Status is partial or blocked or Verify says not_satisfied:
1. Name the blocker in one sentence.
2. Propose the cheapest next check or action.
3. Do not rewrite the entire plan unless upstream dependencies actually changed.
4. Preserve every completed task and its evidence.

Enter fullscreen mode Exit fullscreen mode

9. JSON Contracts That Survive Production

Free-form text is fine for humans. Agents need schemas.

Here is a minimal production-ready plan schema and a corresponding execution record:

{
  "run_id": "uuid",
  "goal": "...",
  "status": "running|completed|failed|budget_exhausted",
  "tasks": [
    {
      "id": "t3",
      "status": "done|partial|blocked|failed",
      "attempts": 2,
      "last_evidence": "...",
      "verified_at": "ISO timestamp"
    }
  ],
  "cost_so_far": {
    "tokens": 12840,
    "usd_estimate": 0.41
  },
  "circuit_breaker": {
    "max_turns": 40,
    "max_cost_usd": 5.0,
    "identical_failure_limit": 3
  }
}

Enter fullscreen mode Exit fullscreen mode

In TypeScript this maps cleanly to interfaces that the compiler and the runtime both enforce:

interface Task {
  id: string;
  title: string;
  description: string;
  depends_on: string[];
  tool_hint: "none" | "search" | "code" | "browser" | "api" | "file";
  done_when: string;
  status?: "pending" | "running" | "done" | "partial" | "blocked" | "failed";
  attempts?: number;
  last_evidence?: string;
  verified_at?: string;
}

interface AgentPlan {
  goal: string;
  assumptions: string[];
  clarifying_questions: string[];
  tasks: Task[];
  risks: string[];
}

interface RunState {
  run_id: string;
  goal: string;
  status: "running" | "completed" | "failed" | "budget_exhausted";
  tasks: Task[];
  cost_so_far: { tokens: number; usd_estimate: number };
  circuit_breaker: {
    max_turns: number;
    max_cost_usd: number;
    identical_failure_limit: number;
  };
}

Enter fullscreen mode Exit fullscreen mode

These interfaces become the single source of truth between your orchestrator, edge functions, and logging layer.

10. The Prompts We Actually Use in Production

You already have the three core ones (Planner, Executor, Verifier).

Here is the outer loop controller that ties them together:

Act as the Loop Controller. You own the overall trajectory.

Your only job:
1. Load or create the plan.
2. Select the next ready task (dependencies satisfied, status not done).
3. Hand it to Executor.
4. Feed the result to Verifier.
5. On satisfied → mark done and continue.
6. On not_satisfied → trigger Repair (local first).
7. Enforce circuit breakers before every new turn.
8. When all tasks are verified done, emit final result + residual risks.
9. Never invent completion.

You speak only in structured status updates and JSON state.

Enter fullscreen mode Exit fullscreen mode

These four prompts form a complete, deployable skeleton for the PAOVR Loop. Keep them versioned in git the same way you version any other critical configuration.

11. Context Engineering Inside the Loop

Context is a finite resource. In long runs it becomes the primary failure mode.

Practical rules that still hold:

  • Keep the master policy (role, constraints, output contract) stable and cached.
  • Give the Executor only the current task + recent observations + the original done_when.
  • Summarize or offload completed tasks instead of replaying the entire history.
  • Prefer fresh context for pure execution workers and accumulated context only for the planner/orchestrator.
  • Measure context fill. When it crosses ~60–70% of the useful window, force a compression or checkpoint step.

This is why the best 2026 systems treat the file system, git, and external memory as first-class context tools rather than dumping everything into the prompt.

Vector Memory as a First-Class Citizen

Context windows are large, but dumping everything into them destroys attention. Production agents in 2026 use external memory architectures.

A practical pattern:

  1. After every completed (or failed) task, embed a short structured summary of what happened, the evidence, and the outcome.
  2. Store those embeddings in a vector store. pgvector is the default choice for many teams because it lives next to the relational state.
  3. Before the Plan stage of a new run, the orchestrator performs a micro-RAG retrieval against the agent’s own historical executions.
  4. The retrieved constraints are injected into the Planner’s context as hard lessons (“previous attempts failed when the shadow-DOM selector timed out; prefer the data-testid path”).

The effect is compounding. An agent that failed to interact with a particular UI element hundreds of times across past sessions no longer has to rediscover the failure mode. Memory turns a brilliant amnesiac into a worker that actually improves.

Pair the embeddings with a fast, high-quality text-embedding model. Gemini text-embedding models are a common 2026 choice for the cost/quality balance. Keep the retrieval budget tiny — usually the top 3–5 most relevant past failures or successes are enough. Anything more and you re-introduce context rot under a different name.

12. Circuit Breakers, Budgets, and Stopping Conditions

A loop without hard stops is a liability.

Minimum set:

Signal Typical setting Enforcement Max turns / iterations 20–60 depending on task Runtime Max cost (USD or tokens) Task-specific budget Runtime Identical failure streak 2–3 Instruction + runtime Context budget 70% of useful window Instruction Wall-clock timeout Optional Runtime

When a breaker trips, the agent must:

  1. Stop new actions.
  2. Return partial results that were already verified.
  3. State clearly what triggered the stop and what remains open.
  4. Escalate if a human gate exists.

Partial verified work is always more valuable than a confident hallucination.

13. Failure Patterns I Keep Seeing in 2026

  1. Narrated completion — the model says “done” without evidence.

    Fix: hard Verify stage with external or independent judgment.

  2. Plan that is actually a novel — tasks that still require a short essay of instructions.

    Fix: keep splitting until each leaf is 1–3 tool calls.

  3. Context rot — original goal buried under 30 tool observations.

    Fix: aggressive pruning + separate orchestrator context + vector memory for long-term lessons.

  4. Repair by total rewrite — one failure causes the agent to discard everything.

    Fix: local-first repair rule.

  5. Missing done_when — “make it good” or “optimize the page.”

    Fix: refuse to accept a task without an observable completion condition.

  6. Tool hallucination — model invents tool results.

    Fix: runtime always supplies Observation; model is never allowed to generate it.

  7. Infinite polite loops — agent keeps “trying one more thing.”

    Fix: circuit breakers with identical-failure detection.

These seven still account for the majority of production pain.

14. How Real Production Systems Use This Loop

The pattern appears (under different names) in the systems that actually ship:

  • Claude Code and the Anthropic Agent SDK — gather → act → verify → repeat, with explicit loop types and stopping conditions.
  • Coding agents that treat the test suite as the verifier.
  • Research agents that force a verification step against sources before claiming a fact.
  • Content and SEO pipelines that run a quality gate after generation.

The 2026 Implementation Layer

The theory maps directly to modern stacks. You do not need a massive monolithic Python backend to run this loop cleanly.

A common high-leverage architecture in 2026:

  • Orchestration: Next.js App Router (or a lightweight server component layer) owns the Loop Controller. Strict TypeScript interfaces enforce the JSON contracts at compile time.
  • State & Logs: Supabase (Postgres + pgvector) stores run state, task history, and the vector memory of past executions.
  • Execution: Serverless / edge functions on Vercel handle individual Act steps. This keeps the surface small and the cold starts acceptable.
  • Tool surface: Many teams standardize on the Model Context Protocol (MCP) so agents can talk to tools in a consistent way.
  • Local development & coding agents: The same philosophy powers advanced refactoring sessions in tools like OpenCode and Cline. They do not just write code; they observe terminal output, verify against the linter and test suite, and repair locally without wiping the whole file.

The key insight is that the PAOVR Loop is language-agnostic. Once you have typed contracts and a reliable state store, the same shape works for coding agents, research agents, and domain-specific crawlers.

Case Study: Surviving the Chaos of Web Crawling

Let’s look at a real 2026 production environment. When building the crawler pipeline for the AI SEO platform AuditMe, the biggest nightmare wasn’t parsing HTML — it was the sheer unpredictability of the web. Sites timeout, DOMs shift, JavaScript-heavy pages render differently every time, and standard linear scripts break constantly.

To fix this, the entire auditing engine was rewritten around the PAOVR Loop. Instead of a monolithic script, the system uses Next.js App Router and Supabase to orchestrate atomic tasks. For example, if you run a URL through the free Website SEO Checker, you are actually triggering a multi-stage Plan → Act → Verify pipeline under the hood.

If a check fails (for example, an API timeout during a heavy DOM render), it doesn’t kill the audit. The loop simply catches the failure in the Verify stage, triggers a multi-provider API failover via the Repair stage, and continues seamlessly. Only the affected leaf is retried.

It took months of refactoring — and countless local sessions with tools like OpenCode and Cline — to get the vector memory and stopping conditions right. We regularly document these architectural hard lessons, including how to handle AI search readiness and context windows, over on the AuditMe blog.

This is the PAOVR Loop applied to a real production crawler that has to stay reliable under noisy network conditions and constantly changing page structures.

15. A One-Week Install Plan

Day 1

Write the three core prompts (Planner, Executor, Verifier). Run them manually on a simple multi-step task. Measure where the model tries to skip Verify.

Day 2

Add strict JSON schemas (or TypeScript interfaces) and a simple state object. Make the outer loop refuse to continue without a valid status.

Day 3

Introduce one external verifier (tests, schema check, or a second model call). Force the system to use it.

Day 4

Add circuit breakers: max turns, cost, identical failure. Test them by deliberately breaking a tool.

Day 5

Implement local-first Repair. Confirm that a single failed leaf does not destroy the whole plan. Optionally wire a minimal pgvector memory store for past failures.

Day 6

Run a real 20–40 step task. Log every observation and verification. Identify the highest-friction stage.

Day 7

Write the one-page internal playbook for your team. Version the prompts and schemas. Put the state schema in git.

By the end of the week you will have a PAOVR Loop that is already more reliable than 90% of the agents currently running in the wild.

16. Ship Checklist

Before you call any agent “production”:

  • [ ] Every task has an explicit done_when
  • [ ] Planner and Executor are separate
  • [ ] Verify stage exists and is independent
  • [ ] Repair is local-first
  • [ ] Circuit breakers are enforced by the runtime, not just the prompt
  • [ ] Observations are never invented by the model
  • [ ] Completed work is preserved and evidenced
  • [ ] Cost and turn budgets are visible
  • [ ] Partial results are returned on early stop
  • [ ] Prompts and schemas are versioned
  • [ ] Long-term lessons are stored outside the context window (vector memory or equivalent)

If any box is unchecked, the agent is still a demo.

17. What to Do in the Next 15 Minutes

  1. Copy the Planner prompt into your current agent stack.
  2. Take one real task you care about and force it to emit the JSON plan schema.
  3. Write a done_when for the first three leaf tasks that a stranger could verify.
  4. Add a single Verify call after the first Act.
  5. Run it once and look at the difference between narration and evidence.

That is the entire difference between “it usually works” and “I can trust it when I’m not watching.”

18. Further Reading, People & Tools

Foundational papers

People & practice

  • Boris Cherny (Claude Code, Anthropic) — loop-first mindset
  • Addy Osmani — popularized “loop engineering”
  • Anthropic Agent SDK / Claude Code docs
  • OpenAI’s agent and Codex documentation

Tools & platforms worth watching

  • Claude Code / Anthropic Agent SDK
  • Cursor, OpenCode, Cline and modern coding agent harnesses
  • Model Context Protocol (MCP)
  • pgvector + modern embedding models for agent memory
  • Next.js App Router and Supabase for the orchestration + state layer
  • Production observability for agents (cost, turns, verification rate)

19. Frequently Asked Questions

Isn’t this just ReAct with extra steps?

ReAct is the necessary interleaving of reasoning and acting. The PAOVR Loop adds explicit planning with contracts, independent verification, and controlled repair. Those three additions are what make long-horizon work reliable.

Do I still need a strong system prompt?

Yes. The prompts above are the system prompts. They are just focused on policy and contracts instead of personality.

Can the same model do Plan, Act, and Verify?

It can, but reliability drops. Prefer separation, even if it is the same base model with different system prompts and temperature.

What about multi-agent systems?

The same loop still applies. The orchestrator runs the outer PAOVR Loop; specialist agents become the Act stage for particular tools or domains.

How do I add long-term memory without exploding context?

Use vector memory (pgvector + embeddings) and retrieve only the top few relevant past failures or successes before planning. Keep the retrieval budget tiny.

How do I know when to stop adding stages?

When the agent can finish a 30-step task, survive a tool failure, and return verified partial results under a hard budget — stop. Further complexity usually adds more failure modes than it removes.

Final note

The agents that will still be running in production in 2027 are not the ones with the cleverest personality block. They are the ones whose loops enforce a contract, demand evidence, remember their past failures, and know how to repair without starting over.

Build the PAOVR Loop.

Version the contracts.

Verify everything.

Give the agent a memory that compounds.

Then the model can finally do what we have been asking it to do for three years: finish the job.

Written for practitioners who ship. Updated for the 2026 agent landscape.

원문에서 계속 ↗