We asked a local agent fleet how to stop AI from making things up. It demonstrated the problem instead.

Robot Brains — Local AI Compute, Measured

Verification

Verifiers Beat Models At Catching Models

Document text

We asked a local agent fleet how to stop AI from making things up. It demonstrated the problem instead.

One evening, 4 September 2026. A production newsroom pipeline, two real defects, and three research runs on a self-hosted DGX Spark fleet asked to help fix them. Everything below is what actually happened, including our own mistake. The fleet's outputs are quoted verbatim.

The interesting result was not planned. We shipped a deterministic verifier for AI-written articles, it immediately caught two real defects in production, and then we pointed our local research fleet at the question "how do we stop this class of error?" — three runs, 27 sub-questions, hundreds of pages fetched. All three came back MIXED. One of them reproduced, in its own output, the exact failure mode it had been asked to prevent.

That contrast is the finding: a 200-line deterministic checker caught two live defects on the day it shipped, while a fleet of language models asked to reason about the same problem produced almost nothing usable. Both cost roughly the same evening.

Companion documents: Twelve ways a local AI agent fleet breaks, Your benchmark probably cannot tell a 7B from a 32B, and What a local research-agent fleet actually delivers.


1. The setup

A newsroom pipeline generates articles from a structured brief. The prompt in use was a rewriter — "take the original article below and write a fresh story based on it" — with no mechanism for a fact you must not assert, no word budget, and no citation discipline. It was being used for original reporting anyway.

We added two things:

  • an investigation prompt that states facts may come only from the brief, that unknowns may be reported as unknown but never rounded into a conclusion, and that carries a word budget;
  • a deterministic verifier that runs on the generated text before it can be saved.

The verifier checks five things. Four are exact: forbidden-assertion regexes, word budget, figures whose digits relate to nothing in the brief, and calendar dates absent from the brief. The fifth delegates citation identifiers — URLs, DOIs, docket and Bates numbers — to an existing grounding module. Nothing in it is a model. It costs no GPU.

2. What the verifier caught, on day one

Defect 1 — a forbidden assertion, in the most quotable position. The brief said, in as many words, that one document carried the word "delete" above a pasted article, that the record does not establish who typed it, and "Do not assert it." The model closed the article with:

"…and he appears to have deleted it."

An explicit negative instruction, violated, in the final sentence, attributing a state of mind to a named dead man. This reproduced across two independent generations, so it was not an unlucky sample.

Defect 2 — a length overrun. 889 words against a 550-word budget; on the next piece, 843 against 600. Also reproduced.

Defect 3, found the next hour — a false positive in the verifier itself. Its first production run flagged the phrase 600,000+ FALSE STATEMENTSinside the quoted claim the article was debunking. A rule about assertion was matching attributed quotation. Left alone it would have misfired on every debunk, which is a core output of this newsroom.

The fix is worth stating because it is the whole design in miniature: forbidden matches that fall wholly inside a quoted span are skipped; the same claim unquoted still trips; the match loop became finditer so a quoted instance cannot mask an unquoted one later in the body. Three tests pin all three behaviours.

None of these needed a model to find. All three are mechanically checkable.

3. What the fleet returned when asked to help

Three research runs, ~10 minutes wall-clock each, on a GB10 Grace-Blackwell serving a 7B reader and a 30B-A3B planner/synthesiser. Zero external inference cost.

Run Question Confidence Usable?
A How to stop a small local model asserting what its source forbids MIXED Partly
B How to stop a local fleet returning WEAK/UNDOCUMENTED when the answer is on the web MIXED Yes
C Where can our own verifier still be defeated (run with the repo bundled) MIXED No

Run C failed in a specific and instructive way

It was given the repository. It was asked to audit verify_investigation and verify_grounded for bypasses. Its summary listed six vulnerabilities — the same six named in the question — and marked every one [UNDOCUMENTED]. Five of six sub-questions returned no usable evidence.

The cause is visible in its own sub-question text: it went looking on the open web for "common regex patterns used in content moderation systems" rather than reading the bundled source files. Its closing section hands the entire job back:

