LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 158 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/8
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/11
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageClustering and PCACore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/24
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsContext EngineeringPrompt Injection DefenseResponsible AI GovernanceData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BPrompt Optimization with DSPyModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/8
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned Classifier
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/15
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineMixed Precision TrainingDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight Interpolation
🤖Advanced Agents & Retrieval0/16
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryRecursive Language Models (RLM)Multi-Agent OrchestrationCapstone: Production Agent
⚡Inference & Production Scale0/19
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning & Test-Time Compute
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
Back to Topics
LearnSystem Design CapstonesLLM-Powered Search Engine
🏗️HardSystem Design

LLM-Powered Search Engine

Master the architecture of an end-to-end AI search engine, covering freshness routing, hybrid retrieval, evidence packing, citation verification, and streaming synthesis.

35 min read
Learning path
Step 149 of 158 in the full curriculum
Multi-Tenant LLM PlatformVision-Language Models & CLIP

Multi-tenant serving made tenant identity, cost, and visibility part of every request. Large language model (LLM)-powered search applies that discipline to evidence: retrieval, ranking, caches, citations, and generated claims must all respect freshness and authorization before the model writes an answer.

You're the Staff AI Engineer at CodeAtlas. Developers type questions such as "can service accounts rotate OAuth tokens every 90 days?" and "what happens if parser-v2 deprecation affects our SDK migration?" A generative search experience must retrieve allowed API docs, release notes, and workspace policies, synthesize a cited answer, and keep private roadmaps and incident notes outside unauthorized contexts.

An LLM-powered search engine combines retrieval, ranking, synthesis, and citation into a user-facing answer system. The core engineering challenge is balancing retrieval and generation latency with factual accuracy, freshness, and workspace isolation.

Building a search engine that generates answers rather than just lists of links requires orchestrating retrieval, reranking, and LLM synthesis inside an interactive latency budget. This CodeAtlas case study designs that system around evidence and measurable service objectives.

If the ideas of embeddings or chunking feel rusty, here's a quick reminder: embeddings turn sentences into dense vectors so similar meanings sit close together in math space, and chunking splits long documents into short, self-contained passages so retrieval can grab the right snippet. Both are prerequisites for everything that follows.

From keywords to reasoning

Traditional search points users to candidate documents. LLM-powered search retrieves API docs, policy pages, release notes, and incident records, then returns a cited answer with a support state. This relies on Retrieval-Augmented Generation (RAG)[1]Reference 1Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks.https://arxiv.org/abs/2005.11401, which conditions generation on retrieved evidence rather than treating model memory as the source of truth.

Traditional search leaves synthesis to the user. Generative search performs that synthesis, which means it also owns citation binding, abstention, and authorization failures.

This capstone uses a practical answer-engine architecture: retrieve with keyword and embedding signals, rerank candidates, apply visibility and freshness policy, then synthesize a short cited answer whose claims can be checked.

Traditional vs LLM search

FeatureTraditional SearchGenerative Search
OutputRanked links or snippetsAnswer plus cited evidence
InteractionQuery and result navigationAnswer and optional follow-up
User validationUser opens sources directlyUser must be able to inspect cited sources
Source trackingSource page is the resultClaim-to-source binding is an application duty

What the system must deliver

Before selecting components, define performance and functional constraints. These are example SLOs for this interactive developer-product case study, not universal constants.

DimensionConstraintExample target
LatencyTime to first token (TTFT)~0.8-1.5 seconds
ThroughputPeak queries per second (QPS)1K-10K QPS per region
QualityAnswer accuracyHigh citation precision, low unsupported claims
CostAverage query costLow single-digit cents at scale
FreshnessInformation latencySeconds to minutes for hot updates, hours for stable docs

How the pipeline works end to end

The architecture has four query-time layers: plan the query, retrieve candidate evidence, pack the best evidence into context, and generate an answer while verifying citations.

Separate from this online path, a background ingestion system crawls or receives source updates, cleans them, chunks them, and keeps sparse and dense indexes fresh. Without that ingest path, an "AI search engine" quickly becomes a prompt wrapper around stale data.

LLM search architecture with an offline build lane for source normalization and hybrid indexing, then an online query lane that retrieves through access control, reranks evidence, and returns a cited answer. LLM search architecture with an offline build lane for source normalization and hybrid indexing, then an online query lane that retrieves through access control, reranks evidence, and returns a cited answer.
Build indexes offline. At query time, retrieve through access control, rerank evidence, and answer with citations.

Tracing a concrete query

Follow the same question through every stage of the pipeline: "Which deprecation policy applies to parser-v2 SDK migration for service accounts?"

StageWhat the system does
Query planThe router classifies the question as a comparison needing both API deprecation policy and service-account migration rules. It decomposes the query into sub-queries for "parser-v2 deprecation policy" and "service-account SDK migration exceptions."
RetrievalBM25 (Best Match 25, a keyword-scoring algorithm) pulls the exact "Parser v2 Deprecation" and "Service Account Migration" pages from the doc store. Dense retrieval finds a related FAQ about legacy SDK workflows.
RerankingThe cross-encoder scores the candidate passages and keeps the top 3 that mention both parser-v2 and service accounts.
SynthesisThe LLM receives the packed passages with source IDs and writes a two-sentence answer with inline citations like [1] and [2].
VerificationA verifier returns support labels for answer claims against cited text. Product policy decides whether pending or unsupported claims are hidden, marked, or regenerated.

This trace will reappear as we look at each component in detail.


Inside the pipeline

1. Query understanding

The first step is classifying intent and deciding whether retrieval needs rewriting. A large synthesis model can perform this task, but using it on every query adds measured latency and cost that many simple routes don't need.

A common approach uses specialized, smaller models or encoder-class classifiers for routing, rewriting, and decomposition. Benchmark the chosen planner on your hardware and traffic shape; its job is to distinguish a simple fact lookup from an exploratory or freshness-sensitive request and attach retrieval hints such as "prefer exact matches" or "fresh data required."

