flowchart TD
subgraph Ingestion ["Phase 1 — Ingestion (offline)"]
A[("CBI Speeches CSV")] -->|load_speeches_csv| B["LangChain Documents"]
B -->|chunk_documents\nsize=1000, overlap=100| C["Text Chunks"]
C -->|nomic-embed-text\n768-dim vectors| D[("ChromaDB\nVector Store")]
end
subgraph Query ["Phase 2 — Query (online)"]
E["User Question"] -->|nomic-embed-text| F["Question Vector"]
F -->|cosine similarity k=4| D
D -->|top-4 chunks| G["Context Block"]
G --> H["Prompt Template"]
E --> H
H -->|LangChain LCEL| I["LLM"]
I --> J["Answer + Sources"]
end
subgraph Eval ["Phase 3 — Evaluation"]
J --> K["RAGAS Metrics\nfaithfulness · relevancy · recall"]
end
style Ingestion fill:#e8f4f8,stroke:#4a90d9
style Query fill:#f0f8e8,stroke:#5a9d4a
style Eval fill:#fdf5e8,stroke:#d9944a
Pipeline Diagrams
This page contains architecture diagrams of the RAG pipeline. Two formats are provided:
- Mermaid diagrams (below) — rendered natively by Quarto; always available in CI and on the published site.
- PaperBanana illustrations — AI-generated academic-quality figures produced by running
scripts/generate_diagrams.pylocally. When those images are committed, they appear in the AI-Generated Illustrations section.
Related issue: #58 — Generate RAG pipeline diagrams with PaperBanana.
1 RAG Architecture
The pipeline moves through three stages: ingest, retrieve, and generate. Documents are chunked and embedded once; at query time the question is embedded, the top-4 chunks are retrieved by cosine similarity, and the LLM generates an answer grounded in that context.
1.1 Key implementation files
| Stage | File | Key functions |
|---|---|---|
| Ingestion | rag/ingest.py |
load_speeches_csv, chunk_documents, ingest_to_chromadb |
| Query | rag/query.py |
build_rag_chain, ask, get_llm |
| Evaluation | rag/evaluate.py |
run_evaluation, score_dataset |
2 LLM Provider Fallback Chain
Ollama (local) is the primary LLM. If it is unavailable the system falls back through OpenAI → Anthropic → Google Gemini in order. Each cloud provider is only tried when the corresponding API key is present in the environment.
flowchart LR
Q["Query"] --> OL{"Ollama\nrunning?"}
OL -->|yes| A["llama3.2\n(local)"]
OL -->|no| OI{"OPENAI_API_KEY\npresent?"}
OI -->|yes| B["gpt-4o-mini\n(OpenAI)"]
OI -->|no| AN{"ANTHROPIC_API_KEY\npresent?"}
AN -->|yes| C["claude-haiku-4-5\n(Anthropic)"]
AN -->|no| GG{"GOOGLE_API_KEY\npresent?"}
GG -->|yes| D["gemini-1.5-flash\n(Gemini)"]
GG -->|no| E["RuntimeError:\nno provider available"]
A & B & C & D --> R["Answer"]
style A fill:#d4edda,stroke:#28a745
style B fill:#cce5ff,stroke:#004085
style C fill:#fff3cd,stroke:#856404
style D fill:#f8d7da,stroke:#721c24
style E fill:#f8d7da,stroke:#721c24
The selection logic lives in rag/query.py — get_llm() queries Ollama’s /api/tags endpoint and then checks environment variables in the order above.
3 AI-Generated Illustrations (PaperBanana)
PaperBanana is a reference-driven multi-agent framework that generates publication-quality academic illustrations from method-section prose and figure captions. It uses a five-agent pipeline: Retriever → Planner → Stylist → Visualizer → Critic.
To generate illustrations for this project, run:
# 1. Clone PaperBanana next to this repo
git clone https://github.com/dwzhu-pku/PaperBanana.git ../PaperBanana
# 2. Set up its environment (requires Python 3.12 + Google Gemini or OpenRouter key)
cd ../PaperBanana
uv venv && uv python install 3.12 && uv pip install -r requirements.txt
cp configs/model_config.template.yaml configs/model_config.yaml
# add your google_api_key to configs/model_config.yaml
# 3. Return here and run the wrapper script
cd ../private-rag-assistant
python scripts/generate_diagrams.pyThe script writes PNGs to quarto/assets/diagrams/. Commit them and they appear below.
### RAG Architecture
{width=90%}
### LLM Provider Fallback Chain
{width=90%}