"Verify regex patterns used in content moderation systems (requires code review) · Analyze quoted-span exemption mechanics in newsroom_bob.py (requires code review) · Identify identifier patterns in grounding.py (requires code review)"

A code-audit question was planned as a web-research question, and no stage noticed. The planner decomposes before it knows whether the corpus is the web or the repo, so a --repo run can spend its whole budget searching the internet for the answer sitting in the bundle.

Run A reproduced the failure it was asked to prevent

Sub-question 2 of Run A — "How do classifier or critic models as a second pass work…" — returned this as its answer, verbatim:

"markdown, 120-350 words, with inline [n] citations matching the source numbers given below"

That is the instruction template, emitted as content. A run about preventing models from producing unsupported text produced text with no source at all, and the pipeline labelled it UNDOCUMENTED · certainty 10/10. The confidence field was maximally confident about having nothing. Nothing downstream rejected it; a human reading the report caught it.

4. What did survive, with numbers

The salvage is real and worth recording. From Run B:

  • Cross-encoder reranking is the highest-value fix available. GTE-reranker-modernbert-base149M parameters, small enough for a consumer GPU — improved Hit@1 from 62% → 83% (+20 points). Requires a two-stage pipeline (HNSW/BM25 → reranker) because cross-encoder cost is O((Lq + Ld)²).
  • Page-level chunking scored highest on RAG accuracy (0.648) with low variance. Fixed-size chunking is discouraged for complex text.
  • LLM-based query rewriting improves recall, with over-expansion as the named failure mode.
  • Multi-agent coordination helps parallelisable tasks and degrades sequential ones — which argues against decomposing a question whose parts depend on each other.

From Run A:

  • Chain-of-Verification reported a 28% improvement, unspecified whether it transfers to small models.
  • Structured decoding constrains format, not content. JSON Schema addresses roughly 5% of unpredictable output, and one source found plain JSON generation matched or beat constrained decoding on accuracy. A grammar cannot stop a well-formed false sentence.
  • Negative-constraint prompting is brittle — sensitive to wording, degrades under adversarial input. Consistent with Defect 1: the instruction "Do not assert it" was in the prompt and was ignored.
  • Schema adherence is not instruction adherence. One model measured 99.2% schema compliance; instruction-following on another sat at 87.75%, with mismatched prompts causing 4.7–7.2% failures.
  • Length control: no evidence found at all. Which matches Defect 2 — the budget was in the prompt both times and was exceeded both times.

5. Our own error, since it is the same error

While this was running we published a claim that a document corpus contained "no bullion business anywhere in these records." It was wrong. A file with 11 relevant hits had never been opened, despite its hit count being on screen. The conclusion was generalised from zero-counts on self-chosen search terms rather than from reading the retrieved hits.

The fleet caught that one. Not by reasoning — its report on that topic was also WEAK — but by having read the files and surfacing two names a human then verified independently. That is the honest description of what a local fleet is good for: coverage, not judgement.

6. What we take from it

  1. Put the cheap deterministic check between the model and the reader. It caught three defects in two hours, including one in itself, at zero GPU cost. The fleet asked to audit that same checker returned nothing.
  2. Never let the thing being checked do the checking. Run A's confidence field reported certainty 10/10 on an answer that was template text.
  3. A negative instruction in a prompt is a request, not a constraint. Both reproduced defects were things the prompt explicitly forbade.
  4. Fix retrieval before generation. The one run that produced usable output was the one about retrieval, and its top finding — a 149M reranker worth +20 points Hit@1 — is smaller than any model in the fleet.
  5. Say which half failed. A report can fail at search or at reasoning, and the current confidence label does not distinguish them. Run C's MIXED looked identical to a run that had read everything and found little.
  6. Quoting a claim is not making it. Any verifier used on debunk journalism needs that exemption, and needs it scoped to quoted spans only.

Method note: the three research runs are 20260904-190635, 20260904-190647 and 20260904-190702 on the local fleet. Confidence labels, sub-question statuses and the quoted strings are the fleet's own output, unedited. The verifier described here is verify_investigation() in profoundd/search/newsroom_bob.py, with citation checking delegated to profoundd/search/grounding.py; 18 tests, plus 10 for the grounding layer.