Managed RAG: Bedrock Knowledge Bases, Hybrid Search, and Rerankers (AWS GenAI Developer Pro, Module 5)

Module 5 of 16 15 min read D1 · 31% Lab code ↗

This is Module 5 of AWS GenAI Pro Mastery, a free 16-module course that takes you from your first Amazon Bedrock call to AWS-certified.

A CloudCart customer asks Relay: “How do I downgrade my plan without losing my order history?” Module 4’s hand-built retrieval returns three correct chunks, until someone notices the billing doc was edited two weeks ago and the index never heard about it. The price in the answer is stale. To fix it you would write a cron job to re-ingest, a retry loop for the embedding calls, a delta check so you do not re-embed all 200 docs every night, an alert for when a job fails silently. None of that is the support agent. It is a second product (a data-pipeline product) someone now owns full time. A DIY RAG stack is an infrastructure team you did not budget for.

This module hands that burden to AWS. You replace your pipeline with a managed Bedrock Knowledge Base that ingests the CloudCart docs, keeps the index in sync, and returns answers with citations, then you benchmark it against the retrieval you wrote by hand. By the end, Relay answers from the official docs, cites its sources, and you decide, with numbers, which managed levers earn their keep.

In this module

  • You’ll learn to connect a documentary system to a foundation model through a managed integration component (skill 1.4.4); design data maintenance — incremental sync, change detection, scheduled refresh, all driven by an ingestion job — and prove freshness with a test (1.4.5); improve relevance with a reranker (and hybrid search as the store-dependent trade-off it is — you’ll see why it is N/A on S3 Vectors), measured against Module 4’s raw retrieval (1.5.4); transform queries with reformulation and decomposition (1.5.5); and choose between the Retrieve and RetrieveAndGenerate access patterns (1.5.6).
  • You’ll build Relay’s answer(): a Bedrock Knowledge Base over the CloudCart docs that returns cited, grounded answers — and a benchmark against Module 4’s DIY retrieval.
  • Exam domains covered: D1 — Foundation Model Integration, Data Management, and Compliance — 31% (this module covers skills 1.4.4–1.4.5 and 1.5.4–1.5.6; chunking, embeddings, and vector-store deployment — the other half of Tasks 1.4/1.5 — are Module 4).
  • Prerequisites: Modules 1–4 (a secured account with AWS_PROFILE, the relay/llm.py layer, the Ticket/Triage schemas, and the Module 4 data bucket relay-<account_id> with docs/ populated plus the S3 Vectors index). Region is us-east-1 throughout.

Where you are in the build

You are at Module 5 of 16. The destination is the AWS Certified Generative AI Developer - Professional (AIP-C01) exam; the vehicle is Relay, CloudCart’s support agent.

  • M1 — secured account, budget alarm, first Converse call.
  • M2 — triage: structured output, Prompt Management, a prompt test suite.
  • M3 — the FM integration layer: model routing, streaming, retries, cross-Region fallback.
  • M4 — RAG foundations: chunking, embeddings, S3 Vectors, a raw-retrieval comparison.
  • 👉 M5 — managed RAG: a Bedrock Knowledge Base, hybrid search, rerankers, cited answers, freshness.
  • M6–M16 — multimodal intake, agents, safety, deployment, cost, evals, observability, capstone.

Relay before this module triages and retrieves raw chunks, but it does not answer: no generation, no citation, no Answer object. After it, Relay has relay/kb.py: an answer() that returns cited, grounded answers from the managed Knowledge Base relay-kb, plus a benchmark that proves which levers earn their keep. You are no longer reading chunks by hand; Relay writes the answer and cites the source.

From DIY retrieval to managed RAG: what Knowledge Bases actually manage