One useful trick is HyDE (Hypothetical Document Embeddings): generate a hypothetical relevant document, embed that document, and use its vector as an alternate dense-search query.[2]Reference 2Precise Zero-Shot Dense Retrieval without Relevance Labels.https://arxiv.org/abs/2212.10496 The generated text may contain false details, so HyDE is a retrieval technique, not answer evidence. Validate whether it improves recall for your query mix.

Routing targets

Not every query should hit the same retriever. Exact, structured questions often route to APIs, SQL, or an entity store first, then optionally use the LLM only for verbalization. Treating every request like unstructured RAG adds latency and often makes numeric answers less reliable.

Query patternBest first backendWhy
"What is deploy job build-1042 doing right now?"Live APIFreshness and exact values matter more than semantic similarity
"Find the parser-v2 deprecation policy"BM25 + doc storeExact title and keyword match dominate
"Compare OAuth rotation exceptions for service accounts"Hybrid sparse + denseNeeds multi-document synthesis and terminology overlap
"What changed in the latest SDK migration guide?"Fresh web / hot indexRecency matters, then reranking decides quality
ComponentPurposeExample
Intent ClassifierRoute to appropriate pipeline"build-1042 status" -> direct API call
Query DecomposerBreak complex queries into sub-queries"Compare service-account rotation exceptions" -> 3 sub-queries
Safety FilterBlock harmful queries earlyContent policy enforcement
Freshness DetectorDetermine if real-time data is needed"latest SDK migration guide" -> force fresh crawl

This Python code structures a low-latency query planner. It takes the raw user query as input and returns a structured execution plan, including classified intent and decomposed sub-queries. In production, the decision can come from a small classifier, rules plus embeddings, or a compact model rather than a frontier synthesis model.

routing-targets.py
1import json 2from dataclasses import asdict, dataclass, field 3 4@dataclass(frozen=True) 5class QueryPlan: 6 intent: str 7 route: str 8 sub_queries: list[str] = field(default_factory=list) 9 filters: dict[str, str | bool] = field(default_factory=dict) 10 needs_fresh_data: bool = False 11 complexity: str = "simple" 12 13def understand_query(user_query: str) -> QueryPlan: 14 """Plan with fast routing logic; swap rules for a small classifier in production.""" 15 text = user_query.lower() 16 17 if any(term in text for term in ("build-", "quota", "runner status")): 18 return QueryPlan( 19 intent="factual", 20 route="structured_api", 21 filters={"requires_live_data": True}, 22 needs_fresh_data=True, 23 ) 24 25 if "parser-v2" in text and "service account" in text: 26 return QueryPlan( 27 intent="comparison", 28 route="hybrid_search", 29 sub_queries=[ 30 "parser-v2 deprecation policy", 31 "service-account SDK migration exceptions", 32 ], 33 filters={"doc_type": "policy", "tenant_scoped": True}, 34 complexity="moderate", 35 ) 36 37 return QueryPlan( 38 intent="exploratory", 39 route="hybrid_search", 40 sub_queries=[user_query], 41 complexity="moderate", 42 ) 43 44plan = understand_query("Which deprecation policy applies to parser-v2 SDK migration for service accounts?") 45print(json.dumps(asdict(plan), indent=2))
Output
1{ 2 "intent": "comparison", 3 "route": "hybrid_search", 4 "sub_queries": [ 5 "parser-v2 deprecation policy", 6 "service-account SDK migration exceptions" 7 ], 8 "filters": { 9 "doc_type": "policy", 10 "tenant_scoped": true 11 }, 12 "needs_fresh_data": false, 13 "complexity": "moderate" 14}

2. Multi-stage retrieval

We use a hybrid retrieval strategy to broaden candidate recall before refining for precision. A single retrieval method is rarely sufficient for complex queries. Relying only on keyword search might miss documents that use synonyms, while relying entirely on dense vector embeddings (encoding data as points in a high-dimensional space so related concepts are near each other) can overlook exact matches for specific names, product IDs, or acronyms.

By designing a multi-stage pipeline, we capture the best of both approaches. The first stage runs sparse retrieval and dense retrieval in parallel, then fuses the ranked lists with Reciprocal Rank Fusion (RRF)[3]Reference 3Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods.https://dl.acm.org/doi/10.1145/1571941.1572114. The second stage applies a more expensive reranker (often a cross-encoder or late-interaction model[4]Reference 4ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT.https://arxiv.org/abs/2004.12832) to a much smaller candidate set, passing only the most relevant chunks or parent passages to the LLM.

This visual outlines the flow of this multi-stage retrieval process.

Hybrid retrieval funnel: BM25, dense, and fresh or API routes fan out for recall, access control runs before fusion, a reranker cuts to top 50, and packing keeps 8 cited chunks. Hybrid retrieval funnel: BM25, dense, and fresh or API routes fan out for recall, access control runs before fusion, a reranker cuts to top 50, and packing keeps 8 cited chunks.
Retrieve wide, filter access before fusion, rerank a small set, then pack only cited evidence.

Why hybrid retrieval?

BM25 (Best Match 25, a reliable keyword search algorithm) excels at exact keyword matching; dense retrieval captures semantic similarity. Dense retrieval typically uses bi-encoders (which encode queries and documents separately for fast lookup), though more advanced systems may use architectures like ColBERT (Contextualized Late Interaction over BERT) for late interaction between query and document tokens.[4]Reference 4ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT.https://arxiv.org/abs/2004.12832 On a mixed workload, combining retrievers can surface candidates that either one would miss alone.

In practice, hybrid search isn't just "run two retrievers." You also need rank fusion, chunking, and evidence assembly. A common pattern is to embed short child chunks for recall, then retrieve the larger parent passage for synthesis so the model sees enough surrounding context to answer cleanly.

