Building Modular and Scalable RAG Systems with Hybrid Batch/Incremental Processing

bell · Telecommunications · 2023 · source Agentic: no · promotional bias: low · source-backed · extracted with prompt 0.5.5 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Enterprise RAG knowledge-base management

Bell needed production infrastructure for RAG systems whose source documents, chunking configuration, embedding models, and vector indexes change over time. The team treated document embedding pipelines and knowledge-base management as an MLOps product rather than a one-off chatbot feature, because dynamic HR, Confluence, and automation knowledge bases create synchronization, lineage, quota, deployment, and race-condition problems that a simple RAG prototype does not solve.

Constraints:

Architecture

Bell built a hybrid RAG knowledge-base platform. A primary batch pipeline, orchestrated by Cloud Composer/Apache Airflow, runs Apache Beam/Dataflow pre-processing, embedding, and post-processing jobs against a structured knowledge-base bucket and a vector database. The knowledge base stores raw documents, processed chunks, processed embeddings, timestamped batch-run folders, and a current folder read by the chatbot API. An optional incremental path adds a Pub/Sub topic on bucket changes and a streaming Dataflow job that processes changed documents, windows events, and keeps the vector database synchronized between batch refreshes. YAML configuration files drive loaders, chunking, embedding models, regions, projects, endpoints, source URIs, and sync targets; a DAG generator turns each YAML into an Airflow DAG so new RAG pipelines can be deployed with little custom code.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  source-systems["Source systems"] --> document-ingestion-workflow["Document ingestion workflow"]
  document-ingestion-workflow --> knowledge-base-bucket["Knowledge base bucket"]
  yaml-configuration-file["YAML configuration file"] --> dag-generator["DAG generator"]
  dag-generator --> cloud-composer-orchestrator["Cloud Composer orchestrator"]
  cloud-composer-orchestrator --> batch-dataflow-pipeline["Batch Dataflow pipeline"]
  batch-dataflow-pipeline --> pre-processing-job["Pre-processing job"]
  pre-processing-job --> embedding-job["Embedding job"]
  embedding-job --> post-processing-job["Post-processing job"]
  post-processing-job --> vector-database["Vector database"]
  knowledge-base-bucket --> pub-sub-topic["Pub/Sub topic"]
  pub-sub-topic --> incremental-dataflow-pipeline["Incremental Dataflow pipeline"]
  incremental-dataflow-pipeline --> vector-database
  knowledge-base-bucket --> rag-chatbot-api["RAG chatbot API"]
  vector-database --> rag-chatbot-api
  rag-chatbot-api --> llm-provider["LLM provider"]
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Source systems Origin systems such as HR policy repositories, Confluence pages, storage buckets, cloud sources, or other document systems. Document ingestion workflow
Document ingestion workflow Either a librarian process or automated pipeline that determines changed documents and syncs raw files into the knowledge base. Source systems, Knowledge base bucket
YAML configuration file Serving configuration describing loaders, chunking parameters, embedding model, project, region, endpoints, sources, and vector sync targets. DAG generator, Batch Dataflow pipeline, Incremental Dataflow pipeline
DAG generator Creates a standardized Airflow DAG from the uploaded YAML configuration for each RAG use case. Cloud Composer orchestrator, YAML configuration file
Cloud Composer orchestrator Managed Apache Airflow layer that coordinates batch runs, incremental-drain/restart behavior, and shared pipeline resources. DAG generator, Batch Dataflow pipeline, Incremental Dataflow pipeline, Pub/Sub topic
Batch Dataflow pipeline Primary Apache Beam/Dataflow pipeline for initialization, scheduled refreshes, large document changes, and configuration changes. Cloud Composer orchestrator, Pre-processing job, Embedding job, Post-processing job, Knowledge base bucket, Vector database, YAML configuration file
Pre-processing job Loads documents with document loaders, chunks and pre-processes content, and writes intermediate chunks. Batch Dataflow pipeline, Knowledge base bucket, Embedding job
Embedding job Embeds chunks using the configured embedding model or endpoint. Pre-processing job, Post-processing job, Embedding model
Post-processing job Formats embeddings for the target vector database and writes synced artifacts. Embedding job, Vector database, Knowledge base bucket
Embedding model Google Gecko, Gemini, or a configurable self-hosted model endpoint used to embed documents. Embedding job
Knowledge base bucket Structured bucket holding raw documents, timestamped batch artifacts, processed chunks, embeddings, and the current folder consumed by the chatbot. Document ingestion workflow, Batch Dataflow pipeline, Incremental Dataflow pipeline, Pub/Sub topic, RAG chatbot API
Pub/Sub topic Bucket-change event stream for incremental updates, including additions, updates, and deletions. Knowledge base bucket, Incremental Dataflow pipeline, Cloud Composer orchestrator
Incremental Dataflow pipeline Optional streaming Apache Beam/Dataflow job that processes changed documents atomically and updates the current knowledge base and vector database. Pub/Sub topic, Knowledge base bucket, Vector database, YAML configuration file, Cloud Composer orchestrator
Vector database GCP Vector Search or another configured vector database storing formatted embeddings for retrieval. Batch Dataflow pipeline, Incremental Dataflow pipeline, Post-processing job, RAG chatbot API
RAG chatbot API Downstream API/prompt layer that retrieves from the vector database and knowledge base before calling the LLM. Knowledge base bucket, Vector database, LLM provider
LLM provider Model endpoint, such as Gemini, that generates grounded user-facing answers after retrieval. RAG chatbot API

