<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AddWeb Solution Pvt Ltd</title>
    <description>The latest articles on DEV Community by AddWeb Solution Pvt Ltd (addwebsolutionpvtltd).</description>
    <link>https://dev.to/addwebsolutionpvtltd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F11063%2F0b7a4ce4-43ab-4718-abd0-1d314bc88f99.png</url>
      <title>DEV Community: AddWeb Solution Pvt Ltd</title>
      <link>https://dev.to/addwebsolutionpvtltd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/addwebsolutionpvtltd"/>
    <language>en</language>
    <item>
      <title>LangGraph: A Framework for Building Production-Ready AI Agents</title>
      <dc:creator>Manthan Prajapati</dc:creator>
      <pubDate>Fri, 06 Nov 2026 12:45:58 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/langgraph-a-framework-for-building-production-ready-ai-agents-200i</link>
      <guid>https://dev.to/addwebsolutionpvtltd/langgraph-a-framework-for-building-production-ready-ai-agents-200i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Build resilient agents.” - LangGraph / LangChain&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Artificial intelligence applications are moving beyond simple question-and-answer interactions. Modern AI systems increasingly need to reason through multiple steps, use tools, maintain context, recover from failures, interact with humans, and make decisions dynamically.&lt;/p&gt;

&lt;p&gt;This is where LangGraph becomes particularly useful.&lt;/p&gt;

&lt;p&gt;LangGraph is an open-source, low-level orchestration framework from the LangChain ecosystem for building stateful, long-running AI agents and workflows. Instead of treating an AI application as a single prompt sent to an LLM, LangGraph allows developers to model an application as a graph of states, nodes, and transitions.&lt;/p&gt;

&lt;p&gt;Its architecture is particularly useful when an application needs explicit control over execution, persistence, human approval, retries, memory, and complex multi-step workflows.&lt;/p&gt;

&lt;p&gt;LangGraph's official documentation describes it as a low-level orchestration framework for building, managing, and deploying long-running, stateful agents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/" rel="noopener noreferrer"&gt;LangGraph official documentation&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;LangGraph is a low-level orchestration framework designed for stateful, long-running AI agents and workflows.&lt;/li&gt;
&lt;li&gt;It represents application logic as a graph of nodes and transitions, making complex workflows easier to control.&lt;/li&gt;
&lt;li&gt;LangGraph provides infrastructure for durable execution, persistence, memory, streaming, and human-in-the-loop workflows.&lt;/li&gt;
&lt;li&gt;Developers can create workflows that contain loops, conditional routing, retries, parallel execution, and multiple agents.&lt;/li&gt;
&lt;li&gt;Its checkpointing mechanism allows applications to save and resume state instead of starting an execution from scratch.&lt;/li&gt;
&lt;li&gt;LangGraph can be used with LangChain, but LangChain is not required.&lt;/li&gt;
&lt;li&gt;LangGraph is especially useful when developers need more control than a simple pre-built agent abstraction provides.&lt;/li&gt;
&lt;li&gt;LangGraph supports both Python and JavaScript/TypeScript ecosystems.&lt;/li&gt;
&lt;li&gt;Its graph-based approach makes it suitable for applications such as AI automation, research agents, coding agents, customer-support workflows, document processing, and multi-agent systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What Is LangGraph?&lt;/li&gt;
&lt;li&gt;Why Do We Need LangGraph?&lt;/li&gt;
&lt;li&gt;How LangGraph Works&lt;/li&gt;
&lt;li&gt;Core Concepts of LangGraph&lt;/li&gt;
&lt;li&gt;Nodes, Edges, and State&lt;/li&gt;
&lt;li&gt;Persistence and Checkpointing&lt;/li&gt;
&lt;li&gt;Human-in-the-Loop Workflows&lt;/li&gt;
&lt;li&gt;Memory in LangGraph&lt;/li&gt;
&lt;li&gt;Conditional Routing and Loops&lt;/li&gt;
&lt;li&gt;Multi-Agent Workflows&lt;/li&gt;
&lt;li&gt;LangGraph vs. LangChain&lt;/li&gt;
&lt;li&gt;Building a Simple LangGraph Application&lt;/li&gt;
&lt;li&gt;Real-World Use Cases&lt;/li&gt;
&lt;li&gt;Advantages of LangGraph&lt;/li&gt;
&lt;li&gt;Challenges and Considerations&lt;/li&gt;
&lt;li&gt;Statistics&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  1. What Is LangGraph?
&lt;/h2&gt;

&lt;p&gt;LangGraph is an open-source framework created by LangChain for orchestrating stateful and long-running AI applications.&lt;br&gt;
Rather than forcing developers to implement an AI application as one linear sequence, LangGraph allows them to represent the application as a graph.&lt;/p&gt;

&lt;p&gt;A graph can contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nodes - individual operations or steps&lt;/li&gt;
&lt;li&gt;Edges - connections between steps&lt;/li&gt;
&lt;li&gt;State - information shared throughout the workflow&lt;/li&gt;
&lt;li&gt;Conditional edges - decisions about where execution should go next&lt;/li&gt;
&lt;li&gt;Checkpoints - saved versions of application state&lt;/li&gt;
&lt;li&gt;Interruptions - opportunities for human intervention&lt;/li&gt;
&lt;li&gt;Loops - repeated reasoning or processing&lt;/li&gt;
&lt;li&gt;Subgraphs - smaller workflows embedded within larger workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The official LangGraph reference describes it as a framework providing infrastructure for durable execution, streaming, human-in-the-loop interactions, persistence, and memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reference.langchain.com/python/langgraph/" rel="noopener noreferrer"&gt;LangGraph Python Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important idea is that LangGraph is not simply an LLM wrapper.&lt;br&gt;
It is an orchestration layer for applications in which an LLM is one component of a larger workflow.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Why Do We Need LangGraph?
&lt;/h2&gt;

&lt;p&gt;A basic LLM application can often be represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  ↓
Prompt
  ↓
LLM
  ↓
Response
This works well for simple applications.
However, production AI systems often look more like this:
User Request
     ↓
Understand Request
     ↓
Search Knowledge
     ↓
Call Tool
     ↓
Analyze Result
     ↓
Need More Information?
   ↙           ↘
 Yes           No
 ↓              ↓
Search Again   Generate Answer
 ↓
Validate
 ↓
Human Approval?
   ↙       ↘
 Yes       No
 ↓          ↓
Execute    Stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A traditional chain can become difficult to manage when the workflow contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;branching&lt;/li&gt;
&lt;li&gt;loops&lt;/li&gt;
&lt;li&gt;retries&lt;/li&gt;
&lt;li&gt;tool calls&lt;/li&gt;
&lt;li&gt;human approval&lt;/li&gt;
&lt;li&gt;persistent state&lt;/li&gt;
&lt;li&gt;multiple agents&lt;/li&gt;
&lt;li&gt;long-running tasks&lt;/li&gt;
&lt;li&gt;failure recovery
LangGraph addresses these requirements by allowing developers to explicitly model the workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“Balance agent control with agency.” - LangGraph&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This reflects one of the central ideas behind LangGraph: AI agents can have autonomy while developers retain control over the application's execution.&lt;/p&gt;

&lt;p&gt;LangGraph official product page&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How LangGraph Works
&lt;/h2&gt;

&lt;p&gt;At a high level, LangGraph applications can be visualized as a directed graph.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ┌─────────────┐
                  │    Start      │
                  └──────┬──────┘
                         ↓
                ┌─────────────────┐
                │ Analyze Request    │
                └────────┬────────┘
                         ↓
                  ┌─────────────┐
                  │  Need Tool?   │
                  └──────┬──────┘
                     Yes │ No
                         │
             ┌───────────┘
             ↓
      ┌───────────────┐
      │ Execute Tool     │
      └───────┬───────┘
              ↓
      ┌───────────────┐
      │ Validate Data    │
      └───────┬───────┘
              │
              └──────────────┐
                             ↓
                    ┌────────────────┐
                    │ Generate Result   │
                    └───────┬────────┘
                            ↓
                         Finish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every node can read from and update the shared state.&lt;br&gt;
The graph determines what happens next.&lt;/p&gt;

&lt;p&gt;This separation between state, processing steps, and routing logic is one of the reasons LangGraph is useful for complex agent architectures.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Core Concepts of LangGraph
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;State represents the information currently available to the workflow.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;tool_result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the workflow progresses, nodes can read and modify this state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A node represents an individual operation.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;analyze_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Request analyzed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A node might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call an LLM&lt;/li&gt;
&lt;li&gt;call an API&lt;/li&gt;
&lt;li&gt;query a database&lt;/li&gt;
&lt;li&gt;execute a tool&lt;/li&gt;
&lt;li&gt;validate information&lt;/li&gt;
&lt;li&gt;ask for human approval&lt;/li&gt;
&lt;li&gt;transform data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Edges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edges determine what happens after a node completes.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze
   ↓
Search
   ↓
Generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conditional edges make workflows more dynamic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dot"&gt;&lt;code&gt;         &lt;span class="nv"&gt;Analyze&lt;/span&gt;
                &lt;span class="err"&gt;↓&lt;/span&gt;
         &lt;span class="err"&gt;┌──────┴──────┐&lt;/span&gt;
         &lt;span class="err"&gt;↓&lt;/span&gt;             &lt;span class="err"&gt;↓&lt;/span&gt;
      &lt;span class="nv"&gt;Search&lt;/span&gt;        &lt;span class="nv"&gt;Generate&lt;/span&gt;
         &lt;span class="err"&gt;↓&lt;/span&gt;
      &lt;span class="nv"&gt;Validate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Nodes, Edges, and State
&lt;/h2&gt;

&lt;p&gt;The combination of nodes, edges, and state creates the core programming model.&lt;/p&gt;

&lt;p&gt;Consider a customer-support agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Customer Message
                     ↓
               Classify Issue
                     ↓
          ┌──────────┴──────────┐
          ↓                     ↓
       Billing               Technical
          ↓                     ↓
    Billing Agent         Technical Agent
          ↓                     ↓
          └──────────┬──────────┘
                     ↓
               Human Review
                     ↓
                Send Reply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The state can contain:&lt;br&gt;
customer_message&lt;br&gt;
issue_type&lt;br&gt;
customer_id&lt;br&gt;
search_results&lt;br&gt;
draft_response&lt;br&gt;
approval_status&lt;br&gt;
final_response&lt;/p&gt;

&lt;p&gt;This makes the workflow explicit instead of hiding the entire process inside a single prompt.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Persistence and Checkpointing
&lt;/h2&gt;

&lt;p&gt;One of LangGraph's important capabilities is checkpointing.&lt;/p&gt;

&lt;p&gt;A checkpoint represents a saved snapshot of graph state.&lt;/p&gt;

&lt;p&gt;This becomes valuable when a workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;takes a long time&lt;/li&gt;
&lt;li&gt;needs human approval&lt;/li&gt;
&lt;li&gt;encounters a temporary failure&lt;/li&gt;
&lt;li&gt;needs to resume later&lt;/li&gt;
&lt;li&gt;needs conversation memory&lt;/li&gt;
&lt;li&gt;needs recovery from an intermediate state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1 → Step 2 → Step 3 → Step 4
                    ↓
               Checkpoint
                    ↓
                 Failure
                    ↓
              Resume Here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of restarting the entire workflow, the application can resume from saved state.&lt;/p&gt;

&lt;p&gt;LangGraph's checkpoint system is specifically designed to support persistence, human-in-the-loop workflows, memory, and durable execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reference.langchain.com/python/langgraph.checkpoint" rel="noopener noreferrer"&gt;LangGraph Checkpoint Reference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The LangGraph team describes persistence as a core part of enabling human-agent collaboration because a graph can be paused and later resumed from its stored state.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Every step of the graph, it reads from and then writes to a checkpoint of that graph state.” - LangChain&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7. Human-in-the-Loop Workflows
&lt;/h2&gt;

&lt;p&gt;Not every AI action should happen automatically.&lt;br&gt;
Consider an AI system that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send an email&lt;/li&gt;
&lt;li&gt;approve a refund&lt;/li&gt;
&lt;li&gt;modify a database&lt;/li&gt;
&lt;li&gt;deploy code&lt;/li&gt;
&lt;li&gt;make a financial transaction&lt;/li&gt;
&lt;li&gt;publish content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A human may need to approve the action first.&lt;/p&gt;

&lt;p&gt;LangGraph allows a workflow to pause before executing a sensitive action.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI analyzes request
       ↓
AI prepares action
       ↓
Human approval
    ↙       ↘
 Reject     Approve
   ↓          ↓
 Stop       Execute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes human-in-the-loop workflows a first-class part of the architecture rather than something developers have to build entirely from scratch.&lt;/p&gt;

&lt;p&gt;LangGraph's official documentation includes patterns for approval, interruption, streaming, subgraphs, retries, and tool integration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.langchain.com/blog/making-it-easier-to-build-human-in-the-loop-agents-with-interrupt" rel="noopener noreferrer"&gt;LangChain: Human-in-the-loop with interrupt&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Memory in LangGraph
&lt;/h2&gt;

&lt;p&gt;AI agents often need memory.&lt;/p&gt;

&lt;p&gt;For example, a customer-support agent might need to remember:&lt;/p&gt;

&lt;p&gt;Customer:&lt;br&gt;
    Name&lt;br&gt;
    Account&lt;br&gt;
    Previous issues&lt;br&gt;
    Preferences&lt;br&gt;
    Previous conversations&lt;/p&gt;

&lt;p&gt;LangGraph separates workflow state from longer-term persistence mechanisms.&lt;/p&gt;

&lt;p&gt;Checkpointing can maintain state across interactions, while storage mechanisms can be used for longer-term information.&lt;/p&gt;

&lt;p&gt;This makes it possible to build agents that do more than remember the current prompt.&lt;/p&gt;

&lt;p&gt;They can maintain context across multiple interactions and workflow executions.&lt;/p&gt;
&lt;h2&gt;
  
  
  9. Conditional Routing and Loops
&lt;/h2&gt;

&lt;p&gt;Traditional application workflows are often linear.&lt;/p&gt;

&lt;p&gt;AI agents are not necessarily linear.&lt;/p&gt;

&lt;p&gt;An agent may need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analyze a problem.&lt;/li&gt;
&lt;li&gt;Search for information.&lt;/li&gt;
&lt;li&gt;Evaluate the result.&lt;/li&gt;
&lt;li&gt;Decide that more information is required.&lt;/li&gt;
&lt;li&gt;Search again.&lt;/li&gt;
&lt;li&gt;Validate the final answer.&lt;/li&gt;
&lt;li&gt;Return the response.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That creates a loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze
   ↓
Search
   ↓
Evaluate
   ↓
Enough Information?
   ↓
  No ───────→ Search
   │
  Yes
   ↓
Generate Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangGraph's graph structure naturally supports this type of routing.&lt;br&gt;
This is particularly useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;research agents&lt;/li&gt;
&lt;li&gt;coding agents&lt;/li&gt;
&lt;li&gt;planning agents&lt;/li&gt;
&lt;li&gt;data-analysis agents&lt;/li&gt;
&lt;li&gt;RAG systems&lt;/li&gt;
&lt;li&gt;autonomous workflows&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  10. Multi-Agent Workflows
&lt;/h2&gt;

&lt;p&gt;LangGraph can also be used to coordinate multiple specialized agents.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     Manager Agent
                            ↓
          ┌──────────────┼──────────────┐
          ↓                 ↓                ↓
      Researcher           Coder          Reviewer
          ↓                 ↓                ↓
          └──────────────┼──────────────┘
                            ↓
                       Final Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each agent can have a specific responsibility.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Research Agent&lt;/strong&gt;&lt;br&gt;
Finds and summarizes information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coding Agent&lt;/strong&gt;&lt;br&gt;
Creates or modifies code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing Agent&lt;/strong&gt;&lt;br&gt;
Runs tests and identifies problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review Agent&lt;/strong&gt;&lt;br&gt;
Evaluates the output.&lt;/p&gt;

&lt;p&gt;This architecture can be particularly useful for complex software-development and automation workflows.&lt;/p&gt;
&lt;h2&gt;
  
  
  11. LangGraph vs. LangChain
&lt;/h2&gt;

&lt;p&gt;LangGraph and LangChain are closely related, but they solve different problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4fnt8wgk4kfx261qg7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4fnt8wgk4kfx261qg7q.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The official documentation recommends LangGraph when developers need advanced control, deterministic and agentic workflows, significant customization, and carefully controlled execution.&lt;/p&gt;

&lt;p&gt;LangChain's current agents are themselves built on LangGraph's durable runtime.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reference.langchain.com/python/langgraph/" rel="noopener noreferrer"&gt;LangGraph Python Reference - LangChain vs. LangGraph guidance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple way to think about the difference is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LangChain
    ↓
Higher-level building blocks
    ↓
Agents + Models + Tools + Integrations


LangGraph
    ↓
Workflow / orchestration layer
    ↓
State + Nodes + Edges + Persistence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are complementary rather than mutually exclusive.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Building a Simple LangGraph Application
&lt;/h2&gt;

&lt;p&gt;A basic Python workflow can be created with LangGraph.&lt;/p&gt;

&lt;p&gt;First, install LangGraph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt; langgraph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then define a state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;Build&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;graph_builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph_builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Run&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Build an AI workflow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting workflow is conceptually:&lt;br&gt;
 START&lt;br&gt;
  ↓&lt;br&gt;
process&lt;br&gt;
  ↓&lt;br&gt;
 END&lt;/p&gt;

&lt;p&gt;The example is intentionally simple. In a production system, nodes can call LLMs, databases, APIs, search tools, other agents, or internal services.&lt;/p&gt;

&lt;p&gt;The official LangGraph documentation provides Python and JavaScript/TypeScript APIs and examples for more advanced workflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.langchain.com/oss/python/langgraph/" rel="noopener noreferrer"&gt;LangGraph documentation&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  13. Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;13.1 Customer Support Agents&lt;/strong&gt;&lt;br&gt;
A customer-support agent can:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Receive Request
      ↓
Identify Intent
      ↓
Search Customer Data
      ↓
Search Knowledge Base
      ↓
Generate Response
      ↓
Need Human Approval?
      ↓
Send Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;13.2 Research Agents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A research agent can repeatedly search, evaluate, and refine information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Search
   ↓
Analyze
   ↓
Missing Information?
 ↙          ↘
Yes          No
 ↓            ↓
Search       Summarize
Again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;13.3 Coding Agents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A coding workflow could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirement
     ↓
Analyze
     ↓
Generate Code
     ↓
Run Tests
     ↓
Tests Passed?
   ↙       ↘
 No        Yes
 ↓          ↓
Fix Code   Review
 ↓          ↓
 └────→ Run Tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type of iterative process is a natural fit for graph-based orchestration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13.4 Document Processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LangGraph can coordinate document-processing workflows such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upload Document
      ↓
Extract Text
      ↓
Classify
      ↓
Extract Information
      ↓
Validate
      ↓
Human Review
      ↓
Store Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;13.5 Business Process Automation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A business workflow can connect AI reasoning with deterministic business logic.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirement
    ↓
Planner
    ↓
Developer Agent
    ↓
QA Agent
    ↓
Review
    ↓
Deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This architecture becomes especially interesting when AI agents need to operate alongside traditional software services.&lt;/p&gt;

&lt;h2&gt;
  
  
  14. Advantages of LangGraph
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Explicit Workflow Control&lt;/strong&gt;&lt;br&gt;
Developers can clearly define how an application moves from one step to another.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Stateful Execution&lt;/strong&gt;&lt;br&gt;
State can be maintained throughout a workflow rather than reconstructed at every step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Durable Execution&lt;/strong&gt;&lt;br&gt;
Long-running workflows can persist state and recover from interruptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Human-in-the-Loop&lt;/strong&gt;&lt;br&gt;
Human approval can be integrated directly into agent execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Flexible Architecture&lt;/strong&gt;&lt;br&gt;
Developers can build single-agent, multi-agent, hierarchical, or custom workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Conditional Logic&lt;/strong&gt;&lt;br&gt;
Applications can dynamically decide what happens next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Loops and Iterative Reasoning&lt;/strong&gt;&lt;br&gt;
Agents can repeat operations until a condition is satisfied.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Streaming&lt;/strong&gt;&lt;br&gt;
Applications can expose execution progress and intermediate results to users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Model Flexibility&lt;/strong&gt;&lt;br&gt;
LangGraph is an orchestration framework rather than a model provider, allowing developers to work with different model providers and application components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Open Source&lt;/strong&gt;&lt;br&gt;
LangGraph is available as an open-source project and can be used independently of LangChain.&lt;/p&gt;

&lt;p&gt;LangGraph GitHub repository&lt;/p&gt;
&lt;h2&gt;
  
  
  15. Challenges and Considerations
&lt;/h2&gt;

&lt;p&gt;LangGraph is powerful, but it is not necessarily the right abstraction for every AI application.&lt;/p&gt;

&lt;p&gt;For a simple chatbot such as:&lt;br&gt;
User → LLM → Response&lt;/p&gt;

&lt;p&gt;introducing a graph-based orchestration layer may add unnecessary complexity.&lt;/p&gt;

&lt;p&gt;LangGraph becomes more valuable as requirements grow.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Simple
User → LLM → Response
        ↓
More complex
User
 ↓
Router
 ↓
Agent
 ↓
Tools
 ↓
Validation
 ↓
Human Approval
 ↓
Database
 ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers should also consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state design&lt;/li&gt;
&lt;li&gt;checkpoint storage&lt;/li&gt;
&lt;li&gt;failure handling&lt;/li&gt;
&lt;li&gt;observability&lt;/li&gt;
&lt;li&gt;security&lt;/li&gt;
&lt;li&gt;tool permissions&lt;/li&gt;
&lt;li&gt;cost&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;evaluation&lt;/li&gt;
&lt;li&gt;concurrency&lt;/li&gt;
&lt;li&gt;versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework provides orchestration capabilities, but production reliability still depends on how the overall system is designed.&lt;/p&gt;

&lt;h2&gt;
  
  
  16. Statistics
&lt;/h2&gt;

&lt;p&gt;The AI-agent ecosystem has grown considerably, and current industry data helps explain why orchestration frameworks such as LangGraph are receiving increasing attention.&lt;/p&gt;

&lt;p&gt;57% of surveyed professionals reported having agents in production&lt;br&gt;
LangChain's 2026 State of Agent Engineering report surveyed 1,340 professionals and reported that 57% of respondents had AI agents in production.&lt;/p&gt;

&lt;p&gt;Original source:&lt;br&gt;
&lt;a href="https://www.langchain.com/state-of-agent-engineering" rel="noopener noreferrer"&gt;LangChain - State of Agent Engineering&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;32% identified quality as a major barrier&lt;br&gt;
The same 2026 survey reported that 32% of respondents identified quality as a top barrier to agent adoption.&lt;/p&gt;

&lt;p&gt;Original source:&lt;br&gt;
&lt;a href="https://www.langchain.com/state-of-agent-engineering" rel="noopener noreferrer"&gt;LangChain - State of Agent Engineering&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nearly 89% reported agent observability&lt;/p&gt;

&lt;p&gt;The report states that nearly 89% of respondents had implemented observability for their agents, compared with 52% using evaluations.&lt;/p&gt;

&lt;p&gt;Original source:&lt;br&gt;
&lt;a href="https://www.langchain.com/state-of-agent-engineering" rel="noopener noreferrer"&gt;LangChain - State of Agent Engineering&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  17. Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. What is LangGraph?&lt;/strong&gt;&lt;br&gt;
LangGraph is an open-source framework for building stateful and long-running AI agents and workflows. It allows developers to control how information moves between different steps using states, nodes, and edges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. What are the main components of LangGraph?&lt;/strong&gt;&lt;br&gt;
The three core components are State, Nodes, and Edges. State stores workflow information, nodes perform tasks, and edges determine how execution moves between nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. What is a node in LangGraph?&lt;/strong&gt;&lt;br&gt;
A node is an individual unit of work, usually represented by a Python function. It can call an LLM, database, API, external tool, or perform normal application logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. What is an edge in LangGraph?&lt;/strong&gt;&lt;br&gt;
An edge connects nodes and defines the execution path. LangGraph also supports conditional edges, allowing the workflow to choose the next node based on the current state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Can LangGraph create loops?&lt;/strong&gt;&lt;br&gt;
Yes. Conditional edges can route execution back to an earlier node. This is useful for workflows such as code generation and testing, content review, research, and iterative AI agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Does LangGraph support memory?&lt;/strong&gt;&lt;br&gt;
Yes. LangGraph provides persistence and checkpointing mechanisms that allow workflow state to be saved and associated with a conversation or execution thread.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Can LangGraph work without LangChain?&lt;/strong&gt;&lt;br&gt;
Yes. LangGraph can be used independently, although it also integrates well with LangChain and its ecosystem of models and tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Does LangGraph support human-in-the-loop workflows?&lt;/strong&gt;&lt;br&gt;
Yes. A workflow can be interrupted so that a human can review or approve an action before execution continues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. When should I use LangGraph?&lt;/strong&gt;&lt;br&gt;
LangGraph is most useful when an AI application requires multiple steps, state management, conditional routing, loops, persistence, human approval, or coordination between multiple agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Is LangGraph suitable for simple AI applications?&lt;/strong&gt;&lt;br&gt;
Not always. For a simple workflow such as User → LLM → Response, a direct model call or simpler framework may be sufficient. LangGraph becomes more valuable as workflow complexity increases.&lt;/p&gt;

&lt;p&gt;About the Author: &lt;em&gt;Manthan Prajapati is an AI Engineer working at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;Addweb Solution&lt;/a&gt;.Writing code today to shape the intelligent systems of tomorrow.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>langgraph</category>
      <category>langchain</category>
      <category>ai</category>
      <category>generativeai</category>
    </item>
    <item>
      <title>Gutenberg Responsive Styling: How to Create Responsive Blocks Without Custom CSS</title>
      <dc:creator>Khushi Thakrar</dc:creator>
      <pubDate>Thu, 05 Nov 2026 12:50:18 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/gutenberg-responsive-styling-how-to-create-responsive-blocks-without-custom-css-180e</link>
      <guid>https://dev.to/addwebsolutionpvtltd/gutenberg-responsive-styling-how-to-create-responsive-blocks-without-custom-css-180e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Good design is obvious. Great design is transparent.” - Joe Sparano&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you ever finished designing a page on your computer, opened it on your phone, and found that the headings look too big, the columns feel cramped, or the buttons are awkward to tap? It is a common problem when building websites.&lt;/p&gt;

&lt;p&gt;The good news is that you can fix many of these issues right inside the WordPress Gutenberg editor, without writing custom CSS for every little change.&lt;/p&gt;

&lt;p&gt;Gutenberg lets you build pages using blocks such as headings, images, buttons, columns, and groups. Each block has its own settings, and many of those settings help you control how your content looks. With the right block structure and a few thoughtful adjustments, you can create pages that are easier to use on desktop, tablet, and mobile.&lt;br&gt;
In this guide, we'll walk through practical ways to make Gutenberg layouts responsive, explain where the built-in tools can help, and point out when you may still need support from your theme or a developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use Gutenberg's built-in settings:Adjust spacing, typography, alignment, and layout without writing CSS for every change.&lt;/li&gt;
&lt;li&gt;Choose the right blocks:Group, Columns, Row, and Stack help you organize content in ways that can adapt to smaller screens.&lt;/li&gt;
&lt;li&gt;Keep your design consistent:Global Styles help you manage fonts, colors, and spacing across your website.&lt;/li&gt;
&lt;li&gt;Check responsive styling support:Separate desktop, tablet, and mobile settings depend on your WordPress version, theme, and block.&lt;/li&gt;
&lt;li&gt;Test before publishing:Preview the actual page at different screen sizes to catch layout problems.&lt;/li&gt;
&lt;li&gt;Know when to use CSS:Gutenberg handles many everyday design needs, but advanced layouts may still require custom styling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to Gutenberg Responsive Styling&lt;/li&gt;
&lt;li&gt;What Does Responsive Design Mean in Gutenberg?&lt;/li&gt;
&lt;li&gt;How to Create Responsive Blocks Without Custom CSS&lt;/li&gt;
&lt;li&gt;Useful Gutenberg Blocks for Responsive Layouts&lt;/li&gt;
&lt;li&gt;Best Practices for Mobile-Friendly Pages&lt;/li&gt;
&lt;li&gt;Technical Specifications&lt;/li&gt;
&lt;li&gt;Statistics and Industry Insights&lt;/li&gt;
&lt;li&gt;Interesting Facts About Gutenberg&lt;/li&gt;
&lt;li&gt;Frequently Asked Questions&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction to Gutenberg Responsive Styling
&lt;/h2&gt;

&lt;p&gt;A responsive website adjusts to the screen it is being viewed on. Text should be comfortable to read, images should fit the layout, and buttons should be easy to use whether someone visits from a laptop or a phone.&lt;/p&gt;

&lt;p&gt;In the past, developers often handled these changes by writing CSS media queries and testing several screen sizes. Gutenberg makes many common adjustments easier because you can work directly with the blocks on the page. You can change spacing, alignment, typography, and layout from the editor, depending on the block and theme you're using.&lt;/p&gt;

&lt;p&gt;Imagine a row of three service cards. On a large screen, showing all three cards side by side may look great. On a phone, those cards may become too narrow to read. A better layout lets them stack or rearrange so each card has enough room.&lt;/p&gt;

&lt;p&gt;The main idea is simple: build a layout that can adjust to its content and screen size, rather than forcing every device to look exactly like the desktop version.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What Does Responsive Design Mean in Gutenberg?
&lt;/h2&gt;

&lt;p&gt;Gutenberg is the block editor built into WordPress. Instead of building a page as one large piece of content, you put it together using individual blocks. A heading is a block, an image is a block, and a button is a block. This makes it easier to edit one part of a page without rebuilding everything else.&lt;/p&gt;

&lt;p&gt;Responsive design in Gutenberg usually means using a combination of these features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layout settings:Arrange blocks horizontally or vertically.&lt;/li&gt;
&lt;li&gt;Spacing controls:Manage padding, margins, and gaps.&lt;/li&gt;
&lt;li&gt;Typography settings:Make headings and paragraphs readable.&lt;/li&gt;
&lt;li&gt;Width and alignment controls:Keep content from feeling cramped or stretched.&lt;/li&gt;
&lt;li&gt;Global Styles:Apply consistent design choices across your website.&lt;/li&gt;
&lt;li&gt;Responsive style controls:Where supported, set different values for selected properties at different screen sizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WordPress 7.1 introduced a dedicated Responsive Styles interface for compatible block themes. Availability still depends on the theme, the block, and the setting you want to change, so you may not see these controls on every website.&lt;br&gt;
Learn more: &lt;a href="https://wordpress.org/documentation/article/respon" rel="noopener noreferrer"&gt;WordPress Responsive Styles documentation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One important distinction: a layout can adapt naturally to a smaller screen without having separate mobile settings. For example, columns may stack as the available space gets smaller. Changing a heading size only on mobile, however, requires a control that supports different values for different viewports.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to Create Responsive Blocks Without Custom CSS
&lt;/h2&gt;

&lt;p&gt;Let's look at some practical ways to make your Gutenberg pages work better on smaller screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Start with the Right Blocks&lt;/strong&gt;&lt;br&gt;
Before adjusting the design, think about how the content should be arranged. Choosing suitable blocks at the start can save time later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Group:Keeps related blocks together, such as a heading, paragraph, and button.&lt;/li&gt;
&lt;li&gt;Columns:Places content side by side, useful for service cards or image-and-text sections.&lt;/li&gt;
&lt;li&gt;Row:Keeps items on one horizontal line when there is enough room.&lt;/li&gt;
&lt;li&gt;Stack:Arranges items vertically with consistent spacing.&lt;/li&gt;
&lt;li&gt;Cover:Adds text or other content over a background image or video, often for a hero section.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try to keep the structure straightforward. If a section needs several layers of nested Groups and Columns just to line up correctly, it may be worth simplifying the layout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Set a Sensible Width&lt;/strong&gt;&lt;br&gt;
Select a block and look at the settings in the sidebar. Depending on the block and theme, you may be able to choose default, wide, or full-width alignment, or set a content width or minimum height.&lt;/p&gt;

&lt;p&gt;Full-width images and banners can look great, but long paragraphs are usually easier to read when their line length is limited. Avoid giving every block a fixed width just because it looks right on your monitor. A flexible layout generally has a better chance of fitting different screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Use Spacing Controls&lt;/strong&gt;&lt;br&gt;
Spacing can make a page feel polished-or make it feel crowded. Gutenberg's Dimensions and Styles panels may let you adjust padding inside a block, margins around it, and gaps between child blocks.&lt;/p&gt;

&lt;p&gt;For example, a section with generous padding can feel comfortable on desktop but leave too little room for content on a phone. If your theme supports responsive values, you can reduce that padding for smaller screens. If it doesn't, start with sensible spacing and test how the layout behaves before adding more complicated fixes.&lt;/p&gt;

&lt;p&gt;Helpful guide: &lt;a href="https://learn.wordpress.org/lesson/dimensions-paddi" rel="noopener noreferrer"&gt;Dimensions: Padding, Margin, and Block Spacing.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Make Text Easy to Read&lt;/strong&gt;&lt;br&gt;
A heading that looks balanced on desktop may take up half the screen on a phone. Use typography settings to adjust font size, line height, font family, and alignment where those options are available.&lt;/p&gt;

