GO TO A SECTION

↑ ↓ to navigate · Enter to openExplore all sections →
FDEInterviews logo

Deep Research Agents Need a Reviewer: What a Jev Review Layer Gets Right, and the Gaps We Found Testing One

A deep research agent with a separate review layer is the right design: the model that writes the report should not decide it is done. We read and tested an open-source Nemotron, Tavily and Jev build. It fails open, retries without feedback and judges grounding against snippets. Here is the fix.

BY MEI LIN · FDEINTERVIEWS EDITORIAL · UPDATED OCTOBER 21, 2026 · 9 MIN READ

PRACTICE THIS:What is Jev, TypeSafe's System One model ·System One decision models, the concept ·RAG and agent design questions ·The must-know FDE questions

A deep research agent should not grade its own homework. Putting a separate review layer between the draft and the user is the right design, and an open-source build that uses Nemotron to research, Tavily to search and Jev to review shows the pattern cleanly. We read every file and tested the review path. The idea holds up. The implementation has three gaps that most research agents share. It fails open when the reviewer breaks. It retries without telling the agent what was wrong. And it checks grounding against search snippets instead of sources. Each gap is fixable in under a hundred lines, and fixing them is what turns a reviewer from decoration into a gate. Below: how the build works, what we found, the design we would ship to a customer, and when this pattern is worth its cost.

The build, and why the design is right

The project is deep_research_agent_with_review in Sumanth P's Hands-On-AI-Engineering repository on GitHub, built during the Nebius AI Builder Program; the README discloses the program's credits. It is a Streamlit app with about 700 lines of Python, tests included. A LangChain Deep Agent running nvidia/Nemotron-3-Ultra-550b-a55b on Nebius Token Factory plans the work and calls a search_web tool backed by Tavily (five results per query, deduplicated by URL, numbered as sources). It writes a Markdown report with numbered citations. A small function checks those citations. Then the report, the question, the sources and any citation issues go to Jev, TypeSafe's decision model, with three structured questions:

  • evidence_coverage (yes or no): is the evidence enough to answer the question without major gaps?
  • claim_grounding (yes or no): are the report's material claims supported by its numbered sources?
  • action (a choice of approve or research_again).

A probability of 0.70 or higher counts as a pass. If Jev asks for more research, the agent runs once more and Jev reviews the new report. LangSmith traces each step.

The README states the principle in one line worth keeping: Jev "does not write the report". That separation is the point. The model that produced the work is the worst-placed judge of whether it is finished, because it shares the blind spots that produced the gaps. This is the maker-checker rule from banking and from our agentic software factory guide, and it applies to research agents for the same reason it applies to code. Using a fast decision model as the checker is also a good choice: as we covered in what Jev is, it returns calibrated probabilities for structured questions in about a tenth of a second, and at the input price we recorded in September 2026 ($0.042 per million tokens, output free), a review of a 5,000-token state costs about two hundredths of a cent.

How it actually flows

Where the current review lets a report throughissues passed along. approve / reviewer unavailable. research_again. any outcome. Research agent: Deep Agent + Nemotron plans and calls search_web.. Tavily search: Five results per query. The draft sees snippets, not fetched full pages.. Draft report: Report text with numbered [n] citations.. Validate citation syntax: Checks presence and index range. Issues do not block.. Jev review: Coverage, grounding and action.. Fresh research run: Generic search-again instruction.. Recheck + review: Any result releases the report.. Report shown: A failed or unavailable review can still reach the reader.. The research agent gets search snippets, drafts a report, validates citation indices, and passes any issues to Jev. Approval or reviewer unavailability releases the report. A research-again action starts fresh research, then validates citations and reviews once more. Any second-review outcome releases the report. Where the current review lets a report through Observed project behavior. The reviewer is advisory in this implementation. issues passed along approve / reviewer unavailable research_again any outcome Research agent Deep Agent + Nemotron plans and calls search_web. Tavily search Five results per query. The draft sees snippets, not fetched full pages. Draft report Report text with numbered [n] citations. Validate citation syntax Checks presence and index range. Issues do not block. Jev review Coverage, grounding and action. Fresh research run Generic search-again instruction. Recheck + review Any result releases the report. Report shown A failed or unavailable review can still reach the reader.

Source: the project’s workflow and review implementation. This is the observed flow, including its release behavior after the second review.

Read the edge labels. They are where the three gaps live.

What we found when we tested the review path

The project's three unit tests pass. They cover response parsing and citation validation. We then called the same functions with the inputs a production system eventually sees. Running the full app needs Nebius, Tavily and Jev keys, so we tested the decision logic directly; nothing below depends on model behavior.