Why fuse on rank instead of raw score? BM25 and dense-similarity scores have different scales, so adding them without calibration is brittle. Reciprocal Rank Fusion scores documents from rank positions: score(d) = sum over lists of 1 / (k + rank(d)). Cormack et al. evaluated RRF with k = 60; treat that value as a starting point to validate, not a universal optimum.[3]Reference 3Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods.https://dl.acm.org/doi/10.1145/1571941.1572114 Apply authorization filtering before fusion so a high-ranked forbidden document never becomes generation context.

authorized-rrf-fusion.py
1from collections import defaultdict 2 3tenant = "workspace-a" 4acl = {"deprecation": {"workspace-a"}, "rotation": {"workspace-a"}, "private-roadmap": {"workspace-b"}} 5sparse_ranked = ["deprecation", "private-roadmap", "rotation"] 6dense_ranked = ["private-roadmap", "rotation", "deprecation"] 7 8def allowed_ranked(document_ids: list[str]) -> list[str]: 9 return [document_id for document_id in document_ids if tenant in acl[document_id]] 10 11def reciprocal_rank_fusion(rankings: list[list[str]], k: int = 60) -> list[str]: 12 scores: defaultdict[str, float] = defaultdict(float) 13 for ranking in rankings: 14 for rank, document_id in enumerate(ranking, start=1): 15 scores[document_id] += 1 / (k + rank) 16 return sorted(scores, key=scores.get, reverse=True) 17 18fused = reciprocal_rank_fusion([allowed_ranked(sparse_ranked), allowed_ranked(dense_ranked)]) 19assert "private-roadmap" not in fused 20print("authorized_fused_docs:", fused)
Output
1authorized_fused_docs: ['deprecation', 'rotation']

Freshness and index tiers

Real search products rarely use one monolithic index. A useful pattern is a hot-warm split:

TierTypical contentUpdate patternQuery behavior
HotNews, changelogs, live API snapshotsSeconds to minutesQueried when freshness detector fires
WarmProduct docs, internal wikis, help center contentMinutes to hoursDefault hybrid search tier
ColdStable archive and long-tail corpusBatch compactionBackfill recall when warm tier misses

Freshness should influence ranking, not replace relevance. A common pattern is to combine retrieval score with time decay, then let the reranker decide whether the newer document is better. If you rank purely by recency, a low-quality post from five minutes ago can outrank the canonical source.

Latency budget

TTFT is a critical constraint of this system. The values below are an illustrative budget; validate them against product objectives and measured stage timings.

StageExample latencyMethodParallelism
Query planning10-50msSmall router / rewriterCan overlap with initial retrieval
Retrieval and fetch150-500msSparse, dense, API, or web callsFan-out within allowed routes
Reranking50-150msCross-encoder GPU batchBatch allowed candidates together
Evidence packing10-30msDedupe, trim, retain source IDsSequential after ranking
LLM prefill to first token300-800msStreaming generationSequential after context exists
Total to first token~0.8-1.5 secondsExample product objectiveDepends on overlap and tail latency
Time-to-first-token timeline where planning overlaps initial retrieval, then reranking, evidence packing, and model prefill run in sequence until the first token at 800 milliseconds. Time-to-first-token timeline where planning overlaps initial retrieval, then reranking, evidence packing, and model prefill run in sequence until the first token at 800 milliseconds.
Budget TTFT on one timeline. Overlap what you can, then measure the remaining serial path by route.

Note: If you support speculative retrieval, cheap lexical or dense search can begin before rewrite finishes. If you don't, planning and retrieval stack sequentially. Make that decision explicit when you budget TTFT.

ttft-critical-path.py
1planner_ms = 40 2initial_retrieval_ms = 260 3rerank_ms = 90 4pack_ms = 20 5prefill_to_first_token_ms = 430 6 7sequential_ttft_ms = planner_ms + initial_retrieval_ms + rerank_ms + pack_ms + prefill_to_first_token_ms 8overlapped_ttft_ms = max(planner_ms, initial_retrieval_ms) + rerank_ms + pack_ms + prefill_to_first_token_ms 9 10assert sequential_ttft_ms == 840 11assert overlapped_ttft_ms == 800 12print("sequential_ttft_ms:", sequential_ttft_ms) 13print("overlapped_ttft_ms:", overlapped_ttft_ms)
Output
1sequential_ttft_ms: 840 2overlapped_ttft_ms: 800

3. LLM synthesis with grounded citations

The synthesis prompt can require citations and abstention, but prompting can't prove grounding. The product must keep source IDs attached to evidence, check generated claims, and decide what may be shown while support is pending or missing.

Grounding isn't just a prompt problem. Evidence packing matters too. Put the strongest chunks first, leave room for the model to answer, and avoid stuffing dozens of mediocre passages into the middle of a huge prompt. Long-context models still show "lost in the middle" behavior, where evidence in the center of the context window gets used less reliably.[5]Reference 5Lost in the Middle: How Language Models Use Long Contextshttps://arxiv.org/abs/2307.03172 That's one more reason reranking and tight top-K beat dumping everything into a large context window.

The citations a user sees can be a subset of retrieved evidence, but each visible citation must bind to a specific claim and its source span. Don't treat a source list as proof that every generated sentence is supported.

Before generation, pack allowed passages into a bounded context while preserving source IDs:

evidence-packing-boundary.py
1from dataclasses import dataclass 2 3@dataclass(frozen=True) 4class Passage: 5 source_id: int 6 tenant: str 7 text: str 8 tokens: int 9 rerank_score: float 10 11def pack_allowed(passages: list[Passage], tenant: str, budget: int) -> list[Passage]: 12 selected: list[Passage] = [] 13 used = 0 14 for passage in sorted(passages, key=lambda item: item.rerank_score, reverse=True): 15 if passage.tenant != tenant or used + passage.tokens > budget: 16 continue 17 selected.append(passage) 18 used += passage.tokens 19 return selected 20 21candidates = [ 22 Passage(1, "workspace-a", "Parser-v2 migration starts within 30 days.", 7, 0.95), 23 Passage(2, "workspace-b", "Private roadmap milestone.", 4, 0.99), 24 Passage(3, "workspace-a", "Service-account exceptions require security approval.", 5, 0.82), 25] 26packed = pack_allowed(candidates, tenant="workspace-a", budget=12) 27assert [passage.source_id for passage in packed] == [1, 3] 28print("packed_source_ids:", [passage.source_id for passage in packed])
Output
1packed_source_ids: [1, 3]