&lt;p&gt;If your theme supports responsive typography, switch to the mobile view and adjust the heading size there. Keep body text comfortable to read, and don't make text so small that visitors need to zoom in. Use heading levels in a logical order so the page is easier to navigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Check Your Columns&lt;/strong&gt;&lt;br&gt;
Columns are handy for feature lists, testimonials, service cards, and sections that pair an image with text.&lt;/p&gt;

&lt;p&gt;Add the Columns block, choose a layout, and put your content into each column. Then preview the page at narrower widths.&lt;/p&gt;

&lt;p&gt;If the columns become too narrow or the content feels squeezed, try a simpler arrangement or use a Group or Stack layout. Don't assume every theme will handle columns in exactly the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Set Up Global Styles&lt;/strong&gt;&lt;br&gt;
If you find yourself choosing the same font, color, or spacing again and again, Global Styles can save time.&lt;/p&gt;

&lt;p&gt;In a compatible block theme, open Appearance → Editor → Styles. From there, you can manage site-wide design choices and, where supported, the default appearance of individual block types.&lt;/p&gt;

&lt;p&gt;For instance, setting a consistent heading font globally means you don't have to fix every heading individually. It also makes future redesigns easier because you can update the shared style in one place.&lt;/p&gt;

&lt;p&gt;Official guide: &lt;a href="https://developer.wordpress.org/block-editor/how-t" rel="noopener noreferrer"&gt;WordPress Global Settings and Styles.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Use Responsive Styles If Your Site Supports Them&lt;/strong&gt;&lt;br&gt;
WordPress 7.1 introduced dedicated Responsive Styles controls for compatible block themes. If the feature is available on your site, you may be able to adjust supported settings for different viewport sizes.&lt;/p&gt;

&lt;p&gt;Here's how to get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the page, post, template, or pattern in the editor.&lt;/li&gt;
&lt;li&gt;Open the View menu in the top toolbar.&lt;/li&gt;
&lt;li&gt;Turn on Responsive styles if that option is available.&lt;/li&gt;
&lt;li&gt;Choose the Tablet or Mobile viewport.&lt;/li&gt;
&lt;li&gt;Select the block you want to change.&lt;/li&gt;
&lt;li&gt;Adjust the settings that support responsive values.&lt;/li&gt;
&lt;li&gt;Return to the default view and check that the overall design still looks right.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You may also find viewport controls when editing block styles through Appearance → Editor → Styles → Blocks.&lt;/p&gt;

&lt;p&gt;The exact options depend on your WordPress version, theme, and block. If you can't find a responsive control, you haven't necessarily missed a step-your current setup may not support it.&lt;/p&gt;

&lt;p&gt;For more details, visit the &lt;a href="https://wordpress.org/documentation/article/respo" rel="noopener noreferrer"&gt;official Responsive Styles documentation.&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Preview the Actual Page&lt;/strong&gt;&lt;br&gt;
Before publishing, preview the page at desktop, tablet, and mobile sizes.&lt;/p&gt;

&lt;p&gt;Look for headings that wrap awkwardly, images that appear stretched, buttons that are hard to tap, columns that feel cramped, and any horizontal scrolling.&lt;/p&gt;

&lt;p&gt;The editor preview is a useful first check, but the published page can look a little different because of theme styles and plugins. When possible, also test the page in a browser at different widths and on a real phone.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Design is not just what it looks like and feels like. Design is how it works.” - Steve Jobs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. Useful Gutenberg Blocks for Responsive Layouts
&lt;/h2&gt;

&lt;p&gt;Different blocks serve different purposes. Choosing the right one makes your layout easier to manage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9r45369ha4cryag1x3hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9r45369ha4cryag1x3hr.png" alt=" " width="683" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There isn't one block that makes a page responsive by itself. The result comes from choosing the right blocks, setting them up sensibly, and checking how the complete page behaves.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Best Practices for Mobile-Friendly Pages
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Plan the Content First&lt;/strong&gt;&lt;br&gt;
Put headings, text, images, and buttons in a clear order before spending time on decoration. A logical structure is easier to use on every screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid Fixed Sizes When They Aren't Needed&lt;/strong&gt;&lt;br&gt;
A fixed width or height can cause content to overflow when the screen or text changes. Use flexible sizing where possible, and avoid forcing every element into the same dimensions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep Spacing Consistent&lt;/strong&gt;&lt;br&gt;
Spacing presets and Global Styles help different sections feel like part of the same website. Consistent spacing also makes pages easier to scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Appropriately Sized Images&lt;/strong&gt;&lt;br&gt;
Large images can slow a page down, and poorly chosen dimensions can make the layout look awkward. Use images that suit the space they occupy, and avoid stretching small images to fill large areas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember Accessibility&lt;/strong&gt;&lt;br&gt;
Use readable text, sufficient color contrast, meaningful headings, descriptive alt text, and clear button labels. Responsive design should make the page easier for everyone to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't Overcomplicate the Block Structure&lt;/strong&gt;&lt;br&gt;
Too many nested containers make pages harder to edit and maintain. Start with the simplest structure that meets the design goal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Know When to Use CSS&lt;/strong&gt;&lt;br&gt;
Gutenberg covers many everyday needs, but custom CSS or theme development may still be necessary for complex animations, unusual breakpoints, advanced hover effects, or styling options the editor doesn't provide.&lt;/p&gt;

&lt;p&gt;The aim isn't to avoid CSS at all costs. It's to use the simplest approach that works reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Technical Specifications
&lt;/h2&gt;

&lt;p&gt;Here's a quick overview of the main tools and limitations to keep in mind when working with Gutenberg responsive styling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjp9rr5owggl4zl0tthpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjp9rr5owggl4zl0tthpb.png" alt=" " width="705" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A note for developers:theme.jsonis a configuration file used by block themes to define settings, design presets, layout options, and styles. It helps a theme provide consistent defaults so content editors don't have to style every block manually.&lt;br&gt;
Reference: &lt;a href="https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/theme-json-living/" rel="noopener noreferrer"&gt;WordPress theme.jsondocumentation.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Statistics and Industry Insights
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;WordPress's Presence on the Web&lt;/strong&gt;&lt;br&gt;
WordPress remains one of the most widely used website platforms. According to W3Techs, as of October 14, 2026, WordPress powered 40.0% of all websites and accounted for 58.5% of websites with a known content management system (CMS).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WordPress Usage Statistics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Source: W3Techs – &lt;a href="https://w3techs.com/technologies/comparison/cm-w" rel="noopener noreferrer"&gt;WordPress Usage Statistics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Do These Numbers Matter?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These figures highlight WordPress's continued relevance for website owners, developers, and businesses.&lt;/p&gt;

&lt;p&gt;As websites evolve, creating pages that are easy to manage and work well across different devices becomes increasingly important. &lt;/p&gt;

&lt;p&gt;Gutenberg's built-in styling options help developers and content editors make routine layout and design adjustments without writing custom CSS for every change.&lt;/p&gt;

&lt;p&gt;However, the time saved depends on the website, its theme, and the complexity of the design. Built-in controls are useful for everyday layouts, while advanced design requirements may still call for custom CSS or development.&lt;/p&gt;

&lt;p&gt;Note: WordPress usage statistics can change over time. Check the &lt;a href="https://w3techs.com/technologies/comparison/cm-w" rel="noopener noreferrer"&gt;latest W3Techs statistics&lt;/a&gt; before publishing to ensure the figures remain accurate.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Interesting Facts About Gutenberg
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Gutenberg is more than a writing tool. Blocks are used to build page content, and block themes can also use blocks in templates and other parts of a website.&lt;br&gt;
Source: &lt;a href="https://wordpress.org/documentation/article/wordpress-editor/" rel="noopener noreferrer"&gt;https://wordpress.org/documentation/article/wordpress-editor/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Global Styles can save repetitive work. You can manage shared design choices, such as typography and colors, in one place instead of styling every block individually.&lt;br&gt;
Source: &lt;a href="https://wordpress.org/documentation/article/styles-overview/" rel="noopener noreferrer"&gt;https://wordpress.org/documentation/article/styles-overview/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Responsive styling is evolving. WordPress 7.1 introduced dedicated Responsive Styles controls for compatible block themes, allowing supported settings to vary by screen size.&lt;br&gt;
Source: &lt;a href="https://wordpress.org/documentation/article/responsive-styles/" rel="noopener noreferrer"&gt;https://wordpress.org/documentation/article/responsive-styles/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not every block has the same controls. The available responsive options depend on the block, theme, and setting being edited.&lt;br&gt;
Source: &lt;a href="https://wordpress.org/documentation/article/responsive-styles/" rel="noopener noreferrer"&gt;https://wordpress.org/documentation/article/responsive-styles/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A good mobile experience is about more than screen size. Readability, content order, usable controls, and accessibility all matter.&lt;br&gt;
Source: &lt;a href="https://www.w3.org/WAI/WCAG22/Understanding/" rel="noopener noreferrer"&gt;https://www.w3.org/WAI/WCAG22/Understanding/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The theme.json file connects design and development. It lets theme developers define settings, design presets, and styling defaults for the block editor and website.&lt;br&gt;
Source: &lt;a href="https://developer.wordpress.org/themes/global-settings-and-styles/" rel="noopener noreferrer"&gt;https://developer.wordpress.org/themes/global-settings-and-styles/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  9. Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Can I make Gutenberg blocks responsive without custom CSS?&lt;/strong&gt;&lt;br&gt;
Yes. Built-in layout, spacing, typography, alignment, and dimension settings can handle many common needs. Separate values for desktop and mobile depend on whether your WordPress setup supports responsive styles for the property you want to change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Which WordPress version supports dedicated Responsive Styles?&lt;/strong&gt;&lt;br&gt;
WordPress 7.1 introduced dedicated Responsive Styles controls for compatible block themes. If you can't see the option, check your WordPress version, active theme, and the block you're editing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. How can I make columns stack on mobile?&lt;/strong&gt;&lt;br&gt;
Start with a Columns block and preview it at a narrow width. If the result isn't suitable, simplify the layout or use a Group or Stack. The exact behavior can vary by theme and block implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Can I use a different font size on mobile?&lt;/strong&gt;&lt;br&gt;
You can if your WordPress version, theme, and block support responsive typography. Switch to the mobile viewport and adjust the supported typography setting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Do all Gutenberg blocks support responsive styles?&lt;/strong&gt;&lt;br&gt;
No. The available controls differ from block to block and theme to theme. Some settings can be changed for individual viewports, while others apply everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. What does theme.json do?&lt;/strong&gt;&lt;br&gt;
theme.jsonlets theme developers define settings, design presets, layout options, and styles in a structured file. It helps create consistent defaults for the block editor and the website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Is Gutenberg better than custom CSS?&lt;/strong&gt;&lt;br&gt;
It depends on the job. Gutenberg is convenient for common layouts and changes that content editors need to make themselves. CSS offers more control for unusual or advanced designs. Many websites use both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. How should I test a responsive page?&lt;/strong&gt;&lt;br&gt;
Use the editor preview, resize your browser, and test the published page on real devices when possible. Check for horizontal scrolling, clipped text, awkward spacing, small tap targets, and images that don't fit correctly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The details are not the details. They make the design.” - Charles Eames&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  10. Conclusion
&lt;/h2&gt;

&lt;p&gt;You don't need to write custom CSS for every responsive adjustment in Gutenberg. For many websites, the built-in block settings, sensible layouts, and Global Styles are enough to create a page that works well across different screens. If your theme supports Responsive Styles, you may also be able to fine-tune certain settings for tablet and mobile.&lt;/p&gt;

&lt;p&gt;Start with a clear structure, avoid unnecessary fixed sizes, use images that suit the layout, and take a few minutes to check the finished page on different devices.&lt;/p&gt;

&lt;p&gt;If the editor can't achieve a specific design, there's nothing wrong with using a small amount of well-maintained CSS or asking a developer for help.&lt;/p&gt;

&lt;p&gt;The best responsive design isn't the one with the most settings. It's the one that makes your content clear, usable, and comfortable to view on every screen.&lt;/p&gt;

&lt;p&gt;About the Author: &lt;em&gt;Khushi is a web developer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, working with WordPress, PHP, MySQL, and other web technologies.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>gutenberg</category>
      <category>responsivedesign</category>
      <category>wordpressdevelopment</category>
    </item>
    <item>
      <title>Traditional SDLC vs AI-Native SDLC: How AI Is Changing Software Development</title>
      <dc:creator>Mayank Goyal</dc:creator>
      <pubDate>Tue, 03 Nov 2026 10:54:11 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/traditional-sdlc-vs-ai-native-sdlc-how-ai-is-changing-software-development-4hlf</link>
      <guid>https://dev.to/addwebsolutionpvtltd/traditional-sdlc-vs-ai-native-sdlc-how-ai-is-changing-software-development-4hlf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AI’s primary role in software development is that of an amplifier.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Software development has evolved significantly over the past few decades. From writing code manually and testing applications through traditional processes to using cloud platforms, DevOps practices, and automated deployment pipelines, every generation of technology has changed how software is built and delivered.&lt;/p&gt;

&lt;p&gt;Today, Artificial Intelligence (AI) is introducing another major shift. AI coding assistants, large language models (LLMs), automated testing tools, and AI agents are helping developers perform tasks that previously required considerable manual effort.&lt;/p&gt;

&lt;p&gt;Traditionally, software teams have followed the Software Development Life Cycle (SDLC), which includes planning, requirement analysis, design, development, testing, deployment, and maintenance. These stages provide structure, predictability, and quality control.&lt;/p&gt;

&lt;p&gt;However, the emerging AI-Native Software Development Life Cycle (AI-Native SDLC) takes a different approach. Instead of treating AI as a tool used only for writing code, it integrates AI throughout the development process, from understanding requirements to generating tasks, implementing features, identifying defects, and supporting continuous improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Traditional SDLC follows structured development stages, with most planning, coding, testing, and decision-making performed by people using conventional tools and automation.&lt;/li&gt;
&lt;li&gt;AI-Native SDLC integrates AI into multiple development stages, enabling AI-assisted planning, code generation, testing, debugging, documentation, and continuous improvement.&lt;/li&gt;
&lt;li&gt;AI does not eliminate the need for SDLC. It changes how its activities are performed and coordinated.&lt;/li&gt;
&lt;li&gt;Faster code generation does not automatically mean faster software delivery. Code quality, integration, security, testing, and deployment reliability remain essential.&lt;/li&gt;
&lt;li&gt;Human oversight remains critical. Developers must validate AI-generated code, review architecture, protect sensitive data, and approve high-impact changes.&lt;/li&gt;
&lt;li&gt;Feature-based development can improve integration. For example, completing a login API and login UI together can expose integration problems earlier than implementing all backend features before starting the frontend.&lt;/li&gt;
&lt;li&gt;AI-Native development works best with strong engineering practices, including automated tests, code reviews, CI/CD, version control, observability, and clear technical guidelines. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Understanding Traditional SDLC&lt;/li&gt;
&lt;li&gt;Understanding AI-Native SDLC&lt;/li&gt;
&lt;li&gt;Traditional SDLC vs AI-Native SDLC&lt;/li&gt;
&lt;li&gt;How AI Changes Each Development Stage&lt;/li&gt;
&lt;li&gt;Real-World Example: Building an Employee Management System&lt;/li&gt;
&lt;li&gt;Code Example: Traditional vs AI-Assisted Development&lt;/li&gt;
&lt;li&gt;Technical Specifications and Architecture&lt;/li&gt;
&lt;li&gt;Benefits of AI-Native SDLC&lt;/li&gt;
&lt;li&gt;Statistics and Research Findings&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Understanding Traditional SDLC
&lt;/h2&gt;

&lt;p&gt;The Traditional Software Development Life Cycle is a structured process used to plan, design, develop, test, deploy, and maintain software applications.&lt;/p&gt;

&lt;p&gt;Depending on the project, organizations may follow Waterfall, Agile, Scrum, or a hybrid methodology. These approaches differ in how they organize work, but they generally rely on defined requirements, engineering decisions, testing procedures, and release controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key stages of Traditional SDLC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Planning and requirement analysis&lt;/strong&gt;&lt;br&gt;
The team identifies business objectives, gathers requirements, defines project scope, and estimates time and resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. System design&lt;/strong&gt;&lt;br&gt;
Architects and developers decide the application architecture, database structure, APIs, user interface, security mechanisms, and technology stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Development&lt;/strong&gt;&lt;br&gt;
Developers write backend logic, frontend components, database queries, and integration code according to the approved requirements and designs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Testing and quality assurance&lt;/strong&gt;&lt;br&gt;
QA engineers and developers perform unit, integration, system, regression, performance, and security testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Deployment&lt;/strong&gt;&lt;br&gt;
The application is released to a staging or production environment using a manual process or an automated CI/CD pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Maintenance&lt;/strong&gt;&lt;br&gt;
The team monitors the application, resolves defects, applies security updates, and develops enhancements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of a traditional workflow&lt;/strong&gt;&lt;br&gt;
Imagine a team developing an employee management application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The business analyst prepares the Software Requirements Specification (SRS).&lt;/li&gt;
&lt;li&gt;The architect designs the database and API structure.&lt;/li&gt;
&lt;li&gt;The backend developer creates authentication and employee APIs.&lt;/li&gt;
&lt;li&gt;The frontend developer builds the login page and employee dashboard.&lt;/li&gt;
&lt;li&gt;The QA team tests the integrated application.&lt;/li&gt;
&lt;li&gt;The DevOps engineer deploys it to the server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process provides clear responsibilities and checkpoints. However, when the backend and frontend are developed separately, integration issues may not become visible until later in the project.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Understanding AI-Native SDLC
&lt;/h2&gt;

&lt;p&gt;AI-Native SDLC is an approach in which artificial intelligence is integrated into the software development process as a core capability rather than being used only as an occasional coding assistant.&lt;/p&gt;

&lt;p&gt;AI can help teams interpret requirements, identify missing functionality, decompose epics into tasks, generate code, create tests, analyze failures, produce documentation, and support deployment and monitoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key stages of AI-Native SDLC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. AI-assisted requirement analysis&lt;/strong&gt;&lt;br&gt;
AI analyzes business requirements, identifies ambiguities, suggests missing scenarios, and helps create user stories and acceptance criteria.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Intelligent planning and task decomposition&lt;/strong&gt;&lt;br&gt;
AI can divide a large feature into smaller, manageable tasks based on dependencies, complexity, and architectural boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AI-assisted architecture and design&lt;/strong&gt;&lt;br&gt;
AI can suggest database schemas, API contracts, system components, and technology choices. Human architects remain responsible for validating the design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. AI-assisted implementation&lt;/strong&gt;&lt;br&gt;
Coding agents and assistants generate code, modify files, explain existing implementations, and help developers resolve errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Automated testing and validation&lt;/strong&gt;&lt;br&gt;
AI can propose unit tests, integration tests, edge cases, and regression scenarios. Conventional deterministic tests still provide essential verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. AI-supported code review and debugging&lt;/strong&gt;&lt;br&gt;
AI can identify suspicious code patterns, explain stack traces, propose fixes, and summarize potential risks. Findings must be verified rather than automatically assumed correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Automated deployment and monitoring&lt;/strong&gt;&lt;br&gt;
CI/CD pipelines can build, test, and deploy approved changes. AI may assist with log analysis, failure diagnosis, and remediation proposals, while controlled systems enforce release policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Continuous feedback and improvement&lt;/strong&gt;&lt;br&gt;
Production metrics, user feedback, test failures, and incident reports can inform future planning and refinement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of an AI-Native workflow&lt;/strong&gt;&lt;br&gt;
For the same employee management application, the process could look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The product owner provides the SRS.&lt;/li&gt;
&lt;li&gt;AI identifies the major modules: authentication, employee management, attendance, and reporting.&lt;/li&gt;
&lt;li&gt;The planning system generates epics and feature-level tasks.&lt;/li&gt;
&lt;li&gt;AI assists with implementation of the login API and login UI as one integrated feature.&lt;/li&gt;
&lt;li&gt;Automated tests verify valid login, invalid credentials, missing fields, and unauthorized access.&lt;/li&gt;
&lt;li&gt;CI checks code quality, dependencies, and security.&lt;/li&gt;
&lt;li&gt;A developer reviews the pull request and approves the change.&lt;/li&gt;
&lt;li&gt;The deployment pipeline releases the approved build and monitors its health.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This workflow can reduce repetitive work and reveal defects earlier. However, the actual benefit depends on the quality of the requirements, the AI model, the codebase, the test suite, and the safeguards surrounding automation.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Traditional SDLC vs AI-Native SDLC
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4kmbzjbptrxpf15yi2zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4kmbzjbptrxpf15yi2zg.png" alt=" " width="443" height="588"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foy2rjk3r5271n3n8uery.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foy2rjk3r5271n3n8uery.png" alt=" " width="442" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The primary difference is not whether a team uses modern tools. It is how AI participates in the development lifecycle and how responsibility is distributed between people, AI systems, and conventional automation.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. How AI Changes Each Development Stage
&lt;/h2&gt;

&lt;p&gt;AI can contribute more than code completion. Its broader impact becomes visible when it is integrated across the development lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.1 Requirement analysis&lt;/strong&gt;&lt;br&gt;
In traditional development, business analysts and product owners manually translate business needs into functional requirements.&lt;/p&gt;

&lt;p&gt;With AI assistance, a team can provide a requirement such as:&lt;br&gt;
"Users should be able to log in securely using their email address and password."&lt;br&gt;
AI can suggest additional questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should users be able to reset forgotten passwords?&lt;/li&gt;
&lt;li&gt;How many failed login attempts are allowed?&lt;/li&gt;
&lt;li&gt;Should accounts support multi-factor authentication?&lt;/li&gt;
&lt;li&gt;How long should sessions remain valid?&lt;/li&gt;
&lt;li&gt;What happens when a user is deactivated?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These suggestions help the team identify gaps before development begins. The product owner must still confirm the actual business rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.2 Task decomposition and planning&lt;/strong&gt;&lt;br&gt;
A large requirement often contains multiple backend, frontend, database, and testing activities.&lt;br&gt;
AI can break an employee management epic into smaller tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the employee database schema.&lt;/li&gt;
&lt;li&gt;Implement employee creation and retrieval APIs.&lt;/li&gt;
&lt;li&gt;Add input validation and authorization.&lt;/li&gt;
&lt;li&gt;Build the employee list UI.&lt;/li&gt;
&lt;li&gt;Build the employee creation form.&lt;/li&gt;
&lt;li&gt;Connect the UI to the backend API.&lt;/li&gt;
&lt;li&gt;Add integration tests.&lt;/li&gt;
&lt;li&gt;Verify role-based access control.
The team can then define dependencies and acceptance criteria. This reduces ambiguity and makes progress easier to track.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4.3 Feature-based implementation&lt;/strong&gt;&lt;br&gt;
One useful AI-Native practice is to organize development around complete features instead of separating all backend work from all frontend work.&lt;br&gt;
For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sprint 0: project setup, database configuration, and CI/CD.&lt;/li&gt;
&lt;li&gt;Sprint 1: authentication API and authentication UI.&lt;/li&gt;
&lt;li&gt;Sprint 2: employee APIs and employee UI.&lt;/li&gt;
&lt;li&gt;Sprint 3: reporting APIs and reporting UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benefit is that each feature can be integrated and tested before the next feature is built. This is a workflow design choice rather than an automatic property of AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.4 Deployment and monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional CI/CD pipelines automate repeatable operations such as building, testing, packaging, and deployment. AI can extend this process by analyzing logs, summarizing failed stages, identifying likely configuration errors, and proposing corrective changes.&lt;/p&gt;

&lt;p&gt;For example, if a deployment succeeds but the application health check reports that the backend is disconnected, an AI assistant can help investigate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing or incorrect environment variables.&lt;/li&gt;
&lt;li&gt;Incorrect database connection strings.&lt;/li&gt;
&lt;li&gt;A backend process that failed to start.&lt;/li&gt;
&lt;li&gt;Reverse-proxy routing errors.&lt;/li&gt;
&lt;li&gt;Health-check configuration problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The proposed fix should be tested in a controlled environment before it reaches production.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Real-World Example: Building an Employee Management System
&lt;/h2&gt;

&lt;p&gt;Consider a company that wants to build an Employee Management System for managing employee records, roles, departments, and attendance.&lt;br&gt;
The following is a practical illustrative scenario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario A: Traditional SDLC&lt;/strong&gt;&lt;br&gt;
The team receives an SRS containing employee login, registration, profile management, and reporting requirements.&lt;br&gt;
The team follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The business analyst prepares the requirements document.&lt;/li&gt;
&lt;li&gt;The architect designs the database, backend APIs, and frontend structure.&lt;/li&gt;
&lt;li&gt;Backend developers implement authentication and employee management APIs.&lt;/li&gt;
&lt;li&gt;Frontend developers build the login page, employee list, and dashboard.&lt;/li&gt;
&lt;li&gt;The team integrates the frontend and backend.&lt;/li&gt;
&lt;li&gt;QA engineers test the integrated application.&lt;/li&gt;
&lt;li&gt;DevOps deploys the application to staging and production.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Potential challenge:&lt;/strong&gt; If the backend returns a response that differs from what the frontend expects, the mismatch may be discovered only during integration testing.&lt;br&gt;
For example, the backend might return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"accessToken"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"example-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"employee@example.com"&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the frontend might expect a property called token rather than accessToken. The login integration fails even though both components may work independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario B: AI-Native SDLC&lt;/strong&gt;&lt;br&gt;
The same team uses AI-assisted planning, coding, testing, and deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Analyze requirements&lt;/strong&gt;&lt;br&gt;
AI proposes authentication tasks and highlights security requirements such as password hashing, session handling, and authorization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Define the API contract&lt;/strong&gt;&lt;br&gt;
The backend and frontend teams agree on a shared response format before implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Build the complete feature&lt;/strong&gt;&lt;br&gt;
AI assists with generating the login API, form validation, frontend components, and test cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Validate integration early&lt;/strong&gt;&lt;br&gt;
The frontend is connected to the real API in the same feature cycle. Contract tests and integration tests detect response mismatches before the next module begins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Review and deploy&lt;/strong&gt;&lt;br&gt;
The CI/CD pipeline runs tests, linting, build checks, and security scans. A developer reviews the changes before deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expected workflow improvement&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0cy85um4efa210990mpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0cy85um4efa210990mpr.png" alt=" " width="660" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AI-Native approach can reduce repetitive effort and shorten feedback loops, but it does not guarantee a faster project. Incorrect generated code, unclear requirements, expensive AI calls, and weak testing can increase rework.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Code Example: Traditional vs AI-Assisted Development
&lt;/h2&gt;

&lt;p&gt;Let us use a small login-validation example to understand how the two approaches differ.&lt;/p&gt;

&lt;p&gt;The following code is illustrative and uses TypeScript. The AI-assisted version is not a special programming language; it is ordinary application code that an AI assistant could help generate, explain, or test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 Traditional implementation&lt;/strong&gt;&lt;br&gt;
In Traditional SDLC, a developer manually writes the login-validation logic based on the application requirements.&lt;br&gt;
JavaScript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;employee@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output: []&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The function returns an empty array because both required fields are present.&lt;/p&gt;

&lt;p&gt;In a traditional workflow, the developer writes the function, identifies edge cases, creates tests, and submits the implementation for review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.2 AI-Assisted Implementation&lt;/strong&gt;&lt;br&gt;
In an AI-Native SDLC workflow, a developer can ask an AI coding assistant to review the existing implementation, identify missing validation rules, improve the code, and generate test cases.&lt;/p&gt;

&lt;p&gt;For example, the developer could provide this prompt:&lt;br&gt;
Review the login-validation function. Improve it to validate email format, handle whitespace-only passwords, and generate unit tests for valid and invalid inputs. Do not implement authentication or store passwords.&lt;/p&gt;