In Module 4 you built retrieval as a pipeline you owned end to end: chunk the docs, embed them with Amazon Titan Text Embeddings V2, upsert the vectors into Amazon S3 Vectors, run a kNN at query time. A Bedrock Knowledge Base is that same pipeline run as a managed service: you point it at a data source, and it parses, chunks, embeds, writes to a vector store, and re-syncs on demand. The skill the exam labels 1.4.4 is exactly this: the Knowledge Base is the integration component that connects a documentary system (Amazon S3 here; wikis and document-management systems plug in the same way) to a foundation model.

What it manages is real work. Parsing turns each file into text; chunking cuts it (the same fixed/hierarchical/semantic choice from Module 4, now a configuration instead of your code); embedding runs Titan over each chunk; the vector store holds the result; and an ingestion job orchestrates all of that. What it does not manage is your judgment: which docs to include, how to chunk, which store fits your cost profile, and whether the retrieved passage actually answers the question. It automates the plumbing, not the decisions.

The vector store under our Knowledge Base is Amazon S3 Vectors, the same store Module 4 used: it bills roughly $0 when idle. The pre-2026 default for a Bedrock Knowledge Base was an always-on serverless search cluster that bills around $174/month, 24/7, whether or not a single query runs (as of June 2026, re-verify on the Bedrock pricing page) — the single biggest cost trap in old Knowledge Base tutorials. We never provision it; it shows up only as an exam scenario.

One live finding shaped the lab. A Bedrock Knowledge Base writes vectors in its own schema and can only read those back, so it cannot reuse Module 4’s hand-built relay-docs vectors: mixing the two makes the KB return half-empty results. The Knowledge Base therefore owns a clean index, relay-kb-docs, in the same vector bucket, while relay-docs stays the DIY baseline the benchmark measures against. Both are S3 Vectors, idle ~$0.

flowchart LR
  A["S3 docs/<br/>CloudCart help center"] --> B["Ingestion job<br/>parse → chunk → embed (Titan V2)"]
  B --> C["S3 Vectors<br/>index relay-kb-docs"]
  C --> D{"Access pattern"}
  D -->|Retrieve| E["raw passages<br/>your prompt + model"]
  D -->|RetrieveAndGenerate| F["cited answer<br/>smart tier"]
  E --> G["Relay"]
  F --> G["Relay"]

Here is the trade-off the exam wants you to make on sight, managed Knowledge Base versus the DIY pipeline:

DimensionManaged KB (relay-kb)DIY pipeline (your Module 4 code)
Ingestion / syncIngestion jobs; incremental sync re-embeds only changed docsYou write the cron, retry, and delta logic
Chunking controlConfigurable strategies (fixed/hierarchical/semantic), less granularFull control — your code, any boundary rule
Vector store choiceS3 Vectors, Aurora, Mongo, serverless search — managedAny store you wire up (Module 4: S3 Vectors)
Native citationsYes — RetrieveAndGenerate returns sourcesYou build the citation mapping yourself
Operational cost~$0 idle (S3 Vectors); no pipeline to staffThe pipeline is a product someone owns
Lock-inBedrock-shaped vectors + APIPortable code, more of it
When to chooseNo ops bandwidth; want citations + auto-syncNeed fine chunking control or a custom store

Retrieve vs RetrieveAndGenerate: two access patterns

A Knowledge Base exposes two standardized access patterns (the “standardized API patterns for retrieval augmentation” the exam lists under skill 1.5.6), and choosing between them is a real design decision. Retrieve gives you the raw passages back: you own the prompt, you pick the model, you generate yourself. RetrieveAndGenerate does both in one call. It retrieves and generates a grounded answer with turnkey citations, and you get back text plus the sources it used.

Relay uses RetrieveAndGenerate here, on purpose. At this stage the win is citations: a support answer a human can verify against the exact passage it came from, with no citation-mapping code to write. When the agent arrives in Module 7 and needs to own its prompt and control the model precisely, it switches to Retrieve. The pattern follows the need.