Keeping temperature low reduces answer variance, but it doesn't create factuality. The next deterministic example represents a support gate around generated claims: a real synthesizer can draft text, while publication depends on evidence checks.

grounded-answer-contract.py
1from dataclasses import dataclass 2 3@dataclass(frozen=True) 4class Source: 5 source_id: int 6 title: str 7 content: str 8 9def contains_all(source: Source | None, required_terms: tuple[str, ...]) -> bool: 10 if source is None: 11 return False 12 text = source.content.lower() 13 return all(term in text for term in required_terms) 14 15def grounded_answer(sources: list[Source]) -> str: 16 by_id = {source.source_id: source for source in sources} 17 if not contains_all(by_id.get(1), ("parser-v2", "within 30 days")): 18 return "Insufficient cited evidence to answer." 19 if not contains_all(by_id.get(2), ("security approval", "service-account")): 20 return "Insufficient cited evidence to answer." 21 return ( 22 "Start the parser-v2 SDK migration within 30 days [1]. " 23 "Service-account OAuth rotation exceptions require security approval [2]." 24 ) 25 26sources = [ 27 Source( 28 source_id=1, 29 title="Parser v2 Deprecation Policy", 30 content="Parser-v2 SDK migrations must start within 30 days.", 31 ), 32 Source( 33 source_id=2, 34 title="Service Account Rotation Exceptions", 35 content="Service-account OAuth rotation exceptions require security approval.", 36 ), 37] 38 39answer = grounded_answer(sources) 40assert grounded_answer(sources[:1]) == "Insufficient cited evidence to answer." 41assert grounded_answer(sources[:1] + [Source(2, "Service Account Rotation Exceptions", "No approval rule.")]) == "Insufficient cited evidence to answer." 42print(answer)
Output
1Start the parser-v2 SDK migration within 30 days [1]. Service-account OAuth rotation exceptions require security approval [2].

4. Streaming architecture

For one-way progressive delivery, Server-Sent Events (SSE) work through the browser EventSource API over HTTP and are straightforward to render[6]Reference 6Using server-sent eventshttps://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events. Streaming creates a product-policy choice: either hold factual claims until verification completes, or label streamed text as provisional and update or retract unsupported claims.

Streaming answer flow where citations and provisional text render first, a parallel claim-check branch verifies support, and the UI later attaches supported or blocked status. Streaming answer flow where citations and provisional text render first, a parallel claim-check branch verifies support, and the UI later attaches supported or blocked status.
Stream text early only when it's marked provisional. Support checks run in parallel and attach final status after verification.

Streaming endpoint

This event contract fits a low-risk answer path that permits provisional rendering. It emits the plan and sources, declares pending support, streams text, then attaches the result of claim checks. A higher-risk workflow can omit text frames until support becomes supported.

streaming-endpoint.py
1import json 2 3def sse(event_type: str, data: object) -> str: 4 payload = {"type": event_type, "data": data} 5 return f"data: {json.dumps(payload, separators=(',', ':'))}\n\n" 6 7def event_stream() -> list[str]: 8 return [ 9 sse("plan", {"intent": "comparison", "route": "hybrid_search"}), 10 sse("sources", [{"title": "Parser v2 Deprecation Policy", "source_id": 1}]), 11 sse("support_state", {"state": "pending", "display": "provisional"}), 12 sse("text", "For parser-v2 SDK migration"), 13 sse("text", ", start within 30 days [1]."), 14 sse( 15 "support_state", 16 {"state": "supported", "claim_ids": ["migration-window"]}, 17 ), 18 "data: [DONE]\n\n", 19 ] 20 21for frame in event_stream(): 22 print(frame, end="")
Output
1data: {"type":"plan","data":{"intent":"comparison","route":"hybrid_search"}} 2 3data: {"type":"sources","data":[{"title":"Parser v2 Deprecation Policy","source_id":1}]} 4 5data: {"type":"support_state","data":{"state":"pending","display":"provisional"}} 6 7data: {"type":"text","data":"For parser-v2 SDK migration"} 8 9data: {"type":"text","data":", start within 30 days [1]."} 10 11data: {"type":"support_state","data":{"state":"supported","claim_ids":["migration-window"]}} 12 13data: [DONE]

In production, add periodic heartbeat events and configure upstream proxies not to buffer the stream. Also log state transitions so provisional output that becomes blocked can be audited.


Why answers still hallucinate and how to catch them

One of the most critical challenges in search is hallucination, when the LLM generates plausible but incorrect facts. Even with RAG, models can misinterpret complex details. Strong systems usually stack multiple checks rather than betting on one verifier:

MethodWhat it checksRelative costMain weakness
Quote / span matchingDoes the cited span appear in the source?Very lowMisses paraphrases and logical contradictions
Natural Language Inference (NLI)Does the cited passage entail the claim?MediumCan struggle on ambiguous or very long passages
LLM-as-judge / fallback passShould unsupported claims be flagged or regenerated?HighRequires measured latency, cost, and calibration

NLI-based verification estimates whether a cited passage entails a claim rather than merely sharing words. TRUE[7]Reference 7TRUE: Re-evaluating Factual Consistency Evaluation.https://arxiv.org/abs/2204.04991 found that large-scale NLI methods and question-generation-plus-answering methods were strong automatic factual-consistency checks on its benchmarks, so NLI is a useful measured layer, not proof of correctness.

This function is deliberately only a lexical precheck. It can cheaply reject a missing phrase; it can't label entailment. Claims that pass it still need a calibrated verifier or a policy that keeps them provisional.