SituationWhat the code doesWhy it matters
Jev returns research_againTriggers one more research runCorrect
Grounding probability 0.69Triggers a retryCorrect
Grounding probability exactly 0.70PassesA hard line at 0.70 with no logging of near misses
Jev times out or no key is setReport shown with a warning that it was not reviewedFails open, but at least says so
Jev's response has an unexpected shapeReport shown; the review panel reads Decision "Unavailable" next to the explanation "JEV approved the evidence review."Fails open and contradicts itself
Second review still says research_againReport shown anywayThe cap is right; the missing escalation is not
Citation check finds problemsProblems sent to Jev as context; never blocks on their ownA deterministic failure becomes a suggestion

The fifth row is the one to fix first. When the review response parses to nothing (a renamed field, a gateway error page returned with a 200, a schema change), the parser marks the review "completed", finds no rejection, and writes the default explanation, which is approval. A reviewer that fails open is a progress bar. One that reports approval when it read nothing is worse than no reviewer, because it removes the user's own caution.

We also probed the citation checker with common formats:

Report textResult
Latency fell 40% [1]. Costs rose [2].Passes
Latency fell 40% [1, 2]. Costs rose [3, 9]. (source 9 does not exist)"No numbered citations"
Three studies agree [1-3]."No numbered citations"
Overview [1]. Revenue doubled in 2026. The CEO resigned.Passes
Revenue doubled [7]. (only five sources)Flags source 7

The regular expression only matches a single number in brackets, so grouped citations look like none at all, and the invented source 9 in the second row is never flagged. The fourth row is the bigger issue: one real citation anywhere lets every uncited claim through. That is a reasonable first version of a check, and it shows why citation checks should run per sentence, not per report.

The three gaps, and what each one costs

1. Failing open. Covered above. In a demo this is harmless. In a customer deployment, the day the reviewer's API key rotates is the day every report ships unreviewed, and nobody notices because the UI still says "approved". Decide the failure policy explicitly: block, or show with a prominent unreviewed label, and alert someone either way.

2. Retrying without the reviewer's reasons. When Jev asks for more research, the second run starts from scratch: a new search collector, a new agent, the original question and one generic sentence saying evidence was weak. It does not receive the first report, the first sources or which check failed. The code asks Jev only for two booleans and a choice, so there are no reasons to pass along in any case. Research again without the reviewer's reasons is a re-roll, not a revision. You get a different report with different problems, and the second review grades a new draw from the same distribution.

3. Grounding against snippets. The search tool requests results with include_raw_content off, so each source is a title, a URL and a short snippet, and the review payload trims snippets to 1,200 characters. When Jev answers "are the claims supported by the numbered sources?", the sources it sees are teasers. A claim can match the snippet and contradict the page. Grounded in a snippet is not grounded in a source. The fetch layer is part of the evidence: if the agent never read the page, nobody in the pipeline did.

None of these are exotic. We see all three in research agents built by well-funded teams, which is why this small project is a good teaching case.

The design we would ship

Repair evidence before asking for another reviewfail. unsupported. coverage gaps. targeted search + fetch. reviewer error. retry cap. Plan, search and fetch: Store full pages with passage offsets. Repair retries return here.. Draft claims with citations: Each sentence points to a source passage.. Deterministic citation gates: Parse citation forms; reject or flag uncited claims.. Per-claim grounding: Does each cited passage support its claim?. Coverage check: Have the requested sub-questions been answered?. Show supported report: Include per-claim support scores.. Targeted repair: Carry failed claims, missing questions and existing sources.. Hold or disclose gaps: Label unreviewed work; route to a human and alert.. Plan, search and fetch lead to drafting, deterministic citation gates, grounding, coverage, and publication. Failed citation gates or unsupported claims enter targeted repair. Coverage gaps also enter repair. Repair returns to search and fetch before redrafting and repeating every gate. Reviewer errors or an exhausted retry cap go to a human with work held or visibly labeled as incomplete. Repair evidence before asking for another review Proposed design. A report needs citation, grounding and coverage checks. fail unsupported coverage gaps targeted search + fetch reviewer error retry cap Plan, search and fetch Store full pages with passage offsets. Repair retries return here. Draft claims with citations Each sentence points to a source passage. Deterministic citation gates Parse citation forms; reject or flag uncited claims. Per-claim grounding Does each cited passage support its claim? Coverage check Have the requested sub-questions been answered? Show supported report Include per-claim support scores. Targeted repair Carry failed claims, missing questions and existing sources. Hold or disclose gaps Label unreviewed work; route to a human and alert. pass supported pass

