Marketing

A Verification Prompt That Checks Enriched Fields

Antonio Evans8 min read

A laptop shows a table of enriched fields with green check, red cross and amber question mark marks beside a highlighted sentence, while a matching sentence is marked on a printed source page next to it.
Key points

Key points

  1. 1A verifier call takes the enriched value, the URL it cites, and the fetched page text, and returns pass, fail or unclear plus an evidence quote.
  2. 2Send the cleaned page text, not just the URL, so the model judges the same bytes a human reviewer would.
  3. 3Validate the verifier against a small hand-labeled set before trusting it, and measure precision on the pass verdict, not overall accuracy.
  4. 4Route only pass values to the CRM; fail and unclear go to a review queue with the evidence attached.

Why a second call beats trusting the first one

Enrichment prompts are asked to do two jobs at once: produce a value and decide whether it is right. Those goals pull against each other. A model told to extract a phone number is rewarded for producing one, and a model that produces nothing looks unhelpful, so it improvises. A separate verifier is asked a different question (does this source support this value?) and has no incentive to be generative. That division of labor is the same reasoning behind LLM-as-a-judge evaluation, where one model produces output and another assesses it against a rubric and reference material Arize's guide and Evidently's guide both describe the pattern and stress that the judge must receive the source material to judge groundedness.

The published evidence for verification stages is encouraging. One survey of LLM-based extraction reports a dual-stage verifier that flagged missing data before filtering incorrect extractions and gained up to 20 points of F1 over a single-pass method, and a two-model cross-critique setup that reached 94 percent accuracy on the responses where both models agreed the extraction survey. The same paper notes that mismatches between agreeing models still needed human review, which is exactly why the output schema below has three verdicts rather than two.

The decision rule that matters: run a verifier for any field that will trigger automated action (email sends, territory assignment, pricing tiers, outbound sequences) and skip it for fields a human will read before acting. Verification costs a model call and a page fetch; a bad email address that lands your domain on a blocklist costs more.

The input schema: what the verifier must receive

The verifier is only as good as its inputs. Three components, assembled by your orchestration code and not by the model:

  1. The claim. The field name from your enrichment schema, the value the extractor produced, and the exact URL the extractor cited. If the extractor did not cite a URL, there is nothing to verify and the value goes to review.
  2. The page text. The raw or lightly cleaned text your fetcher retrieved, plus the fetch timestamp and HTTP status.
  3. The rubric. A short, field-specific definition of what counts as support. "An address is supported only if the page lists a street address at or near the company name" is a rubric. "Check the address" is not.

Do not paste the extracted value's surrounding JSON into the page slot. Keep the claim and the evidence in separate, labeled sections of the prompt so the model cannot confuse the thing being tested with the thing testing it. For structured inputs and outputs generally, the mechanics of enforcing a schema are well documented in OpenAI's structured outputs guide and the broader survey of approaches in Agenta's structured output guide.

A minimal request body:

{
  "claim": {
    "field": "company.phone",
    "value": "+1 512 555 0143",
    "cited_url": "https://example.com/contact"
  },
  "source": {
    "url": "https://example.com/contact",
    "http_status": 200,
    "fetched_at": "2025-03-04T10:12:00Z",
    "text": "Head office: 400 Congress Ave, Austin TX. Call us on (512) 555-0143."
  },
  "rubric": "The phone value is supported only if the page shows the same number, allowing differences in formatting and country code. A different number or no number means fail."
}

The output schema: pass, fail or unclear plus evidence

Three verdicts are the heart of the design. Pass means the page contains a sentence that supports the value. Fail means the page is readable and contradicts it, or plainly does not mention the field. Unclear means the verifier could not tell: the page is a login wall, the content changed, the text is truncated, or two plausible readings exist. Unclear is not a polite fail. It is a signal to a human.

