{"slug": "how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes", "title": "How to Add a Verification Loop to Your AI Agent in 30 Minutes", "summary": "A developer has published a tutorial showing how to add a verification loop to an AI agent in about 30 minutes, separating the component that generates work from the one that judges it. The approach builds a verifier as a Bit component that returns one of four verdicts — NO, YES, MAYBE, or IFF — instead of a binary done condition, drawing on Addy Osmani's work on owning the outer loop. The verifier receives only the generator's output and a predefined done condition, not the generator's reasoning, so the agent cannot declare its own work complete.", "body_md": "AI agent loops can produce an output, run some checks and move on without establishing that the result actually satisfies the task. The problem gets worse when the same generator writes the work, checks it and decides when it is done.\n\nSay you ask an agent to modify an API and add tests. It writes the implementation, creates the tests, runs them, sees green results and declares the task complete. If the tests missed part of the requirement, the loop has no reason to stop and question the result.\n\nIn this tutorial, you'll add a verification step to that loop. You'll build the verifier as a Bit component, give it a four-value done condition and wire it into a TypeScript agent loop. You'll then export the component to a Bit scope so you can reuse it across projects.\n\nMake sure you have:\n\nA [bit.cloud](http://bit.cloud) account with access to Hope AI. Head to [bit.cloud/signup](https://bit.cloud/signup) if you don't have one.\n\n**Bit installed through BVM.** Run `npx @teambit/bvm install` if you haven't installed it yet.\n\n**A Bit workspace.** You can use an existing workspace or initialize one with `bit init --default-scope` `my-org.my``-project`.\n\n**Basic TypeScript knowledge.** You should be comfortable reading typed function signatures, imports and switch statements.\n\nYour loop has no mechanism to catch bad output before it continues. The generator declares the task done and the loop moves on, whether the output is correct or not.\n\nThis is the same failure [AgentField describes](https://agentfield.ai/blog/beyond-vibe-coding) with agents that write both the implementation and its tests. The tests can pass because the generator created the checks that determine whether its own work passes. That is the generator checking its own homework, not verification.\n\nThe structural problem is your done condition. It is usually binary: the task is complete, or it is not. The generator evaluates the output, picks one of those two states and the loop continues.\n\nA verifier separates those responsibilities. The generator produces the output. The verifier decides whether that output satisfies the condition you defined before the loop started.\n\nA verification loop gives your agent a separate decision-maker. The generator produces the output, while the verifier receives that output and evaluates it against a done condition defined before the loop starts.\n\nInstead of returning only `true` or `false`, your verifier returns one of four outcomes:\n\n| Verdict | What it means | What the loop does | \n|---|---|---|\n| NO | The output failed the condition. | Retry with the verifier's reason as context. | \n| YES | The output passed the condition. | Continue to the next step. | \n| MAYBE | The verifier cannot determine whether the output is correct. | Pause and send it for human review. | \n| IFF | The output is correct only if a named dependency is satisfied. | Check that dependency before continuing. | \n\nThis four-value model comes from [Addy Osmani's work on owning the outer loop](https://addyosmani.com/blog/own-the-outer-loop/). It gives your loop more useful information than a binary done condition because not every output falls neatly into pass or fail.\n\nThe important part is the separation. Your verifier gets the generator's output and the condition it needs to evaluate. It does not get the generator's reasoning or rely on the generator's claim that the work is complete.\n\nThat gives you a loop where the component producing the work is not the component deciding whether the work passed.\n\nA verifier component takes agent output and a done condition, then returns a verdict and a reason. To build it, open [Hope AI](https://bit.cloud) and enter this prompt:\n\n```\nBuild a TypeScript Bit component that verifies agent output against a done condition.\n\nThe component should:\n\n- Define a DoneCondition type with four values: NO, YES, MAYBE, IFF\n\n- Define a VerificationResult type with a verdict and a reason string\n\n- Export a verify() function that takes an output string and a condition and returns a VerificationResult\n\n- Isolate signal extraction from the verification logic\n\n- Be pure and deterministic: the same input always produces the same result\n```\n\nHope AI scaffolds the component into several files, some of which include:\n\n`done-condition.ts`: the `DoneCondition` type, runtime values and a type guard\n\n`verification-result.ts`: the `VerificationResult` type with verdict and reason\n\n`signals.ts`: lexical signal extraction from the output text only\n\n`done-verifier.ts`: a thin dispatcher with one pure branch per condition\n\nBelow is an example code of the `signals.ts` which is used to enforce the isolation between the generator and the verifier:\n\n```\nexport type Signals = {\n  empty: boolean;\n  completion: boolean;\n  failure: boolean;\n  uncertainty: boolean;\n  qualification: boolean;\n  evidence: boolean;\n};\n```\n\nEach signal maps to a pattern group. `completion` fires on words like \"done\", \"finished\" or \"all tests passed.\" `failure` fires on \"error\", \"blocked\" or \"unable to.\" `evidence` is the strictest: it looks for test counts, exit codes, file paths and code blocks. An output that claims completion without triggering `evidence` will never return `YES` under the `IFF` condition, no matter how confident the language sounds.\n\nOnce you're satisfied with the code, click \"Start review\" in Hope AI. This creates a change request and triggers [Ripple CI](https://bit.dev/reference/ci/ripple-ci/) (Bit's built-in component CI/CD pipeline) to build and test the component automatically. Here's what a successful build looks like:\n\nOnce the build passes, click \"Release\" to publish the component to your scope on [bit.cloud](http://bit.cloud). This is what makes the verifier installable in any other project.\n\nIf you're following along with this tutorial, create a new Bit component to serve as the agent loop we're using to demonstrate the wiring:\n\n```\nbit create module agent/loop\n```\n\nIf you already have an existing loop in your Bit workspace, skip this step and work directly with your existing component.\n\nWith your loop component ready, install the verifier. If you're working in a Bit workspace, run:\n\n```\nbit install @your-username/your-scope.verify.done-verifier\n```\n\nReplace `your-username` and `your-scope` with your actual [bit.cloud](http://bit.cloud) username and scope name.\n\nIf you're working outside a Bit workspace, configure your `.npmrc` to point to the Bit registry first:\n\n```\n@your-username:registry=https://node-registry.bit.cloud\n```\n\nThen install via npm:\n\n```\nnpm install @your-username/your-scope.verify.done-verifier\n```\n\nThen import the `done-verifier` into your workspace so the loop component can consume it locally:\n\n``` python\nbit import your-username.your-scope/verify/done-verifier\n```\n\nBit lands the verifier at `your-scope/verify/done-verifier` and links it into `node_modules` as `@your-username/your-scope.verify.done-verifier`, ready to import.\n\nHere's what the loop looks like before the verifier is wired in. The generated stub has no done condition and no evaluation:\n\n```\nexport function loop() {\n  return 'hello world';\n}\n```\n\nOpen `agent-loop/agent/loop/loop.ts` and replace it with this:\n\n``` js\nimport { verify, type DoneCondition, type VerificationResult } from '@your-username/your-scope.verify.done-verifier';\n\nexport type Step = (iteration: number, feedback?: string) => string;\nexport type LoopResult = { output: string; iterations: number; verification: VerificationResult };\n\nexport function loop(step: Step, condition: DoneCondition, maxIterations = 5): LoopResult {\n  let output = '';\n  let feedback: string | undefined;\n  let verification: VerificationResult = { verdict: 'NO', reason: 'Loop has not run yet.' };\n\n  for (let iteration = 1; iteration <= maxIterations; iteration += 1) {\n    output = step(iteration, feedback);\n    verification = verify(output, condition);\n\n    switch (verification.verdict) {\n      case 'YES':\n        return { output, iterations: iteration, verification };\n      case 'NO':\n        feedback = verification.reason;\n        continue;\n      case 'MAYBE':\n        return { output, iterations: iteration, verification };\n      case 'IFF':\n        return { output, iterations: iteration, verification };\n    }\n  }\n  return { output, iterations: maxIterations, verification };\n}\n```\n\nThe loop takes three arguments: a `step` function that produces output on each iteration, a `DoneCondition` defined before the loop starts and an optional `maxIterations` cap. On every iteration it passes the step output to `verify()` and branches on the verdict.\n\n`YES` exits immediately and returns the output. `NO` sets `feedback` to the verifier's reason and continues to the next iteration, so the step function receives a specific signal about what failed rather than starting blind. `MAYBE` returns immediately for human review without continuing the loop automatically. `IFF` returns the result to the caller, which is then responsible for resolving the qualification before deciding whether to continue. The verifier signals that the output is conditionally correct but does not extract the dependency itself.\n\nThe `feedback` parameter is what makes `NO` useful beyond a simple retry. The step function receives the verifier's reason on the next call, which means the generator has context about why the previous attempt failed. Without that, `NO` is just a counter.\n\nThe verifier runs outside the step function's context. It receives only the output string and the condition, nothing from prior iterations or the step function's internal state.\n\nTo confirm the wiring works, run:\n\n```\nbit test agent/loop\n```\n\nThe four tests cover each verdict branch. `YES` confirms the loop stops on the first iteration when the output satisfies the condition. `NO` confirms the verifier's reason carries into the next iteration as feedback and the loop exhausts `maxIterations` if never satisfied. `MAYBE` confirms the loop stops immediately and returns for human review. `IFF` confirms the loop stops immediately and returns the result to the caller when the output is conditionally correct. Resolving the qualification is the caller's responsibility.\n\nWith the verifier wired into your loop, tag the agent loop component and release it to your scope. Run:\n\n```\nbit tag --message \"add verification loop to agent\"\n```\n\nYou'll see output confirming the component was tagged at version `0.0.1`:\n\nThen export to your scope on [bit.cloud](http://bit.cloud) using this command:\n\n```\nbit export\n```\n\nYou'll see Bit indexing the component and confirming a successful push:\n\nAfter you run `bit export`, [Ripple CI](https://bit.dev/reference/ci/ripple-ci/) picks up the push and runs the build and test pipeline automatically. Here's what a successful build looks like:\n\nWith the agent loop live on [bit.cloud](http://bit.cloud), any project can install it with a single command:\n\n```\nbit install @your-username/your-scope.agent.loop\n```\n\nBefore this tutorial, your generator had two jobs: produce the output and decide whether the work was done. When the same context performs both jobs, a passing result does not tell you that the work actually satisfied the condition.\n\nThe verifier changes that. It runs independently, sees only the output and the condition, and returns one of four verdicts before the loop decides what happens next. `NO` gives the generator a reason to retry. `YES` lets the loop continue. `MAYBE` pauses for review. `IFF` surfaces a result that needs its qualification resolved.\n\nThat separation is not a quality-of-life addition. The verifier is the part of the loop responsible for deciding whether the output satisfies the condition in the first place.\n\nThe verifier is now versioned on [bit.cloud](http://bit.cloud) and ready to reuse across projects. If you're running agent loops without a separate verification step, [create a scope](https://bit.cloud/signup) and add one to your next loop.", "url": "https://wpnews.pro/news/how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes", "canonical_source": "https://dev.to/hackmamba/how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes-4530", "published_at": "2026-09-14 09:19:19+00:00", "updated_at": "2026-09-14 09:36:02.882356+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["Bit", "Hope AI", "Addy Osmani", "AgentField", "TypeScript", "bit.cloud"], "alternates": {"html": "https://wpnews.pro/news/how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes", "markdown": "https://wpnews.pro/news/how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes.md", "text": "https://wpnews.pro/news/how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes.txt", "jsonld": "https://wpnews.pro/news/how-to-add-a-verification-loop-to-your-ai-agent-in-30-minutes.jsonld"}}