Data flow

Documents enter the raw knowledge-base folder through either a librarian workflow or an automated source-sync pipeline. Batch runs create timestamped intermediate artifacts for raw chunks, pre-processed chunks, and embeddings, then sync the newest run to the current folder that the chatbot API reads. Incremental runs listen to Pub/Sub bucket events, group recent upload/delete/update events, process only the latest action for each changed document, and update the current knowledge base and vector database. When a batch refresh runs, orchestration drains and stops the incremental job, rebuilds the full knowledge base, restarts incremental processing, and then consumes unacknowledged Pub/Sub messages that arrived during the batch window.

5 supporting quotes
“the orchestration project is well to orchestrate the pipeline uh it contains the orchestrator and common pipeline resources”transcript, stated
“consists of a pre-processing job this is the component which houses all the Lang chain our our pre our basically document loading”transcript, stated
“one data flow job which encompasses the pre-processing betting and post-processing and basically we listen to that topic”transcript, stated
“orchestration will drain your incremental pipeline stop acknowledging accepting messages from your pub subtopic stop the incremental data flow job launch the batch pipeline”transcript, stated
“when the incremental pip line restarts it will consume those messages to reflect the most recent changes so again what you're left with is a nice harmonized solution which kind of gives you the best of both batch and incremental pipelines I do want to”transcript, stated

Why this architecture

Bell separated batch and incremental paths because configuration rebuilds and large document changes need quota-friendly full processing, while small high-velocity updates need near-real-time synchronization. Apache Beam/Dataflow gave the same programming model for batch and streaming work. Pub/Sub was chosen over isolated cloud functions because grouped event windows can avoid upload/delete races. YAML-driven reusable components and generated DAGs turned the platform into a product that could support many RAG use cases without custom engineering for each one.

4 supporting quotes
“if you have any change in your configuration or you have a large change in documents they both warrant a batch solution”transcript, stated
“small document changes at even in a batch or incremental delivery it does warrant an increment in realtime solution”transcript, stated
“with pubsub plus Apache beam you can window and group events if we Define a sliding window of 60 seconds or you know x amount of seconds our job will only take the most recent action within that window and therefore we can only focus on the most relevant”transcript, stated
“all components are reasonable across pipelines no additional developments needed and this allows you to deploy a pipeline within minutes”transcript, stated

Models used: Google Gecko embedding model · Gemini · Google embedding models · Self-hosted LLM model option