Require an evidence quote for every verdict except unclear, and require the quote to be copied verbatim from the supplied text. That single constraint does most of the work: it turns the verifier from a rater into a witness. If the quote cannot be found in the page text by a substring check, treat the verdict as unclear regardless of what the model said. This is a cheap, deterministic post-check that catches fabricated quotes.

Field in outputTypeRequiredPurpose
fieldstringalwaysEcho of the claim field, for joining
verdictenum: pass, fail, unclearalwaysRouting decision
evidence_quotestringpass and failVerbatim sentence from the source
reasonstring, max 200 charsunclearWhy the verifier could not decide
confidencenumber 0 to 1alwaysSort order for the review queue

A strict enum is what makes routing safe. If the model can return free text, you end up writing regex over prose. Schema enforcement of enums and required keys is the specific problem structured outputs solve, as OpenAI's documentation and this practitioner write-up on replacing function calling with structured output both explain: without it you get valid-looking JSON with a renamed key or an invented verdict.

Fetching and cleaning the page

Fetch the page yourself and send the text. Sending the URL and asking the model to "look it up" puts the evidence outside your control and outside your logs.

Practical fetch rules:

  • Follow redirects and record the final URL. A cited URL that redirects to a parked domain is itself a signal.
  • Strip navigation, cookie banners and footers before sending, but keep headings and the body text. Aggressive cleaning that removes a contact block produces false fails.
  • Set a character budget and note truncation. If the page exceeds your budget, send the head and the section around any keyword hit, and mark the source as truncated so the verifier knows to prefer unclear over fail when the field is absent.
  • Store the fetched text hash and timestamp with the verdict. When a verdict is later questioned, you can show what the verifier read.

Cleaning matters more than people expect. The extraction benchmarking literature is blunt about this: errors introduced at the parsing layer, including in tables and multi-column layouts, propagate directly into the extraction result LlamaIndex's benchmarking guide. If your cleaner mangles a two-column contact table, the verifier will fail a value that was correct, and you will start ignoring the verifier.

Handling long, paywalled and changed pages

Three page types break naive verification. Each has a specific answer.

Long pages. Chunk the text and verify per chunk, but make the verdict "pass if any chunk passes, unclear if no chunk passes and at least one was truncated, fail otherwise." Sending a truncated page and asking for a binary judgment guarantees false fails.

Paywalled or blocked pages. Do not let the verifier guess. Your fetcher should detect login pages and bot blocks and mark the source unavailable, which maps to unclear with reason "source unavailable." Never let a 403 become a fail; the value may be perfectly correct.

Changed pages. A page that no longer mentions the value is not necessarily proof the value was wrong when it was extracted. Compare the fetch timestamp to the extraction timestamp. If the page changed between extraction and verification, downgrade fail to unclear and send both timestamps to the reviewer. This is the same discipline behind keeping evaluator versions and evaluation data visible when comparing results, as Arize recommends.

A small routing table keeps the logic honest:

VerdictEvidence quote found in textRoute
passyeswrite to CRM
passno (quote not verifiable)review, as unclear
failyesreview
failsource blocked, truncated or changedreview, as unclear
unclearnot applicablereview, sorted by confidence

Scoring the verifier against a hand-labeled set

Before the verifier gates anything, check whether it agrees with a human. Sample 50 to 100 enriched fields, have someone read each cited page and label pass, fail or unclear, then run the verifier blind on the same cases. Do this before you or anyone else has tuned the prompt on those examples, or you will measure memorization.

Two numbers decide whether it is ready:

  • Precision on pass. Of the fields the verifier passed, how many did the human also pass? This is your CRM contamination rate. A verifier that passes 98 percent of correct values but also passes 15 percent of wrong ones is not safe as a gate.
  • Recall on fail. Of the fields the human failed, how many did the verifier catch? This is how much junk you actually block.

Tune toward precision on pass. A verifier that sends too much to review is annoying; one that passes bad values is worthless. Track disagreement cases in a spreadsheet with the evidence quotes side by side, and when the human and the model keep disagreeing on the same field type, fix the rubric rather than the prompt wording.

