May 13, 2026

RAG Architecture Patterns for Enterprise AI

Author-Yash Vibhandik

Yash Vibhandik

CEO

RAG Architecture Patterns for Enterprise AI

Key Takeaways

Naive RAG - embed, retrieve top-k, stuff into context - fails in production above 10,000 documents. Every Bitontree RAG deployment past that scale uses hybrid search plus reranking at minimum.

  • The five patterns that matter in 2026 are naive RAG, hybrid + rerank, agentic RAG, graph RAG, and multimodal RAG. Most enterprise systems land on pattern 2 or 3; pattern 4 wins for connected entities like contracts and case law.
  • In regulated knowledge-retrieval work (legal, clinical, finance), the stack that has held up across deployments is hybrid retrieval (BM25 + dense embeddings) with a Cohere reranker on top, plus an agentic verification step that catches retrieval failures before they reach the end user.
  • The biggest production wins came from evaluation infrastructure, not model upgrades. Without Ragas, TruLens, or a custom eval harness you cannot tell which retrieval change actually helped.

Most RAG systems fail not at retrieval but at evaluation - the team ships a demo that looks brilliant, then has no way to tell when it regresses. We have rebuilt three RAG deployments where the original team had no evaluation harness and no idea their retrieval was 40% wrong. The right rag architecture starts with the evaluation contract, not the embedding model. This guide walks through the five patterns that ship in production in 2026, the stack we use for each (Pinecone, Weaviate, pgvector, Cohere, Voyage, Qdrant, LangChain, LlamaIndex), the code we write to glue them together, and the honest tradeoffs between them. Every pattern below is in production at Bitontree across legal, healthcare, finance, or logistics workloads.

What Is RAG Architecture?

RAG architecture is the system design that lets a language model answer questions using information it was not trained on, by retrieving relevant context from an external store and injecting it into the prompt at inference time. The acronym - Retrieval-Augmented Generation - is the bare summary; for the conceptual foundation read our explainer on what retrieval-augmented generation is and how it works. In production, RAG is a pipeline of seven or more components: ingestion, chunking, embedding, indexing, retrieval, reranking, and generation.

The reason RAG exists is straightforward - fine-tuning a model on your knowledge base is expensive, slow to update, and impossible to audit. RAG keeps the model frozen and the knowledge external. Update a document, reindex it, and the next query sees the new content. This is non-negotiable for any system that touches regulated data: clinical records, contracts, financial filings, or audit trails.

The components of a production RAG pipeline:

1. Ingestion - pulling documents from S3, SharePoint, Google Drive, Confluence, or a database

2. Parsing - turning PDFs, docx, HTML, and emails into structured text plus metadata

3. Chunking - splitting documents into retrievable units (paragraph, section, or fixed-token)

4. Embedding - converting chunks to vectors using a model like Voyage 3, Cohere Embed v4, or OpenAI text-embedding-3-large

5. Indexing - storing vectors plus metadata in a vector database (Pinecone, Weaviate, Qdrant, or pgvector)

6. Retrieval - finding the top-k most relevant chunks for a query, often combining keyword (BM25) and vector search

7. Reranking - using a cross-encoder model like Cohere Rerank or BGE reranker to score the top-k more accurately

8. Generation - sending the reranked chunks plus the query to the LLM (GPT-4o, Claude Sonnet 4.5, Gemini 2.5 Pro)

Most teams obsess over step 4 (embeddings) and step 8 (the LLM), then discover their failure mode is in step 3 (chunking) or step 7 (reranking). The order of operations matters. The Bitontree default is to instrument the whole pipeline first, then optimize the component with the worst measured contribution to end-to-end quality.

The Four RAG Patterns That Ship in Production

Four RAG patterns cover 95% of production deployments - naive RAG, hybrid search with reranking, agentic RAG, graph RAG, and multimodal RAG. The right pattern depends on corpus size, query complexity, document structure, and whether the answers must cite specific sources. We pick the simplest pattern that meets the evaluation bar; complexity is a cost, not a virtue.

