Spaces:
Running on Zero
Running on Zero
File size: 31,480 Bytes
0828c2c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | # ποΈ Architecture Overview
## System Architecture
<p align="center">
<img src="docs/arch_system_design.png" alt="System Architecture Diagram" width="900" />
</p>
<p align="center"><em>High-level system architecture diagram illustrating the complete RAG pipeline flow</em></p>
### Detailed Component View
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Interface β
β (Streamlit Web App) β
β app.py β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RAG Pipeline β
β (rag_pipeline.py) β
β β
β ββββββββββββββββββ ββββββββββββββββ β
β β System Prompt β β QA Chain β β
β β Template βββββββΆβ (LangChain) β β
β ββββββββββββββββββ ββββββββ¬ββββββββ β
βββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ
β
βββββββββββββββ΄ββββββββββββββ
βΌ βΌ
βββββββββββββββββββββββββ ββββββββββββββββββββββββ
β Vector Store β β LLM Handler β
β (vectorstore.py) β β (llm_handler.py) β
β β β β
β βββββββββββββββββββ β β βββββββββββββββββ β
β β ChromaDB β β β β Ollama β β
β β (Embeddings) β β β β (llama3.2) β β
β βββββββββββββββββββ β β βββββββββββββββββ β
β β β β
β βββββββββββββββββββ β ββββββββββββββββββββββββ
β β HuggingFace β β
β β Embeddings β β
β β (all-MiniLM) β β
β βββββββββββββββββββ β
βββββββββββββββββββββββββ
β²
β
βββββββββββββ΄βββββββββββββ
β Document Processor β
β (document_processor.py)β
β β
β ββββββββββββββββββββ β
β β PDF Loader β β
β β DOCX Loader β β
β β HTML Loader β β
β β Text Loader β β
β ββββββββββββββββββββ β
β β
β ββββββββββββββββββββ β
β β Text Splitter β β
β β (Chunking) β β
β ββββββββββββββββββββ β
ββββββββββββββββββββββββββ
β²
β
βββββββββββββ΄βββββββββββββ
β Source Documents β
β data/documents/ β
β β
β β’ Resume.pdf β
β β’ LinkedIn.html β
β β’ Projects.docx β
β β’ ... β
ββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Configuration Layer β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β config.yaml env.template (.env) β
β ββ profile ββ OLLAMA_BASE_URL β
β ββ llm ββ CHROMA_PERSIST_DIR β
β ββ embeddings ββ DOCUMENTS_DIR β
β ββ vectorstore ββ LOG_LEVEL β
β ββ document_proc ββ API_KEYS (optional) β
β ββ rag β
β ββ ui β
β ββ logging β
β β
β (config_loader.py) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
## Data Flow
### 1οΈβ£ Indexing Phase (One-time Setup)
```
Documents β Load β Chunk β Build Indexes
β β β β
resume.pdf PyPDF Split βββββββββββββββββββββββββββββββ
linkedin.html BS4 into β BM25 Index (keyword) β
projects.docx docx chunks β ./bm25_index/ β
βββββββββββββββββββββββββββββββ€
β Vector Index (semantic) β
β ./chroma_db/ (ChromaDB) β
βββββββββββββββββββββββββββββββ
```
**Command:** `python -m src.build_vectorstore`
**Strategy Options:**
- `--strategy bm25_vector` - Build both indexes (default, recommended)
- `--strategy vector` - Vector index only
- `--strategy bm25` - BM25 index only
### 2οΈβ£ Query Phase (Runtime) - WITH HYBRID SEARCH
```
User Question
β
βββββββββββββββββββββββββββββββββββββββ
β Extract Chat History (if enabled) β
β β’ Format previous Q&A pairs β
β β’ Truncate by turns/tokens β
β β’ Include in context β
ββββββββββββββ¬βββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββ
β Load Main Document (if enabled) β
β β’ Check cache validity β
β β’ Auto-detect format β
β β’ Count tokens β
β β’ Summarize if needed β
ββββββββββββββ¬βββββββββββββββββββββββββ
β
[Main Doc Content]
β
βββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββ Main Doc (Priority)
β Hybrid Retrieval Strategy β β
β β [Always Available]
β βββββββββββββββ βββββββββββββββ β [10k tokens max]
β β BM25 β β Vector β β
β β (keyword) β β (semantic) β β
β ββββββββ¬βββββββ ββββββββ¬βββββββ β
β β β β
β βββββββββ¬βββββββββ β
β β β
β Reciprocal Rank Fusion (RRF) β
β (70% vector, 30% BM25) β
ββββββββββββββββββ¬βββββββββββββββββββββ
β
[Retrieved Context]
β
βββββββββββ¬ββββββββββββββββββββ
β
Construct Prompt:
System Prompt β Chat History β Main Doc β Retrieved Context β Question
β
Send to LLM (Ollama/Groq)
β
Generate Answer (streaming)
β
Response Enhancer
β’ Detect negative phrases
β’ Rewrite positively
β’ Fix markdown formatting
β’ Add forward-looking closings
β
Display in Streamlit UI (with source citations)
```
## Component Details
### π Main Document Integration
The Main Document feature ensures critical profile information is always available in the LLM context, regardless of VectorDB retrieval quality.
```python
MainDocumentLoader
βββ Format Auto-Detection
β βββ Markdown (.md) β LangChain TextLoader
β βββ Plain Text (.txt) β LangChain TextLoader
β βββ PDF (.pdf) β Existing PDF loader
β βββ Word (.docx) β Existing DOCX loader
β βββ HTML (.html) β Existing HTML loader
β
βββ Token Management
β βββ Counting: tiktoken (cl100k_base encoding)
β βββ Max Limit: 10,000 tokens (configurable)
β βββ Truncation: Smart token-based trimming
β βββ Summarization: LLM-based if exceeds limit
β
βββ Caching Strategy
β βββ File hash-based invalidation (MD5)
β βββ Configurable check interval (60s default)
β βββ Automatic reload on file changes
β
βββ Integration Point
βββ Positioned BEFORE VectorDB context (high priority)
```
**Architecture Flow:**
```
Main Document (Priority Context)
β
[Essential Info Always Available]
β
VectorDB Retrieval (Additional Context)
β
[Supplementary Information]
β
Combined Context β LLM β Response
```
**Benefits:**
- β
Critical information never missed by retrieval
- β
Auto-format detection (no manual config)
- β
Intelligent token management with LLM summarization
- β
Efficient caching for performance
- β
Graceful degradation if unavailable
**Note:** The system also supports chat history for conversational context. Previous Q&A pairs are included in the prompt (after system prompt, before main document) with configurable truncation by turns or tokens. Responses are post-processed to improve tone, remove negative language, and fix markdown formatting.
### π Document Processing Pipeline
```python
DocumentProcessor
βββ Supported Formats
β βββ PDF β pypdf
β βββ Word β python-docx
β βββ HTML β BeautifulSoup4
β βββ Text/MD β LangChain TextLoader
β
βββ Chunking Strategy
β βββ Size: 1000 chars (configurable)
β βββ Overlap: 200 chars (configurable)
β βββ Separators: ["\n\n", "\n", ". ", " ", ""]
β
βββ Output: List[Document]
βββ Each with content + metadata
```
### π Retrieval Strategy System
The retrieval system uses a pluggable strategy pattern for extensibility.
```python
RetrieverFactory
βββ Registered Strategies
β βββ "vector" β VectorStrategy (semantic search)
β βββ "bm25" β BM25Strategy (keyword search)
β βββ "bm25_vector" β BM25VectorStrategy (hybrid)
β βββ (future: "page_index", "graph_vector")
β
βββ Strategy Interface (BaseRetrieverStrategy)
βββ build_index(documents) β Build/update index
βββ load_index() β Load from disk
βββ retrieve(query, k) β Get relevant docs
βββ as_retriever() β LangChain compatible
```
#### Hybrid Search (BM25 + Vector)
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BM25VectorStrategy β
β β
β βββββββββββββββββββββββ βββββββββββββββββββββββββββ β
β β BM25Retriever β β VectorRetriever β β
β β (keyword match) β β (semantic match) β β
β β β β β β
β β β’ Exact terms β β β’ Meaning/context β β
β β β’ Abbreviations β β β’ Synonyms β β
β β β’ Proper nouns β β β’ Related concepts β β
β ββββββββββββ¬βββββββββββ βββββββββββββ¬ββββββββββββββ β
β β (k=10) β (k=10) β
β ββββββββββββ¬ββββββββββββββββββββ β
β β β
β Reciprocal Rank Fusion (RRF) β
β weights: {vector: 0.7, bm25: 0.3} β
β β β
β Top K results (k=4) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
**RRF Formula:** `score(d) = Ξ£ (weight Γ 1/(k + rank(d)))`
### π§ Vector Store Architecture
```python
VectorStoreManager
βββ Embedding Model
β βββ sentence-transformers/all-MiniLM-L6-v2
β βββ Dimension: 384
β βββ Speed: ~2000 sentences/sec (CPU)
β βββ Quality: Good for semantic search
β
βββ ChromaDB
β βββ Type: Persistent (SQLite)
β βββ Location: ./chroma_db/
β βββ Collection: profile_documents
β βββ Indexing: HNSW (approximate NN)
β
βββ Retrieval
βββ Search Type: Similarity (or MMR)
βββ Top K: 10 (before fusion)
βββ Distance: Cosine similarity
```
### π BM25 Store Architecture
```python
BM25Store
βββ Algorithm: BM25Okapi (rank-bm25)
β
βββ Tokenization
β βββ "simple": Whitespace + punctuation split
β βββ "nltk": NLTK word_tokenize (optional)
β
βββ Persistence
β βββ Location: ./bm25_index/
β βββ Format: Pickle (index + documents)
β βββ Metadata: JSON (hash, stats)
β
βββ Retrieval
βββ Top K: 10 (before fusion)
βββ Scoring: BM25 term frequency
```
### π€ LLM Integration
```python
LLMHandler
βββ Provider Support
β βββ Ollama (Local)
β β βββ Base URL: http://localhost:11434
β β βββ Protocol: HTTP/REST API
β β βββ Auto-detected if no API key
β β
β βββ Groq (Cloud)
β βββ Base URL: https://api.groq.com/openai/v1
β βββ Protocol: OpenAI-compatible API
β βββ Requires GROQ_API_KEY env var
β
βββ Model Options (Ollama)
β βββ llama3.2:3b (Recommended)
β βββ phi3:mini
β βββ gemma2:2b
β βββ llama3.1:8b (with GPU)
β
βββ Model Options (Groq)
β βββ openai/gpt-oss-120b
β βββ llama-3.3-70b-versatile
β βββ llama-3.1-8b-instant
β βββ mixtral-8x7b-32768
β βββ gemma2-9b-it
β
βββ Parameters
βββ Temperature: 0.7
βββ Max Tokens: 800 (increased for better formatting)
βββ Top P: 0.9
βββ Context Window: Model-dependent (8192-128k tokens)
```
### π RAG Chain
```python
RAGPipeline
βββ Retrieval Strategy
β βββ RetrieverFactory.create(strategy_name)
β βββ "vector" β Vector-only retriever
β βββ "bm25" β BM25-only retriever
β βββ "bm25_vector" β Fusion retriever (default)
β
βββ Prompt Template Structure
β βββ System Prompt (from config)
β βββ Chat History (formatted previous Q&A pairs)
β βββ Main Document (priority context, always available)
β βββ Retrieved Context (from strategy)
β βββ User Question
β
βββ LLM
β βββ Ollama or Groq (auto-detected or configured)
β
βββ Output
βββ Answer (post-processed for tone/formatting, streaming support)
βββ Source Documents (citations)
```
## Configuration Hierarchy
```
1. Environment Variables (.env)
βββ Override config.yaml values
βββ Secrets (API keys)
βββ Runtime settings (ports, URLs)
β
2. config.yaml
βββ Application defaults
βββ Model selection
βββ Retrieval strategy (vector, bm25, bm25_vector)
βββ RAG parameters
β
3. Code Defaults
βββ Fallback values if config missing
```
### Retrieval Configuration
```yaml
retrieval:
strategy: "bm25_vector" # Which strategy to use
final_k: 4 # Documents returned to LLM
vector:
search_type: "similarity" # or "mmr"
k: 10 # Docs before fusion
bm25:
k: 10 # Docs before fusion
persist_path: "./bm25_index"
tokenizer: "simple"
fusion:
algorithm: "rrf" # Reciprocal Rank Fusion
rrf_k: 60 # RRF constant
weights:
vector: 0.7
bm25: 0.3
```
### Chat History Configuration
```yaml
chat:
enable_history: true # Enable conversation context
max_history_turns: 10 # Max Q&A pairs to include
max_history_tokens: 2000 # Token limit for history
```
### RAG Configuration
```yaml
rag:
enhance_responses: true # Enable post-processing enhancement
include_sources: true # Show source citations
source_max_length: 150 # Max length of source preview
```
## Deployment Architecture
### Local Development
```
ββββββββββββββββββββ
β Developer β
β Machine β
β β
β ββββββββββββββ β
β β Ollama β β β Port 11434 (optional)
β β Server β β
β ββββββββββββββ β
β β
β ββββββββββββββ β
β β Groq API β β β https://api.groq.com (optional)
β β (Cloud) β β
β ββββββββββββββ β
β β
β ββββββββββββββ β
β β Streamlit β β β Port 8501
β β App β β
β ββββββββββββββ β
β β
β ββββββββββββββ β
β β ChromaDB β β β ./chroma_db/
β β (local) β β
β ββββββββββββββ β
β β
β ββββββββββββββ β
β β BM25 Index β β β ./bm25_index/
β β (local) β β
β ββββββββββββββ β
ββββββββββββββββββββ
```
### Hugging Face Spaces
```
βββββββββββββββββββββββββββββββββ
β HF Spaces Container β
β β
β βββββββββββββββββββββββββββ β
β β Dockerfile β β
β β ββ Install Ollama β β
β β ββ Pull Model β β
β β ββ Build Indexes β β
β β ββ Start Services β β
β βββββββββββββββββββββββββββ β
β β
β ββββββββββββ ββββββββββββ β
β β Ollama β βStreamlit β β
β β Server β β App β β
β ββββββββββββ ββββββββββββ β
β β
β βββββββββββββββββββββββββββ β
β β Persistent Storage β β
β β ββ chroma_db/ β β
β β ββ bm25_index/ β β
β βββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββ
β
β HTTPS
β
ββββββββββ΄βββββββββββ
β Public Users β
β (Recruiters) β
βββββββββββββββββββββ
```
## Build & Packaging
### UV + Hatchling + Versioningit
```
pyproject.toml
βββ [build-system]
β βββ requires: ["hatchling", "versioningit"]
β βββ build-backend: "hatchling.build"
β
βββ [project]
β βββ name: "profillybot"
β βββ version: <from git tags via versioningit>
β βββ dependencies: [...]
β
βββ [tool.versioningit]
β βββ Read git tags (v0.1.0, v0.2.0, etc.)
β βββ Generate version string
β βββ Write to src/_version.py
β
βββ [tool.ruff]
βββ Linting rules
βββ Formatting config
```
### Version from Git Tags
```bash
# Tag release
git tag v0.1.0
git push origin v0.1.0
# Version automatically set
python -c "from src import __version__; print(__version__)"
# Output: 0.1.0
# Development version (after tag)
# Output: 0.1.0+5.g1a2b3c4 (5 commits after v0.1.0)
```
## Code Quality Pipeline
```
Developer Writes Code
β
βββββββββββββββββββββ
β Pre-commit β
β (Optional) β
βββββββββββ¬ββββββββββ
β
βββββββββββββββββββββ
β Ruff Check β β Linting
β Ruff Format β β Formatting
βββββββββββ¬ββββββββββ
β
βββββββββββββββββββββ
β Git Commit β
βββββββββββ¬ββββββββββ
β
βββββββββββββββββββββ
β Push to GitHub β
βββββββββββ¬ββββββββββ
β
βββββββββββββββββββββ
β GitHub Actions β
β β’ Lint Check β
β β’ Format Check β
β β’ Tests (future) β
βββββββββββββββββββββ
```
## Module Dependencies
```
app.py
ββ src.config_loader
ββ src.rag_pipeline
ββ src.llm_handler (provider detection)
ββ src.response_enhancer (post-stream enhancement)
ββ src.main_document_loader (token counting for history)
ββ streamlit (UI, chat history management)
src.rag_pipeline
ββ src.config_loader
ββ src.llm_handler
ββ src.retrieval (RetrieverFactory, strategies)
ββ src.main_document_loader
ββ src.response_enhancer
ββ langchain (LCEL chains)
src.retrieval
ββ src.retrieval.base (BaseRetrieverStrategy)
ββ src.retrieval.factory (RetrieverFactory)
ββ src.retrieval.fusion (RRF, FusionRetriever)
ββ src.retrieval.stores.bm25_store
ββ src.retrieval.strategies.*
src.retrieval.strategies.vector
ββ src.vectorstore
ββ src.retrieval.base
src.retrieval.strategies.bm25
ββ src.retrieval.stores.bm25_store
ββ rank_bm25
src.retrieval.strategies.bm25_vector
ββ src.retrieval.strategies.vector
ββ src.retrieval.strategies.bm25
ββ src.retrieval.fusion
src.main_document_loader
ββ src.config_loader
ββ src.document_processor
ββ src.llm_handler
ββ tiktoken
ββ pathlib, hashlib, time
src.response_enhancer
ββ src.config_loader
ββ re (regex pattern matching)
src.vectorstore
ββ src.config_loader
ββ chromadb
ββ langchain_huggingface
src.llm_handler
ββ src.config_loader
ββ langchain_community.llms (Ollama)
ββ langchain_groq (Groq support)
src.document_processor
ββ src.config_loader
ββ pypdf
ββ python-docx
ββ beautifulsoup4
ββ langchain
src.config_loader
ββ pyyaml
ββ python-dotenv
src.build_vectorstore
ββ src.document_processor
ββ src.retrieval (RetrieverFactory)
ββ src.vectorstore
```
## Performance Characteristics
### Indexing (One-time)
| Documents | Chunks | Embedding Time | ChromaDB Insert | Total |
|-----------|--------|----------------|-----------------|-------|
| 5 PDFs | ~100 | ~5 seconds | ~1 second | ~6s |
| 20 PDFs | ~400 | ~20 seconds | ~2 seconds | ~22s |
| 50 PDFs | ~1000 | ~50 seconds | ~5 seconds | ~55s |
### Query (Runtime)
| Step | Time (CPU) | Time (GPU) | Notes |
|------|------------|------------|-------|
| Chat history extraction | <1ms | <1ms | Token counting overhead |
| Main doc loading | <1ms | <1ms | Cached after first load |
| Embed query | 50ms | 10ms | Sentence transformers |
| Vector search | 10-50ms | 10-50ms | ChromaDB HNSW |
| BM25 search | 5-20ms | 5-20ms | In-memory index |
| Fusion (RRF) | <1ms | <1ms | Rank combination |
| LLM inference (Ollama) | 2-5s | 0.5-1s | Local model |
| LLM inference (Groq) | 0.5-2s | N/A | Cloud API |
| Response enhancement | <10ms | <10ms | Post-processing |
| **Total (Ollama)** | **2-5s** | **0.5-1s** | |
| **Total (Groq)** | **0.6-2s** | **N/A** | Faster cloud option |
### Memory Usage
| Component | RAM | Disk |
|-----------|-----|------|
| Streamlit | ~200MB | - |
| Ollama (llama3.2:3b) | ~2GB | ~2GB |
| ChromaDB | ~100MB | ~50MB per 1k docs |
| BM25 Index | ~50MB | ~10MB per 1k docs |
| Embeddings | ~500MB | ~500MB |
| Chat History | ~1-10MB | - |
| Response Enhancer | <1MB | - |
| **Total** | **~3GB** | **~3GB** |
## Security Architecture
```
User Input
β
βββββββββββββββββββββββ
β Input Validation β β Length limits
β (Streamlit) β β Character filtering
βββββββββββ¬ββββββββββββ
β
βββββββββββββββββββββββ
β RAG Pipeline β β Context isolation
βββββββββββ¬ββββββββββββ
β
βββββββββββββββββββββββ
β LLM (Local) β β No external API calls
β β β Data stays local
βββββββββββββββββββββββ
Secrets Management:
ββ .env (local)
ββ .gitignore (.env excluded)
ββ HF Spaces Secrets (cloud)
```
## Extensibility Points
### π Plugin Architecture
```python
# Easy to extend:
# 1. New document types
DocumentProcessor.load_custom_format()
# 2. New LLM providers
LLMHandler.get_openai_llm()
LLMHandler.get_anthropic_llm()
# Already supports: Ollama (local), Groq (cloud)
# 3. New retrieval strategies (extensible system!)
@RetrieverFactory.register("page_index")
class PageIndexStrategy(BaseRetrieverStrategy):
"""Vision-based document retrieval (ColPali)"""
...
@RetrieverFactory.register("graph_vector")
class GraphVectorStrategy(BaseRetrieverStrategy):
"""Knowledge graph + vector hybrid"""
...
# 4. New UI features
app.py β add_authentication()
app.py β add_analytics()
# Already supports: Chat history, provider switching, streaming responses
# 5. New embedding models
VectorStoreManager(embedding_model="...")
# 6. New fusion algorithms
# Add to src/retrieval/fusion.py
def custom_fusion(results_list, weights):
...
# 7. New response enhancement patterns
# Edit src/response_enhancer.py
ResponseEnhancer.negative_patterns.append((pattern, rewrite_func))
# 8. Custom chat history strategies
# Modify truncate_chat_history() in app.py
# Add custom truncation logic (e.g., importance-based)
```
### Adding a New Retrieval Strategy
1. Create `src/retrieval/strategies/my_strategy.py`
2. Implement `BaseRetrieverStrategy` interface
3. Register with `@RetrieverFactory.register("my_strategy")`
4. Add config section in `config.yaml`
5. Import in `src/retrieval/strategies/__init__.py`
```python
from src.retrieval import RetrieverFactory
from src.retrieval.base import BaseRetrieverStrategy
@RetrieverFactory.register("my_strategy")
class MyStrategy(BaseRetrieverStrategy):
@property
def name(self) -> str:
return "my_strategy"
def build_index(self, documents): ...
def load_index(self) -> bool: ...
def retrieve(self, query, k=4): ...
def as_retriever(self, **kwargs): ...
```
---
**This architecture prioritizes:**
- β
Simplicity (easy to understand)
- β
Modularity (easy to extend)
- β
Performance (optimized for small-medium datasets)
- β
Privacy (local processing)
- β
Deployability (cloud-ready)
|