Retrieval · Free preview

Cite or Refuse

Only answer from the docs

A faithful answer is grounded: respond only when the answer actually appears in a retrieved snippet — cite that snippet — and refuse instead of guessing when it doesn't.

Only answer from the docs

In the last lesson your RAG agent retrieved a snippet and grounded its answer in it. But retrieval handing back a snippet doesn't force the model to stay faithful to it — a model will cheerfully blend in a detail from memory the docs never mentioned. A user asks for the support phone number; your snippets cover refunds and pricing but say nothing about phones, and the model invents "1-800-555-0199." Fluent, specific, and completely fabricated. The damage is worse than a wrong general fact, because it arrives wearing the authority of "answered from your documents."

A faithful agent enforces two rules. First, answer only when the answer phrase actually appears in a retrieved snippet — the snippets are the entire universe of what it's allowed to know. Second, cite the snippet it came from, so any reader can trace the claim back to its source. And when no snippet contains the answer, the faithful move isn't a softer guess — it's a flat refusal: "Not in the provided documents."

Walk the three questions. "What is the refund window?" → the answer 30 days appears in the refunds snippet, so you emit 30 days [refunds]. "How much is the free tier?"$0 for the free tier is right there in pricing → cite it. "What's the phone support number?" → you scan every snippet, find 1-800-555-0199 in none of them, and refuse rather than reach into memory. The citation isn't decoration: the act of having to name a source is what mechanically blocks the hallucination — if you can't find the phrase to point at, there's nothing to cite, so you can't answer.

Why it matters: this is the trust contract of a grounded agent. Hallucinated facts are the fastest way to lose a user, and "no answer" beats a confident wrong one every time — especially for prices, policies, and numbers people act on.

Below you have two snippets and three questions; the first two answers live in the snippets, the third does not. Make the agent print <answer> [<id>] when the answer phrase appears in some snippet, and exactly Not in the provided documents. when it doesn't. Done means two cited answers followed by one refusal.

Grounding isn't about sounding confident — it's about being checkable. If you can't point to the snippet, you don't get to say it.

In the full academy, you write and run this — live, graded:

// Retrieved snippets — this is ALL the agent is allowed to know.
const snippets = [
  { id: "refunds", text: "Customers can request a refund within 30 days of purchase." },
  { id: "pricing", text: "The free tier costs $0 for the free tier. Pro is $20/month." },
];

// Each question comes with the answer phrase the agent WANTS to give.
// Your job: only let it through if that phrase is actually in a snippet.
const questions = [
  { q: "What is the refund window?", answer: "30 days" },
  { q: "How much is the free tier?", answer: "$0 for the free tier" },
  { q: "What's the phone support number?", answer: "1-800-555-0199" },
];

// 🚨 The unfaithful agent: it just answers from memory, every time.
for (const { answer } of questions) {
  // TODO: only answer if the phrase appears in a snippet, and cite that snippet.
  // Otherwise print exactly: "Not in the provided documents."
  console.l

🔒 Live code execution, real agent runs, mastery tracking and verifiable credentials unlock with the full academy.

This is 1 of 50 lessons.

The full academy: write real code, watch real agents run, and earn verifiable credentials — across 8 tracks, in a 3D campus.

Unlock the full academy — $100 →

14-day refund · 🔒 Stripe-secured checkout · lifetime access

More free lessons: An LLM Is a Function  ·  The Agent Loop  ·  Define a Tool  ·  Give an Agent a Tool  ·  Durable State

← The Agent Marketplace