PatternUse WhenStack ExampleBitontree Use Case
Naive RAG< 5K docs, single domain, internal toolOpenAI embeddings + pgvector + GPT-4oInternal engineering wiki search
Hybrid + Rerank5K, 1M docs, regulated, citation requiredVoyage + Qdrant + BM25 + Cohere RerankLegal research, clinical knowledge
Agentic RAGComplex multi-hop questions, self-correction neededLangGraph + hybrid retrieval + verifierSales workflow research
Graph RAGConnected entities, relationships matterNeo4j + LlamaIndex + GPT-4oContract analysis, case law
Multimodal RAGDocuments with charts, diagrams, scansColPali + Qdrant + Claude Sonnet 4.5Insurance claims, medical imaging reports

The graduation path between patterns is well-defined. Almost every system starts at naive RAG for the prototype, moves to hybrid + rerank when retrieval quality plateaus, adds agentic verification when hallucinations become unacceptable, and reaches for graph or multimodal only when the document structure or relationships demand it. Reaching for graph RAG on day one is a common mistake - the operational complexity is high and the wins only show up on the right corpus.

Four RAG architecture patterns: naive, hybrid search with reranking, agentic and graph RAG, and the retrieval failure each fixes

Pattern 1: Naive RAG (Baseline Architecture)

Naive RAG is the simplest production RAG pattern - embed every chunk, store in a vector DB, retrieve the top-k for each query, send to the LLM. It works for corpora under 5,000 documents in a single domain. Above that scale, retrieval quality degrades because pure semantic similarity misses keyword matches, acronyms, and rare technical terms.

from openai import OpenAI
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct, VectorParams, Distance

client = OpenAI()
qdrant = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)

def embed(text: str) -> list[float]:
    return client.embeddings.create(
        model="text-embedding-3-large",
        input=text,
    ).data[0].embedding

def ingest(chunks: list[dict]):
    points = [
        PointStruct(
            id=chunk["id"],
            vector=embed(chunk["text"]),
            payload={"text": chunk["text"], "source": chunk["source"]},
        )
        for chunk in chunks
    ]
    qdrant.upsert(collection_name="docs", points=points)

def query(question: str, top_k: int = 5) -> str:
    results = qdrant.search(
        collection_name="docs",
        query_vector=embed(question),
        limit=top_k,
    )
    context = "\n\n".join(r.payload["text"] for r in results)
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": f"Answer using only:\n{context}"},
            {"role": "user", "content": question},
        ],
    )
    return response.choices[0].message.content

The honest assessment - this ships in a day, demos beautifully, and fails on three predictable inputs. Queries with rare terms ("our 2023 Q4 EBITDA adjustment") miss because semantic similarity does not weight rarity. Queries with multiple sub-questions return chunks for the first sub-question only. Queries that need data from two different documents pull two chunks from the same document because they cluster tightly in embedding space.

Naive RAG is the right starting point. It is not the right ending point for any system that goes into production with users who will notice the failures.

Pattern 2: Hybrid Search with Reranking

Hybrid retrieval combines keyword search (BM25) and dense vector search, then reranks the merged result set with a cross-encoder model. This is the production default at Bitontree for any RAG system with more than 5,000 documents or regulated content. The pattern fixes the three failure modes of naive RAG and adds a 15-30% measured improvement in retrieval precision in every deployment where we have run it head-to-head.See our RAG development services for how this pattern ships across legal, healthcare, and finance deployments. Anthropic's Contextual Retrieval research documented a 49% reduction in retrieval failures by combining BM25, embeddings, and contextual chunking - the same compound architecture this pattern uses.

The pipeline runs three retrieval passes in parallel and merges:

1. BM25 search over a Lucene index (Elasticsearch, OpenSearch, or Tantivy) retrieves top 50 by lexical match

2. Dense vector search over the same chunks retrieves top 50 by semantic similarity

3. Result fusion combines both lists using Reciprocal Rank Fusion (RRF) into a single top-30

4. Cross-encoder reranking with Cohere Rerank v4 or BGE reranker re-scores the top-30 and returns top-5

5. Generation sends the top-5 to the LLM with a strict citation requirement in the prompt

import cohere
from rank_bm25 import BM25Okapi

co = cohere.Client(COHERE_API_KEY)