This is our proposed design. Repair returns to evidence collection and drafting before repeating citation, grounding and coverage checks.

The changes, in order of value:

  1. Fail closed by policy. Any reviewer error, missing key, timeout or unparseable response produces an explicit unreviewed state. Never default to approval.
  2. Make deterministic checks gates. Parse [1, 2], [1-3] and footnote styles. A sentence with a factual claim and no citation is removed or marked before any model sees the report.
  3. Ground per claim, against passages. Split the report into claims and ask the decision model one yes-or-no question per claim against its cited passage. At about a tenth of a second and fractions of a cent per call, Jev is cheap enough to run twenty times per report. Per-claim results also tell the retry exactly what to fix.
  4. Retry with reasons. Pass the failed claims, the unanswered sub-questions and the sources already gathered. Ask for a targeted repair, not a new report.
  5. Log every probability. Keep the coverage and grounding scores for approved reports too. A gate whose scores always sit at 0.95 is not gating anything, and you only see that in the distribution.
  6. Escalate, don't loop. One targeted retry, then show the report with its open gaps listed and route it to a person if the stakes warrant it.

That design separates three different jobs that the original merges into one call: code checks what code can check, a fast decision model answers narrow factual questions, and a person handles what is left. The same split works for an LLM judge in place of Jev; a decision model is simply cheaper and faster for the narrow questions, and an LLM judge is better when you need a written critique.

Pros, cons and when to use the pattern

StrengthsWeaknesses as built
Writer and reviewer are separate models with separate jobsFails open; a malformed review reads as approval
Structured review questions with probabilities and a stated thresholdRetry runs blind and re-researches from scratch
Bounded: at most one automatic revision, so cost and latency are predictableGrounding judged against search snippets
Each part (model, search, reviewer, tracing) is swappableCitation check is advisory and misses grouped citations
Readable code, tests for parsing, traced with LangSmithNo license file in the repository, so reuse terms are unclear

Use a reviewed research agent when a wrong answer is costly but a slow one is fine: competitive and market briefs, vendor due diligence, literature reviews, account research before a customer meeting, policy and regulatory summaries. For a forward deployed engineer, the pre-engagement brief on a customer's industry is a good first use: low risk, high time saved, and easy to spot-check.

Do not use it when the answer must be current to the minute, when sources sit behind logins the agent cannot reach, or when the output goes straight to a customer with no human reading it. A review layer lowers the error rate. It does not make an unread report safe to send.

On cost, the review is the cheap part. A research run with a 550-billion-parameter model and a dozen searches costs far more than twenty Jev calls, so per-claim grounding adds very little to the bill. The expensive mistake is the opposite: saving a fraction of a cent on review and shipping a confident report built on a snippet.

A note on reusing this code

The repository has no license file at the time of writing (21 October 2026). Public code without a license is not open source in the legal sense; by default its author keeps all rights. Read it, learn from it, and ask the author before copying it into a client's codebase. The design ideas carry no such restriction.

If you are preparing for applied AI or FDE interviews, "design a research agent that doesn't hallucinate citations" is now a standard prompt. The answer interviewers want separates the writer from the checker, names the failure policy, grounds per claim against fetched text, and caps retries with an escalation path. Practice it with our RAG and agent questions, and read up on hallucination and RAG evaluation for the measurement side.

PRACTICE THIS

Turn it into offers. Work the real questions and concepts this maps to:

FAQ

A review layer is a separate component that decides whether a research report is good enough to show, instead of letting the model that wrote it decide. It typically checks whether the evidence covers the question and whether each claim is supported by a cited source, then approves the report or sends the agent back to research more. Keeping the writer and the reviewer separate is the maker-checker principle applied to agents.

Discussion (4)

Emily CarterEditor

The snippet point is the one teams miss in production. Search APIs return a few hundred characters per result, and a reviewer reading those can approve a claim the full page contradicts two paragraphs later. If grounding matters, fetch and store the page and let the reviewer read the passage, not the teaser.

Cole SullivanContributor

Reader question: one retry or several?

Mei LinEditor

One targeted retry, then a human. In our experience the second automatic retry mostly rewrites prose and rarely finds new evidence. If the first retry did not close the gap, the question probably needs a source the search tool cannot reach, and a person should know that.

Arjun MehtaEditor

Worth adding: log the reviewer's probabilities for every report, approved or not. After a month you can plot approval rate against the 0.7 threshold and see whether the threshold is doing anything, or whether every report sits at 0.95 and the gate never closes.