lexical-citation-precheck.py
1import json 2import re 3 4def lexical_precheck(claim: str, source_text: str) -> dict[str, str | bool]: 5 claim_terms = set(re.findall(r"[a-z0-9]+", claim.lower())) 6 source_terms = set(re.findall(r"[a-z0-9]+", source_text.lower())) 7 term_match = claim_terms.issubset(source_terms) 8 9 return { 10 "claim": claim, 11 "term_match": term_match, 12 "next_step": "entailment_check" if term_match else "block_claim", 13 } 14 15result = lexical_precheck( 16 claim="Parser-v2 migrations must start within 30 days", 17 source_text="Parser-v2 SDK migrations must start within 30 days.", 18) 19 20print(json.dumps(result, indent=2))
Output
1{ 2 "claim": "Parser-v2 migrations must start within 30 days", 3 "term_match": true, 4 "next_step": "entailment_check" 5}


Skills to defend in review

SkillWhat good looks like
Offline vs online splitYou separate ingestion, cleanup, chunking, and index refresh from the latency-sensitive query path.
Multi-stage query pathYou can explain planning, hybrid retrieval, reranking, evidence packing, synthesis, and verification as distinct stages.
Recall improvementsYou know when to use query rewriting, decomposition, routing, and HyDE-style hypothetical documents.
Citation verificationYou check claims against cited sources with span checks, NLI, and selective fallback regeneration.
Streaming UXYou design progressive rendering with SSE events for plan, sources, text, and verification state.
Latency budgetYou allocate TTFT across planning, retrieval, reranking, prefill, and generation instead of treating "LLM latency" as one number.
Serving leversYou know where PagedAttention and speculative decoding help, and why they don't replace retrieval discipline.
Evaluation loopYou combine RAGAS-style reference-free metrics, labeled retrieval metrics, citation metrics, and online feedback.

Production questions to answer

How do you handle queries that need real-time data? Real-time data needs its own freshness pipeline. Use a hot index for newly crawled content plus direct routes to live APIs or structured stores for exact numeric fields. When the planner marks a query as freshness-sensitive, search the hot tier first, apply recency-aware scoring, then merge with the warmer corpus so the LLM sees both new evidence and canonical background context.

How would you detect and handle hallucinated citations? Decompose the generated answer into atomic claims, attach each claim to its cited source, and verify entailment with NLI or a calibrated lighter check. If support is weak or contradictory, flag the statement, remove it, or regenerate with stricter grounding and a smaller evidence set.

What's your latency budget for each pipeline stage? For a consumer-facing experience, a reasonable example SLO is roughly 0.8-1.5 seconds to first token. Query planning often fits in 10-50ms, retrieval fan-out in 150-500ms, reranking in 50-150ms, evidence packing in 10-30ms, and synthesis in roughly 300-800ms to first token. Split synthesis into prefill and decode because prompt length drives prefill cost while answer length drives decode cost.

How do you evaluate answer quality at scale? Start with reference-free metrics such as faithfulness, answer relevance, and context relevance. Add labeled retrieval metrics such as Recall@k or nDCG on benchmark sets, plus citation precision and unsupported-claim rate. In production, track citation click-through, reformulation rate, dwell time, abandonment, and explicit user feedback.

Common design failures

  • Designing everything around a single LLM call instead of specialized routers, retrievers, rerankers, and verifiers.
  • Treating structured or freshness-critical queries like generic vector search.
  • Ignoring latency requirements for interactive search experiences.
  • Skipping rigorous citation verification and trusting prompt instructions alone.
  • Treating long context windows as a replacement for reranking and evidence packing.
  • Overlooking inference cost per query when scaling to millions of users.

Common mistakes when building generative search

SymptomCauseFix
TTFT is consistently >2 secondsRunning a frontier LLM on every query, even simple lookupsAdd a lightweight router that sends factual queries to a small model or cache
Answers cite the wrong sourceEvidence packing stuffs too many mediocre passages into the promptReduce top-K after reranking and place the strongest chunks at the start and end of context
Hallucinations persist despite RAGMissing claim-level verification; relying only on prompt instructionsStack span matching, NLI, and selective LLM-as-judge checks
Cost per query spikes unpredictablyNo freshness tiering; every query hits real-time web retrievalRoute only freshness-marked queries to the hot tier and cache stable answers
Retrieval misses exact API versions or build IDsUsing only dense semantic search without keyword fallbackHybrid sparse + dense retrieval with BM25 for exact matches

What running this costs

Building a search engine at scale requires careful cost management. Exact dollar figures drift with vendor pricing, model choice, and answer length, so reason from units of work rather than one fixed price table.

Cost routing ladder where requests escalate from cache to small model to mid-tier synthesis to frontier reasoning only when freshness, evidence burden, or ambiguity require it. Cost routing ladder where requests escalate from cache to small model to mid-tier synthesis to frontier reasoning only when freshness, evidence burden, or ambiguity require it.
Promote queries only when requirements force it. Freshness, retrieval fan-out, prompt length, and verification policy change route cost.
Cost centerBillable unitWhat makes it expensive
Web retrievalAPI calls and fetched documentsMore sub-queries, more URLs fetched
RerankingQuery-document pairsLarger candidate set or heavier reranker
SynthesisPrompt + completion tokensLong context windows and long answers
VerificationClaims checked against passagesDense citation requirements, many claims

Before writing the formula, use scenario inputs rather than presenting provider pricing as fixed:

  • Web retrieval: ~$0.002
  • Reranking 200 query-document pairs: ~$0.001
  • 1,500 prompt tokens + 400 output tokens at $0.003 per 1K tokens: ~$0.006
  • Verifying 5 claims: ~$0.001

For these inputs, total cost is roughly $0.01 per query. At 1,000 QPS, that scenario approaches $600 per minute, which is why routing and caching need their own budgets.