def hybrid_retrieve(question: str, top_k: int = 5) -> list[dict]:
    dense_results = qdrant.search(
        collection_name="docs",
        query_vector=embed(question),
        limit=50,
    )
    tokenized_query = question.lower().split()
    bm25_scores = bm25.get_scores(tokenized_query)
    bm25_top = sorted(enumerate(bm25_scores), key=lambda x: -x[1])[:50]

    fused = reciprocal_rank_fusion(dense_results, bm25_top)

    rerank_response = co.rerank(
        model="rerank-v3.5",
        query=question,
        documents=[doc["text"] for doc in fused[:30]],
        top_n=top_k,
    )
    return [fused[r.index] for r in rerank_response.results]

The reranker is the single highest-ROI component we add to RAG systems. In a legal research deployment we shipped, adding a Cohere reranker on top of the existing dense retrieval moved precision@5 from 0.62 to 0.84 on the evaluation set. That improvement is what made the system useful to lawyers - once the top-5 contains the right authority 84% of the time, the model stops fabricating case law because it always has something correct to ground on.

Related: Top RAG Use Cases Delivering Real Business Value in 2026 - the use-case patterns where this exact reranker pipeline pays back its cost within the first month.

The cost dimension: rerankers add ~$0.001 per query and 100-300ms of latency. In every regulated deployment we have shipped, that cost is trivial against the value of correct answers.

Pattern 3: Agentic RAG with Self-Correction

Agentic RAG wraps the retrieval pipeline in a LangGraph agent that judges its own retrieval quality and re-queries when the initial results are insufficient. The pattern matters for multi-hop questions ("Compare the termination clauses in vendor contracts A and B"), questions with implicit sub-questions, and any high-stakes workflow where a wrong answer is worse than no answer.

The agent runs four nodes in a loop:

1. Decompose - break the user's question into sub-questions if it has multiple parts

2. Retrieve - run hybrid retrieval for each sub-question

3. Grade - a separate LLM call grades whether the retrieved chunks actually contain the answer

4. Decide - route to "generate" if grade is high, "re-query with refined terms" if grade is medium, "escalate" if low

We use a Pydantic schema for the grader output to keep it auditable:

from pydantic import BaseModel, Field
from typing import Literal

class RetrievalGrade(BaseModel):
    relevant: bool
    confidence: float = Field(ge=0, le=1)
    missing_info: str | None = None
    suggested_query: str | None = None

def grade_retrieval(question: str, chunks: list[str]) -> RetrievalGrade:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": GRADER_PROMPT},
            {"role": "user", "content": f"Q: {question}\n\nChunks:\n{chunks}"},
        ],
        response_format={"type": "json_object"},
    )
    return RetrievalGrade.model_validate_json(response.choices[0].message.content)

The agentic layer catches a specific failure class: the retrieval returns plausible-looking but incorrect chunks, and a naive RAG system would generate a confident wrong answer. The grader flags the mismatch, the agent re-queries with refined terms, and the lawyer or analyst sees an "insufficient context" response instead of fabricated case law.

The cost - agentic RAG runs 2-4x more model calls per query than naive RAG. The latency goes from 1-2 seconds to 4-8 seconds. We only use this pattern when the cost of a wrong answer exceeds the cost of latency. For legal research and clinical knowledge, that math is easy. For an internal engineering wiki, it is overkill.

Related: AI Workflow Automation Tool - RAG inside a production agent - a deployment where this agentic-RAG pattern lives inside a wider workflow that classifies, retrieves, verifies, and routes inside a single graph.

Pattern 4: Graph RAG for Connected Knowledge

Graph RAG indexes documents as a knowledge graph - entities and relationships rather than free text - and retrieves by traversing the graph plus matching vectors. The pattern wins when the answer requires connecting facts across documents: "Which of our suppliers signed the new compliance clause and also had a delivery delay in Q3?" Naive RAG cannot answer this because the two facts live in two unrelated documents.

The stack - Neo4j or Memgraph for the graph store, LlamaIndex or Microsoft GraphRAG for the entity extraction and graph construction, plus a vector index for hybrid retrieval. Ingestion is more expensive: each document is parsed twice - once for vector chunks and once for entity extraction. Construction time for a 10,000-document corpus runs 4-8 hours on commodity hardware.

The query path:

1. Extract entities from the question using a prompt or an NER model

2. Traverse the graph from those entities to find connected nodes and edges

3. Retrieve text chunks anchored to the relevant nodes