DimensionRetrieveRetrieveAndGenerate
Prompt / model controlYours — own prompt, own modelManaged — you pass a model ARN; the KB prompts
CitationsBuild them yourself from resultsTurnkey — returned in a citations block
Session / multi-turnYou manage conversation stateOptional managed session id
CostOne retrieval; you pay generation separatelyRetrieval + one managed generation
Best forAgents, custom prompts, tool context (M7)Cited Q&A out of the box (Relay, M5)

The output of answer() is the frozen Answer contract — introduced here and reproduced field-for-field everywhere it appears:

# Citation — frozen M5 (NO score/confidence field — ever)
class Citation:
    source_uri: str
    snippet: str

# Answer — frozen M5 (grounded = bool(citations) heuristic M5; real check M9)
class Answer:
    text: str
    citations: list[Citation]
    grounded: bool

The grounded boolean deserves a precise definition, because the exam tests the distinction. Grounding means an answer’s claims are actually supported by the retrieved context. At Module 5 grounded is the heuristic bool(citations): an answer that cited at least one retrieved source is treated as grounded. The real contextual grounding check (a Bedrock guardrail that verifies support and escalates when it is missing) arrives in Module 9 and recomputes this same field. The name and type do not change; only the computation does.

⚠️ Common misconception: “citations present” means “answer verified.” It does not. A citation says the model retrieved a source and attached it; it does not prove the sentence it wrote is supported by that source. A model can cite the right doc and still paraphrase it wrong. At Module 5 grounded is a cheap signal (“did it cite anything?”), useful but not a verification. Treating the two as the same is the trap Domain 3 sets; the tooled grounding check is a separate control, and it is Module 9.

Hybrid search and rerankers: squeezing relevance

Pure semantic search has a blind spot the exam loves: exact identifiers. Ask “How much does the Growth plan cost?” and a semantic search blurs “Growth” across all three CloudCart plans, because the embedding for the word sits near “Starter” and “Scale”. Ask about error code ERR-402 and the token “402” has no semantic neighborhood at all; it is a string, not a meaning. Hybrid search is the fix: it combines keyword matching (BM25-style, which pins exact tokens) with vector matching (which captures meaning), so “Growth” and “402” are matched as literals while the rest of the query still matches by sense (skill 1.5.4). In the API it is the overrideSearchType field set to HYBRID.

Here is the live finding that reshapes the textbook story. Hybrid search is a property of the vector store, not a free switch. As of June 2026, Bedrock Knowledge Bases run hybrid search only on hybrid-capable stores: Aurora PostgreSQL, MongoDB Atlas, or the always-on serverless search cluster. On Amazon S3 Vectors, our ~$0-idle store, the API rejects HYBRID outright (“HYBRID search type is not supported”). Choosing S3 Vectors trades hybrid for near-zero idle cost, exactly the trade-off Domain 1 asks you to reason about. So the lab runs semantic retrieval and reaches for the reranker as its precision lever instead.

A reranker is a cross-encoder that re-scores the retriever’s candidates against the query and reorders them for precision of the top-k. The live us-east-1 catalogue (June 2026) carries exactly one: Cohere Rerank 3.5 (cohere.rerank-v3-5:0). Amazon Rerank (amazon.rerank-v1:0) is the documented alternative in Regions that carry it, but returns “the provided model identifier is invalid” here, so Cohere Rerank is the lab default. Re-verify the catalogue and its pricing on the Bedrock pricing page the day you run this; reranker availability moves.

⚠️ Common misconception: “a reranker fixes bad retrieval.” It does not. A reranker reorders what the retriever already returned. If the right chunk is not among the candidates (bad chunking, a malformed query, a stale index), no reranker conjures it. It improves the order of what came back; it cannot widen it. Coverage first (hybrid search, healthy sync, good chunking), order second (the reranker). Reach for it when the right passage is in the top-k but ranked too low, not when it is missing entirely.