Benchmarking practice from the extraction world applies directly: use a task-specific, repeatable ground truth set and rerun it whenever the prompt, the model or the cleaner changes LlamaIndex's guide. The judge is a model too, and judges drift when their inputs change the LLM-as-judge survey covers the meta-evaluation problem at length.

A worked example with numbers. Suppose your last batch had 1,000 enriched records. The hand-labeled set says 80 percent of values are genuinely correct. Your verifier has 95 percent precision on pass and 70 percent recall on fail. Pass 810 records to the CRM, of which about 40 are wrong. Send 190 to review, which is roughly a day of work for one person. If you cut the review queue by loosening the rubric so that 950 pass, the wrong-value count rises unless precision rises with it, so check both numbers together before you change anything. And remember that repeated model calls are not free: the extraction survey notes that iterative prompting improved fidelity but added notable latency and variance the extraction survey.

Routing only verified values to the CRM

The routing layer should be boring. Verdict pass plus a verifiable evidence quote equals a CRM write. Everything else lands in a review queue with the claim, the source URL, the fetched text hash, the quote and the confidence. When a reviewer overrides a verdict, log the override; that log becomes your next labeled set.

Two governance points that save pain later:

  • Write the verdict and quote alongside the field in your CRM, in a custom property or a linked audit object. When someone asks why a record says what it says, the answer is one click away.
  • Keep communication rules aligned. If verified contact data feeds outbound email, the rules that govern that email still apply regardless of how good the data is. Commercial email in the United States is covered by the CAN-SPAM Act, which applies to business-to-business messages and imposes requirements on commercial messages the compliance guide. Verified data and permission are different questions.

If you would rather not run the fetch, prompt and review plumbing yourself, a specialist can build the pipeline with you at Quanta.

FAQ

FAQ

Do I need a separate model for the verifier, or can I reuse the enrichment model?

Reuse is fine, but change the prompt entirely and pass the source text explicitly. If you want stronger separation, use a smaller, cheaper model for the verifier and reserve the larger one for extraction; the disagreement rate between the two is useful signal. Whatever you choose, pin the model and record it with each verdict so you can compare runs.

What stops the verifier from fabricating an evidence quote?

A substring check. After the call, confirm the evidence quote appears in the page text you sent (normalize whitespace first). If it does not, downgrade the verdict to unclear. This one check removes most of the risk of confident-sounding passes that rest on nothing.

How many labeled examples do I need before trusting it?

Fifty to one hundred representative fields is enough to see whether precision on pass is acceptable, provided the sample reflects your real mix of page types. Stratify it: some direct company sites, some directories, some pages that will fail, some that will be blocked. Rerun the whole set whenever the prompt, cleaner or model changes.

Should a blocked or paywalled page ever produce a fail?

No. Blocked, paywalled and truncated pages have not been read, so the correct output is unclear with a reason. Treating them as fail teaches the system to punish correct values that happen to live behind a login, and it hides the real problem, which is your fetch coverage.

Can I verify several fields against the same page in one call?

Yes, and you should, because the fetch is often the slow part. Pass a list of claims for one URL and ask for one verdict object per field, each with its own quote. Keep the batch small (a handful of fields) so a single bad quote does not contaminate the rest, and validate that every claim submitted has exactly one verdict returned.

Sources

Sources

  1. LLM-as-a-Judge: Guide & Pre-built Evaluators
  2. LLM-as-a-judge: a complete guide to using LLMs for ...
  3. Efficient and Verified Research Data Extraction with LLM
  4. Structured model outputs | OpenAI API
  5. The guide to structured outputs and function calling with ...
  6. Structured Output as a Full Replacement for Function Calling
  7. What is Extraction Accuracy Benchmarking?
  8. A Comprehensive Survey on LLM-based Evaluation Methods
  9. PDF The CAN-SPAM Act: A Compliance Guide for Business
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles