---
title: "Modular RAG: Swappable Components for Production Builds"
description: "Modular RAG: named modules with typed contracts, swappable components, no framework lock-in. The engineering posture that keeps RAG builds maintainable past month six."
source: "https://www.kensink.com/llm/rag/architectures/modular/"
canonical: "https://www.kensink.com/llm/rag/architectures/modular/"
---
★ Modular RAG Specialised pattern Eval-gated

MODULAR RAG · ENGINEERING POSTURE

# Modular RAG. Swappable parts, no framework lock-in.

Modular RAG is not a pattern, it is an engineering posture. Build the pipeline from named modules (retriever, fusion, reranker, generator, evaluator) so any one can be swapped without rewriting the rest. The default engineering posture for every Kensink RAG build.

TypeScript Direct LLM Eval pipelines

[Start a conversation →](https://www.kensink.com/contact) [All architectures →](https://www.kensink.com/llm/rag/architectures)

Best for

Every production build

Stack

Whatever the underlying pattern needs

Cost

Module-design overhead pays back twice

Risk

Over-modularisation on prototypes

\[AT A GLANCE\]

Best for: Any RAG build that is going to live past month six. Modular shape pays back the first time you need to swap a reranker or change the embedding model.

Origin

Industry consensus, 2024 onward

Year

2024-present

Complexity

Medium

Production stage

Mature

\[THE PIPELINE\]

## Each step is a named module with a typed contract.

The shape is the same as whatever underlying pattern (Naive, Advanced, Agentic) but every step is a named module with a typed input and output. The pipeline is composed; modules are swappable; tests are written at module boundaries.

01

### Define typed module interfaces

Retriever, fusion, reranker, generator, evaluator each get a typed contract. Inputs and outputs are explicit. Modules talk through these contracts, not through each other's internals.

02

### Implement against the interface

Each module has at least one implementation, often more (Cohere reranker, BGE reranker, no reranker). Production picks one; tests can run against several.

03

### Compose the pipeline

The pipeline is a small piece of glue that composes the modules. Adding a step or replacing one is a glue change, not a refactor.

\[TECHNICAL STACK\]

## What we'd actually deploy.

Stack is whatever the underlying pattern needs; what makes it modular is how the code is organised, not which technology is in use.

INTERFACE DEFINITIONS

### TypeScript types or Python protocols

Typed contracts at every module boundary. The interface is the unit of stability; implementations come and go.

DEPENDENCY INJECTION

### Constructor injection, no framework

Modules receive their dependencies through constructors. No service locator, no global registry, no dependency framework. Plain composition.

MODULE TESTING

### Per-module unit + integration

Each module has its own test suite at the interface level. Pipeline tests run end-to-end. Eval tests run quality against golden sets.

FEATURE FLAGGING

### Configuration per environment

Module choices configurable per environment so we can A/B a new reranker in staging without code changes.

\[HOW WE DEPLOY\]

## Day one to live traffic.

Modular RAG deploys the same as whatever pattern is underneath; the work is in how the code is organised so the patterns can be swapped.

1.  01
    
    ### Name the modules
    
    Retriever, reranker, generator, evaluator, etc. Names match the pattern in use; types match the data flow.
    
2.  02
    
    ### Define the contracts
    
    Each module's input and output types. Explicit, documented, versioned.
    
3.  03
    
    ### Implement and compose
    
    Concrete modules behind the contracts. Pipeline is glue.
    
4.  04
    
    ### Test at boundaries
    
    Unit tests at module interfaces, integration tests at the pipeline level, eval tests on golden sets.
    
5.  05
    
    ### Configure per environment
    
    Module choices flagged per environment so staging can run different shapes from production safely.
    

\[ ACCURACY + BENCHMARKS \]

## What the numbers say.

Modular RAG does not change accuracy; it changes the cost of changing the system. Pays back when the team needs to swap a component, which is almost always.

Same

Accuracy as the underlying pattern

1-2 days

Component swap effort

Months

Time saved on first migration

Maintainable

What this really buys

Our eval methodology

Modular RAG is evaluated by how cleanly the modules swap, not by accuracy. We measure component-swap cost (how long does it take to replace the reranker?) as a build-quality metric.

\[COMMUNITY FEEDBACK\]

## What practitioners report.

Modular RAG is the 2024+ industry consensus engineering posture. Every serious production RAG codebase converges on this shape, framework or not.

Practitioners report the same lesson: the patterns and components in 2026 are not the patterns and components in 2024. The reranker model changes. The embedding model changes. The vector DB might change. Builds that designed for swappable modules survive; builds that did not get rewritten. The posture is the win; the framework choice is secondary.

\[COMMON PITFALLS\]

-   Over-modularising prototypes. If we are not going to swap a component, we do not need an interface around it.
-   Module boundaries in the wrong places. The right boundaries are where data flow naturally splits.
-   Frameworks that hide the shape. We prefer plain composition; frameworks add abstraction we have to maintain through migrations.

\[KENSINK LABS EVALUATION\]

## Our honest take.

Every Kensink RAG build is modular. We do not advertise it as a feature because it is engineering hygiene, not a product. But it is the engineering posture that keeps RAG builds maintainable past month six.

We have rebuilt RAG systems for customers who shipped on a framework-heavy stack two years ago and got stuck on the migration tax. The pattern we keep recommending: plain composition, typed interfaces, no framework. Swap a reranker in an afternoon, not a quarter.

\[WHEN WE REACH FOR IT\]

-   Every production RAG build that is going to live past month six.
-   Any build the buyer will own and extend after handoff.

What we'd substitute

Not modular only on throwaway prototypes. Anything else, modular by default.

\[RELATED PATTERNS\]

## Worth a look next.

[Related pattern

### Advanced RAG

Modular Advanced RAG is what most production builds converge to.

Read playbook](https://www.kensink.com/llm/rag/architectures/advanced/) [Related pattern

### Agentic RAG

Per-source retrievers in agentic RAG are textbook modules.

Read playbook](https://www.kensink.com/llm/rag/architectures/agentic/) [Related pattern

### Naive RAG

Even naive RAG benefits from modular boundaries the moment you want to swap an embedding.

Read playbook](https://www.kensink.com/llm/rag/architectures/naive/)

\[COMMON QUESTIONS\]

## What buyers ask before they sign.

Is Modular RAG a framework?

No. It is a code-organisation posture. We use TypeScript types and constructor injection, no framework. The modular shape is the win; framework lock-in is the cost we avoid.

What about LangChain or LlamaIndex?

Frameworks have their place for prototypes. For production builds that need to outlive their first version of the underlying components, we prefer plain composition. The migration tax on framework-heavy stacks is the issue.

How much overhead does modularisation add?

Light if the boundaries are in the right places. Heavy if you over-modularise. The boundaries that pay back are: retriever, fusion, reranker, generator, evaluator. Anything finer-grained than that usually does not earn the build.

DIRECT RAG · APPLIED K

## Bring the corpus. We'll bring the build.

Senior engineers, eval suite at handoff, full source ownership. We integrate against the model and the index the same way we integrate against Postgres. Sized to the work in front of you.

[Start a conversation →](https://www.kensink.com/contact) [All RAG topics](https://www.kensink.com/llm/rag)