The third lever is query transformation. Compound questions like “How do I downgrade my plan and keep my order history?” pull in two directions, and a single embedding lands between both, retrieving neither well. Query decomposition (skill 1.5.5) splits the question into sub-queries (“downgrade plan”, “keep order history”), retrieves for each, and synthesizes one answer: the QUERY_DECOMPOSITION orchestration setting, one flag on answer(). It is query expansion’s sibling, where expansion broadens one query with synonyms and decomposition breaks one compound query into several.

flowchart LR
  Q["query"] --> T{"transform?"}
  T -->|"compound"| D["decompose<br/>(QUERY_DECOMPOSITION)"]
  T -->|"simple"| S0["as-is"]
  D --> R["retrieve per sub-query"]
  S0 --> R
  R --> V["vector search<br/>(semantic on S3 Vectors)"]
  V --> K["candidates (top-k)"]
  K --> RR["reranker<br/>(Cohere Rerank 3.5)"]
  RR --> G["generate cited answer"]

Three retrieval configurations, three different jobs:

ConfigurationAdded latencyAdded costWins on
Semantic onlybaselineretrieval onlyMeaning-based questions; cheapest, fastest
Semantic + rerank+ cross-encoder pass+ reranker fee (~$2/1k queries)Noisy top-k where the right chunk ranks too low
Hybrid (+rerank)+ keyword indexneeds a hybrid-capable storeExact tokens (SKUs, error codes, plan names)

Keeping the knowledge fresh: sync and change detection

A managed Knowledge Base does not magically notice the docs changed. Edit a file in S3 and the index keeps serving the old vectors until you re-run an ingestion job. The job does an incremental sync: it detects which objects changed (by S3 ETag and last-modified) and re-embeds only those, not the whole corpus (skill 1.4.5). On thousands of docs, that is the difference between a few cents and a full re-embed bill every night. The exam’s freshness scenarios turn on exactly this: the right answer is incremental re-sync, not a scheduled full re-ingestion of everything.

The lab proves it rather than assuming it. freshness_test.py reads the answer (the Growth plan is “$79”), edits billing-plans.md to “$99”, re-syncs, and reads it again (“$99”). The re-sync reports numberOfModifiedDocumentsIndexed: 1, confirming only the one changed doc was re-embedded. Freshness is something you test, not something you suppose.

In production you would not edit a doc by hand. An Amazon EventBridge schedule fires the ingestion job nightly, or an S3 event fires it the moment a doc lands (the event-driven version is Module 11). The incremental-sync mechanism underneath is the same one the lab exercises.

One more lever rides on the same machinery: metadata filtering. Each CloudCart doc carries a category the Knowledge Base indexes as a filterable attribute, so retrieval can be scoped to one category, narrowing the candidate pool before ranking (skill 1.4.2, recalled from Module 4). That is the multi-tenant lever: a tenant_id filter keeps one customer’s docs out of another’s answers, from one shared index.

Build it: a cited Knowledge Base for Relay

The lab creates relay-kb over the CloudCart docs, gives Relay an answer(), and benchmarks rerank and freshness against Module 4’s DIY retrieval. At the end, uv run python -m relay.kb "How do I change my CloudCart subscription plan?" prints a grounded answer with citations. The full code is in module-05/; excerpts below.

Step 1 — carry the cumulative state forward. Module 5 starts from Module 4’s relay/ package byte-for-byte plus its ingest/ pipeline and storage: the data bucket with docs/ populated and the S3 Vectors index. It never re-ingests by hand; setup.py prechecks the prerequisites and names exactly what is missing rather than rebuilding someone else’s resource.

Step 2 — stand up the Knowledge Base. setup.py is idempotent: it prechecks the Module 4 storage, creates the least-privilege IAM role relay-kb-role (explicit ARNs, zero wildcards), creates relay-kb with S3 Vectors storage on the KB-owned index relay-kb-docs, uploads a category metadata sidecar per doc, attaches the S3 data source over docs/, and runs the first ingestion job to COMPLETE.