4. Combine the structured graph context and unstructured text in the LLM prompt

Graph RAG produces measurably better answers on connected-entity questions - Microsoft's published benchmark in 2024 showed 30-90% improvements on multi-document QA tasks, and our internal evaluation on legal contract analysis showed a similar pattern. The cost is operational complexity: a graph store to maintain, entity extraction quality to monitor, and a more complex query path to debug.The benchmark methodology and results are documented in the GraphRAG paper by Edge et al. (2024).

We recommend graph RAG when three conditions hold simultaneously:

  • The corpus has rich entity relationships (contracts, case law, organizational structures, supply chains)
  • Users ask multi-hop questions that span multiple documents
  • The team has the operational maturity to run a graph database in production

Two out of three is not enough. A common mistake is to choose graph RAG because the corpus has entities, even though users only ask single-document questions. The added complexity costs more than the marginal answer quality gain.

Choosing Embedding Models, Vector Databases, and LLMs

The model and infrastructure choices matter less than the pattern, but they still matter. The 2026 defaults at Bitontree are Voyage 3 or Cohere Embed v4 for embeddings, Qdrant or pgvector for the vector store, and Claude Sonnet 4.5 or GPT-4o for generation. None of these is the only right answer, but each has a specific reason.

Embedding models - Voyage 3 leads on the MTEB benchmark as of early 2026 and handles long context (32K tokens). Cohere Embed v4 is close behind and ships with a paired reranker that integrates cleanly. OpenAI text-embedding-3-large is the easy default if you are already on OpenAI; it is competitive but not the leader. For domain-specific corpora (medical, legal, code), a fine-tuned BGE or a domain-trained Voyage model can outperform general embeddings by 5-15%.

Vector databases - Qdrant for greenfield deployments; the open-source story, hybrid search, and metadata filtering are production-grade. Pinecone for managed simplicity when the team does not want to run infrastructure. pgvector for teams already on Postgres who want to keep their stack small (a real consideration; one fewer service to monitor). Weaviate for projects that need built-in modules for embedding and reranking. Avoid Chroma for production at scale - it is excellent for prototypes, not for multi-tenant production.

LLMs for generation - Claude Sonnet 4.5 for any workflow with citation requirements or long context (200K windows handle multi-document synthesis without aggressive chunking). GPT-4o for general-purpose generation where speed matters. Gemini 2.5 Pro for multimodal RAG with images and tables. Open-weight options (Llama 3.3 70B, Mistral Large) served on Together or Fireworks make sense when data residency or per-token cost is a hard constraint.

The decision matrix we use on every project:

  • Regulated industry? - Anthropic Claude (BAA available) or Azure OpenAI
  • Long-context synthesis? - Claude Sonnet 4.5
  • Strict latency? - Gemini 2.5 Flash or GPT-4o-mini
  • Self-hosted required? - Llama 3.3 70B on vLLM
  • Multimodal documents? - Claude Sonnet 4.5 or Gemini 2.5 Pro

How Do You Evaluate RAG Quality in Production?

You evaluate RAG with an offline test set plus online quality monitoring - and you do this before tuning anything. The single biggest mistake in RAG deployments is shipping without an evaluation harness. Without one, every change is a guess and every regression goes unnoticed. The standard Bitontree evaluation stack is Ragas for retrieval metrics, TruLens or a custom harness for end-to-end faithfulness scoring, and a labeled question set built with the domain SMEs.

The four metrics we track for every RAG system:

MetricWhat It MeasuresTarget
Context precisionAre retrieved chunks relevant?> 0.80
Context recallDid we retrieve everything needed?> 0.85
FaithfulnessDoes the answer match the retrieved chunks?> 0.90
Answer relevanceDoes the answer address the question?> 0.85

Faithfulness is the safety metric. It measures whether the LLM hallucinated facts not present in the retrieved chunks. In every deployment where we run faithfulness scoring continuously, we catch model drift within days of it happening - usually triggered by a new release of the underlying LLM.

Online monitoring uses a sampling-based eval. We score 5-10% of production queries with Ragas faithfulness, log the score, and alert when the rolling 7-day average drops more than 0.05. This is the closest analog to APM for RAG - it catches regressions before users do.The Ragas official documentation covers the faithfulness, context precision, context recall, and answer relevance metrics in detail.

Build the evaluation set from real questions, not synthetic ones. Have domain experts label 200-500 question/answer pairs from the actual workload. Synthetic evaluation sets miss the long-tail queries that production systems must handle.

Production Lessons from Real Deployments

Three lessons from shipping RAG systems at Bitontree across legal, healthcare, and finance - chunking matters more than embedding choice, metadata filters do more work than vector search, and ingestion pipelines break more often than retrieval.

Chunking strategy does more work than embedding choice: We tested four chunking strategies on the legal corpus - fixed 512-token, semantic (sentence-aware), structural (section-aware), and hierarchical (parent-child). Structural chunking - splitting on document headers and preserving section context - beat the others by 12% on retrieval precision. The embedding model swap from OpenAI to Voyage 3 added another 4%. Chunking did three times the work.

Metadata filters are underrated: Every chunk should carry metadata - document type, date, author, jurisdiction, status, version. Filter on these fields before vector search, not after. A legal research query for "California employment law 2023" should filter by jurisdiction=CA and year=2023 first, then run vector search on the remaining 200 chunks instead of the full 200,000. Filter-then-search cuts latency by 60-80% and improves precision.

Ingestion pipelines fail silently: A PDF parser that worked for 100 documents during testing will fail on the 1,000th document because the source produced a malformed PDF. A new SharePoint folder gets created and the ingestion job does not pick it up because the discovery query was wrong. Build observability on ingestion: count documents in, count chunks out, count embedding API errors, alert on anomalies. Half the production "model is bad" incidents we have debugged were ingestion incidents.

Where to Start With RAG Architecture

The pattern we recommend to every team starting on RAG - build the evaluation harness before the prototype, ship naive RAG, measure the failure modes, then add hybrid retrieval and reranking as the data justifies it. Most teams skip the evaluation step and ship a system they cannot debug. If you are designing a rag architecture for regulated or high-stakes workflows and want a second opinion on the pipeline, Book a Free AI Fit Assessment and we will tell you which RAG pattern fits your corpus and which components to skip.

Thank you for reading!
author

I am the founder and CEO of Bitontree, where I lead embedded AI engineering teams that build and run production AI: agents, RAG and knowledge systems, document AI, and workflow automation for healthcare, logistics, legal, and SaaS companies. I write about what it actually takes to ship AI that survives contact with production.

Frequently Asked Questions

What is a RAG architecture pattern?

A RAG architecture pattern is a repeatable system design for retrieval-augmented generation, defining how documents are ingested, indexed, retrieved, and passed to a language model. Each pattern makes a different tradeoff between retrieval quality, latency, and operational complexity. The five patterns that cover most production deployments are naive RAG, hybrid search with reranking, agentic RAG, graph RAG, and multimodal RAG. You pick a pattern based on corpus size, query complexity, document structure, and whether answers must cite specific sources.

What is the RAG design pattern?

The RAG design pattern keeps the language model frozen and the knowledge external, so you update a document, reindex it, and the next query sees the new content. This avoids the cost, slow update cycle, and audit difficulty of fine-tuning a model on your knowledge base. In its production form, the pattern is a pipeline of eight stages: ingestion, parsing, chunking, embedding, indexing, retrieval, reranking, and generation. The design goal is auditable, updatable answers grounded in retrieved source text.

What is RAG architecture?

RAG architecture is the system design that lets a language model answer questions using external knowledge by retrieving relevant context at inference time and injecting it into the prompt. A production RAG pipeline has eight components: ingestion, parsing, chunking, embedding, indexing, retrieval, reranking, and generation. The full stack matters more than any single component, and teams that obsess over the embedding model often find their real failure is in chunking or reranking.

What is the difference between naive RAG and advanced RAG patterns?

Naive RAG embeds chunks, retrieves the top-k by vector similarity, and sends them to the LLM. Advanced RAG patterns add hybrid retrieval (BM25 + dense), cross-encoder reranking, query rewriting, and often an agentic verification layer. The performance gap shows up above 5,000 documents, where naive RAG plateaus and advanced patterns keep scaling. Naive RAG is the right place to start a prototype, not the right place to end for a system real users depend on.

Which RAG pattern should I use?

