RAG/flow/ — Pipeline Orchestration
DAG-based document processing pipeline
Pipeline execution engine (pipeline.py, base.py), pluggable chunker selection, parser framework, extractor framework.
❓ What is this & why?
The flow module orchestrates the entire chunking and extraction pipeline as a directed acyclic graph (DAG). This separation allows different document paths to take different routes (e.g., PDFs skip OCR if already text), enables parallel execution, and makes the pipeline configurable without changing code.
💡 Real-world analogy
Like an assembly line factory. Raw materials (documents) enter at one end. Specialized stations (chunker, extractors) process them in parallel. A central scheduler (DAG executor) routes tasks and manages dependencies. The flow module IS the assembly line controller.
🤔 Why Is It Designed This Way?
{{DESIGN_RATIONALE}} — 150+ words explaining the design choices: what pattern does this follow and why? What constraints shaped the implementation? What trade-offs were made and what was sacrificed?
| Design Choice | What Was Chosen | What Was Rejected | Why |
|---|---|---|---|
| Example: data layout | Array of structs | Struct of arrays | Random access pattern dominates; cache locality for single items matters more than SIMD sweeps |
Contents
Architecture
flowchart TD
subgraph Parser["Parser Layer"]
P1["Detect Format"]
P2["Extract Metadata"]
end
subgraph Chunker["Chunker Selection"]
C["Route to Specialized Chunker"]
end
subgraph Extract["Extraction Pipeline"]
E1["Entity Extraction"]
E2["Relation Extraction"]
E3["Keyword Extraction"]
end
subgraph DAG["DAG Execution"]
D["Execute Task Graph"]
end
subgraph Output["Indexing"]
O["Store Chunks + Index"]
end
Parser --> Chunker
Chunker --> Extract
Extract --> DAG
DAG --> Output
Key Classes
| Class / Function | File | Purpose |
|---|---|---|
ClassName | file.h | Brief description |
Data Structures
| Type | Name | Description |
|---|---|---|
| enum | EnumName | Brief description |
Interactions
| Direction | Partner | Interface | Description |
|---|---|---|---|
| → | Other Module | methodName() | Brief description |
Configuration
| Knob / Parameter | Default | Description |
|---|---|---|
param_name | value | What it controls |
Directory Map
Source tree for flow
submod_name/
├── file_a.ext ← Role: brief annotation
├── file_b.ext ← Role: brief annotation
├── file_c.ext ← Role: brief annotation
└── index.ext ← Role: entry point
📑 Annotated Code Walkthrough
The most important code in this sub-module, annotated with WHY each piece exists:
{{KEY_FUNCTION_NAME}}
// Replace with actual code from the source
void key_function() {
// ← WHY: Explain the purpose of this line
// ← WHY: What constraint or requirement drives this?
}
Line-by-line:
- Line N: What this does and WHY — what would break if removed
- Line M: The design choice here — why this approach over the obvious alternative
⚠️ Edge Cases & Boundaries
| Edge Case | What Happens | Where in Code | Risk Level |
|---|---|---|---|
| Empty input | How it's handled | function_name:line | 🟢 Low |
| Concurrent access | How it's handled | function_name:line | 🔴 High |
Deep-Dive Highlights
Core mechanisms from this sub-module have been extracted into dedicated focus pages for in-depth exploration. Each page covers one algorithm, protocol, or subsystem with diagrams, code walks, and configuration details.
Deep-Dive Pages
Pipeline Execution Flow
sequenceDiagram
participant API as API
participant Parser as Parser
participant Chunker as Chunker
participant DAG as DAG Executor
API->>Parser: Parse document
Parser->>Chunker: Select chunker
Chunker->>Chunker: Split chunks
Chunker->>DAG: Queue tasks
DAG->>DAG: Execute graph
DAG->>API: Return results
Code Examples
Example: Typical Usage
// Replace with actual code example
void example() {
// ...
}