uv run python setup.py
# ... data source 'relay-docs-source': CREATED ...
# ... ingestion job <id>: COMPLETE — docs/ embedded into 'relay-kb-docs'.

Step 3 — the two access patterns. relay/kb.py exposes retrieve() (the Retrieve API: raw passages, your prompt) and answer() (RetrieveAndGenerate: cited answer, smart tier). The answer model is resolved through relay/config.py, never a hard-coded ID:

def answer(query: str, *, top_k: int = config.KB_DEFAULT_TOP_K,
           search_type: str = SEARCH_SEMANTIC, rerank: bool = True,
           decompose: bool = False, ...) -> Answer:
    client = client or _agent_runtime_client()
    kb = resolve_kb_id(kb_id)
    vsc = _vector_search_config(top_k=top_k, search_type=search_type,
                                rerank=rerank, category=category, account=account)
    kb_config = {
        "knowledgeBaseId": kb,
        "modelArn": config.model_arn(config.KB_ANSWER_TIER, account=account),
        "retrievalConfiguration": {"vectorSearchConfiguration": vsc},
    }
    response = _call_with_retry(lambda: client.retrieve_and_generate(...), ...)
    text = response.get("output", {}).get("text", "")
    citations = _citations_from_rag(response)
    return Answer(text=text, citations=citations, grounded=bool(citations))

Running the headline question hits the real API and returns a grounded answer with one citation:

Open Billing -> Subscription and click Change plan. Pick the new plan and confirm;
the change takes effect immediately. Upgrades are prorated; downgrades take effect
at the start of your next billing cycle, and nothing — including your order history
— is lost.

Citations (1):
  [1] s3://relay-<account_id>/docs/billing-plans.md
      Changing your plan ... Open Billing -> Subscription and click Change plan. ...

grounded: True

Step 4 — hybrid, the reranker, and decomposition. compare_retrieval.py runs four configurations over the 8 questions in data/kb_questions.json and prints, per question and in aggregate, the top-1 hit rate and recall:

             M4 DIY      KB sem      KB sem+rr   KB hyb*
  top-1 rate 1.00        1.00        1.00        n/a
  mean recall0.94        0.94        0.94        n/a
# KB hyb* = HYBRID, n/a on S3 Vectors (needs a hybrid-capable store)

Read it by hand: on this tidy corpus, semantic retrieval already hits top-1 everywhere, and the reranker reorders the candidates without ever surfacing a doc the retriever missed (coverage first, order second). Relevance is the hand label in the questions file; there is no LLM-as-a-judge and no RAG-eval harness here (that is Module 13). Query decomposition is one flag:

a = kb.answer("How do I downgrade my plan without losing my order history?",
              decompose=True)
print([c.source_uri for c in a.citations])
# decomposition retrieves for "downgrade" AND "order history" -> cites BOTH docs.

The compound question, decomposed, cited both billing-plans.md and orders-export.md, grounded: exactly what a single blended embedding misses.

Step 5 — prove freshness. freshness_test.py reads the answer, edits a price, re-syncs incrementally, and reads it again:

1. Answer BEFORE: "... the Growth plan is $79 per month ..."  cited billing-plans.md
2. Editing billing-plans.md (Growth price -> $99) and re-uploading ...
3. Re-syncing the Knowledge Base (incremental):
     ingestion job <id>: COMPLETE. {... 'numberOfModifiedDocumentsIndexed': 1 ...}
4. Answer AFTER:  "... the Growth plan is $99 per month ..."  PROVEN.
5. Restoring the original price and re-syncing (repeatable lab).