query-cost-envelope.py
1retrieval_usd = 0.002 2rerank_usd = 0.001 3prompt_tokens = 1500 4output_tokens = 400 5token_usd_per_thousand = 0.003 6verification_usd = 0.001 7queries_per_second = 1000 8 9query_usd = ( 10 retrieval_usd 11 + rerank_usd 12 + (prompt_tokens + output_tokens) / 1000 * token_usd_per_thousand 13 + verification_usd 14) 15per_minute_usd = query_usd * queries_per_second * 60 16 17assert round(query_usd, 4) == 0.0097 18print("scenario_query_usd:", round(query_usd, 4)) 19print("scenario_per_minute_usd:", round(per_minute_usd, 2))
Output
1scenario_query_usd: 0.0097 2scenario_per_minute_usd: 582.0
cost/query≈  Csearch+Npairs⋅Crerank+(Tprompt+Toutput)⋅Ctoken+Nclaims⋅Cverify\begin{aligned} \text{cost/query} \approx\;& C_{\text{search}} + N_{\text{pairs}} \cdot C_{\text{rerank}} \\ &+ (T_{\text{prompt}} + T_{\text{output}}) \cdot C_{\text{token}} \\ &+ N_{\text{claims}} \cdot C_{\text{verify}} \end{aligned}cost/query≈​Csearch​+Npairs​⋅Crerank​+(Tprompt​+Toutput​)⋅Ctoken​+Nclaims​⋅Cverify​​

Which stage dominates variable cost depends on provider rates, fan-out, prompt length, and verification policy. Measure the breakdown, then route cacheable or structured queries away from unnecessary synthesis and trim top-K where retrieval evaluation allows it.

Serving-side latency levers

TTFT can be dominated by retrieval, prompt assembly, or prefill; long answers can shift pressure toward decode. Profile the critical path before choosing an optimization.

PagedAttention improves KV-cache memory management and can increase concurrency when KV allocation is the binding constraint.[8]Reference 8Efficient Memory Management for Large Language Model Serving with PagedAttention.https://arxiv.org/abs/2309.06180 If decode is the bottleneck, speculative decoding can reduce latency when a draft model is accepted often enough; benchmark it for the answer shapes and target model in this service.[9]Reference 9Fast Inference from Transformers via Speculative Decoding.https://arxiv.org/abs/2211.17192

These serving optimizations matter only after retrieval depth and prompt length are under control. If you keep sending 40 mediocre passages to the model, no amount of serving cleverness will rescue TTFT.

GPU capacity planning

For a scenario with 1K QPS sustained and 1.5 seconds average latency per request:

Concurrent requests=QPS×avg latency=1000×1.5=1500\text{Concurrent requests} = \text{QPS} \times \text{avg latency} = 1000 \times 1.5 = 1500Concurrent requests=QPS×avg latency=1000×1.5=1500

This is Little's Law (average items in system = arrival rate × average time in system) in practice: at 1000 requests/second with 1.5-second average service time, around 1500 requests are in-flight simultaneously.

capacity-envelope.py
1from math import ceil 2 3queries_per_second = 1000 4average_latency_seconds = 1.5 5average_output_tokens = 120 6effective_decode_tokens_per_second_per_gpu = 6000 7 8in_flight_requests = queries_per_second * average_latency_seconds 9decode_gpus = ceil( 10 queries_per_second 11 * average_output_tokens 12 / effective_decode_tokens_per_second_per_gpu 13) 14 15assert in_flight_requests == 1500 16print("in_flight_requests:", int(in_flight_requests)) 17print("decode_gpus_before_headroom:", decode_gpus)
Output
1in_flight_requests: 1500 2decode_gpus_before_headroom: 20

The next step is to translate concurrency into throughput and memory requirements for your actual serving stack. Don't assume a universal "requests per GPU" number. Measure your own model, context length, batching strategy, and quantization settings. PagedAttention improves packing efficiency and reduces KV-cache fragmentation under concurrent load[8]Reference 8Efficient Memory Management for Large Language Model Serving with PagedAttention.https://arxiv.org/abs/2309.06180, but capacity still depends on empirical tokens-per-second benchmarks.

GPUs needed≈⌈QPS×avg output tokenseffective decode tok/s/GPU⌉\text{GPUs needed} \approx \left\lceil \frac{\text{QPS} \times \text{avg output tokens}}{\text{effective decode tok/s/GPU}} \right\rceilGPUs needed≈⌈effective decode tok/s/GPUQPS×avg output tokens​⌉

For long prompts, also budget prefill separately:

Prefill capacity≈QPS×avg prompt tokenseffective prefill tok/s/GPU\text{Prefill capacity} \approx \frac{\text{QPS} \times \text{avg prompt tokens}}{\text{effective prefill tok/s/GPU}}Prefill capacity≈effective prefill tok/s/GPUQPS×avg prompt tokens​

In practice, size the system against whichever pool saturates first: retriever GPUs, reranker GPUs, prefill workers, or decode workers. The answer model may be an expensive tier, but measured retrieval or reranking can still be the first bottleneck.


How to know it's working

RAGAS[10]Reference 10RAGAS: Automated Evaluation of Retrieval Augmented Generation.https://arxiv.org/abs/2309.15217 introduced reference-free evaluation around faithfulness, answer relevance, and context relevance. It's one offline layer when gold answers are scarce, not a replacement for labeled retrieval metrics, citation checks, or online product metrics: a response can be consistent with mediocre evidence and still fail the user.

LayerMetricWhat it catchesTypical requirement
Reference-free offlineFaithfulnessUnsupported claimsLLM/NLI judge over answer vs context
Reference-free offlineAnswer relevanceMissed user intentGenerated-question similarity or judge
Reference-free offlineContext relevanceNoisy, redundant retrieved contextJudge over question vs retrieved passages
Labeled offlineRecall@k / nDCG / MRRRetriever missed or buried the right sourceGold passages or reliable click labels
Citation qualityCitation precision / unsupported-claim rateWrong citations or uncited claimsClaim extraction + source verification
OnlineReformulation rate / citation CTR / abandonmentReal user dissatisfactionProduction logging and experiments

