- a verification step between generation and display
- a prompt contract that keeps the model inside the provided sources
- multi-turn handling so the application corrects itself on first challenge
- an evaluation suite that gives you numbers instead of impressions
The patterns here apply to Grounded Completions, Grounded Responses, and any RAG pipeline you assemble yourself from the Search API. Nothing in this guide is specific to a model or provider. The same safeguards are needed on any stack.
Shared Responsibility
Grounded endpoints handle retrieval and attribution. Everything downstream of the response body is application logic.
The dividing line is consistent: the platform decides what content reaches the model, and your application decides what text reaches the user.
Failure Modes to Design Against
The examples below use Bezalel Ministries, the fictional organization from the Grounded Completions tutorial, whose five sample documents describe a digital art ministry, its research methodology, and its educational resources.
Notice what most of these share. They are plausible, fluent, and adjacent to something true. Retrieval cannot catch them, because retrieval already succeeded. Only a comparison between the generated text and the retrieved text catches them.
The ungrounded case is the exception. Retrieval returned nothing at all, the answer came entirely from model knowledge, and the only signal that anything is wrong is a boolean in the response body. It can be the most frequent failure of the set, and it is the cheapest to fix, which is why the checks below start there.
How often it happens depends almost entirely on your content and your traffic. A narrow corpus fielding broad questions will return no sources often. A corpus that covers its question space well will rarely do so. Measure it against your own publisher rather than assuming a rate, and see Evaluate before you ship for how to count it.
Search, Generate, Verify
The common starting architecture is two steps: call the grounded endpoint, render the result. It contains no place to catch any of the failures above.Option 1: Citations from the grounded endpoints
Setinclude_citations: true and read citations[].snippets. The endpoint keeps handling retrieval, routing, and tradition.
Option 2: Run retrieval yourself
Call the Search API directly, then pass the passages into a completion as context.properties.snippet with the passage text and properties.item_title with the source title. You hold the full retrieved text, so verification is exact and you control the prompt completely. The tradeoff is that you take on retrieval tuning, prompt assembly, and citation formatting yourself.
Start with option 1. Move to option 2 when verification precision matters more than integration cost, or when you need the retrieved text for anything beyond checking the answer.
Verification Checks
Run these against the retrieved text after generation and before display, in the order given. The order matters: the grounding check is a precondition for the other two.Check the grounding flag first
Both grounded surfaces report whether retrieval contributed anything:sources_returned in the response body, X-Sources-Returned when streaming. Grounding never fails a request, so a false here still returns a fluent, complete, ungrounded answer.
Never treat sources_returned: false as a normal answer. Either label the response as not drawn from your content, or decline. See When no sources are found.
Check this before the containment checks below, not after. When retrieval returned nothing there is no source text to compare against, so every quotation and every title fails containment automatically. Run the span checks in that state and you get a large count of “unverified” spans that is really just one ungrounded answer reported many times, which corrupts both your decision logic and the metrics in Evaluate before you ship.
Check quoted spans
Any text the answer presents as a quotation must appear in a retrieved source. Normalize before comparing: collapse whitespace, fold curly quotes to straight, and strip ellipses so a shortened quote still matches.Check named artifacts
Apply the same containment rule to titles of works, article names, episode names, course names, and product names. This is the check that stops “The Mercy Seat Revealed” from being presented next to a real series name, where its plausibility does the damage. Treat any title the model produces as unverified until it is found in a source. Do not assume a title is safe because the surrounding series or author is real. Apply the same normalization too, and in particular strip punctuation from the edges of the candidate before comparing. This is not a detail. Models routinely place the sentence’s closing punctuation inside the quotation marks, so the raw candidate isThe Tabernacle and Christ. while the source reads The Tabernacle and Christ, and a correct answer naming a real course fails containment over one period. The same happens with a trailing comma in "Phase Two," the test commission. Skip this and you should expect false positives on real titles, which are the verification failures most likely to erode trust in the check itself.
Containment cannot tell an assertion from a denial. An answer that correctly says the series does not have an episode titled “The Mercy Seat” still puts that title in quotation marks, and the check still flags it.This is where the prompt contract earns its place. The rule that the model must not put quotation marks around wording it did not find in a source is what keeps these false positives rare. The prompt contract and the verifier are not independent safeguards: the contract shapes the output into something the verifier can judge accurately.
Escalate before declining
A failed check does not always mean the answer is wrong. Sometimes retrieval was too narrow.- Widen retrieval. Raise
sources_limit, or lowercertainty_thresholdon Grounded Responses andcertaintyon the Search API. - Regenerate once with the broader source set.
- If verification still fails, decline plainly.
sources_limit accepts 1 to 10, so there is little room to escalate further even if it helped: going from 5 to 10 is the whole of the headroom.
Verify Before You Stream
Streaming publishes each token as it is produced. An unverified quotation is on the user’s screen before any check can run, and retracting it afterward is a worse experience than a slightly slower first token.
For anything a user might repeat or act on, buffer. The latency cost is real but bounded, and it is the only approach where nothing unverified is ever displayed.
Streaming has a second failure surface: the stream itself can break mid-answer. Recovery interacts with verification, because a continuation is a fresh generation that also needs checking. See Handling Streaming Failures.
The Prompt Contract
These instructions measurably change behavior. They are rules to encode, not a prompt to copy. Answer only from the provided sources. State that model knowledge outside the sources must not be used, even when it is correct. Without this, the model blends training knowledge with retrieved content and the blend is invisible in the output. Label paraphrase distinctly from quotation. Require quotation marks for verbatim text and explicit framing for paraphrase. This makes your verifier’s job possible: it can only check spans the model marked as quotations. Decline first on attribution and fact-check questions. For “what did X say about Y” or “which resource covers Z,” instruct the model to state up front when it cannot verify something from the sources, rather than assembling a best guess. Declining is the correct answer more often than it feels like it should be. Correct false premises before answering. When a question presupposes something the sources contradict or never establish, the correction comes first. Answering around a false premise implicitly confirms it. Refuse to speak as a real person. No role-play, no “answer as X would,” no first-person voice for a named individual. Offer that person’s sourced material instead.Multi-Turn Conversations
Single-turn correctness does not survive into a conversation on its own. Re-check on challenge. When a user pushes back with “are you sure?” or “that doesn’t sound right,” re-run verification for the challenged answer against the sources retrieved for that original turn. Correct on the first challenge if the answer does not hold, and hold it if it does. Both halves matter. A model that concedes only after repeated pressure has responded to social pressure rather than to the sources, and a model that abandons a verified answer the instant a user objects has done the same thing faster. Keep retrieved sources addressable across turns. Store the sources retrieved for each turn, keyed to that turn. Follow-ups like “which source says that?” are legitimate questions with an answer already in hand, and they should not trigger a fresh search that returns different sources than the ones the answer came from. Cap conversation length. Set an explicit limit on turns or total characters and trim from the oldest turns. Unbounded history eventually exceeds request limits, which surfaces as request validation errors that appear only in long conversations and look unrelated to their cause. Account for your own long turns. Verified answers with quotations and citations are longer than typical assistant messages. History that is trimmed by turn count alone can still exceed limits when your application’s own replies are large, so trim by size as well.Putting It Together
The verification step sits between generation and display, with one escalation and a plain decline as the floor.unverified_titles / unverifiedTitles applies the containment rule from Check named artifacts to titles extracted from the answer.
unsupported and ungrounded as plain statements that the answer could not be confirmed from your content. An honest decline costs one interaction. A fabricated quotation that a user repeats elsewhere costs considerably more.
Evaluate Before You Ship
Verification tells you whether one answer holds up. Evaluation tells you whether your application does. Build a scenario suite covering each category below. A few dozen scenarios is enough to be useful; the categories matter more than the count.
Then automate the scoring. Two metrics carry most of the value, both objective and neither needing human grading:
Report them separately, and exclude ungrounded answers from the second count. An ungrounded answer has no sources, so every span in it fails containment automatically. Fold the two together and one ungrounded answer inflates your fabrication count by however many quotations it happened to contain, which will send you optimizing a number that is not measuring what you think.
Do not assume which one will dominate. Builders tend to arrive worried about invented quotations, because that is the failure that gets reported and the one that causes the most damage per occurrence. It is worth checking whether the confident answer to a question your content never covered is actually the more frequent problem for you, because the two call for different work: closing the ungrounded gap is mostly a decline path and a content-coverage question, while fabricated spans need the verifier.
Which one leads is a property of your corpus and your users, not of grounded completions. In one measured run against a small five-document publisher, answers displayed while ungrounded outnumbered answers containing an unverified span by roughly four to one. That is a single corpus and a small sample. Treat it as an illustration of why you should measure, not as a number to expect.
Run both before and after every prompt or retrieval change so you have numbers rather than impressions.
Finally, turn every reported failure into a permanent test case. When a user reports a bad answer, add that exact conversation to the suite before fixing it. This is what stops the same class of failure from returning three releases later.
Summary
Related Pages
Grounded Completions
RAG on the chat-completions shape, with routing, citations, and
sources_returned.Grounded Responses
The same grounding on the Responses API, with
certainty_threshold.Search API
Standalone retrieval when you want to hold the source text yourself.
Handling Streaming Failures
Retry, continuation, and partial-output UX for interrupted streams.