Start with the simplest pattern that meets your evaluation bar, then graduate as the data justifies it. Use naive RAG for a prototype or an internal tool under 5,000 documents. Move to hybrid search with reranking once retrieval quality plateaus or the content is regulated and citations are required. Add agentic RAG when confident wrong answers become unacceptable, and reach for graph or multimodal RAG only when connected entities or non-text documents demand it. Complexity is a cost, not a virtue.

When should I use hybrid search instead of pure vector search?

Use hybrid search whenever the corpus contains rare terms, acronyms, product names, or technical vocabulary that semantic embeddings underweight. Production legal, medical, and engineering RAG systems almost always need hybrid retrieval. The cost is small - BM25 indexes are cheap to maintain - and the precision lift is 15-30% in most deployments we have measured.

What is the best vector database for production RAG?

Qdrant for greenfield deployments, Pinecone for managed simplicity, pgvector for teams already on Postgres. All three handle production scale. The right choice depends on operational constraints - self-hosted vs managed, hybrid search needs, and existing infrastructure - not benchmark differences. Chroma is excellent for prototypes but not recommended for production at scale.

How do I measure RAG quality?

Use a labeled evaluation set with Ragas or TruLens scoring four metrics: context precision, context recall, faithfulness, and answer relevance. Build the evaluation set from real domain questions labeled by experts. Run it after every change to the pipeline, and sample 5-10% of production queries for online faithfulness scoring to catch regressions.

Is RAG better than fine-tuning?

For knowledge update problems, RAG wins because you can update the knowledge base without retraining. For style or format problems (matching a brand voice, structured output), fine-tuning wins. The two are complementary. We sometimes ship a fine-tuned model for output format plus RAG for knowledge - they do not compete in production.

How do I prevent hallucinations in a RAG system?

Three layers - strict prompts that require citations to the retrieved chunks, a faithfulness evaluator that scores answer-to-context alignment, and an agentic verification step that re-retrieves when faithfulness drops. The prompt alone cuts hallucinations by 60-70%; adding the verifier gets you to 90%+. Zero hallucinations is not achievable; high-confidence detection is.

What is the Graph RAG pattern and when should I use it?

Graph RAG indexes documents as a knowledge graph of entities and relationships, then retrieves by traversing the graph plus matching vectors. Use it when the corpus has rich entity relationships and users ask multi-hop questions spanning multiple documents. Contracts, case law, and organizational data are good fits. Single-document QA is not, and the operational cost of running a graph store rarely pays back on a corpus that only needs vector search.

What are multimodal RAG patterns?

Multimodal RAG patterns retrieve and reason over documents that mix text with charts, diagrams, tables, and scanned images, not just plain text. Instead of relying on text extraction that loses layout, the pattern embeds page images directly using a model like ColPali, stores them in a vector database such as Qdrant, and sends the matched pages to a vision-capable LLM like Claude Sonnet 4.5. This fits documents where the visual layout carries meaning, such as insurance claims and medical imaging reports. Use it when text-only parsing keeps dropping information the answer depends on.

What does an enterprise RAG architecture look like?

An enterprise RAG architecture combines hybrid retrieval (BM25 plus dense embeddings), a cross-encoder reranker such as Cohere Rerank, and an agentic verification step that catches retrieval failures before they reach the user. It runs on an evaluation harness first, because most enterprise RAG systems fail at evaluation rather than retrieval: the demo looks brilliant, then quietly regresses with no way to tell. Metadata filtering, ingestion observability, and continuous faithfulness scoring hold the system together in regulated domains like legal, clinical, and finance. The pattern is HIPAA-aware and SOC 2-aware in how it handles data, and the whole thing starts with the evaluation contract, not the embedding model.

What does a RAG system cost to run in production?

Cost depends on query volume, embedding cost, vector database hosting, and LLM tokens, and the LLM is almost always the largest line item, on the order of 60 to 80 percent of the total. The vector database is a smaller recurring hosting cost that scales with index size, and embeddings are mostly a one-time cost with cheaper incremental updates as content changes. Because the model dominates, the biggest cost lever is retrieving tightly so you send less into each prompt, not switching vector databases. We size this against your real query volume during scoping.

Which RAG pattern fits your corpus?

Send us your corpus and use case. We'll recommend the pattern that ships, and call out the components you can skip.