Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
A RAG answer without citations is unverifiable. Use Anthropic's Citations API (built-in span citations) OR prompt-engineer [#N] markers and render them as clickable links. Either way, every claim gets a source — the user trusts the answer because they can check; you debug failures because you can trace.
Anthropic Citations API: pass documents as content blocks with citations enabled; the response comes with citation spans referencing source passages. For other providers, use a strict system prompt requiring [#N] markers per claim, parse them post-hoc, render as clickable badges. Either way, also include a 'Sources' section listing each cited chunk with section_path + URL.
# --- Pick your provider (set the matching API key env var) ---
# Anthropic: from anthropic import Anthropic; client = Anthropic() # ANTHROPIC_API_KEY
# OpenAI: from openai import OpenAI; client = OpenAI() # OPENAI_API_KEY
# Gemini: from google import genai; client = genai.Client() # GEMINI_API_KEY
from anthropic import Anthropic
client = Anthropic()
def answer(question, chunks):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system="Answer using ONLY the provided documents. Cite every factual claim. If absent, say you don't know.",
messages=[{
"role": "user",
"content": [
*[{
"type": "document",
"source": {"type": "text", "media_type": "text/plain", "data": c["text"]},
"title": c["metadata"].get("source_url", c["id"]),
"citations": {"enabled": True},
} for c in chunks],
{"type": "text", "text": question},
],
}],
)
out = {"text": "", "citations": []}
for block in response.content:
if block.type == "text":
out["text"] += block.text
if hasattr(block, "citations"):
for c in block.citations:
out["citations"].append({
"title": c.document_title,
"cited_text": c.cited_text,
})
return out
# Render in the UI: inline cite badges (hover for preview) + bottom 'Sources' listpython3 main.py