Scale

Alternatives considered (roads not taken)

Use online embedding calls for configuration changes or large document changes.

Rejected because: Bell rejected this for large rebuilds because online processing can consume API quota and interfere with the chatbot API sharing the same project.

“using online methods will consume your API quota right and if you are sharing your your uh your L your chatbot API with this project space”transcript, stated
“you will essentially well take down your API right you your incoming requests won't be able to be embedded and you'll kind of grind your system to a halt uh same goes for large document changes um that are delivered in a batch or interval delivery uh you”transcript, stated

Use Cloud Functions or Lambda-style isolated event handlers for bucket changes.

Rejected because: The team chose Pub/Sub plus Beam because isolated upload/delete handlers can race and leave bad chunks synced after a deletion.

3 supporting quotes
“some of you might be asking why pubsub why not a cloud function or if you're on AWS a Lambda function or Azure I forget what it is on Azure um the answer that's race conditions so let's say you're a librarian and you upload a bad document and you realize it”transcript, stated
“we've all done it a misclick a whoopsie or whatever Cloud functions are isolated Atomic events there's no coordination between them so the first action of upload will cause the bad document to start being processed the second action of delete will remove all existing documents in par well all”transcript, stated
“when the bad document is finished processing it will upload and sync those bad chunks to your vector database and knowledge base”transcript, stated

Handle large high-velocity document changes on managed online LLM quotas.

Rejected because: The presenters framed this as a rare unicorn case and recommended replacing quota limits with self-hosted serving capacity when it occurs.

“this is kind of a unicorn case and I don't think a lot of people see this because knowledge bases don't really change at like high high velocity”transcript, stated
“I would probably urge people to use a self-hosted llm model and replace your quota with QPS and your QPS would be dictated or your queries per second would be dictated by the serving resources you provision to your llm so with with all this being said um I”transcript, stated

Use source loaders for incremental document processing.

Rejected because: Bell focused on document loaders because source loaders process an undefined scope and do not identify the specific changed documents needed for incremental updates.

3 supporting quotes
“a document loader is a loader which utilizes a specific URI or link to load a singular document at like Atomic document instance so you know Pi PDF unstructured loader um BS HTML you know you're reading specific documents uh a source loader on your hand”transcript, stated
“a source loader on your hand attempts to process a variety or like undefined number of documents for example a directory loader you're just going to point at a directory and you're going to load all of the the documents that are in that directory loader uh”transcript, stated
“there's no notion of which documents you're updating since you are basically pulling every document within the scope of the source”transcript, stated

Preserve unchanged chunks and embed only edited parts of a document.

Rejected because: The team treats a document as the atomic unit because partial chunk preservation creates coordination complexity that is not worth the marginal time savings.

“updated document or do you Reed the whole document for re update yeah uh we we the way we treat we treat documents as like kind of a unit right so it's so hard okay so if you've changed for example the part of if you've change if you've added one or two sentences in the middle of”transcript, stated
“for the amount of time it would save just to reprocess a document I I don't think it would warrant it necessarily”transcript, stated

Build a custom pipeline for every RAG use case.

Rejected because: Bell standardized the process and generated DAGs from YAML so reusable components and interfaces can serve new use cases without additional code.

“instead of defining a custom pipeline for every use case we've created a standardized pipeline process that can be applied to every rag use case”transcript, stated
“once it's uploaded a dag generator automatically creates the associated dag for your use case with your specified parameters”transcript, stated

Patterns

rag-retrieval (retrieval)

Bell's system manages the knowledge base, vector index, embedding pipeline, and source-document synchronization layer that makes internal RAG chatbots answer against company-specific documents rather than only model training data.

3 supporting quotes
“it references a knowledge Base outside of its training data sources before generating a response”transcript, stated
“it's going to search for relevant information from the knowledge base that your rag is feeding off of”transcript, stated
“in order to I guess do that search efficiently it's going to use the help of a vector database”transcript, stated