Step 6 — tests, then tear down. The offline suite runs with no credentials: stubbed Retrieve / RetrieveAndGenerate, the hybrid+rerank wiring, decomposition, the four-way scoring, setup/teardown idempotency. The cumulative M2–M5 suite passed 78 passed, 4 skipped; the live marker (RELAY_LIVE_TESTS=1) ran 4 passed on a budgeted ≤5 real calls, and the whole lab cost $0.20 on June 2026 prices, the reranker fee the biggest line. uv run python teardown.py deletes the Knowledge Base, its data source, and the IAM role, and keeps the S3 Vectors indexes and docs bucket (Module 7’s agent retrieves from this KB). Nothing idle-billed remains.

Try it yourself. (1) Pass category="technical" to a billing question: the filter scopes retrieval to the technical docs, so you get back technical chunks — none of which answer the billing question — and the grounded answer comes back empty or refuses for lack of support. The multi-tenant filter made concrete: one customer’s docs stay out of another’s answers. (2) Time retrieve(..., rerank=False) against retrieve(..., rerank=True) on the same query, and decide whether the precision gain justifies the latency and per-query fee on docs this short, with the numbers, not a vibe.

In production

At lab scale the Knowledge Base is one data source and a handful of docs. In a real deployment, four things bite.

Multiple data sources and document permissions. A Knowledge Base can attach several data sources (S3, a wiki, a document-management system), and the moment it does, who can see which document becomes a security question. Metadata-based access filtering on each query keeps a restricted runbook out of a customer-facing answer.

Ingestion jobs fail silently. A job that errors on three of four hundred docs still reports a status, and your answers quietly lose those three docs. Monitor numberOfDocumentsFailed on every sync and alarm on it; a stale index is a wrong answer with a citation. (Module 14 wires this.)

Query cost at scale. S3 Vectors bills ~$0 idle and per-query (around $0.06/GB-month storage and $2.50 per million queries, as of June 2026, re-verify). The always-on cluster bills ~$174/month flat, so it only pays off above a steady, high query volume, or when you need hybrid search. That crossover is the exam’s scale question.

Metadata filtering is your multi-tenancy. One shared index with a tenant_id filter beats one index per customer on cost and ops. Module 9 will add a contextual grounding check on top of these citations.

Exam corner

What the exam tests here. This module covers D1’s managed-RAG skills: connecting documentary systems through integration components (1.4.4), maintaining vector stores with incremental sync and change detection (1.4.5), improving relevance with hybrid search and rerankers (1.5.4), transforming queries with expansion and decomposition (1.5.5), and the standardized access patterns (1.5.6). Chunking and embeddings, the other half of Tasks 1.4/1.5, are Module 4. Nothing below touches agents, guardrails, or evaluation.

Five scenario questions in the exam’s style; answers follow.

1. A small team must ship a cited-answer feature over a help center next week. They have no ops bandwidth, need answers with sources, and want the index to refresh when docs change — but do not need exotic chunking control. Which fits best? A. Build a custom retrieval pipeline so you control every chunk boundary. B. A managed Bedrock Knowledge Base with RetrieveAndGenerate and incremental sync. C. Fine-tune a model on the help center so it knows the docs. D. Put the whole help center in the system prompt on every request.

2. Answers about specific CloudCart error codes (like ERR-402) and exact plan names keep retrieving the wrong passage, while conceptual questions retrieve fine. What is the targeted fix? A. Increase top_k so more candidates come back. B. Add a reranker to reorder the semantic candidates. C. Use hybrid search so keyword matching pins the exact tokens. D. Switch to a higher-dimensional embedding model.

3. Retrieval returns the right document in the top-k, but it is ranked third and the generated answer leans on a weaker passage. You have a 200 ms latency budget to spend. Best move? A. Add a Bedrock reranker to re-score and reorder the candidates. B. Re-chunk the entire corpus. C. Double top_k and hope the right chunk ranks higher. D. Switch the vector store.