&lt;p&gt;The AI assistant might suggest the following JavaScript implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailPattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[^\s&lt;/span&gt;&lt;span class="sr"&gt;@&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+@&lt;/span&gt;&lt;span class="se"&gt;[^\s&lt;/span&gt;&lt;span class="sr"&gt;@&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.[^\s&lt;/span&gt;&lt;span class="sr"&gt;@&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+$/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;emailPattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter a valid email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;employee@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.3 AI-Assisted Unit Testing&lt;/strong&gt;&lt;br&gt;
AI can also help developers generate test cases to verify that the function behaves as expected.&lt;/p&gt;

&lt;p&gt;For example, using Node.js's built-in test runner, developers can create a file named validateLogin.test.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:assert/strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateLogin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./validateLogin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;accepts valid-looking input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deepEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;employee@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rejects an empty email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rejects an invalid email format&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid-email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter a valid email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rejects a whitespace-only password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;validateLogin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;employee@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;   &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Export the function from validateLogin.js so the test file can import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateLogin&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the tests using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--test&lt;/span&gt; validateLogin.test.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.4 What Does This Comparison Demonstrate?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F02uyf02tpdsfjwtr1s9o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F02uyf02tpdsfjwtr1s9o.png" alt=" " width="662" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both approaches produce ordinary JavaScript code. The difference lies in how the code is created, tested, reviewed, and integrated into the software development workflow.&lt;br&gt;
Generative AI is rapidly reshaping the software development landscape.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generative AI is rapidly reshaping the software development landscape.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  7. Technical Specifications and Architecture
&lt;/h2&gt;

&lt;p&gt;A practical AI-Native SDLC implementation requires more than an AI model. It combines conventional software engineering infrastructure with AI-assisted planning and execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7.1 Recommended technology stack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcw1crmnx864mb6p1ojj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcw1crmnx864mb6p1ojj4.png" alt=" " width="424" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are example technologies rather than mandatory requirements. Teams should choose tools that fit their architecture, security requirements, and operational constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7.2 Suggested AI-Native workflow architecture&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business Requirements / SRS
↓
AI-Assisted Requirement Analysis
↓
Epic and Task Generation
↓
Dependency and Acceptance Criteria Review
↓
AI-Assisted Feature Implementation
↓
Automated Tests + Code Quality + Security Checks
↓
Human Code Review and Approval
↓
CI/CD Build and Deployment
↓
Health Checks, Logs, and Monitoring
↓
Feedback and Backlog Improvement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage should have a defined input, expected output, validation criteria, and failure-handling process.&lt;/p&gt;

&lt;p&gt;For example, the task-generation stage should not merely produce a task title. It should also provide a description, acceptance criteria, dependencies, expected files or components where appropriate, and test requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7.3 Example sprint structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkoftikokf9z879hkqk55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkoftikokf9z879hkqk55.png" alt=" " width="668" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A feature-oriented workflow for an employee management project might look like this:&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Benefits of AI-Native SDLC
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;8.1 Faster development of routine tasks&lt;/strong&gt;&lt;br&gt;
AI can help generate repetitive code, API boilerplate, data models, documentation, and test scaffolding. Developers can spend more time on architecture, business logic, and complex problem-solving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8.2 Earlier detection of requirement gaps&lt;/strong&gt;&lt;br&gt;
AI can analyze an SRS and suggest missing scenarios before coding starts. This may reduce rework caused by overlooked requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8.3 Improved testing coverage&lt;/strong&gt;&lt;br&gt;
AI can suggest boundary cases and negative scenarios that developers may not initially consider. The resulting tests must still be reviewed and executed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8.4 Better developer productivity&lt;/strong&gt;&lt;br&gt;
AI can help explain unfamiliar codebases, summarize stack traces, suggest refactoring, and speed up technical research.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Statistics and Research Findings
&lt;/h2&gt;

&lt;p&gt;Research indicates that AI tools are becoming common in software development. However, adoption should not be confused with guaranteed productivity gains or better software quality.&lt;br&gt;
The following figures are from published research and surveys. Each statistic reflects its specific study population, methodology, and survey period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.1 AI adoption among developers&lt;/strong&gt;&lt;br&gt;
76% of respondents in Stack Overflow's 2024 Developer Survey were using or planning to use AI tools in their development process, up from 70% in 2023.&lt;br&gt;
Source: &lt;a href="https://survey.stackoverflow.co/2024/ai" rel="noopener noreferrer"&gt;Stack Overflow 2024 Developer Survey - AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.2 Productivity is a leading expected benefit&lt;/strong&gt;&lt;br&gt;
81% of respondents in the same survey identified increased productivity as a key benefit of AI tools in their development workflow.&lt;br&gt;
Source: &lt;a href="https://survey.stackoverflow.co/2024/ai" rel="noopener noreferrer"&gt;Stack Overflow 2024 Developer Survey - AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.3 Trust remains a concern&lt;/strong&gt;&lt;br&gt;
In the 2024 Stack Overflow survey, 43% of respondents said they trusted AI tool accuracy, while 31% were skeptical of it.&lt;br&gt;
This highlights why AI-generated code should be reviewed, tested, and validated rather than accepted automatically.&lt;br&gt;
Source: &lt;a href="https://survey.stackoverflow.co/2024/ai" rel="noopener noreferrer"&gt;Stack Overflow 2024 Developer Survey - AI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.4 AI is used for more than writing code&lt;/strong&gt;&lt;br&gt;
Stack Overflow reported that 82% of respondents using AI tools in the development workflow used them for writing code. Developers also reported interest in applying AI to testing, documentation, and other activities.&lt;br&gt;
Source: &lt;a href="https://survey.stackoverflow.co/2024/ai" rel="noopener noreferrer"&gt;Stack Overflow 2024 Developer Survey - AI&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fact 1: AI can contribute before the first line of code is written.
AI can help analyze requirements, suggest missing scenarios, and produce draft acceptance criteria before implementation begins.&lt;/li&gt;
&lt;li&gt;Fact 2: AI-generated code is still software that must be tested.
A function generated in seconds can still contain bugs, security vulnerabilities, or incorrect assumptions.&lt;/li&gt;
&lt;li&gt;Fact 3: AI-Native SDLC can reduce the gap between frontend and backend development.
When features are planned and implemented end to end, API contracts, UI behavior, and integration tests can be validated earlier.&lt;/li&gt;
&lt;li&gt;Fact 4: Automated testing becomes even more important when code generation becomes faster.
If a team produces more code without increasing its ability to validate that code, the overall defect risk may increase.&lt;/li&gt;
&lt;li&gt;Fact 5: AI can assist with maintenance as well as new development.
It can help summarize legacy code, explain dependencies, generate regression tests, and propose safe refactori
ng strategies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  11. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q1. What is the difference between Traditional SDLC and AI-Native SDLC?&lt;/strong&gt;&lt;br&gt;
Traditional SDLC relies primarily on human-led planning, implementation, and verification, supported by conventional automation. AI-Native SDLC integrates AI into multiple stages, including requirement analysis, task planning, code generation, testing, debugging, and maintenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q2. Does AI-Native SDLC replace Traditional SDLC?&lt;/strong&gt;&lt;br&gt;
No. AI-Native SDLC builds on established software engineering practices. Requirements management, architecture, testing, security, version control, deployment controls, and maintenance remain essential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q3. Is AI-Native SDLC suitable for small teams and startups?&lt;/strong&gt;&lt;br&gt;
Yes. Small teams can begin with AI-assisted coding, test generation, documentation, and code review. They do not need a fully autonomous system to benefit from AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q4. Can AI develop an entire application automatically?&lt;/strong&gt;&lt;br&gt;
AI agents can generate substantial portions of an application, but reliable end-to-end delivery remains challenging. Complex business rules, architecture, integrations, security, and production operations still require careful validation and often human intervention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q5. What tools are needed to implement AI-Native SDLC?&lt;/strong&gt;&lt;br&gt;
A typical setup includes an approved AI model or coding agent, Git-based version control, an issue tracker, automated testing, code-quality checks, CI/CD, deployment infrastructure, and observability tools. Additional orchestration and governance systems may be useful for more advanced implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q6. What is the biggest risk of AI-Native SDLC?&lt;/strong&gt;&lt;br&gt;
One major risk is accepting incorrect or insecure AI-generated changes without adequate verification. Other risks include data exposure, uncontrolled agent permissions, increasing costs, and weak understanding of the existing codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Conclusion
&lt;/h2&gt;

&lt;p&gt;Traditional SDLC has provided software teams with a reliable structure for planning, building, testing, deploying, and maintaining applications. Its core principles remain valuable, even as new technologies transform the way development work is performed.&lt;/p&gt;

&lt;p&gt;AI-Native SDLC represents an evolution in this process. By integrating AI into requirement analysis, task decomposition, code generation, testing, debugging, and continuous feedback, organizations can reduce repetitive effort and improve coordination across the software lifecycle.&lt;/p&gt;

&lt;p&gt;However, AI is not a substitute for sound engineering. Generated code can be incorrect, tests can miss important scenarios, and automated systems can introduce production risks if they operate without suitable controls.&lt;/p&gt;

&lt;p&gt;The most practical path forward is to combine AI-assisted execution with established engineering discipline. Teams should start with clear requirements, build features end to end, automate repeatable checks, review AI-generated changes, and measure delivery quality and cost.&lt;/p&gt;

&lt;p&gt;The future of software development is not simply about writing more code with AI. It is about delivering reliable, secure, maintainable software by combining human judgment, AI capabilities, and disciplined automation.&lt;/p&gt;

&lt;p&gt;About the Author:&lt;em&gt;Mayank is a web developer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWebSolution&lt;/a&gt;, building scalable apps with PHP, Node.js &amp;amp; React. Sharing ideas, code, and creativity.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>ainativesdlc</category>
      <category>webdev</category>
      <category>traditionalsdlc</category>
    </item>
    <item>
      <title>AI Without Sending Your Data Away: A Guide to Local LLMs</title>
      <dc:creator>Tanisha Khakhrani</dc:creator>
      <pubDate>Thu, 22 Oct 2026 07:19:53 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/ai-without-sending-your-data-away-a-guide-to-local-llms-15dl</link>
      <guid>https://dev.to/addwebsolutionpvtltd/ai-without-sending-your-data-away-a-guide-to-local-llms-15dl</guid>
      <description>&lt;p&gt;“Like with all technological revolutions, I expect there to be significant impact on jobs, but exactly what that impact looks like is very difficult to predict…I think it’s important to understand and think about GPT-4 as a tool, not a creature.” - Sam Altman&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Local LLMs run inference on hardware controlled by the user or organization, reducing the need to send prompts and documents to a remote inference service.&lt;/li&gt;
&lt;li&gt;Local deployment can provide greater control over data, infrastructure, customization, and network dependency.&lt;/li&gt;
&lt;li&gt;Model size has a major impact on hardware requirements; smaller models can run on consumer devices while larger models require substantial GPU memory or distributed infrastructure.&lt;/li&gt;
&lt;li&gt;Quantization reduces model memory requirements by representing weights with fewer bits, making larger models practical on constrained hardware.&lt;/li&gt;
&lt;li&gt;Tools such as Ollama, LM Studio, and Hugging Face make local-model experimentation accessible to developers.&lt;/li&gt;
&lt;li&gt;Local AI does not automatically guarantee security. Network exposure, model provenance, access controls, logging, and the applications surrounding the model still need to be secured.&lt;/li&gt;
&lt;li&gt;The best model is not necessarily the largest model; the correct choice depends on the task, latency requirements, available hardware, and quality requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table of Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction &lt;/li&gt;
&lt;li&gt;Understanding Local LLMs 

&lt;ul&gt;
&lt;li&gt;What Is a Local LLM? &lt;/li&gt;
&lt;li&gt;Local LLM vs. Cloud LLM&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Why Run an LLM Locally? 

&lt;ul&gt;
&lt;li&gt;Data Privacy and Control &lt;/li&gt;
&lt;li&gt;Offline Operation &lt;/li&gt;
&lt;li&gt;Customization &lt;/li&gt;
&lt;li&gt;Latency and Infrastructure Control&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Open-Weight Models and the Local AI Ecosystem &lt;/li&gt;
&lt;li&gt;Model Size and Hardware Requirements &lt;/li&gt;
&lt;li&gt;Understanding Quantization &lt;/li&gt;
&lt;li&gt;Popular Tools for Running Local LLMs &lt;/li&gt;
&lt;li&gt;Setting Up a Local LLM with Ollama 

&lt;ul&gt;
&lt;li&gt;Install Ollama &lt;/li&gt;
&lt;li&gt;Download a Model &lt;/li&gt;
&lt;li&gt;Test the Model &lt;/li&gt;
&lt;li&gt;Integrate the Model into an Application&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Security and Practical Considerations &lt;/li&gt;
&lt;li&gt;Statistics &lt;/li&gt;
&lt;li&gt;Interesting Facts &lt;/li&gt;
&lt;li&gt;FAQs &lt;/li&gt;
&lt;li&gt;Conclusion &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Large Language Models (LLMs) have quickly become practical tools for writing, coding, summarization, research, automation, and application development. Cloud-based services make this capability easy to access, but they also introduce an important question: where does the data go when we use an AI model?&lt;/p&gt;

&lt;p&gt;For developers and organizations working with source code, internal documents, customer information, business strategies, or other confidential material, sending every prompt to an external service may not always be appropriate. This is where Local LLMs become valuable.&lt;/p&gt;

&lt;p&gt;A Local LLM runs on hardware controlled by the user or organization rather than requiring every inference request to be processed by a remote AI service. Tools such as Ollama and LM Studio have made this approach significantly easier, allowing developers to download models and interact with them directly from their own machines. LM Studio, for example, states that downloaded models can run completely offline and that messages and documents processed locally do not leave the device. &lt;/p&gt;

&lt;p&gt;However, local deployment is not simply a matter of downloading a model and pressing "run." Hardware, model size, quantization, inference speed, security, model licensing, and application architecture all need to be considered.&lt;/p&gt;

&lt;p&gt;This article explains what Local LLMs are, why organizations may use them, how open-weight models work, how hardware requirements affect model selection, what quantization means, and how to get started with tools such as Ollama and LM Studio.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Understanding Local LLMs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;2.1 What Is a Local LLM?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Local Large Language Model (LLM) is a language model whose inference process runs on hardware controlled by the user or organization.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;strong&gt;Application → Internet → Cloud AI Provider → Response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;a local deployment can look like:&lt;br&gt;
&lt;strong&gt;Application → Local Runtime → Local Model → Response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model's weights are downloaded to the machine, and the computation required to generate a response takes place locally.&lt;/p&gt;

&lt;p&gt;This makes Local LLMs particularly interesting for applications where developers want tighter control over the data-processing environment.&lt;/p&gt;

&lt;p&gt;It is important to distinguish local execution from simply using an open-source model. A model can have publicly available or open weights while still being hosted remotely. Conversely, an open-weight model can be downloaded and executed entirely on local infrastructure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Generative models are changing the way we think about machine intelligence and creativity, and have the potential to transform industries from media to finance to healthcare.” - Oriol Vinyals&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;2.2 Local LLM vs. Cloud LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fundamental difference is where inference takes place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd6ftic58icq1272az230.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd6ftic58icq1272az230.png" alt=" " width="567" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neither approach is universally better.&lt;/p&gt;

&lt;p&gt;Cloud LLMs are convenient and can provide access to extremely capable models without requiring expensive hardware. Local LLMs become attractive when data control, offline operation, customization, predictable infrastructure, or local processing are important.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Artificial intelligence is the new electricity.” - Andrew Ng&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The comparison is therefore less about replacing cloud AI completely and more about choosing the right deployment model for the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Why Run an LLM Locally?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;3.1 Data Privacy and Control&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the strongest reasons for local inference is control over sensitive information.&lt;/p&gt;

&lt;p&gt;Consider an organization developing an internal application. Its employees may need AI assistance while working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source code&lt;/li&gt;
&lt;li&gt;Internal documentation&lt;/li&gt;
&lt;li&gt;Product specifications&lt;/li&gt;
&lt;li&gt;Business strategies&lt;/li&gt;
&lt;li&gt;Customer information&lt;/li&gt;
&lt;li&gt;Research documents&lt;/li&gt;
&lt;li&gt;Proprietary processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a local model, these inputs can remain within the organization's infrastructure.&lt;/p&gt;

&lt;p&gt;However, local does not automatically mean secure. The application can still expose data through APIs, network services, logs, telemetry, plugins, or poorly configured infrastructure. Security therefore needs to cover the entire system, not just the model.&lt;/p&gt;

&lt;p&gt;Cloud services can also provide strong privacy controls. For example, OpenAI states that data from its business products and API platform is not used to train its models by default, while API abuse-monitoring logs may be retained for a limited period under default settings. &lt;a href="https://openai.com/business-data/" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important lesson is that organizations should evaluate the actual data policy and deployment architecture rather than assuming that every cloud service handles data in the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.2 Offline Operation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the model and required runtime files have been downloaded, local inference can continue without an internet connection.&lt;/p&gt;

&lt;p&gt;LM Studio explicitly supports completely offline operation for downloaded models, including local document processing and running a local server. &lt;/p&gt;

&lt;p&gt;This can be useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Air-gapped environments&lt;/li&gt;
&lt;li&gt;Locations with unreliable connectivity&lt;/li&gt;
&lt;li&gt;Development without API dependencies&lt;/li&gt;
&lt;li&gt;Internal systems where external network access is restricted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is one obvious limitation: a local model still requires electricity and functioning hardware. Offline does not mean independent of physical infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3 Customization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open-weight models can provide developers with more control over how an AI system is deployed and adapted.&lt;/p&gt;

&lt;p&gt;Depending on the model's license and capabilities, developers may be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fine-tune a model&lt;/li&gt;
&lt;li&gt;Modify inference parameters&lt;/li&gt;
&lt;li&gt;Create custom prompts&lt;/li&gt;
&lt;li&gt;Build retrieval-augmented applications&lt;/li&gt;
&lt;li&gt;Run specialized workflows&lt;/li&gt;
&lt;li&gt;Integrate the model into internal applications&lt;/li&gt;
&lt;li&gt;Keep the inference pipeline under organizational control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenAI's gpt-oss models, for example, are open-weight models designed to run on infrastructure controlled by the user and are released under Apache 2.0, subject to the applicable usage policy. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.4 Latency and Infrastructure Control&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Local inference can eliminate the network round trip between an application and a remote model server.&lt;/p&gt;

&lt;p&gt;For applications running close to the model, this can reduce network-related latency and make the system less dependent on external service availability.&lt;/p&gt;

&lt;p&gt;However, local does not always mean faster.&lt;/p&gt;

&lt;p&gt;A small cloud model running on powerful infrastructure can be considerably faster than a large model running on a CPU-only laptop. Performance depends on model size, quantization, hardware, context length, batch size, runtime, and workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Open-Weight Models and the Local AI Ecosystem
&lt;/h2&gt;

&lt;p&gt;Modern Local LLM ecosystems depend heavily on open-weight models.&lt;br&gt;
Model weights are the numerical parameters learned during training. They contain much of the information required for the model to perform inference.&lt;/p&gt;

&lt;p&gt;When model weights are made available for download, developers can obtain those weights and run the model using compatible inference software.&lt;/p&gt;

&lt;p&gt;This has helped create an ecosystem involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model developers&lt;/li&gt;
&lt;li&gt;Open-weight model releases&lt;/li&gt;
&lt;li&gt;Model repositories&lt;/li&gt;
&lt;li&gt;Inference runtimes&lt;/li&gt;
&lt;li&gt;Quantization formats&lt;/li&gt;
&lt;li&gt;Desktop applications&lt;/li&gt;
&lt;li&gt;Developer APIs&lt;/li&gt;
&lt;li&gt;Community tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hugging Face's Model Hub, for example, provides a central repository for discovering, storing, downloading, and sharing model checkpoints.&lt;/p&gt;

&lt;p&gt;Some notable model families available for local experimentation include Qwen3, Gemma 3, Llama-family models, Phi models, and OpenAI's gpt-oss.&lt;/p&gt;

&lt;p&gt;As an example, Ollama currently lists Qwen3 variants ranging from 0.6B to 235B parameters, while Gemma 3 is available in sizes from 270M to 27B parameters. &lt;/p&gt;

&lt;p&gt;OpenAI's gpt-oss family currently includes gpt-oss-20b and gpt-oss-120b, with the models designed for infrastructure controlled by the developer or organization. &lt;a href="https://help.openai.com/en/articles/11870455-openai-open-weight-models-gpt-oss" rel="noopener noreferrer"&gt;OpenAI Help Center&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The availability of many model sizes is important because local AI is not one-size-fits-all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Generative AI is teaching us that the way you speak is actually code itself.” - Lisa Huang&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Model Size and Hardware Requirements
&lt;/h2&gt;

&lt;p&gt;A model's parameter count is one of the major factors affecting its memory requirements.&lt;br&gt;
A simplified progression looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk8g2urq7zz9ra59mbuqo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk8g2urq7zz9ra59mbuqo.png" alt=" " width="573" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*These are rough planning ranges rather than strict hardware requirements. Actual memory consumption depends on precision, quantization, context length, runtime overhead, and whether CPU RAM is also used.&lt;/p&gt;

&lt;p&gt;Real model packages illustrate the difference clearly. Ollama currently lists Qwen3 4B at around 2.5 GB, Qwen3 8B at around 5.2 GB, Qwen3 14B at around 9.3 GB, and Qwen3 32B at around 20 GB for listed variants. &lt;/p&gt;

&lt;p&gt;Gemma 3 similarly ranges from small models to a 27B model, with Ollama listing the 27B variant at around 17 GB for its current package. &lt;/p&gt;

&lt;p&gt;This is why developers should select a model based on the task and available hardware, rather than simply choosing the model with the highest parameter count.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Understanding Quantization
&lt;/h2&gt;

&lt;p&gt;Running a large model at full numerical precision can require significant memory.&lt;/p&gt;

&lt;p&gt;Quantization addresses this problem by representing model weights using fewer bits.&lt;/p&gt;

&lt;p&gt;For example, instead of representing weights using higher-precision numerical formats, a model can be converted to a 4-bit representation.&lt;/p&gt;

&lt;p&gt;The result is a substantially smaller model that can often run on hardware that would not have enough memory for the original version.&lt;br&gt;
A simplified workflow is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full-precision model → Quantization → Smaller model representation → Lower memory requirement → Local inference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, Ollama lists Qwen3 4B variants using formats such as Q4_K_M, with the listed 4B model around 2.5 GB. &lt;/p&gt;

&lt;p&gt;Quantization is not magic, however. Lower precision can introduce quality degradation depending on the model, quantization method, task, and configuration.&lt;/p&gt;

&lt;p&gt;Therefore, the right approach is to benchmark the quantized model on the actual workload rather than assuming that every 4-bit model will behave identically to its full-precision counterpart.&lt;/p&gt;

&lt;p&gt;A useful rule is:&lt;br&gt;
&lt;strong&gt;Use the smallest model and lowest precision that still provide acceptable quality for your application.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Aristotle founded or discovered logic by observing the world. ChatGPT thinks logically. Why? Because it notices all the logic in the data in its training set.” - Stephen Wolfram&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7. Popular Tools for Running Local LLMs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;7.1 Ollama&lt;/strong&gt;&lt;br&gt;
Ollama is one of the simplest ways to run local LLMs from the command line.&lt;/p&gt;

&lt;p&gt;A developer can download a supported model and start interacting with it using a command such as:&lt;/p&gt;

&lt;p&gt;ollama run qwen3:4b&lt;/p&gt;

&lt;p&gt;Ollama also exposes APIs that applications can use to communicate with locally running models. Its model library currently includes Qwen3, Gemma 3, and many other model families. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7.2 LM Studio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LM Studio provides a graphical interface for downloading and interacting with local models.&lt;/p&gt;

&lt;p&gt;It can also run a local API server, allowing applications to communicate with models through REST APIs and OpenAI-compatible endpoints. &lt;/p&gt;

&lt;p&gt;One of its useful characteristics is offline operation. After the required model files are available, local chatting, document processing, and local inference can work without an internet connection. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7.3 Hugging Face&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hugging Face is not primarily an inference application like Ollama or LM Studio. Instead, it acts as a major ecosystem for discovering and sharing models, datasets, and other machine-learning resources.&lt;/p&gt;

&lt;p&gt;Its Model Hub provides repositories containing model checkpoints and supports downloading models through tools such as huggingface_hub. &lt;br&gt;
&lt;a href="https://huggingface.co/docs/hub/en/models-the-hub" rel="noopener noreferrer"&gt;Hugging Face&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The three tools therefore serve somewhat different purposes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbszmthrqa44r5o1zx3mq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbszmthrqa44r5o1zx3mq.png" alt=" " width="420" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Setting Up a Local LLM with Ollama
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;8.1 Install Ollama&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On Linux, Ollama provides an installation command:&lt;br&gt;
curl -fsSL &lt;a href="https://ollama.com/install.sh" rel="noopener noreferrer"&gt;https://ollama.com/install.sh&lt;/a&gt; | sh&lt;br&gt;
After installation, verify that Ollama is available from the terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8.2 Download a Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
ollama run qwen3:4b&lt;br&gt;
or:&lt;br&gt;
ollama run gemma3:8b&lt;/p&gt;

&lt;p&gt;The exact model tags available can change, so developers should check the current model library before using a command in production. Ollama currently lists Qwen3 4B and Gemma 3 variants in its model library. &lt;a href="https://ollama.com/library/qwen3" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a lightweight experiment, a smaller model such as Qwen3 4B can be a reasonable starting point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8.3 Test the Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the model starts, provide a simple prompt:&lt;br&gt;
Explain REST APIs in simple terms.&lt;/p&gt;

&lt;p&gt;Then test more application-specific workloads:&lt;br&gt;
Summarize this technical document.&lt;/p&gt;

&lt;p&gt;or:&lt;br&gt;
Extract the action items from this meeting transcript.&lt;/p&gt;

&lt;p&gt;Testing should not only measure whether the model produces an answer. It should also evaluate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accuracy&lt;/li&gt;
&lt;li&gt;Response time&lt;/li&gt;
&lt;li&gt;Memory usage&lt;/li&gt;
&lt;li&gt;Hallucination rate&lt;/li&gt;
&lt;li&gt;Output consistency&lt;/li&gt;
&lt;li&gt;Behavior with long context&lt;/li&gt;
&lt;li&gt;Performance on the actual application workload&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;8.4 Integrate the Model into an Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next step is to connect the local model to an application.&lt;br&gt;
A typical architecture can be represented as:&lt;br&gt;
User&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Application&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Local API&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Inference Runtime&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Local LLM&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Response&lt;/p&gt;

&lt;p&gt;The application can therefore treat the local model as an internal AI service.&lt;/p&gt;

&lt;p&gt;LM Studio, for example, provides OpenAI-compatible local endpoints, which can make integration easier for applications already designed around common LLM APIs. &lt;a href="https://lmstudio.ai/docs/developer/core/server" rel="noopener noreferrer"&gt;LM Studio&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“As this technology continues to evolve, it is essential to leverage its power responsibly and ensure its positive impact on society.” - Mohith Agadi&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  9. Security and Practical Considerations
&lt;/h2&gt;

&lt;p&gt;Local deployment solves some privacy problems, but it introduces responsibilities that a developer must not ignore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.1 Protect the Local API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If an LLM server is bound only to localhost, it is generally accessible only from the same machine.&lt;/p&gt;

&lt;p&gt;If it is exposed to a wider network, authentication and network controls become important. LM Studio specifically warns that binding its server beyond localhost exposes it to other devices and recommends authentication when doing so. &lt;a href="https://lmstudio.ai/docs/developer/core/server/serve-on-network" rel="noopener noreferrer"&gt;LM Studio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9.2 Secure Model Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Model weights should be obtained from trusted sources.&lt;/p&gt;

&lt;p&gt;A downloaded model is software infrastructure, and organizations should consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model provenance&lt;/li&gt;
&lt;li&gt;License&lt;/li&gt;
&lt;li&gt;Hashes or integrity checks&lt;/li&gt;
&lt;li&gt;Repository reputation&lt;/li&gt;
&lt;li&gt;Security policies&lt;/li&gt;
&lt;li&gt;Allowed commercial usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;9.3 Monitor Resource Usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A model that works well on a development machine may behave differently under production workloads.&lt;/p&gt;

&lt;p&gt;Monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage&lt;/li&gt;
&lt;li&gt;GPU utilization&lt;/li&gt;
&lt;li&gt;RAM/VRAM usage&lt;/li&gt;
&lt;li&gt;Request latency&lt;/li&gt;
&lt;li&gt;Concurrent requests&lt;/li&gt;
&lt;li&gt;Context length&lt;/li&gt;
&lt;li&gt;Disk usage&lt;/li&gt;
&lt;li&gt;Power consumption&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;9.4 Evaluate Before Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A local model should be tested against real application examples before being considered production-ready.&lt;/p&gt;

&lt;p&gt;For example, a summarization model should be evaluated against representative documents rather than a handful of simple prompts.&lt;/p&gt;

&lt;p&gt;The goal is not merely:&lt;br&gt;
&lt;strong&gt;"Does the model answer?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;but:&lt;br&gt;
&lt;strong&gt;"Does the model answer correctly enough for this specific application?"&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Statistics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;10.1 AI Inference Has Become Dramatically Cheaper&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to the Stanford AI Index 2025, the cost of querying an AI model performing at approximately GPT-3.5's level on the MMLU benchmark fell from $20 per million tokens in November 2022 to $0.07 per million tokens by October 2024-a reduction of more than 280× in roughly 18 months. &lt;a href="https://hai.stanford.edu/ai-index/2025-ai-index-report/research-and-development" rel="noopener noreferrer"&gt;Stanford HAI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: Stanford Institute for Human-Centered Artificial Intelligence&lt;br&gt;
&lt;a href="https://hai.stanford.edu/ai-index/2025-ai-index-report/research-and-development" rel="noopener noreferrer"&gt;Original Stanford AI Index source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10.2 Smaller Models Are Becoming More Capable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same Stanford AI Index reports that the smallest model exceeding 60% on the MMLU benchmark decreased from 540 billion parameters in 2022 to 3.8 billion parameters in 2024, representing a 142-fold reduction in parameter count for that benchmark threshold. &lt;a href="https://hai.stanford.edu/news/ai-index-2025-state-of-ai-in-10-charts?trk=article-ssr-frontend-pulse_little-text-block" rel="noopener noreferrer"&gt;Stanford HAI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: Stanford Institute for Human-Centered Artificial Intelligence&lt;br&gt;
&lt;a href="https://hai.stanford.edu/news/ai-index-2025-state-of-ai-in-10-charts" rel="noopener noreferrer"&gt;Original Stanford AI Index source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This trend is particularly relevant to Local LLMs because increasingly capable smaller models make local inference more practical on consumer hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A local LLM does not necessarily require a high-end data center. Small models can run on relatively modest hardware.&lt;/li&gt;
&lt;li&gt;Quantization can dramatically reduce model size. For example, Ollama lists Qwen3 4B at roughly 2.5 GB for a Q4 variant. &lt;a href="https://ollama.com/library/qwen3%3A4b-instruct" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Local AI can operate without internet access after setup. LM Studio supports offline inference once the required model files are present. &lt;a href="https://lmstudio.ai/docs/app/offline" rel="noopener noreferrer"&gt;LM Studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Local models can expose APIs. A model running on a developer's machine does not have to be used only through a chat interface; it can become part of an application through a local API server. &lt;a href="https://lmstudio.ai/docs/developer/core/server" rel="noopener noreferrer"&gt;LM Studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The largest model is not always the best model. A smaller model may provide substantially better latency and lower resource consumption while being sufficient for a specific task.&lt;/li&gt;
&lt;li&gt;Open-weight and open-source are not always synonymous. A model can make its weights available while having licensing terms that differ from traditional open-source software licenses.&lt;/li&gt;
&lt;li&gt;Local deployment shifts responsibility toward the developer. Instead of relying entirely on a cloud provider for infrastructure and security, the organization becomes responsible for its own model-serving environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  12. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. What is a Local LLM?&lt;/strong&gt;&lt;br&gt;
A Local LLM is a language model whose inference runs on hardware controlled by the user or organization instead of sending every inference request to a remote model provider.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Are Local LLMs completely private?&lt;/strong&gt;&lt;br&gt;
They can provide significantly greater data control, but local deployment does not automatically guarantee privacy. Network configuration, application logs, APIs, plugins, model sources, and system security must also be considered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Do Local LLMs require a GPU?&lt;/strong&gt;&lt;br&gt;
Not always. Smaller models can run on CPUs, although GPU acceleration can substantially improve inference performance. Larger models generally benefit from significant GPU memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. What is the best model size for a laptop?&lt;/strong&gt;&lt;br&gt;
There is no universal answer. A smaller 3B–8B model is generally easier to run than a 30B or 70B model, but the appropriate choice depends on available RAM/VRAM and the application's quality requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. What does 4-bit quantization mean?&lt;/strong&gt;&lt;br&gt;
It means model weights are represented using a lower-bit numerical format, significantly reducing memory requirements. The trade-off is that some quality can be lost depending on the model and quantization method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Is Ollama the same as a Local LLM?&lt;/strong&gt;&lt;br&gt;
No. Ollama is a tool/runtime for running and interacting with local models. The LLM is the actual model, such as Qwen3 or Gemma 3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Can a Local LLM work without internet?&lt;/strong&gt;&lt;br&gt;
Yes, after the required model and runtime have been downloaded. For example, LM Studio documents that downloaded models can operate entirely offline. LM Studio&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Should organizations completely replace cloud LLMs with Local LLMs?&lt;/strong&gt;&lt;br&gt;
Not necessarily. A hybrid strategy can often be more practical. Sensitive workloads may run locally while workloads requiring highly capable cloud models can use appropriately governed cloud services.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“In a world where ChatGPT and other AI apps can do many things humans once needed to do themselves or needed to hire other humans to do, the question of ‘how will I add value?’ becomes more relevant than ever.” - Hendrith Vanlon Smith Jr.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  13. Conclusion
&lt;/h2&gt;

&lt;p&gt;Local LLMs represent an important shift in how developers think about AI infrastructure.&lt;/p&gt;

&lt;p&gt;Instead of treating AI exclusively as a remote service, organizations can increasingly treat language models as software infrastructure that can run under their own control.&lt;/p&gt;

&lt;p&gt;The advantages can include stronger data control, offline capability, customization, reduced dependence on external APIs, and potentially lower network latency. Simultaneously, local deployment introduces new responsibilities around hardware, model selection, security, maintenance, licensing, and evaluation.&lt;/p&gt;

&lt;p&gt;The rapid improvement of smaller models is making this approach increasingly practical. Stanford's AI Index shows that capable AI models have become dramatically smaller and cheaper to run, while tools such as Ollama and LM Studio have lowered the technical barrier to local inference. Stanford HAI&lt;/p&gt;

&lt;p&gt;The most important lesson is therefore not "always use Local LLMs."&lt;br&gt;
It is:&lt;br&gt;
Choose where your AI runs based on the data, task, performance requirements, cost, and level of control your application actually needs.&lt;/p&gt;

&lt;p&gt;Local AI is not a replacement for every cloud AI workload. It is another deployment option-and for privacy-sensitive and infrastructure-controlled applications, it can be a very powerful one.&lt;/p&gt;

&lt;p&gt;About the Author: &lt;em&gt;Tanisha is an AI Engineer at &lt;a href="https://www.addwebsolution.com" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, working on AI/ML solutions, intelligent applications, and emerging AI technologies.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>vertexai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>A Journey Through Sound: Building an AI Transcription Pipeline with Dograh</title>
      <dc:creator>Saad Ansari</dc:creator>
      <pubDate>Wed, 21 Oct 2026 05:25:53 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/a-journey-through-sound-building-an-ai-transcription-pipeline-with-dograh-2j4e</link>
      <guid>https://dev.to/addwebsolutionpvtltd/a-journey-through-sound-building-an-ai-transcription-pipeline-with-dograh-2j4e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Language is humanity’s most spectacular open source project.”-Gretchen McCulloch&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine a meeting with four people.&lt;/p&gt;

&lt;p&gt;One person is explaining a technical problem. Someone interrupts with a solution. Another person switches from English to Hindi. There is background noise, a few seconds of silence, and sometimes two people speak at the same time.&lt;/p&gt;

&lt;p&gt;Now take that one-hour conversation and ask a computer to turn it into a clean, searchable transcript.&lt;/p&gt;

&lt;p&gt;It sounds simple:&lt;br&gt;
Audio → Speech-to-Text → Text&lt;/p&gt;

&lt;p&gt;In practice, it is not.&lt;/p&gt;

&lt;p&gt;A useful transcription system has to deal with audio quality, silence, multiple speakers, timestamps, languages, technical vocabulary, and unreliable network or model responses.&lt;/p&gt;

&lt;p&gt;That is where an AI transcription pipeline becomes useful.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to build such a pipeline using Dograh as the voice-AI orchestration layer, along with audio processing, Voice Activity Detection (VAD), speech-to-text, transcript normalization, speaker handling, and downstream meeting intelligence.   &lt;/p&gt;
&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A production transcription system is a pipeline, not just an STT API call.&lt;/li&gt;
&lt;li&gt;VAD helps identify speech and reduce unnecessary audio processing.&lt;/li&gt;
&lt;li&gt;Dograh provides an open-source, self-hostable voice-AI platform with configurable STT integrations.&lt;/li&gt;
&lt;li&gt;Speaker identification and transcription are different problems.&lt;/li&gt;
&lt;li&gt;Timestamps and structured transcript data are valuable for summaries and action items.&lt;/li&gt;
&lt;li&gt;Multilingual meetings require deliberate language handling.&lt;/li&gt;
&lt;li&gt;Production systems need retries, logging, monitoring, security, and data-retention policies.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What Is an AI Transcription Pipeline?&lt;/li&gt;
&lt;li&gt;Why Speech Transcription Is Difficult&lt;/li&gt;
&lt;li&gt;Where Dograh Fits&lt;/li&gt;
&lt;li&gt;A Simple Analogy: The Detective’s Notebook&lt;/li&gt;
&lt;li&gt;Architecture and Workflow&lt;/li&gt;
&lt;li&gt;Building the Processing Pipeline&lt;/li&gt;
&lt;li&gt;Speakers, Languages, and Timestamps&lt;/li&gt;
&lt;li&gt;Practical Meeting Example&lt;/li&gt;
&lt;li&gt;Comparison of Approaches&lt;/li&gt;
&lt;li&gt;Advantages and Limitations&lt;/li&gt;
&lt;li&gt;Statistics&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  1. What Is an AI Transcription Pipeline?
&lt;/h2&gt;

&lt;p&gt;Automatic Speech Recognition (ASR) converts spoken audio into text.&lt;br&gt;
A basic system looks like:&lt;/p&gt;

&lt;p&gt;Audio&lt;br&gt;
  ↓&lt;br&gt;
Speech-to-Text Model&lt;br&gt;
  ↓&lt;br&gt;
Text&lt;br&gt;
For a real application, we usually need more stages:&lt;br&gt;
Meeting Audio&lt;br&gt;
      ↓&lt;br&gt;
Audio Validation&lt;br&gt;
      ↓&lt;br&gt;
Voice Activity Detection&lt;br&gt;
      ↓&lt;br&gt;
Speech-to-Text&lt;br&gt;
      ↓&lt;br&gt;
Speaker / Timestamp Processing&lt;br&gt;
      ↓&lt;br&gt;
Language Processing&lt;br&gt;
      ↓&lt;br&gt;
Transcript Cleanup&lt;br&gt;
      ↓&lt;br&gt;
Structured Transcript&lt;br&gt;
      ↓&lt;br&gt;
Summary / Action Items&lt;/p&gt;

&lt;p&gt;Each stage solves a different problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audio Validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before processing audio, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File exists&lt;/li&gt;
&lt;li&gt;Duration is valid&lt;/li&gt;
&lt;li&gt;Sample rate is supported&lt;/li&gt;
&lt;li&gt;Audio is not empty&lt;/li&gt;
&lt;li&gt;File format is valid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Voice Activity Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;VAD determines which parts of an audio recording contain speech.&lt;br&gt;
For example:&lt;/p&gt;

&lt;p&gt;[Silence] [Speech] [Silence] [Speech] [Noise]&lt;br&gt;
The pipeline can concentrate on the speech regions instead of treating the entire recording equally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speech-to-Text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The STT model converts the detected speech into text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-Processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, the transcript can be cleaned, normalized, translated, summarized, or converted into structured data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Speech and language technology … is really the hardest AI challenge we’re facing.”- Xuedong Huang&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That observation explains why a seemingly simple feature such as “convert this meeting recording into text” quickly becomes a systems problem.&lt;/p&gt;

&lt;p&gt;This separation makes the system easier to test and maintain.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Why Speech Transcription Is Difficult
&lt;/h2&gt;

&lt;p&gt;A person can listen to a meeting and understand context naturally.&lt;br&gt;
A machine receives an audio signal.&lt;br&gt;
That creates several challenges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Background Noise&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real meetings may contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keyboard sounds&lt;/li&gt;
&lt;li&gt;fans&lt;/li&gt;
&lt;li&gt;traffic&lt;/li&gt;
&lt;li&gt;room echo&lt;/li&gt;
&lt;li&gt;microphone noise&lt;/li&gt;
&lt;li&gt;multiple audio sources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Poor audio quality can directly affect transcription accuracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Silence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A long meeting may contain many periods where nobody is speaking.&lt;br&gt;
Processing every second unnecessarily increases work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple Speakers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
Saad: We can deploy the service tomorrow-&lt;/p&gt;

&lt;p&gt;Sneha: Did we test the worker first?&lt;/p&gt;

&lt;p&gt;Two voices may overlap.&lt;/p&gt;

&lt;p&gt;The system has to determine what was said and, depending on the pipeline, who said it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple Languages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A meeting may contain:&lt;br&gt;
Saad: Let's deploy the service today.&lt;/p&gt;

&lt;p&gt;Sneha: Pehle worker ko test karna chahiye.&lt;/p&gt;

&lt;p&gt;Manthan: Yes, then we can check the logs.&lt;/p&gt;

&lt;p&gt;A multilingual pipeline needs to handle this deliberately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Vocabulary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software meetings contain terms such as:&lt;/p&gt;

&lt;p&gt;FastAPI&lt;br&gt;
PostgreSQL&lt;br&gt;
Docker&lt;br&gt;
Redis&lt;br&gt;
PyTorch&lt;br&gt;
Kubernetes&lt;br&gt;
WebSocket&lt;/p&gt;

&lt;p&gt;These can be difficult for speech recognition systems, especially when the audio itself is noisy.&lt;/p&gt;

&lt;p&gt;This is why transcription quality depends on the complete pipeline, not only the model.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Where Dograh Fits
&lt;/h2&gt;

&lt;p&gt;Dograh is an open-source, self-hostable voice-AI platform.&lt;br&gt;
Its architecture separates different parts of a voice workflow, including speech-to-text, LLM processing, text-to-speech, and telephony.&lt;/p&gt;

&lt;p&gt;A simplified view is:&lt;br&gt;
Audio&lt;br&gt;
  ↓&lt;br&gt;
STT&lt;br&gt;
  ↓&lt;br&gt;
LLM&lt;br&gt;
  ↓&lt;br&gt;
TTS&lt;br&gt;
  ↓&lt;br&gt;
Response&lt;/p&gt;

&lt;p&gt;Dograh also supports configurable STT providers, allowing developers to choose the speech technology appropriate for their application.&lt;/p&gt;

&lt;p&gt;This is useful because the requirements of a customer-support voice bot may be different from those of a meeting transcription system.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxy3wfwsa6uq1xe9262bq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxy3wfwsa6uq1xe9262bq.png" alt=" " width="799" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important architectural idea is separation of responsibilities.&lt;br&gt;
Dograh can handle voice-AI orchestration while the application can handle domain-specific transcript processing.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. A Simple Analogy: The Detective’s Notebook
&lt;/h2&gt;

&lt;p&gt;Think about a detective investigating a complicated case.&lt;/p&gt;

&lt;p&gt;The detective does not listen to every conversation once and immediately write a final report.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
Evidence&lt;br&gt;
   ↓&lt;br&gt;
Filter useful information&lt;br&gt;
   ↓&lt;br&gt;
Identify people&lt;br&gt;
   ↓&lt;br&gt;
Record timestamps&lt;br&gt;
   ↓&lt;br&gt;
Connect events&lt;br&gt;
   ↓&lt;br&gt;
Write report&lt;/p&gt;

&lt;p&gt;An AI transcription pipeline works similarly. The audio is the evidence. VAD identifies useful speech. STT converts speech into text. Speaker processing identifies participants. Timestamps tell us when something happened. The final transcript becomes structured evidence for another system. That system might then create:&lt;/p&gt;

&lt;p&gt;Summary&lt;br&gt;
Decisions&lt;br&gt;
Action Items&lt;br&gt;
Deadlines&lt;/p&gt;

&lt;p&gt;The transcript is therefore not always the final product. It is often the foundation for everything that comes after it.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Architecture and Workflow
&lt;/h2&gt;

&lt;p&gt;For a meeting-notes application, a practical architecture can look like this:          &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Facae4xygo5y0znn7hgfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Facae4xygo5y0znn7hgfe.png" alt=" " width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frfj0gwn5837oedsp9afh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frfj0gwn5837oedsp9afh.png" alt=" " width="536" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This architecture also makes debugging easier.&lt;/p&gt;

&lt;p&gt;If something goes wrong, we can ask:&lt;br&gt;
Was the recording bad?&lt;br&gt;
       ↓&lt;br&gt;
Did VAD fail?&lt;br&gt;
       ↓&lt;br&gt;
Did STT fail?&lt;br&gt;
       ↓&lt;br&gt;
Did speaker mapping fail?&lt;br&gt;
       ↓&lt;br&gt;
Did the LLM receive bad data?&lt;/p&gt;

&lt;p&gt;Instead of simply saying:&lt;br&gt;
“The transcription is wrong.”&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Building the Processing Pipeline
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Normalize Audio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A preprocessing layer can convert audio into a predictable format.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i meeting.wav \
  -ar 16000 \
  -ac 1 \
  -c:a pcm_s16le \
  meeting-normalized.wav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This converts the recording to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16 kHz sample rate&lt;/li&gt;
&lt;li&gt;Mono audio&lt;/li&gt;
&lt;li&gt;PCM 16-bit audio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact format should depend on the STT system being used. The goal is consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Detect Speech&lt;/strong&gt;&lt;br&gt;
A VAD system can identify speech regions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;speech_regions = vad.detect(audio)

for region in speech_regions:
    print(
        f"{region.start:.2f}s - "
        f"{region.end:.2f}s"
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of treating an entire recording as useful speech, the pipeline can focus on regions where people are actually talking. This becomes especially useful for long recordings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Transcribe&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The speech segments are passed to the configured STT system. Dograh’s architecture treats STT as a separate component of the voice workflow, allowing different providers and models to be integrated into the larger system. This separation also makes it easier to test different transcription approaches without rewriting the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Normalize the Transcript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Different providers may return different response formats. Your application should convert them into a consistent internal structure.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from dataclasses import dataclass, asdict

@dataclass
class TranscriptSegment:
    speaker: str
    start: float
    end: float
    text: str

def normalize_segments(raw_segments):
    result = []

    for segment in raw_segments:
        result.append(
            TranscriptSegment(
                speaker=segment.get("speaker", "unknown"),
                start=float(segment["start"]),
                end=float(segment["end"]),
                text=segment["text"].strip(),
            )
        )

    return [asdict(item) for item in result]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The provider may return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "speaker": "spk_0",
  "start": 12.4,
  "end": 15.8,
  "text": "Let's deploy the service."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our application converts it into a predictable format.The rest of the system does not need to know which provider generated the transcript.That makes the architecture easier to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Speakers, Languages, and Timestamps
&lt;/h2&gt;

&lt;p&gt;A plain transcript might look like:&lt;br&gt;
Let's deploy the service tomorrow.&lt;br&gt;
We should test the worker first.&lt;br&gt;
The API is returning a timeout.&lt;br&gt;
A structured transcript is much more useful:&lt;br&gt;
[00:12] Saad&lt;br&gt;
Let's deploy the service tomorrow.&lt;/p&gt;

&lt;p&gt;[00:18] Sneha&lt;br&gt;
We should test the worker first.&lt;/p&gt;

&lt;p&gt;[00:25] Manthan&lt;br&gt;
The API is returning a timeout.&lt;br&gt;
Now the same data can support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meeting summaries&lt;/li&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Action items&lt;/li&gt;
&lt;li&gt;Speaker-specific analysis&lt;/li&gt;
&lt;li&gt;Auditing&lt;/li&gt;
&lt;li&gt;Meeting playback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Speaker Diarization vs Speaker Identification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are different problems.&lt;/p&gt;

&lt;p&gt;Diarization can produce:&lt;br&gt;
Speaker 0&lt;br&gt;
Speaker 1&lt;br&gt;
Speaker 0&lt;/p&gt;

&lt;p&gt;But that does not automatically mean:&lt;br&gt;
Speaker 0 = Saad&lt;br&gt;
Speaker 1 = Sneha&lt;/p&gt;

&lt;p&gt;The application needs additional information to map technical speaker labels to real participant names. This distinction is important when building meeting applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multilingual Processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For multilingual meetings, preserve the original text whenever possible.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
Original:&lt;br&gt;
"Pehle worker ko test karna chahiye."&lt;/p&gt;

&lt;p&gt;Normalized:&lt;br&gt;
"We should test the worker first."&lt;br&gt;
Keeping both gives the application:&lt;br&gt;
Original Transcript&lt;br&gt;
        +&lt;br&gt;
Normalized Transcript&lt;br&gt;
The original remains the source of truth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diarization is not automatically speaker identification.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Diarization tells us that two different voices exist.&lt;br&gt;
Identification tells us who those voices belong to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Speech is the most natural way humans communicate.”- David Leroy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The engineering challenge begins when we ask a machine to understand that speech under real-world conditions.&lt;/p&gt;
&lt;h2&gt;
  
  
  8. Practical Example: Meeting Notes Bot
&lt;/h2&gt;

&lt;p&gt;Imagine we are building a meeting-notes bot.&lt;br&gt;
The requirements are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Join a meeting.&lt;/li&gt;
&lt;li&gt;Record audio.&lt;/li&gt;
&lt;li&gt;Generate a transcript.&lt;/li&gt;
&lt;li&gt;Identify speakers.&lt;/li&gt;
&lt;li&gt;Generate a summary.&lt;/li&gt;
&lt;li&gt;Extract action items.&lt;/li&gt;
&lt;li&gt;Store the results.&lt;/li&gt;
&lt;li&gt;Delete temporary audio after successful processing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
Meeting Starts&lt;br&gt;
      ↓&lt;br&gt;
Bot Joins&lt;br&gt;
      ↓&lt;br&gt;
Audio Recording&lt;br&gt;
      ↓&lt;br&gt;
Audio Validation&lt;br&gt;
      ↓&lt;br&gt;
VAD&lt;br&gt;
      ↓&lt;br&gt;
STT / Dograh&lt;br&gt;
      ↓&lt;br&gt;
Transcript&lt;br&gt;
      ↓&lt;br&gt;
Speaker + Timestamp Processing&lt;br&gt;
      ↓&lt;br&gt;
Summary + Action Items&lt;br&gt;
      ↓&lt;br&gt;
Database&lt;br&gt;
      ↓&lt;br&gt;
Cleanup&lt;br&gt;
A structured result might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "meeting_id": "meeting_123",
  "segments": [
    {
      "speaker": "Saad",
      "start": 12.4,
      "end": 18.2,
      "text": "Let's test the transcription worker today."
    },
    {
      "speaker": "Sneha",
      "start": 18.5,
      "end": 24.0,
      "text": "I already checked the worker logs."
    }
  ],
  "action_items": [
    {
      "owner": "Saad",
      "task": "Test the transcription worker"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application now has structured information instead of one large text file.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Comparison of Approaches
&lt;/h2&gt;

&lt;p&gt;Different applications require different architectures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwobdxq3okete9tu7jnqr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwobdxq3okete9tu7jnqr.png" alt=" " width="536" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is no universal winner.&lt;/p&gt;

&lt;p&gt;The right choice depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Privacy requirements&lt;/li&gt;
&lt;li&gt;Accuracy requirements&lt;/li&gt;
&lt;li&gt;Cost&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Infrastructure&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Engineering resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Advantages and Limitations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modular&lt;/strong&gt;&lt;br&gt;
Each stage can be tested independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexible&lt;/strong&gt;&lt;br&gt;
STT providers and processing components can be changed without redesigning the entire application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Hostable&lt;/strong&gt;&lt;br&gt;
Dograh can be deployed within infrastructure controlled by the development team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better Downstream Processing&lt;/strong&gt;&lt;br&gt;
Structured transcripts are easier for LLMs and databases to consume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy Is Not Guaranteed&lt;/strong&gt;&lt;br&gt;
Speech recognition can still make mistakes, particularly with noise, accents, technical terms, and overlapping speech.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure Complexity&lt;/strong&gt;&lt;br&gt;
Self-hosting introduces responsibilities such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deployment&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;li&gt;upgrades&lt;/li&gt;
&lt;li&gt;GPU/CPU management&lt;/li&gt;
&lt;li&gt;networking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Speaker Mapping&lt;/strong&gt;&lt;br&gt;
Knowing that two speakers exist is different from knowing their names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multilingual Complexity&lt;/strong&gt;&lt;br&gt;
Mixed-language conversations may require additional language detection, translation, and normalization.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Statistics
&lt;/h2&gt;

&lt;p&gt;Numbers are useful only when we understand what they measure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Whisper Was Trained on 680,000 Hours of Audio&lt;/strong&gt;&lt;br&gt;
Statistic: OpenAI reports that Whisper was trained on 680,000 hours of multilingual and multitask supervised audio data collected from the web.&lt;br&gt;
Why it matters: Large and diverse training data was one factor behind Whisper’s reported robustness across accents, background noise, technical language, and multiple languages.&lt;br&gt;
Year: 2022&lt;br&gt;
Source: &lt;a href="https://openai.com/index/whisper/" rel="noopener noreferrer"&gt;OpenAI- Introducing Whisper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Whisper’s Training Data Covered 98 Non-English Languages&lt;/strong&gt;&lt;br&gt;
Statistic: The Whisper model card reports that approximately 117,000 hours of the training data represented non-English audio paired with corresponding transcripts, covering 98 languages.&lt;br&gt;
Why it matters: Multilingual training is particularly relevant to applications where users switch languages or where English is not the only language being spoken.&lt;br&gt;
Year: Model card, current repository documentation&lt;br&gt;
Source: &lt;a href="https://cdn.openai.com/papers/whisper.pdf" rel="noopener noreferrer"&gt;Whisper Research Paper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. pyannote Community-1 Processes AMI Audio at About 31 Seconds per Hour&lt;/strong&gt;&lt;br&gt;
Statistic: The pyannote project reports approximately 31 seconds of processing time per hour of AMI audio for its community-1 diarization pipeline under the published benchmark setup.&lt;br&gt;
Why it matters: Diarization does not necessarily require processing time comparable to the duration of the recording. Hardware, pipeline configuration, and workload can dramatically affect throughput.&lt;br&gt;
Benchmark setup: NVIDIA H100 80GB HBM3, benchmark updated September 2025.&lt;br&gt;
Source: &lt;a href="https://github.com/pyannote/pyannote-audio" rel="noopener noreferrer"&gt;pyannote.audio GitHub &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. WER Is the Standard Basic Metric for Speech Recognition&lt;/strong&gt;&lt;br&gt;
Statistic: Word Error Rate is calculated as:&lt;br&gt;
WER = (Substitutions + Deletions + Insertions) / Reference Words&lt;br&gt;
Why it matters: A transcript containing fewer word-level errors is generally more accurate, but WER does not treat all mistakes equally. An incorrect person’s name can be much more damaging than an incorrect filler word.&lt;br&gt;
Source: &lt;a href="https://www.assemblyai.com/benchmarks" rel="noopener noreferrer"&gt;AssemblyAI- Speech-to-Text Benchmarks&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Interesting Facts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Transcription and Translation Are Different Tasks&lt;/strong&gt;&lt;br&gt;
An ASR system can produce text in the language that was spoken.&lt;br&gt;
Translation changes that text into another language.&lt;br&gt;
For example:&lt;br&gt;
Hindi Speech&lt;br&gt;
     ↓&lt;br&gt;
Hindi Transcript&lt;br&gt;
     ↓&lt;br&gt;
English Translation&lt;br&gt;
Combining the two concepts too early can make debugging much harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Speaker Diarization Does Not Necessarily Know Names&lt;/strong&gt;&lt;br&gt;
A diarization system can identify:&lt;br&gt;
SPEAKER_00&lt;br&gt;
SPEAKER_01&lt;br&gt;
SPEAKER_02&lt;br&gt;
but that does not automatically mean:&lt;br&gt;
SPEAKER_00 = Alice&lt;br&gt;
SPEAKER_01 = Bob&lt;br&gt;
SPEAKER_02 = Charlie&lt;br&gt;
Additional identity information is required for reliable name mapping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. pyannote Supports Exclusive Speaker Diarization&lt;/strong&gt;&lt;br&gt;
Recent pyannote releases include an exclusive diarization output intended to make reconciliation between speaker timestamps and transcription timestamps easier.&lt;br&gt;
This is particularly useful because ASR and diarization systems do not always produce perfectly matching segment boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Dograh Is More Than an STT Layer&lt;/strong&gt;&lt;br&gt;
Dograh describes itself as an open-source voice AI platform rather than simply a transcription API.&lt;br&gt;
Its platform includes workflow construction, STT, LLM, TTS, telephony integrations, and MCP capabilities.&lt;br&gt;
That makes it possible to think about transcription as one part of a larger voice-agent architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Noise Is Not the Same as Silence&lt;/strong&gt;&lt;br&gt;
A silent section is relatively easy to identify.&lt;br&gt;
Noise is more difficult.&lt;/p&gt;

&lt;p&gt;A microphone can capture:&lt;br&gt;
Keyboard&lt;br&gt;
Fan&lt;br&gt;
Traffic&lt;br&gt;
Echo&lt;br&gt;
People talking in another room&lt;/p&gt;

&lt;p&gt;without producing intentional speech.&lt;/p&gt;

&lt;p&gt;That is why speech detection and audio preprocessing matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Real-World Audio Is Different From Benchmark Audio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A clean test file can produce impressive results.&lt;br&gt;
A real meeting can contain:&lt;br&gt;
Accent&lt;br&gt;
+&lt;br&gt;
Noise&lt;br&gt;
+&lt;br&gt;
Cross-talk&lt;br&gt;
+&lt;br&gt;
Code-switching&lt;br&gt;
+&lt;br&gt;
Technical terminology&lt;br&gt;
A production evaluation should therefore use audio that resembles the application’s actual environment.&lt;/p&gt;

&lt;p&gt;For speech systems, that “open source project” comes with enormous variation: accents, dialects, vocabulary, speaking styles, and context.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is an AI transcription pipeline?&lt;/strong&gt;&lt;br&gt;
It is a series of processing stages that converts audio into structured text. It can include audio validation, VAD, STT, speaker handling, language processing, and post-processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use Dograh?&lt;/strong&gt;&lt;br&gt;
Dograh provides an open-source, self-hostable voice-AI platform with configurable components such as STT, LLM, and TTS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Whisper enough for production?&lt;/strong&gt;&lt;br&gt;
Whisper can be a strong STT component, but production quality depends on the complete pipeline, including audio processing, VAD, language handling, speaker processing, and monitoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does transcription automatically identify speakers?&lt;/strong&gt;&lt;br&gt;
No. Transcription determines what was said. Speaker diarization determines which voice spoke. Mapping that voice to an actual person’s name is another step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why use VAD?&lt;/strong&gt;&lt;br&gt;
VAD identifies speech regions and can reduce unnecessary processing of silence and non-speech audio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How should multilingual meetings be handled?&lt;/strong&gt;&lt;br&gt;
Keep the original transcript and, when required, generate a separate normalized or translated version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should meeting recordings be stored permanently?&lt;/strong&gt;&lt;br&gt;
Not necessarily. Retention should be based on the application’s privacy, security, and business requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can the STT provider be changed later?&lt;/strong&gt;&lt;br&gt;
Yes, if provider-specific code is isolated behind a common interface and the application uses its own internal transcript format.&lt;/p&gt;

&lt;h2&gt;
  
  
  14. Conclusion
&lt;/h2&gt;

&lt;p&gt;Building an AI transcription system looks simple from a distance:&lt;br&gt;
Audio → Text&lt;/p&gt;

&lt;p&gt;Once you build one for real meetings, the complexity becomes obvious. People interrupt each other. Languages change. Microphones introduce noise. Silence fills recordings. Models make mistakes. And the transcript itself is often only the beginning. A better approach is to treat transcription as a pipeline. Audio validation prepares the input. VAD finds useful speech. Dograh can orchestrate the voice workflow and STT layer. Normalization creates consistent data. Speaker and timestamp processing add context. An LLM can then turn that structured transcript into summaries, decisions, and action items.&lt;/p&gt;

&lt;p&gt;The biggest lesson is simple:&lt;br&gt;
Do not build your application around a transcription model. Build a pipeline around the problem you are trying to solve.&lt;br&gt;
The model converts sound into words. Good engineering turns those words into useful information.&lt;/p&gt;

&lt;p&gt;About the Author:&lt;em&gt;Saad Ansari is an AI Engineer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, working on AI-powered applications, LLMs, automation, and backend systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>speechtotext</category>
      <category>transcription</category>
      <category>dograh</category>
    </item>
    <item>
      <title>RAG Evaluation: How to Measure Retrieval and Answer Quality</title>
      <dc:creator>Sneha Patel</dc:creator>
      <pubDate>Thu, 15 Oct 2026 12:42:54 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/rag-evaluation-how-to-measure-retrieval-and-answer-quality-501a</link>
      <guid>https://dev.to/addwebsolutionpvtltd/rag-evaluation-how-to-measure-retrieval-and-answer-quality-501a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Evaluating RAG architectures is, however, challenging because there are several dimensions to consider.” - Es et al., RAGAS &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RAG evaluation should measure both retrieval quality and answer quality.&lt;/li&gt;
&lt;li&gt;A high retrieval similarity score does not automatically mean the generated answer is correct.&lt;/li&gt;
&lt;li&gt;Retrieval metrics such as Hit@K, Recall@K, Precision@K, and MRR help diagnose the retriever.&lt;/li&gt;
&lt;li&gt;Answer evaluation should examine correctness, relevance, completeness, and faithfulness to the retrieved context.&lt;/li&gt;
&lt;li&gt;A small, carefully designed evaluation dataset is often more useful than testing random questions.&lt;/li&gt;
&lt;li&gt;LLM-based evaluation can accelerate RAG testing, but human review remains valuable for high-impact applications.&lt;/li&gt;
&lt;li&gt;Evaluation should be repeated whenever embeddings, chunking, retrievers, prompts, rerankers, or generation models change.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to RAG Evaluation&lt;/li&gt;
&lt;li&gt;Why RAG Evaluation Matters&lt;/li&gt;
&lt;li&gt;Understanding the Two Evaluation Layers&lt;/li&gt;
&lt;li&gt;Retrieval Quality&lt;/li&gt;
&lt;li&gt;Retrieval Metrics&lt;/li&gt;
&lt;li&gt;Answer Quality&lt;/li&gt;
&lt;li&gt;Faithfulness and Groundedness&lt;/li&gt;
&lt;li&gt;Building a RAG Evaluation Dataset&lt;/li&gt;
&lt;li&gt;Practical RAG Evaluation Example&lt;/li&gt;
&lt;li&gt;End-to-End Evaluation Workflow&lt;/li&gt;
&lt;li&gt;LLM-as-a-Judge and Automated Evaluation&lt;/li&gt;
&lt;li&gt;Common RAG Evaluation Problems&lt;/li&gt;
&lt;li&gt;Best Practices&lt;/li&gt;
&lt;li&gt;Statistics&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction to RAG Evaluation
&lt;/h2&gt;

&lt;p&gt;Retrieval-Augmented Generation (RAG) combines information retrieval with a large language model. Instead of relying only on knowledge stored in model parameters, a RAG system retrieves relevant information from an external collection and provides that information to the model as context.&lt;/p&gt;

&lt;p&gt;This architecture is useful for enterprise search, documentation assistants, customer support, internal knowledge bases, research tools, and other applications where answers should be grounded in a controlled knowledge source.&lt;/p&gt;

&lt;p&gt;However, building a RAG pipeline is only the beginning. A system can retrieve irrelevant chunks, miss the most useful passage, or retrieve the right information but still generate an incomplete or unsupported answer. That is why evaluation must examine the retrieval and generation stages separately as well as together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“RAG models combine pre-trained parametric and non-parametric memory for language generation.”-Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Why RAG Evaluation Matters
&lt;/h2&gt;

&lt;p&gt;Traditional application testing often checks whether a function returns an expected value. RAG systems are more complex because the final answer depends on several moving parts: document parsing, chunking, embeddings, retrieval, ranking, prompt construction, and generation.&lt;/p&gt;

&lt;p&gt;A change to any one of these components can improve one type of question while making another type worse. Evaluation gives developers a repeatable way to compare versions of a RAG pipeline rather than relying on a few manually tested examples.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect retrieval failures before they become answer failures.&lt;/li&gt;
&lt;li&gt;Identify whether poor answers originate in the retriever or the generator.&lt;/li&gt;
&lt;li&gt;Compare embedding models, chunk sizes, top-K values, rerankers, and prompts.&lt;/li&gt;
&lt;li&gt;Track regressions when the knowledge base or application changes.&lt;/li&gt;
&lt;li&gt;Measure production quality using a consistent evaluation set.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Understanding the Two Evaluation Layers
&lt;/h2&gt;

&lt;p&gt;A useful mental model is to evaluate RAG in two layers. The first asks whether the system found the right evidence. The second asks whether the model used that evidence correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Retriever
   ↓
Top-K Context
   ↓
Retrieval Evaluation
   ↓
LLM
   ↓
Generated Answer
   ↓
Answer Evaluation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layer 1: Retrieval Evaluation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Retrieval evaluation measures whether the documents or chunks returned for a query contain the information needed to answer it. The goal is not simply to retrieve text that sounds similar to the question; the retrieved context should be useful for answering the question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: Answer Evaluation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Answer evaluation measures the quality of the final response. A response may be fluent and relevant to the question while still containing unsupported claims. Therefore, answer, correctness and faithfulness should be evaluated separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Retrieval Quality
&lt;/h2&gt;

&lt;p&gt;Retrieval quality is the foundation of a RAG system. If the correct information is absent from the retrieved context, the generator has less opportunity to produce a grounded answer.&lt;/p&gt;

&lt;p&gt;For a simple evaluation, create a set of questions and identify which document or chunk is expected to contain the answer. Then compare the expected evidence with the retrieved results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Makes Retrieval Good?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The relevant document appears among the retrieved results.&lt;/li&gt;
&lt;li&gt;The most useful evidence appears near the top of the ranking.&lt;/li&gt;
&lt;li&gt;Irrelevant context is minimized.&lt;/li&gt;
&lt;li&gt;The retrieved chunk contains enough information to answer the question.&lt;/li&gt;
&lt;li&gt;The retriever behaves consistently across different question types.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Retrieval Metrics
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hit@K&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hit@K is 1 when at least one relevant document appears in the top K retrieved results; otherwise it is 0. It is useful for checking whether the retriever can find the required evidence within a practical context window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recall@K&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recall@K measures how many of the relevant items were retrieved within the top K results. It is especially useful when a question may require multiple pieces of evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Precision@K&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Precision@K measures how many of the top K retrieved items are relevant. High precision means the context contains less irrelevant material.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mean Reciprocal Rank (MRR)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MRR rewards systems that place the first relevant result near the top. For each query, reciprocal rank is 1 divided by the position of the first relevant result; MRR is the mean across queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieval_metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retrieved_names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gold_document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Rank-based retrieval metrics for a single question.
gold_document is a single filename (single-label ground truth), or None for a question that no document can answer — those are excluded from retrieval scoring by the caller.
   &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;gold_document&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
   &lt;span class="n"&gt;gold_rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retrieved_names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;gold_document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
           &lt;span class="n"&gt;gold_rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;
           &lt;span class="k"&gt;break&lt;/span&gt;
   &lt;span class="n"&gt;hit_at_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retrieved_names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;retrieved_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gold_document&lt;/span&gt;
   &lt;span class="n"&gt;hit_at_k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gold_rank&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gold_rank&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gold_rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hit@1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hit_at_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hit@k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hit_at_k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recall@k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hit_at_k&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;precision@k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hit_at_k&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mrr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;gold_rank&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;gold_rank&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Examples:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Relevant document rank = 1
Reciprocal Rank = 1 / 1 = 1.00

Relevant document rank = 3
Reciprocal Rank = 1 / 3 = 0.33
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Context Relevance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Context relevance asks whether the retrieved passages actually address the question. This can be evaluated with labels, similarity methods, or an LLM-based judge. It is particularly useful when a vector search returns semantically related but practically unhelpful text.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Answer Quality
&lt;/h2&gt;

&lt;p&gt;Retrieving the correct passage does not guarantee a good answer. The generator can misunderstand the evidence, omit important details, or add information that is not supported by the context.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correctness: Does the answer agree with the expected answer or verified facts?&lt;/li&gt;
&lt;li&gt;Relevance: Does it directly address the user's question?&lt;/li&gt;
&lt;li&gt;Completeness: Does it cover the important information required by the question?&lt;/li&gt;
&lt;li&gt;Clarity: Is the response understandable and appropriately concise?&lt;/li&gt;
&lt;li&gt;Faithfulness: Are the claims supported by the retrieved context?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Faithfulness and Groundedness
&lt;/h2&gt;

&lt;p&gt;Faithfulness is one of the most important RAG-specific concepts. A response can be factually plausible while still failing the RAG requirement if its claims are not supported by the retrieved context.&lt;/p&gt;

&lt;p&gt;For example, suppose the context says that employees receive 20 annual leave days. If the model answers that employees receive 20 days, the claim is grounded. If it additionally states that unused leave can always be converted to cash when the context never mentions such a policy, that additional claim should be flagged as unsupported.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The ability of the LLM to exploit such passages in a faithful way” - Es et al., RAGAS &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  8. Building a RAG Evaluation Dataset
&lt;/h2&gt;

&lt;p&gt;A reliable evaluation dataset should represent the questions users are actually expected to ask. It should not contain only easy questions that can be answered from a single obvious chunk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended Dataset Fields&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"How many annual leave days do employees get?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expected_document"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"leave_policy.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expected_answer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Employees receive 20 days of annual leave per year."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful fields include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Question&lt;/li&gt;
&lt;li&gt;Expected document or chunk&lt;/li&gt;
&lt;li&gt;Expected answer&lt;/li&gt;
&lt;li&gt;Optional supporting evidence&lt;/li&gt;
&lt;li&gt;Question category&lt;/li&gt;
&lt;li&gt;Difficulty level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question Categories&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Direct fact lookup&lt;/li&gt;
&lt;li&gt;Multi-sentence answer&lt;/li&gt;
&lt;li&gt;Comparison&lt;/li&gt;
&lt;li&gt;Multi-hop question&lt;/li&gt;
&lt;li&gt;Negative or exception case&lt;/li&gt;
&lt;li&gt;Ambiguous wording&lt;/li&gt;
&lt;li&gt;Questions with similar distractor documents&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Practical RAG Evaluation Example
&lt;/h2&gt;

&lt;p&gt;Consider a company leave-policy knowledge base.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Question:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;How&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;many&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;annual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;days&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;employees&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;get?&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Retrieved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;document:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;leave_policy.txt&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Retrieved&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;context:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Employees&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;receive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;days&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;annual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;year.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Generated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;answer:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Employees&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;receive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;annual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;days&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;year.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F590xpybp4sugtgi148fn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F590xpybp4sugtgi148fn.png" alt=" " width="620" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This example is intentionally simple. A real evaluation set should include enough questions to expose retrieval misses, distractors, partial answers, and unsupported generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. End-to-End Evaluation Workflow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create evaluation questions.&lt;/li&gt;
&lt;li&gt;Define expected documents and answers.&lt;/li&gt;
&lt;li&gt;Run the retriever.&lt;/li&gt;
&lt;li&gt;Record top-K results and scores.&lt;/li&gt;
&lt;li&gt;Calculate retrieval metrics.&lt;/li&gt;
&lt;li&gt;Generate answers from the retrieved context.&lt;/li&gt;
&lt;li&gt;Evaluate correctness, relevance, and faithfulness.&lt;/li&gt;
&lt;li&gt;Aggregate results.&lt;/li&gt;
&lt;li&gt;Compare against the previous RAG version. Investigate failures and improve the pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A Simple Results Table&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4m9gfpbl0aod7gpb0qxc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4m9gfpbl0aod7gpb0qxc.png" alt=" " width="630" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  11. LLM-as-a-Judge and Automated Evaluation
&lt;/h2&gt;

&lt;p&gt;Manual evaluation provides valuable judgment but can be slow when a dataset grows. LLM-based evaluation can help score properties such as relevance, correctness, and faithfulness at scale.&lt;/p&gt;

&lt;p&gt;RAGAS is one example of a reference-free evaluation approach designed specifically for RAG pipelines. Its paper highlights the need to evaluate retrieval quality, faithful use of retrieved passages, and generation quality rather than treating the final answer as the only signal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We introduce RAGAs, a framework for reference-free evaluation of Retrieval Augmented Generation pipelines.” - Es et al., RAGAS&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Automated evaluation should still be calibrated. Compare automated scores against human judgments on a representative sample, especially for high-impact applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Common RAG Evaluation Problems
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Evaluating only the final answer and ignoring retrieval.&lt;/li&gt;
&lt;li&gt;Using too few evaluation questions.&lt;/li&gt;
&lt;li&gt;Testing only easy questions.&lt;/li&gt;
&lt;li&gt;Treating vector similarity as proof that retrieval is correct.&lt;/li&gt;
&lt;li&gt;Using a judge model without validating its scoring behavior.&lt;/li&gt;
&lt;li&gt;Failing to store retrieved contexts and generated answers for later inspection.&lt;/li&gt;
&lt;li&gt;Changing the RAG pipeline without rerunning the evaluation set.&lt;/li&gt;
&lt;li&gt;Combining retrieval and generation failures into one score without diagnosing the individual components.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  13. Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start with a small, high-quality evaluation set based on real user questions.&lt;/li&gt;
&lt;li&gt;Keep expected evidence and expected answers separate.&lt;/li&gt;
&lt;li&gt;Measure retrieval and generation independently.&lt;/li&gt;
&lt;li&gt;Use both automated metrics and periodic human review.&lt;/li&gt;
&lt;li&gt;Track failures by category rather than looking only at one overall score.&lt;/li&gt;
&lt;li&gt;Record the model, embedding model, chunking strategy, top-K, prompt, and knowledge-base version.&lt;/li&gt;
&lt;li&gt;Set quality thresholds before deploying major changes.&lt;/li&gt;
&lt;li&gt;Re-evaluate after changes to chunking, embeddings, reranking, prompts, or generation models.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  14. Statistics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The following figures are taken from original research sources. Each statistic includes its original source URL.&lt;/li&gt;
&lt;li&gt;The original RAG paper evaluated its approach on three open-domain question-answering tasks. -&lt;a href="https://arxiv.org/abs/2005.11401" rel="noopener noreferrer"&gt;Original source URL&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RAGChecker reported averaged evaluation results for eight RAG systems.-&lt;a href="https://arxiv.org/abs/2408.08067" rel="noopener noreferrer"&gt;Original source URL&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RAGChecker evaluated those systems across ten diverse domain datasets.-&lt;a href="https://arxiv.org/abs/2408.08067" rel="noopener noreferrer"&gt;Original source URL&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RAGChecker's meta-evaluation used ten annotators, including seven in-house annotators and three graduate students.-&lt;a href="https://arxiv.org/abs/2408.08067" rel="noopener noreferrer"&gt;Original source URL&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  15. Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RAG evaluation is not a single-metric problem. Research evaluates multiple dimensions, including retrieval relevance, answer correctness, generation quality, and faithfulness. &lt;a href="https://arxiv.org/abs/2405.07437" rel="noopener noreferrer"&gt;(arXiv)Evaluation of Retrieval-Augmented Generation: A Survey&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A RAG system can retrieve the right evidence and still produce an incorrect answer. The generation component must correctly use the retrieved information, so retrieval quality and answer quality need to be evaluated separately. &lt;a href="https://arxiv.org/abs/2309.15217" rel="noopener noreferrer"&gt;(arXiv)-RAGAS Research Paper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RAGAS was designed as a reference-free evaluation framework. It provides metrics for evaluating RAG pipelines without necessarily relying on ground-truth human annotations for every evaluation case. &lt;a href="https://arxiv.org/abs/2309.15217" rel="noopener noreferrer"&gt;(arXiv)-RAGAS: Automated Evaluation of Retrieval Augmented Generation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RAGChecker provides fine-grained diagnostics for RAG systems. It includes diagnostic metrics for both retrieval and generation modules, helping developers investigate failures beyond a single overall evaluation score. &lt;a href="https://arxiv.org/abs/2408.08067" rel="noopener noreferrer"&gt;(arXiv)-RAGChecker Research Paper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Evaluating only the final generated answer can hide important retrieval problems. RAG research emphasizes evaluating the retrieval and generation components separately because failures can occur at different stages of the pipeline. &lt;a href="https://arxiv.org/abs/2405.07437" rel="noopener noreferrer"&gt;(arXiv)Evaluation of Retrieval-Augmented Generation: A Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  16. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is RAG evaluation?&lt;/strong&gt;&lt;br&gt;
RAG evaluation is the process of measuring how effectively a RAG system retrieves useful evidence and how accurately and faithfully the language model uses that evidence to answer a question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the most important retrieval metric?&lt;/strong&gt;&lt;br&gt;
There is no single best metric. Hit@K is easy to interpret, Recall@K measures coverage, Precision@K measures retrieved relevance, and MRR rewards placing the first relevant result near the top.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is faithfulness in RAG?&lt;/strong&gt;&lt;br&gt;
Faithfulness measures whether the claims in the generated answer are supported by the retrieved context. It is a key signal for detecting unsupported generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I evaluate RAG without expected answers?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Some evaluation frameworks support reference-free evaluation by using the question, retrieved context, and generated answer. However, reference answers or verified evidence can be valuable for correctness checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many questions should an evaluation dataset contain?&lt;/strong&gt;&lt;br&gt;
There is no universal number. Start with a representative set that covers the application's major question types, then expand it as new failure modes are discovered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should retrieval and answer quality be combined into one score?&lt;/strong&gt;&lt;br&gt;
An overall score can be useful for tracking, but the individual metrics should remain visible. A single score can hide whether the problem comes from retrieval or generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can an LLM evaluate another LLM?&lt;/strong&gt;&lt;br&gt;
Yes. LLM-as-a-judge approaches are widely used for scalable evaluation, but they should be calibrated against human judgments and monitored for bias or inconsistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  17. Conclusion
&lt;/h2&gt;

&lt;p&gt;A reliable RAG system should not be judged only by whether its final answers sound convincing. The retrieval stage determines what evidence the model receives, while the generation stage determines how that evidence is transformed into an answer.&lt;/p&gt;

&lt;p&gt;By measuring retrieval with metrics such as Hit@K, Recall@K, Precision@K, and MRR, teams can identify whether the right information is being found. By measuring correctness, relevance, completeness, and faithfulness, they can determine whether the final response is useful and grounded.&lt;/p&gt;

&lt;p&gt;The most effective approach is to build a representative evaluation dataset, measure retrieval and answer quality separately, inspect failed cases, and rerun the evaluation whenever the RAG pipeline changes. With this discipline, RAG evaluation becomes a repeatable engineering practice rather than a subjective demo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Evaluating these RAG systems, however, poses unique challenges due to their hybrid structure and reliance on dynamic knowledge sources.”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yu et al., Evaluation of Retrieval-Augmented Generation: A Survey
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;About Author: &lt;em&gt;Sneha Patel is a Backend Developer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, passionate about AI, Machine Learning, and Generative AI, with a focus on building scalable applications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rag</category>
      <category>vertexai</category>
      <category>llm</category>
      <category>ai</category>
    </item>
    <item>
      <title>From PDF to Knowledge Base: Building an AI-Powered Glossary Assistant for Intelligent Q&amp;A</title>
      <dc:creator>Tanisha Khakhrani</dc:creator>
      <pubDate>Wed, 14 Oct 2026 10:44:53 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/from-pdf-to-knowledge-base-building-an-ai-powered-glossary-assistant-for-intelligent-qa-3eob</link>
      <guid>https://dev.to/addwebsolutionpvtltd/from-pdf-to-knowledge-base-building-an-ai-powered-glossary-assistant-for-intelligent-qa-3eob</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“The technology you use impresses no one. The experience you create with it is everything.” - Sean Gerety&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why is a Knowledge Base useful for PDF-based AI applications?&lt;/li&gt;
&lt;li&gt;How are PDFs converted into searchable knowledge?&lt;/li&gt;
&lt;li&gt;How does semantic search improve document Q&amp;amp;A?&lt;/li&gt;
&lt;li&gt;Why is an AI assistant needed on top of the Knowledge Base?&lt;/li&gt;
&lt;li&gt;How does the glossary handle terminology-based questions?&lt;/li&gt;
&lt;li&gt;How do the Knowledge Base, glossary, retrieval system, and LLM work together?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table of Content(Index)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction

&lt;ul&gt;
&lt;li&gt;From PDF to Knowledge&lt;/li&gt;
&lt;li&gt;Problems with Traditional PDF Search&lt;/li&gt;
&lt;li&gt;Intelligent Document Interaction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Knowledge Base for PDFs

&lt;ul&gt;
&lt;li&gt;What is a Knowledge Base?&lt;/li&gt;
&lt;li&gt;Building a Knowledge Base&lt;/li&gt;
&lt;li&gt;Benefits of a Document-Based Knowledge Base&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AI-Powered Q&amp;amp;A Assistant

&lt;ul&gt;
&lt;li&gt;Why an AI Assistant is Needed&lt;/li&gt;
&lt;li&gt;Natural Language Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Conversation and Ambiguity Handling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Building the Knowledge Base 

&lt;ul&gt;
&lt;li&gt;Text Extraction and Structure Detection&lt;/li&gt;
&lt;li&gt;Chunking&lt;/li&gt;
&lt;li&gt;Embeddings and FAISS&lt;/li&gt;
&lt;li&gt;Semantic Retrieval and Sources&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Role of the Glossary

&lt;ul&gt;
&lt;li&gt;What is a Glossary?&lt;/li&gt;
&lt;li&gt;Automatic Glossary Extraction&lt;/li&gt;
&lt;li&gt;Glossary vs Knowledge Base&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Putting Everything Together

&lt;ul&gt;
&lt;li&gt;LLM and Context&lt;/li&gt;
&lt;li&gt;End-to-End Workflow&lt;/li&gt;
&lt;li&gt;User Interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.1 From PDF to Knowledge&lt;/strong&gt;&lt;br&gt;
PDFs are mainly designed for storing and displaying documents. They are convenient for humans, but their content is not automatically organized in a form that an AI system can efficiently search.&lt;/p&gt;

&lt;p&gt;A Knowledge Base (KB) transforms document content into a structured and searchable representation that an AI application can retrieve when answering questions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F03rbrz5xg0l517tamp0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F03rbrz5xg0l517tamp0y.png" alt=" " width="430" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal is therefore not simply to store PDFs, but to transform their content into usable knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.2 Problems with Traditional PDF Search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional PDF search has several limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keyword Mismatch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keyword-based search mainly looks for matching words. A search for:&lt;br&gt;
"repair ruptured plumbing"&lt;/p&gt;

&lt;p&gt;may not return content describing:&lt;br&gt;
"fixing a leaking pipe"&lt;/p&gt;

&lt;p&gt;even though the two expressions have a similar meaning.&lt;/p&gt;

&lt;p&gt;Semantic search addresses this by representing text as embeddings and comparing their meaning. Sentence Transformers, for example, supports embeddings and semantic search across text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poor Machine Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PDFs are designed around visual layouts. During extraction, issues can occur with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multicolumn text&lt;/li&gt;
&lt;li&gt;Headers and footers&lt;/li&gt;
&lt;li&gt;Reading order&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Text inside images&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PDF extraction tools such as pdfplumber provide text and layout-related extraction capabilities, but the quality still depends on how the original PDF was created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Information Spread Across Multiple Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Important information may be distributed across several PDFs. Users have to search each document separately and combine the results themselves.&lt;/p&gt;

&lt;p&gt;A Knowledge Base brings these documents into a single searchable layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scanned Documents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scanned PDFs may contain images instead of machine-readable text. Such documents require OCR before their content can be processed as text. pdfplumber's documentation also notes that it works best with machine-generated PDFs rather than scanned documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3 Intelligent Document Interaction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of manually searching through hundreds of pages, users can ask questions directly.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What are the termination liabilities in Section 4?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system retrieves relevant information and provides it to an LLM for answer generation.&lt;/p&gt;

&lt;p&gt;A typical RAG-style document workflow is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF → Extract → Chunk → Embeddings → Vector Search → Context → LLM → Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The key idea is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instead of searching only for exact words, search for meaning and context.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Knowledge Base for PDFs
&lt;/h2&gt;

&lt;p&gt;The Knowledge Base is the foundation of the assistant. Before the AI can answer questions, information from PDFs must be extracted, organized, indexed, and made searchable.&lt;/p&gt;

&lt;p&gt;Instead of treating a PDF as one large file, the system divides its content into smaller meaningful units called chunks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.1 What is a Knowledge Base?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Knowledge Base&lt;/strong&gt; is a centralized collection of information that an application can retrieve and use to answer questions.&lt;/p&gt;

&lt;p&gt;In this project:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF → Text → Chunks → Embeddings → FAISS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each chunk represents a small piece of document knowledge. Its embedding allows the system to find it when a user's question is semantically related.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;br&gt;
&lt;strong&gt;A PDF is the source of information.&lt;br&gt;
A Knowledge Base is the searchable representation of that information.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.2 Building a Knowledge Base&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose the system receives several PDFs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning.pdf&lt;/li&gt;
&lt;li&gt;Constructors.pdf&lt;/li&gt;
&lt;li&gt;Encapsulation.pdf&lt;/li&gt;
&lt;li&gt;Inheritance.pdf&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of searching each document independently, the project processes them through the same pipeline:&lt;br&gt;
&lt;strong&gt;PDFs → Text Extraction → Structure Detection → Chunking → Embeddings → FAISS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The chunks and their metadata are combined:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;all_chunks.extend(get_chunks)&lt;br&gt;
all_metadata.extend(get_metadata)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embeddings are then generated for the combined collection:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;chunk_embeddings = embedding_chunks(all_chunks)&lt;br&gt;
stored_chunk_embeddings = store_embeddings(chunk_embeddings)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The result is a single searchable knowledge layer containing information from multiple PDFs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.3 Benefits of a Document-Based Knowledge Base&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Centralized Knowledge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Multiple PDFs can be processed into one searchable system.&lt;br&gt;
Multiple PDFs → Processing → Unified Knowledge Base&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Faster Retrieval&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of processing an entire document for every question, the system searches indexed chunks and retrieves only the most relevant content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Semantic Understanding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embeddings allow the system to retrieve related content even when the question and document use different wording. Semantic search works by embedding the query and corpus into a shared vector space and finding nearby representations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Context Preservation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each chunk can retain metadata such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PDF filename&lt;/li&gt;
&lt;li&gt;Page number&lt;/li&gt;
&lt;li&gt;Heading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;strong&gt;Inheritance.pdf → Page 4 → Types of Inheritance → Relevant Chunk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Reusable AI Foundation&lt;/strong&gt;&lt;br&gt;
Once created, the Knowledge Base can support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Question answering&lt;/li&gt;
&lt;li&gt;Document assistants&lt;/li&gt;
&lt;li&gt;Summarization&lt;/li&gt;
&lt;li&gt;Information extraction&lt;/li&gt;
&lt;li&gt;Intelligent search&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. AI-Powered Q&amp;amp;A Assistant
&lt;/h2&gt;

&lt;p&gt;The Knowledge Base solves the problem of storing and retrieving information, but users still need a simple way to interact with it.&lt;br&gt;
Users should not need to understand embeddings, vector indexes, or similarity calculations. They should simply be able to ask a question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.1 Why an AI Assistant is Needed&lt;/strong&gt;&lt;br&gt;
Manual document search requires users to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the correct document.&lt;/li&gt;
&lt;li&gt;Open it.&lt;/li&gt;
&lt;li&gt;Search for keywords.&lt;/li&gt;
&lt;li&gt;Read surrounding content.&lt;/li&gt;
&lt;li&gt;Compare information across documents.&lt;/li&gt;
&lt;li&gt;Form the answer themselves.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This becomes inefficient as documents become larger or more numerous.&lt;br&gt;
Instead of manually searching:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What is encapsulation and why is it useful?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;the user can ask the assistant directly. The assistant handles the retrieval process in the background.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Any sufficiently advanced technology is indistinguishable from magic.” - Arthur C. Clarke&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;3.2 Natural Language Q&amp;amp;A&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The user can ask questions in normal language.&lt;br&gt;
For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; What is inheritance in Python?&lt;/p&gt;

&lt;p&gt;The question is converted into an embedding and used to retrieve relevant document chunks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question → Relevant Context → LLM → Natural-Language Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The retrieved context is then passed to the LLM.&lt;/p&gt;

&lt;p&gt;This creates an important separation:&lt;br&gt;
&lt;strong&gt;Retrieval finds the knowledge.&lt;br&gt;
Generation explains the knowledge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sentence Transformers supports embedding generation and semantic search, making this type of retrieval possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3 Conversation and Ambiguity Handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A useful assistant should understand follow-up questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; What is inheritance?&lt;br&gt;
&lt;strong&gt;Assistant:&lt;/strong&gt; Inheritance allows one class to derive properties and behavior from another.&lt;br&gt;
&lt;strong&gt;User:&lt;/strong&gt; Explain it with an example.&lt;/p&gt;

&lt;p&gt;The second question depends on the first. The assistant therefore uses conversation history:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current Question + Previous Conversation → LLM → Context-Aware Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The assistant should also avoid guessing when a question is ambiguous.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;strong&gt;What is inheritance?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If multiple contexts are available:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Python inheritance&lt;/li&gt;
&lt;li&gt;Java inheritance&lt;/li&gt;
&lt;li&gt;C++ inheritance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;the assistant can ask the user to clarify instead of selecting one without sufficient evidence.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Knowledge is power. Information is liberating.” - Kofi Annan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. Building the Knowledge Base
&lt;/h2&gt;

&lt;p&gt;The Knowledge Base converts raw PDF content into searchable vector representations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF → Text Extraction → Structure Detection → Chunking → Embeddings → FAISS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.1 Text Extraction and Structure Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step is to extract text from each PDF page.&lt;br&gt;
The project uses &lt;strong&gt;pdfplumber:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;with pdfplumber.open(pdf_path) as pdf:&lt;/strong&gt;&lt;br&gt;
for page in pdf.pages:&lt;br&gt;
page_text = page.extract_text()&lt;/p&gt;

&lt;p&gt;The extracted text is stored along with page information:&lt;br&gt;
&lt;strong&gt;page_text_list.append(page_text)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;pdfplumber supports page-level text extraction and can also work with layout-related information such as character positions and font attributes.&lt;/p&gt;

&lt;p&gt;The basic transformation is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF → Machine-Readable Text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extracted text alone may lose useful document structure. Headings provide additional context.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapter 2&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Inheritance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inheritance allows one class to...&lt;br&gt;
The project uses font-size information to identify headings.&lt;/p&gt;

&lt;p&gt;It calculates the median body font size:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;body_font_size = np.median(all_sizes)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and defines a threshold:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;heading_threshold = body_font_size + 1&lt;/strong&gt;.5&lt;/p&gt;

&lt;p&gt;A sufficiently large and relatively short line can then be treated as a heading.&lt;/p&gt;

&lt;p&gt;The resulting chunk can retain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heading: Inheritance&lt;br&gt;
Text: Inheritance allows one class...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This makes the retrieved information more meaningful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.2 Chunking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Large documents should not be treated as one giant block of text. The content is divided into smaller &lt;strong&gt;chunks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;max_chunk_size = 1000&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;overlap = 200&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The overlap helps preserve context between neighboring chunks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chunk 1 → 1000 characters&lt;br&gt;
200-character overlap&lt;br&gt;
Chunk 2 → 1000 characters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project also associates headings and metadata with chunks, providing additional context during retrieval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.3 Embeddings and FAISS&lt;/strong&gt;&lt;br&gt;
After chunking, each chunk is converted into a numerical representation called an embedding.&lt;/p&gt;

&lt;p&gt;The project uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SentenceTransformer("all-MiniLM-L6-v2")&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;embeddings = model.encode(chunks)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sentence Transformers creates fixed-size vector representations that can be used for semantic search and similarity comparison.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Python inheritance" → [0.12, -0.34, 0.81, ...]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The exact numbers are not meaningful to humans. They allow text to be compared mathematically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question Embedding → Compare Similarity → Document Chunk Embeddings → Relevant Chunks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FAISS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once embeddings are generated, they need to be stored for efficient search.&lt;br&gt;
The project uses FAISS:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dimension = embeddings.shape[1]&lt;br&gt;
index = faiss.IndexFlatL2(dimension)&lt;br&gt;
index.add(&lt;/strong&gt;&lt;br&gt;
np.array(embeddings).astype("float32")&lt;br&gt;
&lt;strong&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;IndexFlatL2 performs nearest-neighbor search using L2 distance.&lt;br&gt;
The simplified flow is:&lt;br&gt;
&lt;strong&gt;Document Chunks → Embeddings → FAISS → Vector Search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FAISS provides indexing and efficient similarity-search functionality for vector data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.4 Semantic Retrieval and Sources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a user asks a question, the question is converted into an embedding using the same model.&lt;/p&gt;

&lt;p&gt;The system then searches FAISS:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Question → Question Embedding → FAISS Search → Relevant Chunks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project retrieves the top &lt;strong&gt;3 relevant chunks:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;distances, indices = index.search(&lt;/strong&gt;&lt;br&gt;
question_embedding,&lt;br&gt;
k=3&lt;br&gt;
&lt;strong&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These chunks become the context for the LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Metadata&lt;/strong&gt;&lt;br&gt;
Each chunk also retains information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File name&lt;/li&gt;
&lt;li&gt;Page number&lt;/li&gt;
&lt;li&gt;Heading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inheritance.pdf&lt;br&gt;
Page 4&lt;br&gt;
Heading: Types of Inheritance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This allows users to verify the answer and return to the original document.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Role of the Glossary
&lt;/h2&gt;

&lt;p&gt;Technical documents often contain specialized terminology. Even when the system retrieves the correct information, users may not understand the terms being used. This is where the glossary becomes important.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Our industry does not respect tradition. It only respects innovation.” - Satya Nadella&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;5.1 What is a Glossary?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;glossary&lt;/strong&gt; is a collection of important terms and their definitions.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encapsulation&lt;/strong&gt;&lt;br&gt;
→ The practice of bundling data and methods within a class.&lt;br&gt;
&lt;strong&gt;Inheritance&lt;/strong&gt;&lt;br&gt;
→ A mechanism through which one class derives properties and behavior from another.&lt;br&gt;
&lt;strong&gt;Polymorphism&lt;/strong&gt;&lt;br&gt;
→ The ability of different objects to respond to the same interface in different ways.&lt;/p&gt;

&lt;p&gt;The glossary provides quick access to definitions without requiring users to search through the complete document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.2 Automatic Glossary Extraction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of manually creating the glossary, the project uses an LLM to identify important terminology from the extracted document content.&lt;/p&gt;

&lt;p&gt;The system can identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key terms&lt;/li&gt;
&lt;li&gt;Abbreviations&lt;/li&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Concepts&lt;/li&gt;
&lt;li&gt;Tools&lt;/li&gt;
&lt;li&gt;Definitions
The expected structure is a dictionary:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;br&gt;
"inheritance": "A mechanism through which one class derives properties and behavior from another.",&lt;br&gt;
"encapsulation": "A technique of bundling data and methods within a class."&lt;br&gt;
&lt;strong&gt;}&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The terms are normalized:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;return {&lt;/strong&gt;&lt;br&gt;
str(k).lower().strip(): str(v).strip()&lt;br&gt;
for k, v in glossary_dict.items()&lt;br&gt;
&lt;strong&gt;}&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This makes lookup more consistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.3 Glossary vs Knowledge Base&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The glossary and Knowledge Base have different responsibilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1genlmn9v53740uf6qua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1genlmn9v53740uf6qua.png" alt=" " width="439" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Glossary Question&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"What is inheritance?"&lt;/p&gt;

&lt;p&gt;Question → Glossary Lookup → Definition&lt;/p&gt;

&lt;p&gt;Knowledge Base Question&lt;/p&gt;

&lt;p&gt;"How is inheritance used in this application?"&lt;/p&gt;

&lt;p&gt;Question → Embedding → FAISS Search → Relevant Chunks → LLM → Answer**&lt;/p&gt;

&lt;p&gt;The glossary is therefore &lt;strong&gt;not a replacement for the Knowledge Base.&lt;/strong&gt; It is an additional layer designed to make terminology-focused questions faster and clearer.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Putting Everything Together
&lt;/h2&gt;

&lt;p&gt;The final assistant combines the Knowledge Base, glossary, retrieval system, conversation history, and LLM into one workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 LLM and Context&lt;/strong&gt;&lt;br&gt;
The LLM is responsible for generating the final natural-language response.&lt;/p&gt;

&lt;p&gt;The basic process is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question → Relevant Context → LLM → Natural-Language Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The important distinction is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The vector index retrieves.&lt;br&gt;
The LLM explains.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The retrieved context helps ground the generated answer in information from the uploaded documents.&lt;/p&gt;

&lt;p&gt;For follow-up questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current Question + Previous Conversation → LLM → Context-Aware Answer&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The advance of technology is based on making it fit in so that you don't really even think about it.” - Bill Gates&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;6.2 End-to-End Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The complete system can be divided into two stages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Knowledge Base Creation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF → Text Extraction → Structure Detection → Chunking → Embeddings → FAISS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The glossary is generated alongside the Knowledge Base:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF Text → Important Terms → Glossary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: Question Answering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a definition-based question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question → Glossary Lookup → Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a broader question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question → Embedding → FAISS Search → Relevant Chunks → LLM → Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a follow-up question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current Question + Previous Conversation → LLM → Context-Aware Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The overall experience is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upload PDF → Ask Question → Get Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.3 User Interface&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The project uses Streamlit to provide the user interface.&lt;br&gt;
The user can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload PDF documents.&lt;/li&gt;
&lt;li&gt;Process the documents.&lt;/li&gt;
&lt;li&gt;Ask questions.&lt;/li&gt;
&lt;li&gt;View generated answers.&lt;/li&gt;
&lt;li&gt;Continue the conversation.&lt;/li&gt;
&lt;li&gt;View relevant sources.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From the user's perspective:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upload PDF → Ask Question → Get Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Behind the scenes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF → Extraction → Chunking → Embeddings → FAISS → Retrieval → LLM → Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The complexity remains in the backend while the user experience remains simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. What is a PDF Knowledge Base?&lt;/strong&gt;&lt;br&gt;
A PDF Knowledge Base converts information from PDFs into searchable chunks. These chunks are represented as embeddings and stored in a vector index such as FAISS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Why not simply search the PDF?&lt;/strong&gt;&lt;br&gt;
Traditional search relies heavily on matching words. Semantic search can retrieve related information even when different wording is used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. What is the role of FAISS?&lt;/strong&gt;&lt;br&gt;
FAISS stores vector representations and performs similarity search to retrieve relevant chunks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Why is a glossary needed?&lt;/strong&gt;&lt;br&gt;
The Knowledge Base handles broader questions, while the glossary provides quick answers to terminology-based questions such as "What is encapsulation?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Can the assistant answer follow-up questions?&lt;/strong&gt;&lt;br&gt;
Yes. Conversation history allows the assistant to interpret questions based on previous messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. What happens when a question is ambiguous?&lt;/strong&gt;&lt;br&gt;
The assistant can identify multiple relevant contexts and ask the user to clarify instead of making an unsupported assumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Semantic search focuses on meaning rather than only exact keywords -&lt;a href="https://www.sbert.net/examples/sentence_transformer/applications/semantic-search/README.html" rel="noopener noreferrer"&gt;Semantic Search Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The entire PDF does not need to be sent to the LLM. Relevant chunks are retrieved first - &lt;a href="https://www.sbert.net/" rel="noopener noreferrer"&gt;Sentence Transformers Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;This project uses 1,000-character chunks with 200-character overlap - &lt;a href="https://faiss.ai/" rel="noopener noreferrer"&gt;FAISS Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The glossary and Knowledge Base serve different purposes.&lt;/li&gt;
&lt;li&gt;Source metadata can connect retrieved content back to its original PDF, page, and heading - &lt;a href="https://github.com/jsvine/pdfplumber/blob/stable/README.md" rel="noopener noreferrer"&gt;pdfplumber Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The same Knowledge Base can support multiple AI applications beyond Q&amp;amp;A.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“We are stuck with technology when what we really want is just stuff that works.” - Douglas Adams&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The project demonstrates how static PDF documents can be transformed into an interactive source of knowledge.&lt;/p&gt;

&lt;p&gt;By combining PDF extraction, structure detection, chunking, embeddings, FAISS-based retrieval, glossary lookup, conversation history, source tracking, and an LLM, users can interact with documents using natural language instead of manually searching through files.&lt;/p&gt;

&lt;p&gt;The key idea is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Knowledge Base retrieves the right information, the glossary explains important terminology, and the AI assistant turns that information into a conversational answer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The result is a document assistant that combines semantic search, contextual understanding, and glossary-based definitions into one simple question-answering experience.sea&lt;/p&gt;

&lt;p&gt;About the Author: &lt;em&gt;Tanisha is an AI Engineer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, working on AI/ML solutions, intelligent document processing, and AI-powered applications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vertexai</category>
      <category>rag</category>
      <category>knowledgebase</category>
    </item>
    <item>
      <title>Scikit-learn vs LLM APIs: Which Should You Use for Your Next AI Project?</title>
      <dc:creator>Saad Ansari</dc:creator>
      <pubDate>Mon, 05 Oct 2026 12:28:24 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/scikit-learn-vs-llm-apis-which-should-you-use-for-your-next-ai-project-1e31</link>
      <guid>https://dev.to/addwebsolutionpvtltd/scikit-learn-vs-llm-apis-which-should-you-use-for-your-next-ai-project-1e31</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Simple and efficient tools for predictive data analysis.” - scikit-learn&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Artificial intelligence has moved far beyond traditional machine learning. Today, developers can build intelligent applications using established frameworks such as scikit-learn or connect directly to powerful Large Language Models (LLMs) through APIs.&lt;/p&gt;

&lt;p&gt;But this creates an important question: Should you build your next AI project with scikit-learn, an LLM API, or a combination of both?&lt;br&gt;
The answer depends less on which technology is more popular and more on the problem you are trying to solve.&lt;/p&gt;

&lt;p&gt;Scikit-learn is designed for traditional machine learning tasks such as classification, regression, clustering, preprocessing, model selection, and predictive analytics. LLM APIs, on the other hand, are designed for working with language, multimodal inputs, reasoning, content generation, structured outputs, and agentic workflows.&lt;br&gt;
As of June 2026, scikit-learn 1.9.0 is the current stable release, while major LLM platforms continue expanding their APIs with capabilities such as structured outputs, tool calling, multimodal input, and agent workflows.&lt;/p&gt;

&lt;p&gt;The real decision is therefore not “scikit-learn or LLMs?” but rather “Which technology best matches my data, task, budget, and production requirements?”&lt;/p&gt;
&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scikit-learn excels at structured/tabular data tasks, is free to run locally, and is ideal for classification, regression, clustering, and dimensionality reduction.&lt;/li&gt;
&lt;li&gt;LLM APIs (OpenAI, Anthropic, Google, Gemini) shine for natural language understanding, generation, zero-shot tasks, and complex reasoning - without training data.&lt;/li&gt;
&lt;li&gt;The choice isn't binary: Scikit-LLM bridges both worlds, letting you call LLM APIs using familiar scikit-learn syntax.&lt;/li&gt;
&lt;li&gt;Cost, data type, latency, interpretability, and task complexity are the key decision factors.&lt;/li&gt;
&lt;li&gt;Most production AI systems in 2025 use both - scikit-learn for structured pipelines and LLM APIs for language-heavy tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What Is Scikit-learn?&lt;/li&gt;
&lt;li&gt;What Are LLM APIs?&lt;/li&gt;
&lt;li&gt;Scikit-learn vs LLM APIs: The Core Difference&lt;/li&gt;
&lt;li&gt;When Should You Use Scikit-learn?&lt;/li&gt;
&lt;li&gt;When Should You Use an LLM API?&lt;/li&gt;
&lt;li&gt;Scikit-learn vs LLM APIs Comparison&lt;/li&gt;
&lt;li&gt;Why Hybrid AI Systems Are Often Better&lt;/li&gt;
&lt;li&gt;Real-World Examples&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  1. What Is Scikit-learn?
&lt;/h2&gt;

&lt;p&gt;Scikit-learn is an open-source Python machine learning library built on NumPy, SciPy, and matplotlib. It provides tools for predictive data analysis and supports a broad range of traditional machine learning workflows.&lt;/p&gt;

&lt;p&gt;Its common capabilities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Classification&lt;/li&gt;
&lt;li&gt;Regression&lt;/li&gt;
&lt;li&gt;Clustering&lt;/li&gt;
&lt;li&gt;Dimensionality reduction&lt;/li&gt;
&lt;li&gt;Preprocessing&lt;/li&gt;
&lt;li&gt;Model selection&lt;/li&gt;
&lt;li&gt;Model evaluation&lt;/li&gt;
&lt;li&gt;Pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, suppose you have customer data containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Age&lt;/li&gt;
&lt;li&gt;Location&lt;/li&gt;
&lt;li&gt;Purchase history&lt;/li&gt;
&lt;li&gt;Average order value&lt;/li&gt;
&lt;li&gt;Number of previous purchases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could train a scikit-learn model to predict whether a customer is likely to make another purchase.This is a classic machine learning problem because the input data is structured and the desired output is a prediction.&lt;/p&gt;

&lt;p&gt;A typical workflow might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.model_selection&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;train_test_split&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.ensemble&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RandomForestClassifier&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;accuracy_score&lt;/span&gt;
&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RandomForestClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;predictions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accuracy:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;accuracy_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;predictions&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. What Are LLM APIs?
&lt;/h2&gt;

&lt;p&gt;Large Language Models are AI models designed to process and generate human-like language. Through APIs, developers can integrate these models into applications without training a large language model themselves.&lt;/p&gt;

&lt;p&gt;Modern LLM APIs can provide capabilities such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text generation&lt;/li&gt;
&lt;li&gt;Summarization&lt;/li&gt;
&lt;li&gt;Question answering&lt;/li&gt;
&lt;li&gt;Translation&lt;/li&gt;
&lt;li&gt;Information extraction&lt;/li&gt;
&lt;li&gt;Structured JSON generation&lt;/li&gt;
&lt;li&gt;Image understanding&lt;/li&gt;
&lt;li&gt;Function or tool calling&lt;/li&gt;
&lt;li&gt;Conversational applications&lt;/li&gt;
&lt;li&gt;Agentic workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, an application could send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Summarize this customer complaint and identify the main issue.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model can return a natural-language response without requiring you to build and train a classification model specifically for that task.&lt;/p&gt;

&lt;p&gt;Modern APIs are also moving beyond simple text generation. For example, Google's Gemini API currently provides functionality for multimodal understanding, structured outputs, function calling, agents, document understanding, and other tools.&lt;/p&gt;

&lt;p&gt;OpenAI's current API platform similarly provides models supporting capabilities such as structured outputs, function calling, image input, web search, file search, and computer-use-related workflows depending on the model.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The future of AI is not about choosing between tools; it is about knowing where each tool fits best.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Scikit-learn vs LLM APIs: The Core Difference
&lt;/h2&gt;

&lt;p&gt;The biggest difference is the type of intelligence you are building.&lt;br&gt;
Scikit-learn is primarily about learning patterns from structured data and using those learned patterns to make predictions.&lt;/p&gt;

&lt;p&gt;LLM APIs are primarily about understanding and generating complex information, especially language and other unstructured inputs.&lt;/p&gt;

&lt;p&gt;Consider two examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Predict Customer Churn&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer age
Subscription plan
Monthly usage
Number of support tickets
Account age
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your objective:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Will this customer leave in the next 30 days?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scikit-learn is a strong candidate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2: Analyze a Customer Complaint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I have been charged twice this month and nobody from support has replied."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your objective:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Identify the customer's issue, sentiment, urgency, and recommended response.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An LLM API is generally much better suited to this kind of language-centric task. The difference becomes clearer when we look at what each technology expects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe6l8vvk56r32zscw7h0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe6l8vvk56r32zscw7h0f.png" alt=" " width="478" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. When Should You Use Scikit-learn?
&lt;/h2&gt;

&lt;p&gt;Scikit-learn is usually the better option when your problem can be clearly represented as a traditional machine learning problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use scikit-learn when your data is structured&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sales data&lt;/li&gt;
&lt;li&gt;Customer records&lt;/li&gt;
&lt;li&gt;Financial metrics&lt;/li&gt;
&lt;li&gt;Sensor measurements&lt;/li&gt;
&lt;li&gt;Product information&lt;/li&gt;
&lt;li&gt;Tabular business data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, predicting house prices from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Area
Bedrooms
Bathrooms
Location
Age of property
Parking availability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is naturally suited to regression algorithms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use scikit-learn when you need predictable output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional ML models usually produce well-defined outputs.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Churn = 0
Churn probability = 0.83
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes traditional models useful in systems where predictable decisions and measurable performance are important.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Artificial intelligence is the most powerful tool humans have ever invented.” - OpenAI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. When Should You Use an LLM API?
&lt;/h2&gt;

&lt;p&gt;An LLM API becomes attractive when language is central to your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build chatbots&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For applications that need natural conversations, contextual responses, and question answering, an LLM API is usually a much better fit than a traditional classifier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summarize large amounts of text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meeting transcripts&lt;/li&gt;
&lt;li&gt;Legal documents&lt;/li&gt;
&lt;li&gt;Customer conversations&lt;/li&gt;
&lt;li&gt;Research papers&lt;/li&gt;
&lt;li&gt;Internal documentation&lt;/li&gt;
&lt;li&gt;Support tickets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of manually designing features for every possible pattern, you can provide the relevant content to an LLM and ask it to summarize or analyze it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extract information from unstructured text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose a support ticket contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"My order 48192 arrived yesterday, but two products were damaged."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An LLM can potentially convert it into structured information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"order_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"48192"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"damaged_products"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"medium"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern LLM APIs increasingly support structured outputs specifically for applications that need machine-readable responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build AI agents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLM APIs are particularly useful when an application needs to reason through a task and use external tools.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User request
     ↓
LLM
     ↓
Call CRM API
     ↓
Check order status
     ↓
Generate response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow is difficult to build using traditional machine learning alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Scikit-learn vs LLM APIs Comparison
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Accuracy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scikit-learn can be extremely effective when your dataset, features, and target are well defined.&lt;/p&gt;

&lt;p&gt;An LLM can perform exceptionally well on language tasks but may sometimes produce incorrect or unsupported information.&lt;/p&gt;

&lt;p&gt;This means you should not compare an LLM and a Random Forest using a single generic definition of “accuracy.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Control&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scikit-learn gives developers direct control over the machine learning pipeline.&lt;/p&gt;

&lt;p&gt;An LLM API gives you less control over the underlying model because the model is generally managed by the provider.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is one of the areas where the decision can become more complicated.&lt;/p&gt;

&lt;p&gt;LLM APIs usually operate on usage-based pricing.&lt;/p&gt;

&lt;p&gt;For example, OpenAI's current API pricing lists GPT-5.6 Luna at $1 per million input tokens and $6 per million output tokens, while GPT-5.6 Sol is listed at $5 per million input tokens and $30 per million output tokens.&lt;/p&gt;

&lt;p&gt;Google's Gemini API also uses token-based pricing, with prices varying significantly by model and processing tier.&lt;/p&gt;

&lt;p&gt;This means an LLM application should monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requests × Input tokens + Output tokens = API cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cheapest model is not automatically the cheapest system.&lt;/p&gt;

&lt;p&gt;A more capable model might solve the task in one request while a weaker model might require multiple retries, larger prompts, or additional processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Why Hybrid AI Systems Are Often Better
&lt;/h2&gt;

&lt;p&gt;One of the strongest approaches is to stop treating scikit-learn and LLM APIs as competing technologies.&lt;/p&gt;

&lt;p&gt;They can work together.&lt;/p&gt;

&lt;p&gt;Imagine a sales intelligence platform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Scikit-learn&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Predict:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer churn probability = 0.84
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stage 2: LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take customer history and the prediction and generate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The customer shows a high churn risk because product usage
has declined significantly and support interactions have increased.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stage 3: Business automation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The system can then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create CRM task
↓
Notify account manager
↓
Generate recommended response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This architecture uses each technology where it is strongest.&lt;/p&gt;

&lt;p&gt;Another example is an AI meeting-notes system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Audio
↓
Speech-to-text model
↓
Transcript
↓
Traditional ML / rules for classification
↓
LLM for summarization and action items
↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is often stronger than attempting to force one technology to perform every task.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Real-World Examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Fraud Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use scikit-learn when your system has structured transaction features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transaction amount&lt;/li&gt;
&lt;li&gt;Location&lt;/li&gt;
&lt;li&gt;Time&lt;/li&gt;
&lt;li&gt;Device&lt;/li&gt;
&lt;li&gt;Transaction frequency&lt;/li&gt;
&lt;li&gt;Historical behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A classification model can estimate fraud probability.&lt;/p&gt;

&lt;p&gt;An LLM may then be used separately to summarize an investigation or explain a case to an analyst.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended approach: Hybrid&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2: Customer Support Chatbot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The primary requirement is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understand customer questions
↓
Find relevant information
↓
Generate natural responses
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An LLM API is a natural fit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended approach: LLM API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended approach: LLM / multimodal API&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Interesting Facts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fact 1: Scikit-learn is not outdated &lt;a href="https://sklearn.org/stable/whats_new/v1.9.html" rel="noopener noreferrer"&gt;Scikit-learn 1.9 Release Notes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rise of LLMs has not made traditional machine learning obsolete. Scikit-learn continues to receive active releases, with version 1.9.0 available in June 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact 2: LLM APIs are becoming more than chat APIs &lt;a href="https://developers.openai.com/api/reference/cli/resources/responses/methods/create" rel="noopener noreferrer"&gt;OpenAI API - Responses API&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern APIs increasingly include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tool calling&lt;/li&gt;
&lt;li&gt;Structured outputs&lt;/li&gt;
&lt;li&gt;Multimodal processing&lt;/li&gt;
&lt;li&gt;Agents&lt;/li&gt;
&lt;li&gt;Long-context processing&lt;/li&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Code execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means developers can build complete AI workflows rather than simple chatbots.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact 3: The cheapest AI model is not always the cheapest solution &lt;a href="https://apexstack.dev/blog/llm-feature-production-cost" rel="noopener noreferrer"&gt;LLM API Cost in Production&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A lower-cost model might require more requests, more context, more retries, or additional validation.&lt;/p&gt;

&lt;p&gt;Total system cost matters more than model price alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact 4: Hybrid systems can outperform “one tool for everything” architectures &lt;a href="https://mlflow.org/articles/llm-application-architecture-a-2026-engineers-guide" rel="noopener noreferrer"&gt;MLflow - LLM Application Architecture&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A system can use:&lt;/p&gt;

&lt;p&gt;Scikit-learn → prediction&lt;/p&gt;

&lt;p&gt;LLM → explanation&lt;/p&gt;

&lt;p&gt;Rules → validation&lt;/p&gt;

&lt;p&gt;Database → storage&lt;/p&gt;

&lt;p&gt;API → automation&lt;/p&gt;

&lt;p&gt;This lets every component focus on the type of work it performs best.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The fastest path from prompt to production.” - Google Gemini API&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  10. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is scikit-learn still relevant in the age of LLMs?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Absolutely.&lt;/p&gt;

&lt;p&gt;Scikit-learn remains useful for structured-data machine learning, classification, regression, clustering, preprocessing, and predictive analytics. Its 1.9.0 release in June 2026 demonstrates that it remains actively maintained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are LLM APIs better than scikit-learn?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not universally.&lt;/p&gt;

&lt;p&gt;LLM APIs are generally stronger for natural-language and generative tasks, while scikit-learn is often better for structured-data prediction and traditional machine learning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use scikit-learn and an LLM together?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. In many production systems, combining both is the strongest approach.&lt;/p&gt;

&lt;p&gt;For example, scikit-learn can predict customer churn while an LLM generates a human-readable explanation or recommended action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which is cheaper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It depends on the workload.&lt;/p&gt;

&lt;p&gt;Scikit-learn can be highly economical for local, high-volume predictions after model training. LLM APIs introduce usage-based costs but can dramatically reduce development effort for language-centric applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which is easier for beginners?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For basic traditional machine learning, scikit-learn is one of the easiest ways to learn concepts such as training, testing, classification, regression, and model evaluation.&lt;/p&gt;

&lt;p&gt;For building a language-based prototype, an LLM API may be faster because you can start with an API request and a prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to train my own LLM?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usually not.&lt;/p&gt;

&lt;p&gt;Many applications can be built using existing LLM APIs combined with prompting, retrieval, structured outputs, tools, and application-level logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can scikit-learn process text?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;Scikit-learn includes traditional text-processing and machine-learning workflows, such as vectorization followed by classifiers. However, modern LLMs are generally better suited to rich semantic language understanding and generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should a startup use scikit-learn or an LLM API?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start from the problem, not the technology.&lt;/p&gt;

&lt;p&gt;If your startup is building predictive analytics over structured business data, evaluate traditional ML.&lt;/p&gt;

&lt;p&gt;If the product depends on conversation, document understanding, generation, or natural-language reasoning, evaluate LLM APIs.&lt;br&gt;
If it needs both, use a hybrid architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Conclusion
&lt;/h2&gt;

&lt;p&gt;Scikit-learn and LLM APIs are not direct replacements for one another.&lt;/p&gt;

&lt;p&gt;They solve different classes of problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scikit-learn is strongest when you need controlled, measurable machine learning over structured data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM APIs are strongest when you need language understanding, generation, reasoning, multimodal processing, or agentic workflows.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The smartest decision is therefore not to follow the latest AI trend blindly.&lt;/p&gt;

&lt;p&gt;For many modern applications, the final answer will not be scikit-learn versus LLM API.&lt;/p&gt;

&lt;p&gt;It will be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;scikit-learn + LLM API + application logic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional machine learning can handle structured prediction, while LLMs can handle language and reasoning. Together, they can form a more practical and scalable AI architecture.&lt;/p&gt;

&lt;p&gt;The best AI technology is not the one with the most impressive benchmark.&lt;/p&gt;

&lt;p&gt;It is the one that solves your actual business problem reliably, securely, and economically.&lt;/p&gt;

&lt;p&gt;About Author: &lt;em&gt;Saad Ansari is an AI Engineer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, passionate about AI, Machine Learning, and building innovative real-world solutions.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>scikitlearn</category>
      <category>llm</category>
    </item>
    <item>
      <title>PageIndex:A Practical Analysis of Vectorless Document Retrieval</title>
      <dc:creator>Manthan Prajapati</dc:creator>
      <pubDate>Tue, 29 Sep 2026 08:16:51 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/pageindexa-practical-analysis-of-vectorless-document-retrieval-3h3l</link>
      <guid>https://dev.to/addwebsolutionpvtltd/pageindexa-practical-analysis-of-vectorless-document-retrieval-3h3l</guid>
      <description>&lt;p&gt;A vectorless, reasoning-based approach to document retrieval is challenging one of the core assumptions behind modern RAG systems - here's what PageIndex actually is, how it works under the hood, and where it fits in a real stack.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Similarity ≠ relevance - what we truly need in retrieval is relevance, and that requires reasoning.” - VectifyAI, PageIndex documentation&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PageIndex is a “vectorless, reasoning-based” RAG framework from VectifyAI. Instead of chunking documents and embedding them into a vector database, it builds a hierarchical tree index (like a table of contents) and has an LLM reason its way through that tree to find answers.&lt;/li&gt;
&lt;li&gt;It was built to close a specific gap: similarity search finds text that looks like the query, not necessarily text that answers it. For long, structured professional documents - 10-Ks, contracts, technical manuals - that gap causes real retrieval failures.&lt;/li&gt;
&lt;li&gt;Its headline result is 98.7% accuracy on FinanceBench, a financial-document QA benchmark, via VectifyAI's Mafin 2.5 system - versus roughly 30–50% for typical vector-based RAG setups on the same benchmark.&lt;/li&gt;
&lt;li&gt;It's open source (MIT license) and ships as a self-hosted framework, a hosted API/MCP server, and a chat platform for uploading and querying PDFs directly.&lt;/li&gt;
&lt;li&gt;It's a specialist tool, not a universal RAG replacement. Reviewers consistently find it excels at deep analysis of a single known document, but tree-building doesn't scale cheaply across large multi-document corpora, where vector search still wins on speed and cost.&lt;/li&gt;
&lt;li&gt;The realistic production pattern is hybrid: vector search to find or narrow down the right document(s), then tree-based reasoning to extract precise, traceable answers from within them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table of Contents (Index)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What Is PageIndex?&lt;/li&gt;
&lt;li&gt;Why It Exists: The Problem With Vector RAG&lt;/li&gt;
&lt;li&gt;How PageIndex Works&lt;/li&gt;
&lt;li&gt;Page Index Vs. Traditional RAG&lt;/li&gt;
&lt;li&gt;Quick Start for Developers&lt;/li&gt;
&lt;li&gt;Statistics&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;Where PageIndex Shines - and Where It Doesn't&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What Is PageIndex?
&lt;/h2&gt;

&lt;p&gt;PageIndex is an open-source document retrieval framework from VectifyAI, positioned as a vectorless, reasoning-based alternative to traditional Retrieval-Augmented Generation (RAG). Rather than splitting a document into fixed-size chunks and embedding them into a vector database for similarity search, PageIndex converts a document into a hierarchical tree structure - essentially a machine-generated, deeply nested table of contents - and lets a large language model reason over that structure to decide where an answer likely lives, section by section, the way an analyst would use an index rather than skim every page (&lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;GitHub: VectifyAI/PageIndex&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The project describes itself as “inspired by AlphaGo”: instead of exhaustively scanning a search space the way similarity search scans every chunk, it uses guided, tree-based reasoning to navigate directly toward the relevant section (&lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;GitHub: VectifyAI/PageIndex&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Why It Exists: The Problem With Vector RAG
&lt;/h2&gt;

&lt;p&gt;Standard RAG pipelines work reasonably well for simple lookups, but they break down on long, structurally complex documents - financial filings, legal contracts, technical manuals, research papers. A technical breakdown of the framework lays out what goes wrong once a document runs into the hundreds of pages: fixed-size chunking cuts straight through tables, and footnotes get separated from the numbers they explain, destroying the structure the answer depended on.&lt;/p&gt;

&lt;p&gt;The deeper issue is conceptual: vector search assumes semantic similarity equals relevance, but the two aren't the same thing. A query about a company's “debt trend” might have its true answer inside a financial table, while the query's embedding matches prose about debt elsewhere - so the system fetches something that reads similarly but isn't the right evidence (&lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;GitHub: VectifyAI/PageIndex&lt;/a&gt;). Cross-references compound the problem: if the real answer is in “Appendix G,” plain vector search has no mechanism for following that pointer the way a human reader would (&lt;a href="https://themenonlab.blog/blog/pageindex-vs-vector-databases-rag-showdown" rel="noopener noreferrer"&gt;PageIndex vs. Vector Databases&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How PageIndex Works
&lt;/h2&gt;

&lt;p&gt;At a high level, PageIndex runs in two phases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1 - Tree index construction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The document (typically a PDF) is parsed page by page. An LLM scans the early pages to detect an existing table of contents, then builds a structured tree - sections, subsections, and their relationships - with each node tied back to specific pages or sentence-level positions in the source text so results stay traceable. The system can also generate summaries for every node, giving the LLM a compressed map of each section before it has to read the full text (&lt;a href="https://blog.stackademic.com/beyond-chunks-pageindexs-hierarchical-summaries-for-powerful-queries-caa82de9f6bc" rel="noopener noreferrer"&gt;Stackademic: PageIndex Explained&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2 - Reasoning-based retrieval&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a query comes in, the LLM doesn't run a similarity search - it reads the tree structure and section summaries, reasons about which branch is most likely to hold the answer, navigates there, and repeats at deeper levels until it has enough evidence, or explicitly abstains rather than guessing.&lt;/p&gt;

&lt;p&gt;Because every retrieved answer is tied to an explicit path through the tree - this section, then this subsection, then this page - the reasoning is auditable in a way opaque vector-similarity scores are not, which matters in regulated, high-stakes domains like legal or financial review (&lt;a href="https://yuv.ai/blog/pageindex" rel="noopener noreferrer"&gt;YUV.AI Blog: PageIndex&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“PageIndex is not the right tool for every situation. It excels at single-document, deep-accuracy retrieval.” - Addepallenikhilvarma, technical deep-dive on PageIndex&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. PageIndex vs. Traditional RAG
&lt;/h2&gt;

&lt;p&gt;The easiest way to understand PageIndex is not to think of it as “RAG without vectors,” but as a different retrieval strategy.&lt;/p&gt;

&lt;p&gt;Traditional RAG primarily treats a document as a collection of text fragments. PageIndex treats the document as a structured information space.&lt;/p&gt;

&lt;p&gt;That distinction changes almost every stage of retrieval.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcf31jn8bk7pbhkvbvq4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcf31jn8bk7pbhkvbvq4n.png" alt=" " width="634" height="460"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzbns3c0kt0u25q213zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzbns3c0kt0u25q213zg.png" alt=" " width="631" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most important difference is therefore not the absence of a vector database. It is where the intelligence sits in the retrieval process.&lt;/p&gt;

&lt;p&gt;In conventional RAG, most of the retrieval decision happens before the LLM sees the evidence. An embedding model converts the query and document chunks into vectors, a retrieval system finds nearby vectors, and the LLM receives the selected chunks.&lt;/p&gt;

&lt;p&gt;PageIndex moves more of that decision-making into the reasoning stage. Instead of asking, “Which pieces of text are mathematically closest to this query?”, the system can ask, “Which section of this document is most likely to contain the evidence required to answer this question?”&lt;/p&gt;

&lt;p&gt;That makes PageIndex particularly interesting for questions whose answers depend on document structure.&lt;/p&gt;

&lt;p&gt;Consider a financial filing containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a revenue table,&lt;/li&gt;
&lt;li&gt;a discussion of revenue,&lt;/li&gt;
&lt;li&gt;a footnote explaining a revenue adjustment,&lt;/li&gt;
&lt;li&gt;and an appendix containing historical figures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A vector retriever may retrieve several semantically similar passages. A reasoning-based retriever can instead use the document's hierarchy to identify the relevant section, inspect the associated pages, and follow the structure until it reaches the evidence required to answer the question.&lt;/p&gt;

&lt;p&gt;This does not mean vector retrieval is obsolete.&lt;/p&gt;

&lt;p&gt;Vector databases remain extremely useful when the first problem is finding the right document.&lt;/p&gt;

&lt;p&gt;If an organization has 100,000 contracts and the user asks:&lt;br&gt;
“Which contract contains the termination clause related to supplier bankruptcy?”&lt;br&gt;
the first challenge is corpus-wide discovery. Searching every document's PageIndex tree would be unnecessarily expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A more practical architecture is therefore:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Corpus discovery → candidate documents → PageIndex reasoning → evidence → answer&lt;/p&gt;

&lt;p&gt;This distinction leads to an important architectural principle:&lt;br&gt;
Vector retrieval is good at finding where to look. Structural reasoning is good at deciding what to read once you are there.&lt;/p&gt;

&lt;p&gt;PageIndex is most compelling when the second problem is harder than the first.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Quick Start for Developers
&lt;/h2&gt;

&lt;p&gt;PageIndex ships in a few forms, so pick based on how much infrastructure you want to run yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-hosted framework: &lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;github.com/VectifyAI/PageIndex&lt;/a&gt; - MIT-licensed Python, works with standard PDF parsing and an LLM of your choice.&lt;/li&gt;
&lt;li&gt;MCP server: &lt;a href="https://github.com/VectifyAI/pageindex-mcp" rel="noopener noreferrer"&gt;github.com/VectifyAI/pageindex-mcp&lt;/a&gt; - plugs the tree-reasoning workflow directly into MCP-compatible tools such as Claude or Cursor, useful when you want to chat with long PDFs without hitting a model's context-window limit.&lt;/li&gt;
&lt;li&gt;Hosted chat platform - upload a PDF and start asking questions with no setup at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A minimal MCP client configuration looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pageindex"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@pageindex/mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the self-hosted side, the core library is a fairly small surface area - roughly 2,579 lines of Python across six files as of a May 2026 snapshot - so it's realistic to read through the tree-construction and retrieval logic in an afternoon if you want to adapt it (&lt;a href="https://alphasignalai.substack.com/p/29k-stars-no-vectors-how-pageindex" rel="noopener noreferrer"&gt;Alpha Signal&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Statistics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;98.7% accuracy on FinanceBench was achieved by Mafin 2.5, VectifyAI's financial-analysis system built on PageIndex, tested across the benchmark's full question set. Source: &lt;a href="https://github.com/VectifyAI/Mafin2.5-FinanceBench" rel="noopener noreferrer"&gt;GitHub: VectifyAI/Mafin2.5-FinanceBench&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Traditional vector-based RAG scores roughly 30–50% on FinanceBench, versus PageIndex's 98.7% - a gap of about 49 percentage points on the same benchmark.&lt;/li&gt;
&lt;li&gt;Mafin 1, an earlier VectifyAI system, scored 38.0% accuracy on the same benchmark before the jump to Mafin 2.5's 98.7% - most of the gain came from the reasoning-based retrieval redesign, not a bigger base model. Source: &lt;a href="https://github.com/VectifyAI/Mafin2.5-FinanceBench" rel="noopener noreferrer"&gt;GitHub: VectifyAI/Mafin2.5-FinanceBench&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mafin 2.5 holds the same 98.7% score on both GPT-4o and DeepSeek v3, suggesting the accuracy gain comes from the retrieval architecture, not any one specific LLM. Source: &lt;a href="https://github.com/VectifyAI/Mafin2.5-FinanceBench" rel="noopener noreferrer"&gt;GitHub: VectifyAI/Mafin2.5-FinanceBench&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A GPT-4o baseline with no retrieval scores roughly 31% on FinanceBench, and Perplexity scores around 45% - both well below PageIndex's reported figure.&lt;/li&gt;
&lt;li&gt;An independently built RAG system on the 150 public FinanceBench questions reported ~76% end-to-end accuracy, versus ~19% for shared vector-store RAG configurations reported in the original FinanceBench paper - a separate team's data point showing the same directional gap. &lt;a href="https://github.com/aquib8112/FinanceBench_RAG" rel="noopener noreferrer"&gt;Source: GitHub: aquib8112/FinanceBench_RAG&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The GitHub repo grew from roughly 23,000 stars (late March 2026) to about 31,800 stars (May 20, 2026), with forks rising from ~2,000 to ~2,700 over the same stretch. Sources: &lt;a href="https://alphasignalai.substack.com/p/29k-stars-no-vectors-how-pageindex" rel="noopener noreferrer"&gt;Alpha Signal&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;The official PageIndex MCP server logged an estimated 53,200 visitors/downloads across the MCP ecosystem as of the date checked, with about 3,600 in the most recent week alone. Source: &lt;a href="https://www.pulsemcp.com/servers/pageindex" rel="noopener noreferrer"&gt;PulseMCP: Official PageIndex MCP Server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The design is explicitly inspired by AlphaGo - a guided search strategy applied to navigating document structure instead of a game board. Source: &lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;GitHub: VectifyAI/PageIndex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;It was built by a small team: Mingtian Zhang (founder of VectifyAI) and Yu Tang, released around September 2025 (with some sources citing an April 1, 2025 GitHub creation date). Source: &lt;a href="https://alphasignalai.substack.com/p/29k-stars-no-vectors-how-pageindex" rel="noopener noreferrer"&gt;Alpha Signal&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;There's no vector database and no chunking step at all - documents are organized along their natural sections, chapters, and tables instead of arbitrary fixed-length windows. Source: &lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;GitHub: VectifyAI/PageIndex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;It plugs straight into AI coding and chat tools via MCP, letting platforms like Claude and Cursor query long PDFs through the same tree-reasoning workflow - partly to work around context-window limits. Source: &lt;a href="https://github.com/VectifyAI/pageindex-mcp" rel="noopener noreferrer"&gt;GitHub: VectifyAI/pageindex-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Its own creators are candid that it doesn't scale like vector search: across a few thousand documents, PageIndex's own system reportedly falls back to standard FAISS vector search rather than building that many trees at once.&lt;/li&gt;
&lt;li&gt;Independent reviewers have flagged that the headline benchmark numbers omit operational data - no published latency, throughput, or per-query cost alongside the accuracy claims.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Where PageIndex Shines - and Where It Doesn't
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Strong fit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deep analysis of a single, known document - a specific 10-K, contract, or technical manual - where accuracy and explainability matter more than raw throughput. &lt;/li&gt;
&lt;li&gt;High-stakes domains that need an auditable “why” behind an answer - legal review, financial due diligence, regulatory compliance.&lt;/li&gt;
&lt;li&gt;Documents where answers depend on cross-references or structured elements like tables, which plain similarity search tends to miss. Source: &lt;a href="https://themenonlab.blog/blog/pageindex-vs-vector-databases-rag-showdown" rel="noopener noreferrer"&gt;PageIndex vs. Vector Databases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Weaker fit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Broad search across a large corpus (thousands of files), where per-document tree-building costs add up and vector search stays more efficient.&lt;/li&gt;
&lt;li&gt;Situations where you don't yet know which document contains the answer - a discovery problem vector search still handles well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern that keeps recurring across independent write-ups is a hybrid architecture: vector retrieval to find or shortlist the right document(s), then tree-based reasoning for precise, traceable extraction within them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“For high-stakes, single-document analysis, the combination of structural reasoning and principled abstention is genuinely valuable.” - Alden Do Rosario, on PageIndex&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  8. FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is PageIndex a replacement for vector databases and RAG entirely?&lt;/strong&gt;&lt;br&gt;
No. It's a specialized tool for deep, single-document analysis rather than a universal replacement. For broad search across many documents, vector-based RAG stays more efficient, and PageIndex's own systems reportedly fall back to FAISS once the document count gets large. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is PageIndex open source?&lt;/strong&gt;&lt;br&gt;
Yes - the core framework is on GitHub under the MIT license, alongside a separate MCP server package also under MIT. Sources: GitHub: &lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;VectifyAI/PageIndex, GitHub: VectifyAI/pageindex-mcp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is it different from a normal RAG pipeline?&lt;/strong&gt;&lt;br&gt;
Normal RAG chunks a document, embeds the chunks into a vector database, and retrieves by similarity search. PageIndex skips embeddings and chunking, building a hierarchical tree of the document's actual sections and having an LLM reason through that tree instead. Source: &lt;a href="https://github.com/VectifyAI/PageIndex" rel="noopener noreferrer"&gt;GitHub: VectifyAI/PageIndex&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the FinanceBench score everyone cites?&lt;/strong&gt;&lt;br&gt;
It refers to Mafin 2.5, VectifyAI's financial-document QA system built on PageIndex, which reported 98.7% accuracy across the full FinanceBench question set. Source: GitHub: &lt;a href="https://github.com/VectifyAI/Mafin2.5-FinanceBench" rel="noopener noreferrer"&gt;VectifyAI/Mafin2.5-FinanceBench&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I take the 98.7% number at face value?&lt;/strong&gt;&lt;br&gt;
Treat it like any vendor-published benchmark. It's a real, full-coverage result, but independent commentary notes the comparison table is self-reported by VectifyAI and that public materials don't include latency, throughput, or per-query cost - details that matter for production decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I try it without setting up infrastructure?&lt;/strong&gt;&lt;br&gt;
Use the hosted chat platform - upload a PDF and start asking questions with no setup. For developers, there's also an API and an MCP server for tools like Claude or Cursor. Sources: GitHub: VectifyAI/PageIndex, GitHub: &lt;a href="https://github.com/VectifyAI/pageindex-mcp" rel="noopener noreferrer"&gt;VectifyAI/pageindex-mcp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it require a specific LLM?&lt;/strong&gt;&lt;br&gt;
The self-hosted version works with an LLM of your choice for the reasoning steps, and Mafin 2.5's benchmark results specifically show the same accuracy across different base models, including GPT-4o and DeepSeek v3. Sources: Alpha Signal, GitHub: &lt;a href="https://github.com/VectifyAI/Mafin2.5-FinanceBench" rel="noopener noreferrer"&gt;VectifyAI/Mafin2.5-FinanceBench&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;PageIndex is a genuinely different answer to an old RAG problem: similarity is not the same thing as relevance, and for long, structurally rich professional documents, that mismatch causes real retrieval failures. By replacing chunking-and-embedding with a hierarchical tree index and LLM-driven reasoning, PageIndex delivers retrieval that is more traceable, more explainable, and - on benchmarks like FinanceBench - meaningfully more accurate than standard vector RAG for deep analysis of a single document.&lt;/p&gt;

&lt;p&gt;It is not, however, a wholesale replacement for vector search. Its own creators and independent reviewers agree that tree-building doesn't scale cheaply across large multi-document corpora, which is exactly where vector-based retrieval keeps earning its keep. The most credible read of where this is heading isn't “PageIndex vs. vector RAG” - it's a hybrid pipeline: vector search to find the right document, and reasoning-based tree navigation to extract the precise, auditable answer once you're inside it.&lt;/p&gt;

&lt;p&gt;For teams working on high-stakes, single-document analysis - financial filings, legal contracts, compliance documents - PageIndex is worth a serious look. For teams doing broad search across thousands of files, it's a tool to watch rather than a drop-in replacement, at least for now.&lt;/p&gt;

&lt;p&gt;About the Author: &lt;em&gt;Manthan Prajapati is an AI Engineer working at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;Addwebsolution&lt;/a&gt;.Writing code today to shape the intelligent systems of tomorrow.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>pageindex</category>
      <category>rag</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>Building OBS-Style Live Video Editing Features: Scenes, Source Reordering &amp; Slideshows</title>
      <dc:creator>Lakashya Upadhyay</dc:creator>
      <pubDate>Tue, 08 Sep 2026 09:55:58 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/building-obs-style-live-video-editing-features-scenes-source-reordering-slideshows-jha</link>
      <guid>https://dev.to/addwebsolutionpvtltd/building-obs-style-live-video-editing-features-scenes-source-reordering-slideshows-jha</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“Your live editor should feel as flexible as OBS, but run in the browser.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A Practical Guide to Building Scenes, Source Reordering, and Slideshows for Modern Live Video Applications.&lt;/p&gt;

&lt;p&gt;In modern live video applications, users expect the same control and flexibility they see in tools like OBS Studio. That means the ability to create multiple scenes, add and reorder different media sources, and build slideshows that run automatically or on demand. Building these features in a web or desktop app requires a clear architecture for managing scenes, sources, transitions, and playback logic.&lt;/p&gt;

&lt;p&gt;This guide explains how to design and implement OBS-style live video editing features, including scenes, source reordering, and slideshows, in a way that scales for real-world streaming and recording workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scenes act as containers for multiple media sources and define the visual layout for each moment in a live stream.&lt;/li&gt;
&lt;li&gt;Sources represent individual media elements such as cameras, images, browser windows, or slideshows that can be layered and reordered.&lt;/li&gt;
&lt;li&gt;Source reordering controls the visual stacking order and determines which elements appear on top.&lt;/li&gt;
&lt;li&gt;Slideshows can be implemented as a special source type that cycles through images with configurable timing and transitions.&lt;/li&gt;
&lt;li&gt;A clean data model and state management layer are essential for smooth scene switching and live updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why This Matters&lt;/li&gt;
&lt;li&gt;Understanding Scenes and Sources&lt;/li&gt;
&lt;li&gt;Designing the Data Model&lt;/li&gt;
&lt;li&gt;Implementing Scene Management&lt;/li&gt;
&lt;li&gt;Adding and Configuring Sources&lt;/li&gt;
&lt;li&gt;Source Reordering and Layering&lt;/li&gt;
&lt;li&gt;Building Slideshow Sources&lt;/li&gt;
&lt;li&gt;Handling Transitions Between Scenes&lt;/li&gt;
&lt;li&gt;Real-Time Preview and Program Output&lt;/li&gt;
&lt;li&gt;Performance and Resource Management&lt;/li&gt;
&lt;li&gt;Frequently Asked Questions (FAQs)&lt;/li&gt;
&lt;li&gt;Interesting Facts &amp;amp; Stats&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Why This Matters
&lt;/h2&gt;

&lt;p&gt;Building OBS-style live video editing features is about more than just copying a UI. It is about creating a flexible system where users can compose complex visual layouts, switch between them instantly, and control every element in real time.&lt;/p&gt;

&lt;p&gt;Scenes let users define different visual setups, such as a starting screen, a talking-head layout, or a gameplay overlay. Sources are the building blocks inside each scene, including cameras, images, browser content, and slideshows. Reordering sources changes which elements are visible on top, while slideshows add automated visual sequences without manual intervention.&lt;/p&gt;

&lt;p&gt;This matters especially in live streaming platforms, webinar tools, church media systems, and educational broadcasting apps where users need professional control without desktop software complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Understanding Scenes and Sources
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Scenes organize your layout. Sources fill it with content.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In OBS-style systems, a scene is a named collection of sources that together form one visual composition. Each scene can have its own set of sources, positions, sizes, and visibility settings.&lt;/p&gt;

&lt;p&gt;Sources represent individual media elements. Common types include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Video capture devices (webcams, capture cards)&lt;/li&gt;
&lt;li&gt;Display or window captures&lt;/li&gt;
&lt;li&gt;Images and image slideshows&lt;/li&gt;
&lt;li&gt;Browser sources (web pages, overlays)&lt;/li&gt;
&lt;li&gt;Text, color, and media sources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each source can be moved, resized, cropped, hidden, or reordered within a scene. A single source can also be reused across multiple scenes using reference patterns, which keeps configuration consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Designing the Data Model
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“A clear data model makes everything else easier.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before writing UI code, define a clean data structure for scenes and sources. This becomes the foundation for your state management, API, and persistence layer.&lt;/p&gt;

&lt;p&gt;A typical model might look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Scene&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;id&lt;/li&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;sources (array of Source)&lt;/li&gt;
&lt;li&gt;transition settings&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Source&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;id&lt;/li&gt;
&lt;li&gt;type (camera, image, slideshow, browser, etc.)&lt;/li&gt;
&lt;li&gt;properties (url, deviceId, folderPath, etc.)&lt;/li&gt;
&lt;li&gt;position and size (x, y, width, height)&lt;/li&gt;
&lt;li&gt;visibility flag&lt;/li&gt;
&lt;li&gt;order index for layering&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Store this in a central state store or database so that changes to scenes and sources are reflected instantly in the preview and program output.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;br&gt;
Predictable behavior,easier debugging and cleaner synchronization between UI and video engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Implementing Scene Management
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Scene management is the heart of your live editor.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Scene management covers creating, renaming, deleting, and switching between scenes. Users should be able to add new scenes, organize them in a list, and switch the active scene with a single action.&lt;/p&gt;

&lt;p&gt;Key features to implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add scene button that creates a new empty scene.&lt;/li&gt;
&lt;li&gt;Rename and delete actions for existing scenes.&lt;/li&gt;
&lt;li&gt;Active scene indicator showing which scene is currently live.&lt;/li&gt;
&lt;li&gt;Scene transitions with configurable duration and effect type (cut, fade, slide, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a user switches scenes, your system should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the active scene in your state.&lt;/li&gt;
&lt;li&gt;Trigger the selected transition effect.&lt;/li&gt;
&lt;li&gt;Render the new scene’s sources in the correct order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits:&lt;br&gt;
Professional broadcast-style workflow,Smooth visual changes during live streams and Clear mental model for users.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Adding and Configuring Sources
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Sources bring your scenes to life.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each scene needs a way to add and configure sources. Provide a source type selector (camera, image, slideshow, browser, etc.) and a configuration form for each type.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Camera source: select device, resolution, and frame rate.&lt;/li&gt;
&lt;li&gt;Image source: pick a file or URL.&lt;/li&gt;
&lt;li&gt;Slideshow source: select a folder of images, set slide duration, transition type, and loop option.youtube+1&lt;/li&gt;
&lt;li&gt;Browser source: enter URL, width, height, and interaction settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Allow users to move, resize, and crop sources directly in a preview canvas. Store these properties in your source model so they persist across sessions.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;br&gt;
Flexible visual layouts,fine-grained control over each element and reusable source configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Source Reordering and Layering
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Order determines what the audience sees on top.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source reordering controls the visual stacking order within a scene. The source with the highest order index appears on top, while lower indices are rendered underneath.&lt;/p&gt;

&lt;p&gt;Implement this with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A list view of sources in the current scene.&lt;/li&gt;
&lt;li&gt;Drag-and-drop or up/down buttons to change order.&lt;/li&gt;
&lt;li&gt;Immediate visual update in the preview canvas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is critical when layering elements like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Background images or videos at the bottom.&lt;/li&gt;
&lt;li&gt;The camera feeds in the middle.&lt;/li&gt;
&lt;li&gt;Overlays, logos, and text on top.wkconquer+1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits&lt;br&gt;
Intuitive layering control and no hidden rendering surprises as well as consistent behavior across scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Building Slideshow Sources
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Slideshows turn static images into dynamic sequences.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A slideshow source is a special type that cycles through a set of images automatically. This is useful for intros, sponsor slides, event schedules, or photo galleries during a live stream.&lt;/p&gt;

&lt;p&gt;Key configuration options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image list or folder path.&lt;/li&gt;
&lt;li&gt;Time per slide (for example, 5 seconds).&lt;/li&gt;
&lt;li&gt;Transition type between slides (fade, slide, cut).&lt;/li&gt;
&lt;li&gt;Transition duration.&lt;/li&gt;
&lt;li&gt;Loop toggle to restart the slideshow when it reaches the end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Internally, your slideshow engine should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load the image list.&lt;/li&gt;
&lt;li&gt;Track the current slide index.&lt;/li&gt;
&lt;li&gt;Use a timer to advance slides at the configured interval.&lt;/li&gt;
&lt;li&gt;Apply the selected transition effect between slides.&lt;/li&gt;
&lt;li&gt;Expose controls to pause, resume, or manually advance slides if needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits:&lt;br&gt;
Automated visual sequences, reduced manual switching during live events and professional-looking intros and interstitials.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Handling Transitions Between Scenes
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Transitions make scene changes feel polished.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Scene transitions define how the visual output changes when switching from one scene to another. Common transition types include cut, fade, fade to color, slide, swipe, and luma wipe.&lt;/p&gt;

&lt;p&gt;Implement a transition system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads the selected transition type and duration from the active scene or global settings.&lt;/li&gt;
&lt;li&gt;Applies the effect between the current program output and the next scene.&lt;/li&gt;
&lt;li&gt;Ensures audio continues smoothly during the transition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For advanced workflows, you can add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preview/Program switching, where users stage the next scene in a preview window before taking it live.&lt;/li&gt;
&lt;li&gt;Custom animated transitions using plugins or CSS-based effects in web implementations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits&lt;br&gt;
Professional broadcast feel, smoother visual changes, more control over live presentation style.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Real-Time Preview and Program Output
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Preview helps users check before they go live.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A professional live video editor should separate preview and program output. The preview shows what will go live next, while the program shows what the audience currently sees.&lt;/p&gt;

&lt;p&gt;Implement this with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two render targets: one for preview, one for program.&lt;/li&gt;
&lt;li&gt;A “Take” or “Cut” button that promotes the preview scene to program with the selected transition.&lt;/li&gt;
&lt;li&gt;Clear visual indicators for which scene is in preview and which is live.&lt;/li&gt;
&lt;li&gt;This pattern reduces accidental scene changes and gives users confidence when switching complex layouts during a live event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits:&lt;br&gt;
Safer live switching, better control over broadcast flow and more professional user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Performance and Resource Management
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Smooth video requires careful resource handling.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Live video editing is resource-intensive. Multiple scenes, high-resolution sources, and real-time transitions can strain CPU, GPU, and memory if not managed properly.&lt;/p&gt;

&lt;p&gt;Key practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit the number of active high-resolution sources at once.&lt;/li&gt;
&lt;li&gt;Use efficient rendering pipelines and hardware acceleration where available.&lt;/li&gt;
&lt;li&gt;Unload or pause sources that are not visible in the current scene.&lt;/li&gt;
&lt;li&gt;Optimize slideshow image loading with caching and preloading.&lt;/li&gt;
&lt;li&gt;Monitor performance metrics such as frame rate, CPU usage, and memory consumption, especially when users add many sources or switch scenes rapidly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits:&lt;br&gt;
Stable live streams, fewer dropped frames and better experience on a wider range of hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Frequently Asked Questions (FAQs)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q. What is a scene in an OBS-style editor?&lt;/strong&gt;&lt;br&gt;
A. A scene is a named collection of sources that together form one visual layout for a live stream or recording.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q. How does source reordering work?&lt;/strong&gt;&lt;br&gt;
A. Source reordering changes the visual stacking order within a scene, so higher-order sources appear on top of lower-order ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q. Can I reuse the same source in multiple scenes?&lt;/strong&gt;&lt;br&gt;
A. Yes. Many systems allow you to copy or reference a source across scenes so that configuration stays consistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q. How do slideshows work as a source type?&lt;/strong&gt;&lt;br&gt;
A. A slideshow source cycles through a list of images with configurable timing, transitions, and loop behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q. Do I need Preview/Program switching for a basic editor?&lt;/strong&gt;&lt;br&gt;
A. It is optional but highly recommended for professional workflows, as it lets users stage changes before going live.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Interesting Facts &amp;amp; Stats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OBS Studio allows several video and audio sources to be combined within the same scene, with each scene containing a different collection of &lt;a href="https://www.wkconquer.com/2026/08/obs-studio-32-2-2-portable.html" rel="noopener noreferrer"&gt;sources.wkconquer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sources can be resized, moved, cropped, layered, hidden, and reordered to create complex broadcast layouts. &lt;a href="https://www.wkconquer.com/2026/08/obs-studio-32-2-2-portable.html" rel="noopener noreferrer"&gt;wkconqueryoutube&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Scene switching can be performed manually or configured with keyboard shortcuts for faster live control.&lt;/li&gt;
&lt;li&gt;Slideshow sources support configurable slide duration, transition speed, and loop playback for automated image sequences.&lt;/li&gt;
&lt;li&gt;Modern OBS-style systems often use Preview/Program workflows to stage shots before taking them live, similar to professional broadcast switchers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building OBS-style live video editing features means creating a flexible system where scenes, sources, and transitions work together smoothly. Scenes act as containers for multiple media sources and define the visual layout for each moment in a live stream. Sources represent individual media elements that can be layered, reordered, and configured in detail. Slideshows add automated visual sequences, while transitions and Preview/Program workflows give users professional control over live output.&lt;/p&gt;

&lt;p&gt;A strong implementation usually comes down to a clear data model, efficient rendering, and intuitive UI for managing scenes and sources. When these pieces align, you get a live video editor that feels powerful, responsive, and ready for real-world streaming and recording workflows.&lt;/p&gt;

&lt;p&gt;About the Author:&lt;em&gt;Lakashya is a full-stack developer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt; specializing in modern backend systems, real-time video applications, and scalable web architectures.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>livevideoediting</category>
      <category>obsstyle</category>
      <category>videoproduction</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building Scalable Microservices with NestJS: Architecture, Communication &amp; Best Practices</title>
      <dc:creator>Abodh Kumar</dc:creator>
      <pubDate>Mon, 07 Sep 2026 10:44:05 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/building-scalable-microservices-with-nestjs-architecture-communication-best-practices-4m8o</link>
      <guid>https://dev.to/addwebsolutionpvtltd/building-scalable-microservices-with-nestjs-architecture-communication-best-practices-4m8o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Any organization that designs a system will produce a design whose structure is a copy of the organization's communication structure. - Melvin Conway&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every growing Node.js backend arrives at the same fork in the road. The Express app that started as three routes now has four hundred, a deploy takes twenty minutes because everything ships together, and one team's bad migration takes checkout down for everybody. The instinct is to split it into microservices. That instinct is often right - and just as often it replaces a slow monolith with a distributed system nobody can debug. NestJS matters at exactly this fork, because it is one of the very few Node.js frameworks that ships an opinion about structure: modules, providers, dependency injection, and a transport-agnostic microservice layer where the same handler code can speak TCP, Redis, NATS, RabbitMQ, Kafka, or gRPC.&lt;/p&gt;

&lt;p&gt;But NestJS is routinely misunderstood as "Angular for the backend" or "Express with decorators." That framing sells it short and, worse, leads teams into the classic distributed-systems bugs: services that quietly share a database, events processed twice because a broker redelivered them, retries that turn a two-second blip into a full outage, sagas with no compensating action. Nest gives you composition primitives and a clean request lifecycle. It does not give you your service boundaries, your idempotency, or your observability - those are design decisions, and each one has correctness rules that are easy to get wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NestJS is an architecture, not a router - modules, providers, and DI are what make a service testable and splittable. Get the module graph right and the eventual service split is mostly mechanical.&lt;/li&gt;
&lt;li&gt;Start with a modular monolith. A boundary you cannot enforce inside one process will not survive being turned into a network call.&lt;/li&gt;
&lt;li&gt;Choose the communication style deliberately - send() for a request whose answer the caller needs, emit() for a fact other services react to. Confusing the two is how you build a distributed monolith.&lt;/li&gt;
&lt;li&gt;Every service owns its data. A shared database re-couples services at the schema level and silently undoes the entire split.&lt;/li&gt;
&lt;li&gt;Distributed transactions are sagas, not transactions - model compensating actions explicitly, and make every consumer idempotent, because at-least-once is the delivery guarantee you actually get.&lt;/li&gt;
&lt;li&gt;Resilience is code you write, not a property you inherit: timeouts, bounded retries with backoff and jitter, circuit breakers, dead-letter queues, and graceful shutdown.&lt;/li&gt;
&lt;li&gt;Without correlation IDs, distributed tracing, and structured logs, a microservice failure is unreadable. Instrument before you split, not after.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Understanding the NestJS Architecture Model&lt;/li&gt;
&lt;li&gt;Designing Service Boundaries&lt;/li&gt;
&lt;li&gt;Inter-Service Communication&lt;/li&gt;
&lt;li&gt;Data, Consistency &amp;amp; Transactions&lt;/li&gt;
&lt;li&gt;Resilience, Observability &amp;amp; Operations&lt;/li&gt;
&lt;li&gt;Stats &amp;amp; Interesting Facts&lt;/li&gt;
&lt;li&gt;FAQ&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;NestJS was released in 2017 by Kamil Mysliwiec, who wanted for Node.js what Angular had given the front end: a framework that answers "where does this code go?" before you have written any of it. It is written in TypeScript, it runs on Express by default with a Fastify adapter available, and the HTTP layer is deliberately the least interesting part of it. What Nest actually provides is an inversion-of-control container, a decorator-driven module system, and a request lifecycle with well-defined extension points - guards, interceptors, pipes, and exception filters - so that cross-cutting concerns are written once rather than copy-pasted into every handler.&lt;/p&gt;

&lt;p&gt;That structure is precisely what makes Nest a good microservices framework, and the connection is not obvious at first. A microservice split is a dependency-graph problem long before it is an infrastructure problem. If your billing logic reaches directly into the orders table and constructs its own database client, no amount of Docker will separate them. A Nest module, by contrast, has an explicit imports list and an explicit exports list: the surface it consumes and the surface it offers are both declared. A module whose exports are small and whose imports are few is already, in effect, a service - moving it out of the process becomes a change of transport rather than a rewrite.&lt;/p&gt;

&lt;p&gt;The failure modes follow from the same place. Nest will happily let you import every module into every other module until the graph is a hairball. It will let you pass a send() call the same way you would call a local function, hiding a network hop behind a method signature that cannot fail locally but absolutely can fail remotely. It will let you emit an event and assume it arrives exactly once. None of these are defects in Nest - they are the ordinary hazards of distributed systems, showing up in a framework that makes distribution easy enough that you reach for it early. This article walks through the architecture model, boundary design, communication patterns, data consistency, and the operational concerns - with concrete, production-shaped code you can adapt.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Understanding the NestJS Architecture Model
&lt;/h2&gt;

&lt;p&gt;Before designing a single service, anchor your mental model. A Nest application is not a list of routes with middleware bolted on; it is a graph of modules resolved by a container at boot, plus a well-defined pipeline that every request passes through. Getting these two things right is most of the design work, and almost every "we cannot split this service" conversation traces back to one of them being wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.1 Modules, Providers &amp;amp; Dependency Injection&lt;/strong&gt;&lt;br&gt;
A module is a unit of ownership. It declares what it needs (imports), what it builds (providers), what it serves (controllers), and - critically - what it lets anyone else use (exports). Anything not exported is genuinely private, enforced by the container rather than by convention. A provider is anything injectable: a service, a repository, a factory, a value. Dependency injection is what makes the whole thing testable, because a class that receives its collaborators through its constructor can be handed fakes in a unit test and a real client in production without changing a line.&lt;/p&gt;

&lt;p&gt;Two rules pay for themselves repeatedly. Inject against an abstraction - an interface plus an injection token - rather than a concrete class, so the implementation can be swapped for a remote client when the module becomes a service. And keep the export list deliberately small: it is the public API of that bounded context, and every extra export is a future coupling you will have to unpick.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// orders.module.ts - the module IS the boundary. Nothing leaks unless exported.&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;TypeOrmModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forFeature&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="nx"&gt;PaymentsClientModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;OrdersController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;OrdersService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ORDER_POLICY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TieredPricingPolicy&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// token, not class&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;OrdersService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;   &lt;span class="c1"&gt;// &amp;lt;- the ONLY public surface of this context&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;// Constructor injection: business logic never news-up its collaborators&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;InjectRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Repository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_POLICY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrderPolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventPublisher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.2 The Request Lifecycle: Guards, Interceptors, Pipes &amp;amp; Filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every request that reaches a Nest handler passes through a fixed pipeline, and knowing the order is what stops you from putting logic in the wrong place. Middleware runs first and is framework-level. Guards decide whether the request is allowed at all - authentication and authorisation live here, and nowhere else. Interceptors wrap the handler on both sides, which makes them the right home for timeouts, caching, response shaping, and tracing spans. Pipes transform and validate the incoming payload just before the handler receives it. Exception filters catch whatever is thrown and turn it into a response.&lt;/p&gt;

&lt;p&gt;The single highest-leverage line in a Nest microservice is a global ValidationPipe with whitelist enabled. It strips properties that are not on your DTO, which means a malformed or hostile payload cannot smuggle fields past your handler - and because the same pipe applies to message handlers as well as HTTP controllers, an event arriving from a broker is validated exactly like a request arriving from the internet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.ts - one global pipe replaces hand-written validation in every handler&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useGlobalPipes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ValidationPipe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// strip properties not on the DTO&lt;/span&gt;
  &lt;span class="na"&gt;forbidNonWhitelisted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// ...or reject the payload outright&lt;/span&gt;
  &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// plain JSON -&amp;gt; typed DTO instance&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// A cross-cutting concern written once, applied everywhere&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeoutInterceptor&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;NestInterceptor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CallHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;throwError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;TimeoutError&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RequestTimeoutException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.3 Configuration as a Boot-Time Contract&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A microservice has more configuration than a monolith and far less tolerance for getting it wrong, because a missing variable in one of twelve services fails at an arbitrary time under load rather than at startup. Validate the whole environment at boot with ConfigModule and a schema, so a bad deployment crashes immediately and visibly instead of at three in the morning on the first request that happens to read the missing value. Never read process.env directly from business logic - inject typed configuration, and the same class becomes trivially testable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fail at boot, loudly - not at 3am on the first request that reads the value&lt;/span&gt;
&lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;isGlobal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;validationSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;NATS_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;HTTP_TIMEOUT_MS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;validationOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;abortEarly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;  &lt;span class="c1"&gt;// report every missing var at once&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you can't build a well-structured monolith, what makes you think microservices are the answer? - Simon Brown&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Designing Service Boundaries
&lt;/h2&gt;

&lt;p&gt;Nest makes it easy to create a service. It does not tell you whether you should. Boundaries are the one decision that is genuinely expensive to reverse, because every wrong boundary becomes a chatty network call, a distributed transaction, or a shared database - and usually all three.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.1 The Modular Monolith Comes First&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build a modular monolith and extract from it. One deployable, one repository, but strict module boundaries: no module reaches into another module's repositories, every cross-module call goes through an exported service, and no two modules share entity classes. This costs almost nothing and buys you the ability to discover your boundaries with a refactor rather than with a migration. When a module has stopped changing for reasons that belong to other modules, when it has its own scaling profile, or when a separate team owns it, that is the signal to extract it.&lt;/p&gt;

&lt;p&gt;Split on ownership, not on nouns. "A service per database table" produces a system where creating an order requires six round trips. The useful question is which pieces of data change together in one transaction and who is accountable when they are wrong - that cluster is a service. If two candidate services need a distributed transaction for their most common operation, they are one service that has been cut in the wrong place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.2 Monorepo, Shared Libraries &amp;amp; Contracts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Nest CLI supports a monorepo layout - multiple apps alongside shared libs - and it is the pragmatic default for a small team. One dependency tree, one CI pipeline, atomic changes across a producer and its consumers. What you share matters far more than where the code lives: share contracts - DTOs, message pattern names, event shapes - and share generic infrastructure such as a logger or a tracing setup. Never share entities, repositories, or business logic. A shared libs/domain becomes exactly the coupling you split the system up to avoid, and every change to it redeploys everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;gateway&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;            &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;HTTP&lt;/span&gt; &lt;span class="nx"&gt;edge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aggregation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt; &lt;span class="nx"&gt;limiting&lt;/span&gt;
  &lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;owns&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;orders&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;
  &lt;span class="nx"&gt;payments&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;           &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;owns&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;payments&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;
&lt;span class="nx"&gt;libs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="nx"&gt;contracts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;          &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;DTOs&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;pattern&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;ONLY&lt;/span&gt; &lt;span class="nx"&gt;shared&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="nx"&gt;surface&lt;/span&gt;
  &lt;span class="nx"&gt;observability&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;      &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;correlation&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;

&lt;span class="c1"&gt;// libs/contracts/src/orders.contract.ts - both sides import this one file&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ORDER_PATTERNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders.create&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders.findOne&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ORDER_EVENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;order.created.v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// version the event, not just the endpoint&lt;/span&gt;
  &lt;span class="na"&gt;cancelled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;order.cancelled.v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderCreatedEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsUUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;       &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsUUID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;       &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;customerId&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;totalCents&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;IsISO8601&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;    &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;occurredAt&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// stamped by the producer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Inter-Service Communication
&lt;/h2&gt;

&lt;p&gt;This is where NestJS earns its place. A Nest microservice is the same controllers, the same providers, and the same pipeline as an HTTP application - only the transport differs, and the transport is a configuration object. That symmetry is a genuine gift, and also a trap: because a remote call looks like a local one, it is easy to forget that it can time out, arrive twice, or arrive out of order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.1 Transporters &amp;amp; the Microservice Bootstrap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nest ships transporters for TCP, Redis, NATS, MQTT, RabbitMQ, Kafka, and gRPC, and a custom transporter interface for anything else. Pick on delivery semantics, not on familiarity. TCP is the built-in default and is fine for internal request-response between a handful of services, but it has no broker, so there is no buffering and no redelivery. NATS is excellent for low-latency request-response plus lightweight pub/sub with queue groups. RabbitMQ gives you real queues, per-message acknowledgement, and dead-letter exchanges - the sane default for work that must not be lost. Kafka is a durable, replayable, partitioned log: the right answer for event streaming and for consumers that need to re-read history, and overkill for simple RPC. gRPC is for typed, high-throughput synchronous calls.&lt;/p&gt;

&lt;p&gt;A single process can be both an HTTP server and a message consumer - the hybrid application - which is how a gateway usually works and how a service exposes health endpoints while consuming from a broker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A pure microservice: same decorators, different transport&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createMicroservice&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MicroserviceOptions&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;OrdersModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NATS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NATS_URL&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders-workers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// queue group =&amp;gt; one delivery per group, load balanced&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useGlobalPipes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ValidationPipe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;whitelist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Hybrid: HTTP for the outside world, a broker for the inside&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connectMicroservice&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MicroserviceOptions&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RMQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RMQ_URL&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orders&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;noAck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startAllMicroservices&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.2 Request-Response vs Event-Driven&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These two are not stylistic alternatives; they encode different couplings. @MessagePattern handles a request-response call: a caller is blocked waiting for your answer, so your latency is their latency and your outage is their outage. @EventPattern handles an event: a statement that something happened, with no reply channel and no waiting caller. On the calling side, send() returns a cold Observable and only dispatches on subscribe - a genuinely common bug is calling send() without subscribing and wondering why nothing happened - while emit() fires and returns.&lt;/p&gt;

&lt;p&gt;The default should be events. Every synchronous hop you add multiplies your failure probability and your tail latency; three services at 99.9% availability chained synchronously give you 99.7%. Reserve request-response for a query whose result the caller cannot proceed without, always with an explicit timeout, and let everything downstream of a write - email, analytics, search indexing, recommendations - be a reaction to a published event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Handlers: @MessagePattern answers a caller; @EventPattern reacts to a fact&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;MessagePattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_PATTERNS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;// request-response&lt;/span&gt;
  &lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FindOrderDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;EventPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_EVENTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// no reply channel&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;onOrderCreated&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrderCreatedEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Ctx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RmqContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                  &lt;span class="c1"&gt;// MUST be idempotent&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getChannelRef&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;          &lt;span class="c1"&gt;// ack only after success&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Callers: send() WAITS and is cold (nothing happens until subscribe).&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;firstValueFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_PATTERNS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// emit() blocks nobody and expects no reply - the default for anything downstream&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_EVENTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.3 gRPC &amp;amp; Contract-First APIs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When two services talk constantly and synchronously, a hand-written JSON DTO shared through a library is a contract only by agreement - nothing stops a producer from shipping a breaking change. gRPC replaces the agreement with an artefact: a .proto file that generates both sides, transmits Protocol Buffers over HTTP/2, and supports streaming in both directions. Nest's gRPC transporter maps @GrpcMethod onto your existing service classes, so adopting it is a controller-layer change rather than an architectural one. Keep the proto files in a shared package, treat field numbers as immutable, and only ever add optional fields - that is the whole of backwards compatibility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="c1"&gt;// orders.proto - a contract that compiles. A shared interface only hopes.&lt;/span&gt;
&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;Orders&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;FindOne&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FindOneRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;FindOneRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="na"&gt;total_cents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// field numbers are forever - only ever ADD&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// orders.controller.ts - the same service class, a different decorator&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;GrpcMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'FindOne'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FindOneRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="n"&gt;this.orders.findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data.id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.4 The Gateway &amp;amp; the Aggregation Trap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An API gateway - a Nest HTTP application that fans out to internal services - is the right edge for authentication, rate limiting, request shaping, and a single public surface. Keep it thin. The moment it contains business rules it becomes a monolith with extra network hops, and every team ends up blocked on the same repository. Aggregate with forkJoin or Promise.all so independent calls run concurrently rather than serially, put a timeout on each one, and decide explicitly what a partial failure returns: a degraded response with a missing section is almost always better than a 500.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Data, Consistency &amp;amp; Transactions
&lt;/h2&gt;

&lt;p&gt;Splitting the code is straightforward. Splitting the data is where microservice projects actually succeed or fail, because the database is the last place coupling hides and the first place it hurts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.1 Database per Service&lt;/strong&gt;&lt;br&gt;
Each service owns its schema, and no other service reads it - not even for a "quick report," not even read-only. A shared table means you cannot change a column without a cross-team migration, which is precisely the constraint you split the system to escape. When another service needs your data, it either asks you for it or subscribes to your events and keeps its own projection shaped for its own queries. The cost is real: you give up joins and you give up cross-service ACID transactions. The benefit is that you get to deploy independently, which was the entire point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.2 Sagas &amp;amp; Compensating Actions&lt;/strong&gt;&lt;br&gt;
Without a shared transaction, a multi-service operation becomes a saga: a sequence of local transactions where each step has a defined compensating action to undo it. Orchestrated sagas put the sequence in one coordinator - easier to reason about, easier to debug, and the right starting point. Choreographed sagas let each service react to the previous one's event - less coupling, but the flow exists only in the collective imagination of the services and becomes very hard to trace.&lt;/p&gt;

&lt;p&gt;The critical discipline is that compensation is not rollback. You cannot un-send an email or un-charge a card without a trace; you send an apology and issue a refund. Model those explicitly as first-class operations, and persist the saga's state so that a coordinator crashing halfway through does not strand the order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A saga: local transactions plus explicit compensating actions.&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;placeOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PlaceOrderCommand&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                    &lt;span class="c1"&gt;// step 1&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;totalCents&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// step 2&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markFailed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payment_declined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// compensate 1&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;            &lt;span class="c1"&gt;// step 3&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                         &lt;span class="c1"&gt;// compensate 2&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markFailed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;out_of_stock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// compensate 1&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_EVENTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;toEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.3 The Outbox Pattern &amp;amp; Idempotency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is one bug that every event-driven system writes at least once: committing a database transaction and then publishing an event. If the process dies in between, the state changed and nobody was told - a silent, permanent inconsistency. The transactional outbox fixes it by writing the event into a table inside the same transaction as the state change, and having a separate relay poll that table and publish. The event can now be published twice, but it can never be lost, and "twice" is a problem you can solve.&lt;/p&gt;

&lt;p&gt;You solve it with idempotency. Every broker worth using guarantees at-least-once delivery, which means your consumer will eventually run the same message twice - after a redelivery, a rebalance, or a retry. Give every message a stable identifier produced by the emitter, claim it in a store with a TTL before doing any work, and treat a duplicate as a successful no-op. Idempotency is not an optimisation for busy systems; it is the correctness requirement that makes retries safe at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Outbox: the state change and the event commit together, or neither does.&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;trx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;OutboxMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messageId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;// stable id, survives every retry&lt;/span&gt;
    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ORDER_EVENTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;toEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// A separate relay polls the outbox and publishes: at-least-once, never lost.&lt;/span&gt;

&lt;span class="c1"&gt;// Consumer side: "handled twice" WILL happen. Make it a no-op.&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;EventPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ORDER_EVENTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;onCreated&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Payload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OrderCreatedEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNew&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dedupe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`order.created:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;86&lt;/span&gt;&lt;span class="nx"&gt;_400&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isNew&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// already processed - ack and move on&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendConfirmation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable. - Leslie Lamport&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. Resilience, Observability &amp;amp; Operations
&lt;/h2&gt;

&lt;p&gt;A monolith fails all at once and tells you so. A distributed system fails partially, intermittently, and somewhere else - which is why the operational work is not a phase after the build but a property of it. The controls below are what keep a NestJS microservice fleet healthy past launch day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 Timeouts, Retries &amp;amp; Circuit Breakers&lt;/strong&gt;&lt;br&gt;
Every remote call needs an explicit timeout, because the default in most clients is to wait forever, and a hung dependency will exhaust your connection pool and take you down with it. Every retry needs a bound, exponential backoff, and jitter - an unbounded bare retry is not resilience, it is a self-inflicted denial of service that keeps a struggling dependency down. Retry only what is safe to retry: idempotent reads always, writes only when they carry an idempotency key.&lt;/p&gt;

&lt;p&gt;When a dependency is genuinely down, retrying at all is waste. A circuit breaker - opossum wraps a Nest provider in a few lines - trips after a failure threshold, fails fast for a cooling-off period, then lets a probe through. Pair it with a fallback: cached data, a queued write, or a degraded response. Failing fast with a useful answer beats timing out with none.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bounded retry with exponential backoff and jitter - never a bare retry()&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PAYMENT_PATTERNS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;jitterMs&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;throwError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ServiceUnavailableException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Circuit breaker: stop hammering a dependency that is already down&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chargeFn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;errorThresholdPercentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;resetTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// cool off, then let one probe through&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;breaker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deferred&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;   &lt;span class="c1"&gt;// degrade, do not 500&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.2 Health Checks &amp;amp; Graceful Shutdown&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two endpoints, and they are not the same endpoint. Liveness answers "is this process wedged and in need of a restart?" and must not check dependencies - if it does, one slow database restarts your entire fleet. Readiness answers "can I serve traffic right now?" and legitimately checks the database and the broker, so the orchestrator stops routing to a pod that cannot work. @nestjs/terminus implements both.&lt;/p&gt;

&lt;p&gt;Graceful shutdown matters more in a consumer than in an HTTP server. On SIGTERM, stop accepting new messages, finish the ones already in flight, then close connections - otherwise every deploy drops whatever was mid-handler. Call enableShutdownHooks() and implement OnApplicationShutdown, and remember that a container's grace period is finite: your drain has to fit inside it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Liveness must NOT check dependencies. Readiness must.&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;health&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HealthController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;live&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;live&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;              &lt;span class="c1"&gt;// am I wedged?&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                             &lt;span class="c1"&gt;// can I serve traffic?&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pingCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;database&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;thresholdPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// main.ts&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enableShutdownHooks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConsumerLifecycle&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnApplicationShutdown&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;onApplicationShutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;     &lt;span class="c1"&gt;// stop accepting new messages&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inFlight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// finish what is already running&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.3 Tracing, Logging &amp;amp; Metrics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In one process a stack trace tells you what happened. Across twelve services it tells you almost nothing, because the cause is three hops upstream. Distributed tracing is the replacement: instrument with OpenTelemetry, propagate context on every hop including broker messages, and you get one waterfall per user action showing exactly which span was slow. Generate a correlation ID at the gateway, put it in an AsyncLocalStorage so it needs no threading through function signatures, attach it to every log line, and forward it as a header or message property on every outbound call.&lt;/p&gt;

&lt;p&gt;Log structured JSON, never interpolated strings - pino through nestjs-pino costs little and makes logs queryable. Redact tokens and PII at the logger, not at the call site, because the call site you forget is the one that leaks. For metrics, the four RED/USE signals per service - request rate, error rate, duration percentiles, and queue depth or consumer lag - answer most incident questions before you open a trace. Alert on p99 latency and consumer lag, not on averages: an average hides exactly the tail your users are complaining about.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Correlation id: created at the edge, carried on every hop, on every log line&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CorrelationInterceptor&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;NestInterceptor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;als&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AsyncLocalStorage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;intercept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CallHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;switchToHttp&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;correlationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-correlation-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;als&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;correlationId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// tracing.ts - must be imported BEFORE anything else in main.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sdk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NodeSDK&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;traceExporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OTLPTraceExporter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OTLP_URL&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;instrumentations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;getNodeAutoInstrumentations&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.4 Security &amp;amp; Performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authenticate at the edge and authorise everywhere. A gateway-only check means any service that gets reached by another route - a misconfigured ingress, a compromised neighbour - is wide open, so validate a signed token in each service with a guard and never trust a plain userId field in a message payload. Use mTLS or a service mesh for internal traffic that crosses a trust boundary, keep secrets in a secret manager rather than in environment files committed by accident, and set a RateLimit guard at the gateway.&lt;/p&gt;

&lt;p&gt;On performance, the framework is rarely your bottleneck - the network and your query patterns are. Swap the Express adapter for Fastify if the HTTP layer measurably matters, batch or pipeline chatty calls instead of looping over send(), and cache read models close to the reader. The most common Nest-specific performance mistake is not a slow framework but an N+1 fan-out: a loop that makes one remote call per item, turning a single request into two hundred.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Stats &amp;amp; Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NestJS was created by Kamil Mysliwiec and first released in 2017. It is written in TypeScript, is platform-agnostic at the HTTP layer, and uses Express by default with an official Fastify adapter available.Source: &lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;https://docs.nestjs.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Nest ships seven built-in transporters out of the box - TCP, Redis, NATS, MQTT, RabbitMQ, Kafka, and gRPC - plus a custom transporter interface, so the same handler code can change protocol with a configuration object.
Source: &lt;a href="https://docs.nestjs.com/microservices/basics" rel="noopener noreferrer"&gt;https://docs.nestjs.com/microservices/basics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;@nestjs/core is downloaded several million times a week on npm, placing it among the most used server-side TypeScript frameworks in the ecosystem.Source: &lt;a href="https://www.npmjs.com/package/@nestjs/core" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@nestjs/core&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Nest repository has accumulated more than 60,000 GitHub stars, and the framework has appeared consistently among the web technologies tracked in the Stack Overflow Developer Survey.
Source: &lt;a href="https://github.com/nestjs/nest" rel="noopener noreferrer"&gt;https://github.com/nestjs/nest&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Nest CLI has a first-class monorepo mode that manages multiple applications and shared libraries in a single project with one tsconfig and one dependency tree.
Source: &lt;a href="https://docs.nestjs.com/cli/monorepo" rel="noopener noreferrer"&gt;https://docs.nestjs.com/cli/monorepo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;gRPC transmits Protocol Buffers over HTTP/2 with multiplexed streams and binary framing - typically far smaller on the wire than equivalent JSON, which is why it is the usual choice for high-volume internal RPC.Source: &lt;a href="https://grpc.io/docs/what-is-grpc/introduction/" rel="noopener noreferrer"&gt;https://grpc.io/docs/what-is-grpc/introduction/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The saga pattern and the transactional outbox are the two canonical answers to "there are no distributed transactions" - both predate microservices by decades and both remain the standard solution.
Source: &lt;a href="https://microservices.io/patterns/data/saga.html" rel="noopener noreferrer"&gt;https://microservices.io/patterns/data/saga.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Microservices are not a goal. They are a trade you make when the cost of coordinating exceeds the cost of distributing. - Backend folk wisdom&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  8. FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Do I actually need microservices, or is a modular monolith enough?&lt;/strong&gt;&lt;br&gt;
Ans: For most teams, a modular monolith is enough for far longer than they expect. Microservices buy independent deployment, independent scaling, and independent team ownership - and they cost you distributed transactions, network failure modes, and an observability bill you must pay before you can debug anything. If your pain is code organisation, fix the module boundaries; that is free. If your pain is that fifteen engineers cannot ship without coordinating, or that one endpoint needs ten times the hardware of the rest, that is what a split solves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. What is the real difference between &lt;code&gt;send()&lt;/code&gt; and &lt;code&gt;emit()&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Ans: send() is request-response: it returns a cold Observable, dispatches only on subscription, and a caller is blocked waiting for your reply - so your latency and your availability become theirs. emit() publishes an event with no reply channel and returns immediately. Use send() only when the caller genuinely cannot proceed without your answer, and always wrap it in a timeout. Everything downstream of a write - email, indexing, analytics - should be an event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Which transporter should I choose?&lt;/strong&gt;&lt;br&gt;
Ans: Match it to the delivery guarantee you need. TCP for simple internal request-response with no broker and no redelivery. NATS for low-latency RPC plus lightweight pub/sub with queue groups. RabbitMQ when work must not be lost and you want per-message acks and dead-letter queues. Kafka when you need a durable, replayable, partitioned log or multiple independent consumer groups over the same stream. gRPC for typed, high-throughput synchronous calls. Do not pick Kafka because it is the one you have heard of.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Can two services share a database if one of them is read-only?&lt;/strong&gt;&lt;br&gt;
Ans: No, and "read-only" is how it always starts. A reader depends on your schema just as hard as a writer, so you can no longer rename a column, change a type, or drop a table without a cross-team migration - which is exactly the coupling you split the system to remove. Expose an endpoint, or publish events and let the other service maintain its own projection shaped for its own queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. How do I do a transaction across services?&lt;/strong&gt;&lt;br&gt;
Ans: You do not - you write a saga. Break the operation into local transactions, one per service, and define an explicit compensating action for each so a later failure can undo the earlier steps. Start with an orchestrated saga where one coordinator owns the sequence; it is far easier to debug than choreography, where the flow exists only as an implicit chain of events. Persist the saga state so a coordinator crash does not strand the work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. How do I stop the same message being processed twice?&lt;/strong&gt;&lt;br&gt;
Ans: Assume it will be, because at-least-once is what brokers guarantee. Have the producer stamp a stable message ID, and have the consumer claim that ID in a deduplication store with a TTL before doing any work - if the claim fails, the message was already handled, so acknowledge and return. Where possible make the operation naturally idempotent (an upsert rather than an insert, SET rather than INCR), which is better than deduplication because it needs no extra state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Monorepo or one repository per service?&lt;/strong&gt;&lt;br&gt;
Ans: Start with a monorepo using the Nest CLI's monorepo mode. It gives you atomic changes across a producer and its consumers, one dependency tree, and one CI pipeline - all of which matter most in the period when your boundaries are still moving. Split into separate repositories when teams need genuinely independent release cadences or different security boundaries. The repository layout is a logistics decision; the module boundaries are the architectural one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. How do I test a service without running the whole system?&lt;/strong&gt;&lt;br&gt;
Ans: In three layers. Unit-test providers with fakes injected through the constructor - this is what DI was for, and it should cover the bulk of your logic. Integration-test the module with Test.createTestingModule() and a real database in Testcontainers, overriding only the remote clients. Then use contract tests so a producer cannot ship an event shape its consumers do not accept. End-to-end tests across every service are slow and flaky; keep a handful for the critical path only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Isn't NestJS slow? All those decorators and that DI container.&lt;/strong&gt;&lt;br&gt;
Ans: The container resolves the dependency graph once at bootstrap, not per request, so the steady-state overhead is small and is nearly always dwarfed by your database queries and network hops. If the HTTP layer is genuinely your bottleneck - measure first - switch to the Fastify adapter. In practice the performance problems in Nest microservices are architectural: an N+1 fan-out of remote calls, a missing timeout that pins the event loop, or a synchronous chain where events would do.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Conclusion
&lt;/h2&gt;

&lt;p&gt;NestJS rewards developers who understand what it actually is. Not a faster Express, and not a licence to start with twelve services, but a framework that makes the structure of your application explicit enough that you can see your boundaries before you have to defend them across a network. Every meaningful decision in a NestJS microservice system follows from a handful of properties, and every classic distributed-systems bug follows from ignoring one of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The module graph is the design. Small export lists, injection through abstractions, and no module reaching into another's data - get that right in one process and extraction becomes a change of transport.&lt;/li&gt;
&lt;li&gt;Split on ownership, not on nouns. If two services need a distributed transaction for their most common operation, they are one service cut in the wrong place.&lt;/li&gt;
&lt;li&gt;The transport is a contract choice. send() couples availability and latency; emit() does not. Default to events and pay for synchronous calls consciously.&lt;/li&gt;
&lt;li&gt;Every consumer runs twice. At-least-once is the guarantee you get, so idempotency is a correctness requirement, and the outbox is what stops the event and the state change from disagreeing.&lt;/li&gt;
&lt;li&gt;Resilience is configuration you write. Timeouts on every call, bounded retries with backoff and jitter, circuit breakers with fallbacks, and a shutdown that drains rather than drops.&lt;/li&gt;
&lt;li&gt;You cannot debug what you did not instrument. Correlation IDs, distributed traces, structured logs, and consumer lag - added before the split, not after the first incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used carelessly, microservices become a distributed monolith: all the network failure modes of a distributed system with none of the independence that was supposed to pay for them. Used deliberately, they disappear - teams ship without asking permission, one hot path scales on its own, and a failure in recommendations leaves checkout untouched. That invisibility is the mark of a system built by someone who understood the trade-offs rather than someone who simply added services.&lt;/p&gt;

&lt;p&gt;About the Author:&lt;em&gt;Abodh is a PHP and Laravel Developer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWeb Solution&lt;/a&gt;, skilled in MySQL, REST APIs, JavaScript, Git, and Docker for building robust web applications.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>microservices</category>
      <category>node</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Best Practices for AI Integration in MERN Stack Applications</title>
      <dc:creator>Mayank Goyal</dc:creator>
      <pubDate>Wed, 02 Sep 2026 11:54:08 +0000</pubDate>
      <link>https://dev.to/addwebsolutionpvtltd/best-practices-for-ai-integration-in-mern-stack-applications-225a</link>
      <guid>https://dev.to/addwebsolutionpvtltd/best-practices-for-ai-integration-in-mern-stack-applications-225a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"AI becomes production-ready when the model is surrounded by good software engineering."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AI should be treated as an application subsystem, not as a frontend feature.&lt;/li&gt;
&lt;li&gt;Keep provider credentials and model calls on the Node.js/Express backend.&lt;/li&gt;
&lt;li&gt;Use direct model calls for simple tasks, RAG for application knowledge, and agents only when dynamic planning is genuinely required.&lt;/li&gt;
&lt;li&gt;Authorization must happen before retrieval so the model never receives data the user is not allowed to access.&lt;/li&gt;
&lt;li&gt;Structured outputs reduce integration errors, but application-side validation remains mandatory.&lt;/li&gt;
&lt;li&gt;Prompt injection, sensitive-information disclosure, excessive agency, and unbounded consumption are major AI application risks.&lt;/li&gt;
&lt;li&gt;Production systems need rate limits, timeouts, retries, cost monitoring, logging, evaluation, and human oversight for high-impact actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The MERN stack has become a popular foundation for modern web applications because it combines a flexible document database, a JavaScript/TypeScript backend, and a component-based frontend. The addition of generative AI makes it possible to build applications that can understand natural language, summarize documents, extract information, answer questions, search semantically, generate content, and assist users with complex decisions.&lt;/p&gt;

&lt;p&gt;But integrating AI into an existing MERN application is not equivalent to adding another REST endpoint. A conventional API generally has a predictable contract: a request enters the server, business logic executes, and a response is returned. AI introduces probabilistic behavior. The same request may produce different wording, the model may misunderstand context, output may not follow an expected format, and the amount of computation can vary significantly.&lt;/p&gt;

&lt;p&gt;A good AI-enabled MERN system keeps the responsibilities clear: React handles user interaction; Express and Node.js handle authentication, authorization, business rules, orchestration, and provider communication; MongoDB stores application data and, where appropriate, vector embeddings; and the AI model performs tasks such as language understanding, generation, classification, or reasoning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What AI Integration Means in a MERN Application?&lt;/li&gt;
&lt;li&gt;AI Integration Architecture&lt;/li&gt;
&lt;li&gt;Choosing the Right AI Pattern&lt;/li&gt;
&lt;li&gt;Backend-First AI Design&lt;/li&gt;
&lt;li&gt;Configuration and Secret Management&lt;/li&gt;
&lt;li&gt;Designing a Dedicated AI Service Layer&lt;/li&gt;
&lt;li&gt;Structured Outputs and Schema Validation&lt;/li&gt;
&lt;li&gt;RAG with MongoDB Vector Search&lt;/li&gt;
&lt;li&gt;Authentication, Authorization, and Tenant Isolation&lt;/li&gt;
&lt;li&gt;Rate Limiting, Cost Control, Caching, and Retries&lt;/li&gt;
&lt;li&gt;Queues and Background AI Jobs&lt;/li&gt;
&lt;li&gt;Observability and Auditability&lt;/li&gt;
&lt;li&gt;Production MERN Folder Structure&lt;/li&gt;
&lt;li&gt;End-to-End MERN Implementation&lt;/li&gt;
&lt;li&gt;Best Practices&lt;/li&gt;
&lt;li&gt;Interesting Facts&lt;/li&gt;
&lt;li&gt;Stats and Industry Context&lt;/li&gt;
&lt;li&gt;FAQs&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What AI Integration Means in a MERN Application?
&lt;/h2&gt;

&lt;p&gt;AI integration means adding model-driven capabilities to the normal lifecycle of a MERN app without allowing the model to bypass the application's existing security and business rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There are several levels of integration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-assisted UI: React asks the backend to generate, summarize, classify, or rewrite content.&lt;/li&gt;
&lt;li&gt;AI service: Node.js owns prompts, provider communication, validation, usage tracking, and error handling.&lt;/li&gt;
&lt;li&gt;RAG application: MongoDB retrieves relevant application knowledge and supplies it to the model.&lt;/li&gt;
&lt;li&gt;Tool-enabled AI: the model can request approved application functions, while Node.js validates and authorizes each action.&lt;/li&gt;
&lt;li&gt;Agentic application: the AI can dynamically select tools and iterate toward a goal within explicit limits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The maturity of the system should increase only when the business problem requires it. A simple summarization feature should not become an agent merely because an agent framework is available.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Integration Architecture
&lt;/h2&gt;

&lt;p&gt;A recommended architecture separates the browser, application API, AI orchestration, retrieval layer, and model provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React UI
↓
Express API
↓
Authentication + Authorization
↓
AI Service / Orchestrator
↓
MongoDB /  Retrieval / Business Context
↓
LLM / Embedding Provider
↓
Output Validation + Policy Checks
↓
React UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical boundary is the backend. The browser should not receive provider secrets, decide which private records can be retrieved, or directly execute privileged AI tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Right AI Pattern
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ft9y540hhff019vgmlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ft9y540hhff019vgmlx.png" alt=" " width="601" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A useful rule is: use the least autonomous architecture that solves the problem reliably. More autonomy generally means more state, more failure modes, more security controls, and more testing requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend-First AI Design
&lt;/h2&gt;

&lt;p&gt;The React application should communicate with an application endpoint such as /api/ai/summarize or /api/ai/chat. The Express layer authenticates the request, validates the input, checks authorization, invokes the AI service, and returns a controlled response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// server/routes/ai.js
router.post("/summarize", requireAuth, async (req, res, next) =&amp;gt; {
  try {
    const { text } = req.body;

    if (typeof text !== "string" || text.length === 0 || text.length &amp;gt; 20000) {
      return res.status(400).json({ error: "Invalid text" });
    }

    const summary = await aiService.summarize({
      userId: req.user.id,
      text
    });

    res.json({ summary });
  } catch (error) {
    next(error);
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design also gives the engineering team one place to introduce rate limits, audit logs, provider fallbacks, feature flags, model selection, and cost policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration and Secret Management
&lt;/h2&gt;

&lt;p&gt;API keys are credentials. They should be treated with the same care as database passwords and signing secrets. Never expose an LLM provider key through a client-side bundle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Server environment
AI_PROVIDER_API_KEY=replace_me
AI_MODEL=production-model
AI_TIMEOUT_MS=30000
AI_MAX_INPUT_CHARS=20000
AI_MAX_OUTPUT_TOKENS=2000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production deployments, secrets can be managed through the hosting platform's secret manager or a dedicated secret-management system. The key should be injected into the server runtime, not committed to source control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing a Dedicated AI Service Layer
&lt;/h2&gt;

&lt;p&gt;A dedicated AI service prevents provider-specific code from spreading through controllers and React components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// server/services/ai/aiService.js
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AI_PROVIDER_API_KEY
});

export async function summarize({ text }) {
  const response = await client.responses.create({
    model: process.env.AI_MODEL,
    input: [
      {
        role: "system",
        content: "Summarize the supplied text. Do not invent facts."
      },
      {
        role: "user",
        content: text
      }
    ]
  });

  return response.output_text;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact SDK and API shape can vary by provider. The architectural principle remains the same: isolate provider details behind an application service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured Outputs and Schema Validation
&lt;/h2&gt;

&lt;p&gt;Natural-language output is appropriate when a human will read it. Machine-to-machine output should generally use a structured contract. Structured outputs can constrain the model response to an expected schema, while application validation provides a second safety layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const response = await client.responses.create({
  model: process.env.AI_MODEL,
  input: "Classify this support ticket.",
  text: {
    format: {
      type: "json_schema",
      name: "ticket_classification",
      strict: true,
      schema: {
        type: "object",
        properties: {
          category: {
            type: "string",
            enum: ["billing", "technical", "account", "other"]
          },
          priority: {
            type: "string",
            enum: ["low", "medium", "high"]
          }
        },
        required: ["category", "priority"],
        additionalProperties: false
      }
    }
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After receiving the result, validate it again with your application schema library and reject unexpected values before writing to MongoDB or triggering downstream operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG with MongoDB Vector Search
&lt;/h2&gt;

&lt;p&gt;Retrieval-Augmented Generation, commonly called RAG, is one of the most useful patterns for MERN apps because MongoDB can store both application documents and metadata needed for retrieval. MongoDB's current documentation describes a basic RAG pipeline as ingestion, retrieval, and generation, with Vector Search used to retrieve semantically relevant data.&lt;/p&gt;

&lt;p&gt;The basic flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source documents
↓
Chunking
↓
Embedding model
↓
MongoDB documents + embeddings
↓
User question
↓
Query embedding
↓
MongoDB Vector Search
↓
Relevant context
↓
LLM generation
↓
Grounded Answers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB Vector Search supports vector retrieval and pre-filtering. Its current documentation describes filters that can narrow semantic search using indexed metadata, which is particularly important for multi-tenant applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "tenantId": "tenant_123",
  "sourceId": "doc_456",
  "title": "Refund Policy",
  "text": "Refunds are available within 30 days...",
  "embedding": [0.012, -0.044, 0.091],
  "permissions": ["support"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Authentication, Authorization, and Tenant Isolation
&lt;/h2&gt;

&lt;p&gt;Authorization is one of the most important differences between a demo and a production AI application. A user should not be able to influence the retrieval query so that private documents become part of the model context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const matches = await searchKnowledgeBase({
  queryEmbedding,
  filter: {
    tenantId: req.user.tenantId,
    allowedRoles: { $in: req.user.roles }
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tenant identifier should come from the authenticated server-side identity, not from an untrusted request body. If the frontend sends tenantId, treat it only as a requested value and independently verify the user's membership.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate Limiting, Cost Control, Caching, and Retries
&lt;/h2&gt;

&lt;p&gt;AI endpoints should be considered expensive and potentially abusable endpoints. A public chat endpoint without limits can consume provider quota quickly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use per-IP and per-user rate limits where appropriate.Set request timeouts.&lt;/li&gt;
&lt;li&gt;Add per-tenant quotas for SaaS applications.&lt;/li&gt;
&lt;li&gt;Set maximum prompt sizes and output limits.&lt;/li&gt;
&lt;li&gt;Use model routing so simple tasks do not automatically use the most expensive model.&lt;/li&gt;
&lt;li&gt;Cache embeddings for unchanged source content.&lt;/li&gt;
&lt;li&gt;Cache safe deterministic results when appropriate.&lt;/li&gt;
&lt;li&gt;Retry only transient failures and use exponential backoff.&lt;/li&gt;
&lt;li&gt;Track usage and cost by user, tenant, feature, and model.&lt;/li&gt;
&lt;li&gt;Move expensive processing to background jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Express's production security guidance similarly emphasizes not trusting user input, TLS, secure cookies, dependency security, and protection against brute-force attacks. These traditional controls remain essential around AI endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queues and Background AI Jobs
&lt;/h2&gt;

&lt;p&gt;Not every AI task should run inside a synchronous HTTP request. Document ingestion, bulk embedding, large-file analysis, report generation, and batch classification can take too long.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Uploads Document
↓
Express stores file + creates job
↓
Queue
↓
Worker extracts/chunks content
↓
Embedding generation
↓
MongoDB indexing
↓
Job status = completed
↓
React receives status/update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A queue also provides retry isolation. If an AI provider temporarily fails, the worker can retry without forcing the user to keep an HTTP connection open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observability and Auditability
&lt;/h2&gt;

&lt;p&gt;AI systems require both traditional application monitoring and AI-specific telemetry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxwwtjm67mm0f82nddha1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxwwtjm67mm0f82nddha1.png" alt=" " width="600" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do not automatically log complete prompts, retrieved documents, or model outputs if they contain sensitive information. Use redaction, access-controlled logs, retention policies, and sampling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production MERN Folder Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server/
  controllers/
    aiController.js
  middleware/
    auth.js
    rateLimit.js
    aiPolicy.js
  routes/
    ai.js
  services/
    ai/
      aiService.js
      modelRouter.js
      prompts/
        summarize.v1.js
        classify.v1.js
        support.v1.js
      retrieval/
        knowledgeSearch.js
        chunker.js
        embeddings.js
      tools/
        calendar.js
        orders.js
      validators/
        schemas.js
  models/
    Document.js
    Conversation.js
    AiRequestLog.js
  workers/
    embeddingWorker.js
    documentWorker.js
  utils/
    redaction.js

client/
  src/
    components/
      AiChat.jsx
      AiSummary.jsx
    api/
      aiApi.js
    hooks/
      useAiChat.js
      useAiSummary.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The structure separates HTTP concerns, AI orchestration, retrieval, tools, validation, background processing, and UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  End-to-End MERN Implementation
&lt;/h2&gt;

&lt;p&gt;Consider a support assistant that answers questions from a company's internal knowledge base. The request lifecycle can be implemented as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// controller
export async function answerSupportQuestion(req, res, next) {
  try {
    const { question } = req.body;

    if (typeof question !== "string" ||
        question.length &amp;lt; 3 ||
        question.length &amp;gt; 4000) {
      return res.status(400).json({ error: "Invalid question" });
    }

    const user = req.user;

    const embedding = await aiService.embed(question);

    const documents = await knowledgeSearch({
      tenantId: user.tenantId,
      userId: user.id,
      roles: user.roles,
      embedding,
      limit: 5
    });

    const result = await aiService.answerFromContext({
      question,
      context: documents
    });

    res.json({
      answer: result.text,
      sources: documents.map(d =&amp;gt; d.sourceId)
    });
  } catch (error) {
    next(error);
  }
}
// retrieval
export async function knowledgeSearch({ tenantId, roles, embedding, limit }) {
  return KnowledgeChunk.aggregate([
    {
      $vectorSearch: {
        index: "knowledge_vector_index",
        path: "embedding",
        queryVector: embedding,
        numCandidates: 100,
        limit,
        filter: {
          tenantId: tenantId,
          allowedRoles: { $in: roles }
        }
      }
    },
    {
      $project: {
        _id: 1,
        sourceId: 1,
        text: 1,
        score: { $meta: "vectorSearchScore" }
      }
    }
  ]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MongoDB's current Vector Search documentation supports vector search with filtering metadata, which is useful for enforcing retrieval boundaries such as tenant IDs and access roles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// generation
export async function answerFromContext({ question, context }) {
  const prompt = `Answer using only the supplied context. If the answer is not available, say so.

QUESTION: ${question}

CONTEXT: ${context.map(x =&amp;gt; `[${x.sourceId}] ${x.text}`).join("\n\n")}`;

  const response = await client.responses.create({
    model: process.env.AI_MODEL,
    input: prompt
  });

  return { text: response.output_text };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example is intentionally simplified. A production system should additionally validate model output, enforce prompt and context limits, apply content policies, record safe telemetry, and handle provider failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Start with the smallest useful AI capability.&lt;/li&gt;
&lt;li&gt;Keep provider calls and credentials on the backend. and validate every external input.&lt;/li&gt;
&lt;li&gt;Treat model output as untrusted until validated.&lt;/li&gt;
&lt;li&gt;Apply authorization before retrieval.&lt;/li&gt;
&lt;li&gt;Keep AI tools least-privileged.&lt;/li&gt;
&lt;li&gt;Version prompts and important model configurations.&lt;/li&gt;
&lt;li&gt;Measure retrieval quality separately from generation quality.&lt;/li&gt;
&lt;li&gt;Use rate limits, timeouts, quotas, and cost monitoring.&lt;/li&gt;
&lt;li&gt;Use queues for long-running tasks.&lt;/li&gt;
&lt;li&gt;Redact sensitive AI logs.&lt;/li&gt;
&lt;li&gt;Maintain an evaluation dataset.&lt;/li&gt;
&lt;li&gt;Require human approval for high-impact actions.&lt;/li&gt;
&lt;li&gt;Have a clear fallback when the model provider is unavailable.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Interesting Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RAG is not simply a chatbot technique; it is a general architecture for grounding generation in external data.&lt;a href="https://www.mongodb.com/docs/atlas/atlas-vector-search/rag" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/atlas/atlas-vector-search/rag&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MongoDB can combine document storage with vector retrieval, allowing application metadata and embeddings to live in the same data platform.  &lt;a href="https://www.mongodb.com/docs/vector-search/about/use-cases" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/vector-search/about/use-cases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vector search can use pre-filters, which is particularly important for permission-aware retrieval. &lt;a href="https://www.mongodb.com/docs/search/query/operators/vectorSearch" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/search/query/operators/vectorSearch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Prompt injection remains a security concern even when an application uses RAG. &lt;a href="https://genai.owasp.org/llm-top-10" rel="noopener noreferrer"&gt;https://genai.owasp.org/llm-top-10&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Agentic AI introduces additional security and governance considerations beyond basic LLM applications. &lt;a href="https://genai.owasp.org/download/49059" rel="noopener noreferrer"&gt;https://genai.owasp.org/download/49059&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stats and Industry Context
&lt;/h2&gt;

&lt;p&gt;AI adoption and market statistics change quickly. For a technical article intended for long-term publication, it is better to avoid unsupported or stale percentages and instead cite the current edition of the original research report. &lt;a href="https://hai.stanford.edu/ai-index/2026-ai-index-report" rel="noopener noreferrer"&gt;https://hai.stanford.edu/ai-index/2026-ai-index-report&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The more durable engineering trend is that organizations are moving from isolated AI experiments toward integrated applications that combine models, retrieval, tools, business workflows, and governance. Security organizations are also expanding guidance from traditional LLM risks toward agentic-system risks. OWASP's evolution from its original LLM Top 10 into the broader GenAI Security Project reflects this expanding scope. &lt;a href="https://hai.stanford.edu/ai-index/2026-ai-index-report/economy" rel="noopener noreferrer"&gt;https://hai.stanford.edu/ai-index/2026-ai-index-report/economy&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q1. Should I call an AI provider directly from React?&lt;/strong&gt;&lt;br&gt;
No. Keep provider credentials and calls on the backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q2. Does RAG eliminate hallucinations?&lt;/strong&gt;&lt;br&gt;
No. It can ground answers in retrieved context, but retrieval and generation can still fail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q3. Can I trust AI-generated JSON?&lt;/strong&gt;&lt;br&gt;
No. Use structured output where supported and validate it in application code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q4. How do I protect multi-tenant data?&lt;/strong&gt;&lt;br&gt;
Apply tenant and permission filters during retrieval using trusted server-side identity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q5. When should I use an agent?&lt;/strong&gt;&lt;br&gt;
When the objective is complex and the execution path cannot reasonably be predefined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q6. Should AI have direct database access?&lt;/strong&gt;&lt;br&gt;
Prefer narrow application tools over unrestricted database access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q7. How should AI failures be handled?&lt;/strong&gt;&lt;br&gt;
Use timeouts, bounded retries, fallback responses, queues for long tasks, and clear user-facing error states.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q8. What should I log?&lt;/strong&gt;&lt;br&gt;
Log safe metadata such as latency, model version, usage, request ID, validation failures, and tool activity; redact sensitive content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI integration in a MERN application should be approached as an architecture problem rather than an API integration problem. The model has only one component. The surrounding system determines whether the feature is secure, reliable, affordable, observable, and maintainable.&lt;/p&gt;

&lt;p&gt;A production-ready design keeps model calls on the server, uses explicit authorization, retrieves only permitted context, validates outputs, controls tool permissions, limits resource consumption, monitors usage, and evaluates quality continuously. MongoDB can support the application data and vector retrieval layer, while Node.js provides a natural orchestration boundary between the browser and AI services.&lt;/p&gt;

&lt;p&gt;The best path for most teams is incremental. Start with a narrow use case such as summarization or classification. Add structured output and validation. Introduce RAG when the model needs private application knowledge. Add tools when the model needs to interact with business systems. Introduce agentic behavior only when dynamic planning is worth the additional complexity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Build the AI capability around the application - not the application around the model."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI Platform Documentation - &lt;a href="https://platform.openai.com/docs/" rel="noopener noreferrer"&gt;https://platform.openai.com/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MongoDB - Retrieval-Augmented Generation with MongoDB Vector Search - &lt;a href="https://www.mongodb.com/docs/vector-search/tutorials/rag/" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/vector-search/tutorials/rag/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MongoDB - Vector Search Use Cases and Design Patterns - &lt;a href="https://www.mongodb.com/docs/vector-search/about/use-cases/" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/vector-search/about/use-cases/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OWASP - Top 10 for LLM Applications 2025 - &lt;a href="https://genai.owasp.org/resource/owasp-top-10-for-llm-applications-2025/" rel="noopener noreferrer"&gt;https://genai.owasp.org/resource/owasp-top-10-for-llm-applications-2025/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OWASP - Top 10 for LLM Applications v2.0 PDF - &lt;a href="https://owasp.org/www-project-top-10-for-large-language-model-applications/assets/PDF/OWASP-Top-10-for-LLMs-v2025.pdf" rel="noopener noreferrer"&gt;https://owasp.org/www-project-top-10-for-large-language-model-applications/assets/PDF/OWASP-Top-10-for-LLMs-v2025.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Express.js - Production Best Practices: Security - &lt;a href="https://expressjs.com/en/advanced/best-practice-security/" rel="noopener noreferrer"&gt;https://expressjs.com/en/advanced/best-practice-security/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;About the Author:&lt;em&gt;Mayank is a web developer at &lt;a href="https://www.addwebsolution.com/" rel="noopener noreferrer"&gt;AddWebSolution&lt;/a&gt;, building scalable apps with PHP, Node.js &amp;amp; React. Sharing ideas, code, and creativity.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mern</category>
      <category>vertexai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