batch-offline-processing (llmops)

Configuration changes, initial builds, scheduled refreshes, and large document changes are handled by a batch pipeline so the system can rebuild the knowledge base and vector database without burning online embedding quota.

3 supporting quotes
“if you have any change in your configuration or you have a large change in documents they both warrant a batch solution”transcript, stated
“the batch pipeline is the primary pipeline every use case requires one it's used for initialization”transcript, stated
“using online methods will consume your API quota right and if you are sharing your your uh your L your chatbot API with this project space”transcript, stated

async-message-orchestration (orchestration)

The incremental path uses Pub/Sub messages plus Apache Beam windowing to coordinate document-change events and process only the most recent action, avoiding race conditions from isolated event handlers.

3 supporting quotes
“the largest addition to to this architecture is the pub subtopic which listens to all the changes which occur in our knowledge based bucket”transcript, stated
“with pubsub plus Apache beam you can window and group events if we Define a sliding window of 60 seconds”transcript, stated
“our job will only take the most recent action within that window and therefore we can only focus on the most relevant action”transcript, stated

observability-tracing (operations)

The knowledge-base structure keeps raw documents, processed chunks, embeddings, timestamped runs, and current artifacts so teams can trace how documents were processed and why the bot answered the way it did.

3 supporting quotes
“keeping track of the data from the knowledge based like the raw documents to being able to say you know where it is embedded in what index”transcript, stated
“that provides the data lineage and Providence for each configuration in each pipeline trigger”transcript, stated
“the most recent timestamp folder will then be synced to the current subfolder which the chatbot API will be retrieving information from”transcript, stated

data-quality-loop (feedback)

Chunking and retrieval parameters are adjusted through a feedback loop on chatbot responses, with data scientists tuning chunk sizes, overlaps, and vector parameters based on response quality signals.

3 supporting quotes
“they depending on the type of the documents and the content of the documents they come up with optimal chunking parameters”transcript, stated
“we have a great feedback loop of on the chat Bots showing thumbs up thumbs down and they're consistently tweaking”transcript, stated
“chunking size or overlap or um you know even if you want to talk about like the actual Vector parameters”transcript, stated

cost-aware-routing (operations)

The solution matrix routes work to batch, incremental, or self-hosted processing based on document-change size, latency requirements, and quota pressure so embedding jobs do not starve online chatbot traffic.

3 supporting quotes
“online API requests per minute and batch requests if your platform offers that”transcript, stated
“small document changes at even in a batch or incremental delivery it does warrant an increment in realtime solution”transcript, stated
“I would probably urge people to use a self-hosted llm model and replace your quota with QPS”transcript, stated

Tradeoffs

Use a hybrid batch plus incremental architecture.

Chose A primary batch pipeline with optional incremental Pub/Sub/Dataflow updates over Only batch refreshes or only real-time incremental updates.

Rationale: Batch handles initialization, scheduled refreshes, config changes, and large document changes, while incremental processing handles small high-velocity updates; combining them adds orchestration but covers both modes.

3 supporting quotes
“the answer is both like what we have done at Bell is we've created a hybrid solution”transcript, stated
“yes there a little more uh I would say orchestration uh involved but it's you really get the best of both words”transcript, stated
“the incremental pipeline is completely optional and supplementary but if you have high data velocity situations you can include it”transcript, stated

Use Pub/Sub and Beam windowing for incremental changes.

Chose Coordinated Pub/Sub events processed by Apache Beam/Dataflow over Cloud Functions, Lambda-style handlers, or isolated atomic event processors.

Rationale: Event windowing and grouping allow the pipeline to resolve upload/delete races by processing the most recent action instead of letting isolated functions finish out of order.

3 supporting quotes
“some of you might be asking why pubsub why not a cloud function or if you're on AWS a Lambda function”transcript, stated
“with pubsub plus Apache beam you can window and group events if we Define a sliding window of 60 seconds”transcript, stated
“our job will only take the most recent action within that window and therefore we can only focus on the most relevant action”transcript, stated