This example wires a scorecard together with simple token-overlap proxies so it stays runnable. Its citation-resolution metric only checks whether a visible citation ID maps to an available passage; it doesn't prove claim support. These proxies aren't RAGAS or calibrated faithfulness judges. Replace them in an evaluation service while keeping labeled retrieval metrics separate.

how-to-know-its-working.py
1import json 2import re 3from dataclasses import dataclass 4from collections.abc import Mapping 5from math import log2 6 7@dataclass(frozen=True) 8class Passage: 9 id: str 10 text: str 11 12def tokens(text: str) -> set[str]: 13 return set(text.lower().replace(",", "").replace(".", "").split()) 14 15def overlap(a: str, b: str) -> float: 16 left = tokens(a) 17 right = tokens(b) 18 return len(left & right) / max(1, len(left)) 19 20def citation_resolution_precision(answer: str, cited_passages: list[Passage]) -> float: 21 available_ids = {passage.id for passage in cited_passages} 22 cited_ids = re.findall(r"\[([^\[\]]+)\]", answer) 23 return sum(cited_id in available_ids for cited_id in cited_ids) / max(1, len(cited_ids)) 24 25def recall_at_k(retrieved_ids: list[str], gold_ids: set[str], k: int) -> float: 26 return len(set(retrieved_ids[:k]) & gold_ids) / max(1, len(gold_ids)) 27 28def ndcg_at_k(retrieved_ids: list[str], gold_ids: set[str], k: int) -> float: 29 gains = [1.0 if item in gold_ids else 0.0 for item in retrieved_ids[:k]] 30 dcg = sum(gain / log2(rank + 2) for rank, gain in enumerate(gains)) 31 ideal = sum(1.0 / log2(rank + 2) for rank in range(min(len(gold_ids), k))) 32 return dcg / ideal if ideal else 0.0 33 34def score_search_response( 35 query: str, 36 answer: str, 37 retrieved_passages: list[Passage], 38 cited_passages: list[Passage], 39 gold_passage_ids: set[str] | None = None, 40) -> Mapping[str, float]: 41 context = " ".join(passage.text for passage in retrieved_passages) 42 scorecard = { 43 "answer_context_token_overlap": overlap(answer, context), 44 "query_answer_token_overlap": overlap(query, answer), 45 "query_context_token_overlap": overlap(query, context), 46 "citation_resolution_precision": citation_resolution_precision(answer, cited_passages), 47 } 48 49 if gold_passage_ids is not None: 50 retrieved_ids = [p.id for p in retrieved_passages] 51 scorecard["recall_at_20"] = recall_at_k(retrieved_ids, gold_passage_ids, k=20) 52 scorecard["ndcg_at_10"] = ndcg_at_k(retrieved_ids, gold_passage_ids, k=10) 53 54 return {metric: round(value, 2) for metric, value in scorecard.items()} 55 56retrieved = [ 57 Passage("1", "Parser-v2 SDK migrations must start within 30 days."), 58 Passage("2", "Service-account OAuth rotation exceptions require security approval."), 59 Passage("3", "Legacy parser-v1 migrations follow a separate workflow."), 60] 61answer = "Parser-v2 SDK migrations must start within 30 days [1]." 62 63print(json.dumps( 64 score_search_response( 65 query="Which deprecation policy applies to parser-v2 SDK migration for service accounts?", 66 answer=answer, 67 retrieved_passages=retrieved, 68 cited_passages=retrieved[:1], 69 gold_passage_ids={"1", "2"}, 70 ), 71 indent=2, 72))
Output
1{ 2 "answer_context_token_overlap": 0.89, 3 "query_answer_token_overlap": 0.18, 4 "query_context_token_overlap": 0.18, 5 "citation_resolution_precision": 1.0, 6 "recall_at_20": 1.0, 7 "ndcg_at_10": 1.0 8}


Scaling without blowing the budget

As traffic grows, evaluate each latency or cost lever against quality and authorization tests:

StrategyImplementation DetailsPrimary Benefit
Semantic response cacheKey answers by authorization scope and evidence version; reuse only after similarity and freshness thresholds pass.Can avoid synthesis work for eligible repeat queries.
Model routingRoute exact live facts to structured backends and measured simple paths to smaller models.Can lower cost without weakening answer routes that require synthesis.
Speculative retrievalStart an allowed cheap retriever while rewrite or decomposition runs, then merge or cancel.Can shorten measured critical path when early retrieval is useful.
Asynchronous verificationMark streamed claims pending, or hold high-risk facts until checks return.Trades display latency against unsupported-claim exposure explicitly.
Geographic distributionPlace permitted retrieval and caches near users when data residency policy allows it.Can reduce network latency for eligible data paths.
Feedback integrationLog interactions with privacy controls and use labeled review before training rerankers.Supplies evidence for retriever or reranker changes.

Mastery check

Key concepts

  • Offline ingest vs online query path
  • Query planning, routing, and freshness detection
  • Hybrid retrieval with BM25, dense retrieval, and rank fusion
  • Reranking, evidence packing, and source-ID preservation
  • Grounded synthesis with citations
  • Claim-level verification with span checks and NLI
  • Streaming answer delivery with SSE
  • Latency budgeting, routing, and cost control
  • Offline and online evaluation for search quality

What strong answers show

  • Foundational: Explains why generative search needs both offline indexing and an online retrieval plus synthesis path
  • Intermediate: Chooses when to route a query to structured APIs, hybrid retrieval, or fresh-web lookup
  • Intermediate: Explains why hybrid sparse plus dense retrieval beats either retriever alone for developer-doc search
  • Intermediate: Designs a TTFT budget that includes planning, retrieval, reranking, packing, and synthesis rather than treating latency as one LLM number
  • Advanced: Designs claim-level verification that distinguishes quote matching, NLI, and selective fallback regeneration
  • Advanced: Defends routing and caching rules that keep cost and latency under control at high QPS
  • Advanced: Separates retrieval metrics, citation metrics, and online product metrics in one search evaluation loop