4. A help center is edited several times a day, and Relay’s answers cite stale prices. The corpus is large. Which keeps answers current at the lowest cost? A. Re-ingest the entire corpus on a nightly schedule. B. Run an ingestion job on change; incremental sync re-embeds only the changed docs. C. Lower the cache TTL on the answers. D. Switch from semantic to hybrid search.

5. Your application must impose its own system prompt and choose its own model per request, then attach tool context before generating. Which access pattern fits? A. RetrieveAndGenerate, because it returns turnkey citations. B. Retrieve, because you own the prompt, the model, and the generation step. C. Either — they are interchangeable. D. Neither — a Knowledge Base cannot support custom prompts.

Answers. 1 → B. No ops bandwidth, citations needed, auto-sync wanted, no special chunking control is the exact managed-KB case; a custom pipeline (A) is the product you are trying not to staff, and fine-tuning (C) cannot cite a source or refresh on a doc edit. 2 → C. Exact identifiers (error codes, plan names) are the hybrid-search case: keyword matching pins the literal token that semantic similarity blurs. A reranker (B) and a bigger k (A) only reorder what semantic retrieval already returned. (On S3 Vectors you would move to a hybrid-capable store to enable it.) 3 → A. The right doc is already in the candidates but ranked too low, exactly what a reranker fixes within a latency budget. Re-chunking (B) and switching stores (D) address coverage, not the problem here. 4 → B. Incremental sync re-embeds only changed docs, current answers at the lowest cost; a nightly full re-ingest (A) re-embeds everything, and caching (C) or hybrid (D) does not address freshness. 5 → B. Retrieve hands back raw passages so the app owns the prompt, the model, and the generation; RetrieveAndGenerate (A) manages those for you, the opposite requirement.

Traps to avoid.

  • Assuming a Knowledge Base requires an always-on serverless search cluster. That was the pre-2026 default and bills ~$174/month, 24/7; S3 Vectors (idle ~$0) is the economical choice — at the cost of hybrid search, which S3 Vectors does not support.
  • Believing a reranker improves recall. It reorders the candidates the retriever already returned; it never surfaces a new document. Coverage (hybrid, sync, chunking) comes first; the reranker only fixes order.
  • Confusing “citations present” with “grounding verified.” Citations say a source was attached; a contextual grounding check (Domain 3, Module 9) is a separate control that verifies the answer is actually supported.

Key takeaways

  • A Knowledge Base manages the pipeline, not your judgment — it parses, chunks, embeds, stores, and syncs; you still choose docs, chunking, store, and whether the answer is right.
  • Hybrid search is the remedy for exact tokens (SKUs, error codes, plan names) that pure semantic retrieval blurs — but it is a property of the vector store, and S3 Vectors does not support it.
  • A reranker buys precision, never recall — it reorders what came back; it cannot surface a missing chunk. Coverage first, order second.
  • Retrieve when you want control, RetrieveAndGenerate when you want turnkey citations — the pattern follows the need; Relay uses RAG now and switches to Retrieve for the agent.
  • Freshness is tested, not assumed — incremental sync re-embeds only changed docs (numberOfModifiedDocumentsIndexed: 1), and you prove it with a before/after answer.
  • “Citations present” is not “grounding verified” — the M5 grounded heuristic is bool(citations); the real contextual grounding check is Module 9, same field, different computation.
  • S3 Vectors idles at ~$0; the always-on cluster bills 24/7 — the store choice is mostly an economics decision, and it is the exam’s #1 RAG cost trap.

What’s next

Relay can answer from the docs, but real tickets do not arrive as clean strings. They arrive as messy emails with typos, forwarded threads, and screenshots of an error the customer cannot describe. Module 6 builds the intake pipeline that validates and normalizes raw email and chat, and reads images with a multimodal model, before the foundation model ever sees the ticket.

Want the full AIP-C01 question bank and the next module in your inbox? Subscribe here — it’s free, like everything in this series.

Links: Module 5 lab · ← Module 4 · Course index · Module 6 →

References