Standardize reusable pipeline services behind YAML.

Chose A generated Airflow DAG and configurable pre-processing, embedding, and post-processing services over Custom pipeline code per RAG use case.

Rationale: The reusable interface lowers deployment effort for new RAG pipelines, but it requires up-front service boundaries, DevOps resources, and a YAML configuration contract.

3 supporting quotes
“so every single one of these services are you should think back to when we were trying to instill those best practices it's modular”transcript, stated
“all you need to do is create a yaml file configure a cicd pipeline to move that emo file into your Cloud composer instant”transcript, stated
“this allows you to deploy a pipeline within minutes in like almost a low no low code no code type of fashion I can't say no code because the yaml file I guess is a bit of code um so so now that we've standardized and productionize the components the in basically the intermediate components”transcript, stated

Use document loaders as the unit of incremental processing.

Chose Specific document URIs and atomic document instances over Source loaders that sweep directories or broad sources.

Rationale: Incremental processing needs to know exactly which document changed; source loaders fit batch jobs but not precise update handling.

3 supporting quotes
“to point at a directory and you're going to load all of the the documents that are in that directory loader uh we tend to focus on document loaders uh because Source loaders would you would basically require it only fits the batch solution right it would require you to reprocess the entire”transcript, stated
“Source loaders would you would basically require it only fits the batch solution right it would require you to reprocess the entire knowledge base”transcript, stated
“in our pre-processing component we need to know exactly which document has changed and only action and process on that specific document”transcript, stated

Reprocess a changed document as a whole.

Chose Re-chunk and upsert the full changed document over Trying to preserve unchanged chunks and embed only modified sections.

Rationale: Partial chunk preservation was judged too complex relative to the time saved by avoiding a full document reprocess.

3 supporting quotes
“like kind of a unit right so it's so hard okay so if you've changed for example the part of if you've change if you've added one or two sentences in the middle of a document you know there's no way no real efficient way that we found preserve the first couple chunks and then only process the”transcript, stated
“there's no way no real efficient way that we found preserve the first couple chunks and then only process the next couple chunks”transcript, stated
“for the amount of time it would save just to reprocess a document I I don't think it would warrant it necessarily”transcript, stated

Choose between librarian and automated ingestion by source velocity.

Chose Manual librarian curation for slow sources and automated source-sync pipelines for high-velocity sources over One universal ingestion method for every knowledge source.

Rationale: Low-velocity sources are simpler to manage manually, while high-velocity systems like Confluence need automated change detection, landing-zone comparison, and rsync-style synchronization.

3 supporting quotes
“the librarian approach which having a person or a collection of people explicitly perform operations on singular or defined groups of documents”transcript, stated
“if you don't want to appoint a librarian you can build an automated pipeline to do this for you however it is definitely more involved”transcript, stated
“the process of implicitly determining which documents have changed at the source and reflecting only those changes in the knowledge base”transcript, stated

Gotchas (what bit them)

Configuration changes cannot be mixed into an existing index piecemeal.

Root cause: Different chunking or embedding configurations make old and new vectors incomparable.

Resolution: Treat configuration changes as full batch rebuild events for the knowledge base and vector database.

“you can't have apples and oranges with your knowledge base you can't process documents one way and then when you're ingesting documents”transcript, stated
“if you're using two different models for examples or two different edings models you know you're you're you're just it's not going to work”transcript, stated

Large rebuilds can starve the production chatbot if they share online embedding quota.

Root cause: Managed embedding APIs impose project-level quotas, and high-volume rebuild traffic competes with live user requests.

Resolution: Run large changes through batch processing, rate-limit small incremental updates, and consider self-hosted serving for rare high-velocity large-change cases.

3 supporting quotes
“using online methods will consume your API quota right and if you are sharing your your uh your L your chatbot API with this project space”transcript, stated
“you will essentially well take down your API right you your incoming requests won't be able to be embedded”transcript, stated
“you'd probably have to rate limit the documents being added to your knowledge base to basically ensure your online quoted Integrity”transcript, stated