Follow-up questions

Common pitfalls

"One LLM call can replace search architecture"

  • Symptom: Answers sound polished but use stale, missing, or unauthorized evidence.
  • Cause: Retrieval, routing, and verification were collapsed into one generation step.
  • Fix: Split the system into planner, retriever, reranker, evidence packer, synthesizer, and verifier. Keep trust boundaries outside the model.

"Dense retrieval is enough"

  • Symptom: Search misses exact API versions, build IDs, or policy titles even though semantically related passages appear.
  • Cause: Dense retrieval is good at paraphrases, not exact lexical anchors.
  • Fix: Use hybrid sparse plus dense retrieval, then fuse ranks before reranking.

"Long context makes reranking optional"

  • Symptom: The right document was retrieved, but the final answer still ignores or misstates it.
  • Cause: Dumping many mediocre passages into context creates prompt bloat and lost-in-the-middle effects.
  • Fix: Rerank aggressively, keep source IDs attached, and pack only the strongest evidence the answer model needs.

"Citations alone prove factuality"

  • Symptom: Answers show footnotes but still contain unsupported or misleading claims.
  • Cause: The system attached sources without checking whether each claim is entailed by the cited text.
  • Fix: Add claim extraction plus span checks, NLI, and selective fallback regeneration for weak support.

"Cost tuning starts at the model endpoint"

  • Symptom: Query cost spikes even after switching to a cheaper model.
  • Cause: Retrieval fan-out, rerank pairs, long prompts, and verification work were left uncontrolled.
  • Fix: Route simple queries earlier, trim top-K harder, cache safely, and reserve frontier synthesis for genuinely multi-hop requests.

Practice drill

Create a search-answer trace for one developer-doc query that mixes live facts and cited policy text:

  1. Split the query into structured API calls, sparse retrieval, dense retrieval, reranking, evidence packing, synthesis, and claim verification.
  2. Log which documents were removed by ACL filtering before fusion or reranking.
  3. Add a claim-support table with atomic claim, cited span, entailment result, and final support state.
  4. Mark latency budget by stage and choose one optimization that doesn't weaken authorization or citation support.

The trace should prove the answer was authorized, fresh, cited, and verifiable, not fluent alone.

Complete the lesson

Mastery Check

Answer every question, then check your score. Score above 75% to mark this lesson complete.

1.A developer asks, "Is deploy job build-1042 still running on the GPU runner, how much workspace quota remains today, and what policy applies to emergency overages?" Job state and quota change minute to minute, while overage policy must be cited. How should the query planner route it?
2.A team wants user requests to crawl sources, clean documents, create chunks, attach access metadata, update indexes, retrieve evidence, and generate an answer in one synchronous path. Which split keeps the search path fast and permission-safe?
3.For a developer-doc query that includes exact API versions and policy titles but may use user paraphrases, why run BM25 and dense retrieval before reranking?
4.For tenant workspace-a, the ACL allows documents deprecation and rotation but not private-roadmap. Sparse ranks are [deprecation, private-roadmap, rotation]; dense ranks are [private-roadmap, rotation, deprecation]. If authorization filtering happens before RRF, which documents can appear in the fused evidence set?
5.A query retrieved the correct deprecation-policy passage, but it was packed between 35 other mediocre passages in the middle of a long prompt. The answer ignored it. What change addresses this failure?
6.A generated answer cites a passage and the cited words mostly overlap the claim, but the passage may not entail the claim's meaning. What verification policy should gate publication?
7.A search endpoint uses SSE and wants sub-second perceived latency for low-risk policy text. Claim verification may finish after the first tokens. Which event policy matches the design?
8.A TTFT budget has planner 40 ms, retrieval 260 ms, reranking 90 ms, evidence packing 20 ms, and LLM prefill to first token 430 ms. If speculative retrieval lets planning overlap the initial retrieval, what is the TTFT critical path?
9.A semantic cache contains an answer for workspace-a built from evidence version 17. A similar query arrives for workspace-b after a policy update. What must be true before the cached answer can be reused?
10.An offline judge gives high faithfulness for an answer against retrieved passages, and every visible citation ID resolves to an available passage. In production, users often reformulate the query and abandon the result. What should the evaluation loop inspect next?

10 questions remaining.

Next Step
Continue to Vision-Language Models & CLIP

Search turned retrieved text evidence into cited answers. Now you'll make images searchable too: learn how CLIP aligns text and images, then see how modern vision-language models bring visual evidence into multimodal systems.

PreviousMulti-Tenant LLM Platform
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks.

Lewis, P., et al. · 2020 · NeurIPS 2020

Precise Zero-Shot Dense Retrieval without Relevance Labels.

Gao, L., Ma, X., Lin, J., & Callan, J. · 2022 · arXiv preprint

Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods.

Cormack, G. V., Clarke, C. L. A., & Buettcher, S. · 2009 · SIGIR '09

ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT.

Khattab, O., & Zaharia, M. · 2020 · SIGIR 2020

Lost in the Middle: How Language Models Use Long Contexts

Liu, N.F., et al. · 2023 · TACL 2023

Using server-sent events

MDN Web Docs · 2026

TRUE: Re-evaluating Factual Consistency Evaluation.

Honovich, O., et al. · 2022 · NAACL 2022

Efficient Memory Management for Large Language Model Serving with PagedAttention.

Kwon, W., et al. · 2023 · SOSP 2023

Fast Inference from Transformers via Speculative Decoding.

Leviathan, Y., Kalman, M., & Matias, Y. · 2023 · ICML 2023

RAGAS: Automated Evaluation of Retrieval Augmented Generation.

Es, S., et al. · 2023 · arXiv preprint

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.