Naive bucket-event functions can process stale documents after a deletion.

Root cause: Upload and delete events run as isolated atomic cloud functions with no coordination, so the slower upload-processing path may finish after the delete.

Resolution: Use Pub/Sub plus Apache Beam windowing/grouping so the incremental job processes only the latest relevant event within the window.

3 supporting quotes
“Cloud functions are isolated Atomic events there's no coordination between them”transcript, stated
“since the deletion process is a fast operation it will finish before the bad document is finished processing”transcript, stated
“when the bad document is finished processing it will upload and sync those bad chunks to your vector database and knowledge base”transcript, stated

Source loaders are a poor fit for precise incremental updates.

Root cause: A source loader sweeps an undefined source scope and does not know which specific document changed.

Resolution: Focus the pre-processing component on document loaders that operate on specific document URIs or atomic document instances.

3 supporting quotes
“a source loader on your hand attempts to process a variety or like undefined number of documents”transcript, stated
“there's no notion of which documents you're updating since you are basically pulling every document within the scope of the source”transcript, stated
“in our pre-processing component we need to know exactly which document has changed and only action and process on that specific document”transcript, stated

Partial re-embedding inside a changed document can become coordination-heavy.

Root cause: Edits in the middle of a document can shift chunks, making it difficult to preserve unchanged chunks while only reprocessing changed sections.

Resolution: Treat documents as the atomic update unit and re-chunk/re-embed the whole document.

3 supporting quotes
“we treat documents as like kind of a unit right so it's so hard”transcript, stated
“there's no way no real efficient way that we found preserve the first couple chunks and then only process the next couple chunks”transcript, stated
“for the amount of time it would save just to reprocess a document I I don't think it would warrant it necessarily”transcript, stated

The public presentation does not describe a formal RAG-quality evaluation harness.

Root cause: The talk focuses on embedding-pipeline infrastructure, deployment, lineage, and operational synchronization more than answer-quality metrics.

Resolution: Use the described thumbs-up/down feedback loop as a quality signal, but treat formal retrieval/answer evaluation as an unstated gap in this source.

“we have a great feedback loop of on the chat Bots showing thumbs up thumbs down and they're consistently tweaking”transcript, stated
“how do you decide on chunking method and size of each data source uh VI your pipeline um no we definitely do not use the same method”transcript, stated

Evaluation

The talk describes engineering validation rather than a formal RAG-answer evaluation suite: modular unit tests, integration tests, CI/CD, lineage/provenance, operational quota reasoning, and a chatbot thumbs-up/down feedback loop that informs chunking and vector-parameter tuning.

Metrics: Unit tests for every component · Integration tests for the overall system · CI/CD deployment of component changes · GCP quota limits such as 100 requests per minute and 30,000 prompts per batch request · Thumbs-up/down response feedback for chunking and vector-parameter iteration

3 supporting quotes
“make sure there is a unit test for every single component make sure we're doing integration tests and so on”transcript, stated
“the cicd pipelines that came with these systems were uh are a big part of what makes these systems um uh easily Deployable and maintainable”transcript, stated
“we have a great feedback loop of on the chat Bots showing thumbs up thumbs down and they're consistently tweaking”transcript, stated

Outcomes

The presentation reports a modular Bell-internal platform used for multiple RAG use cases, including HR policy and Confluence-style sources, but it does not publish production traffic, answer-quality, or business-impact metrics.

4 supporting quotes
“what we've built is a solution that can work for all of these situations and it canot work for constantly changing knowledge bases as well”transcript, stated
“we don't have to go in and build a separate pipeline every single time”transcript, stated
“yes it can yeah I I will run through this really quickly the great part of this is that all of these products we've localized into one project”transcript, stated
“we won't even store your like documents for you or your like your information if if uh if if it need be”transcript, stated