Skip to content

Architecture

antonyrag edited this page Aug 4, 2026 · 1 revision

Architecture

This page mirrors the "How it fits together" diagram in the README — verified against real, current source (inspect.signature() checks against v0.11.1/0.11.2, not assumed from memory).

Request pipeline

             +------------------+
             | Text, 28 formats |
             |  URLs, images,   |
             |   audio, video   |
             +--------+---------+
                      |
             +--------v---------+
             |  rag.ingest(...)  |   chunk -> embed -> store
             +--------+---------+
                      |
             +--------v---------+
             |  Vector backend   |   pgvector (default), or FAISS/Pinecone/
             |  (pluggable)      |   Weaviate/Qdrant/Milvus via vector_backend=
             +--------+---------+
                      |
             +--------v---------+
             |   rag.ask(...)    |
             +--------+---------+
                      |
             +--------v---------+
             | query_rewrite=    |   optional: "contextual"/"hyde"/"multi_query"
             | (optional)        |   transforms the query before retrieval
             +--------+---------+
                      |
             +--------v---------+
             |  Hybrid retrieve  |   dense + sparse (RRF) - degrades to
             |                   |   dense-only if the backend can't do sparse
             +--------+---------+          |
                      |                     v
             +--------v---------+   +---------------+
             |   Generation      |-->| Fallback chain |
             |  (temp/prompt/    |   | (if primary    |
             |   response_format)|   |  fails)        |
             +--------+---------+   +---------------+
                      |
             +--------v---------+
             |  Cost tracking +  |   real token usage -> cost_usd; output
             |  guardrails       |   guardrails run on the answer
             +--------+---------+
                      |
             +--------v---------+
             |  Conversation     |   optional: session_id ->
             |  memory (Postgres)|   prior turns injected as context
             +-------------------+

What's actually verified vs. what's plausible

Per this project's own standard, here's what's been confirmed against real code (not just documented and assumed correct):

  • Hybrid retrieval + RRF: confirmed real — search_hybrid_chunks(), actual Reciprocal Rank Fusion math (RRF_K = 60), tagged retrieval_method: "hybrid_rrf" on results.
  • Query rewriting: confirmed against ask()'s real signature — query_rewrite: Optional[str] accepting "contextual", "hyde", "multi_query".
  • Fallback chain: confirmed — fallbacks: Optional[List[ProviderConfig]] on RagLeap.__init__.
  • Cost tracking: confirmed — CostTracker, real cost_usd / cumulative_cost_usd fields on ask()'s result dict.

Background/async pattern (Celery + Redis)

For multi-worker deployments where you don't want to block a web request on ingestion or generation:

                    +-----------+
  Web request  ---> |   Redis   | ---> worker process 1 (own RagLeap + pool)
  (non-blocking)    |  broker   | ---> worker process 2 (own RagLeap + pool)
                    +-----------+                |
                                                  v
                                          +---------------+
                                          |   PostgreSQL   |
                                          |   + pgvector   |
                                          +---------------+
                                                  ^
                                                  |
                                   (optional) Redis query cache,
                                   shared across all worker processes

This example omits vector_backend=, so it uses the default pgvector — swapping in FAISS, Pinecone, Weaviate, Qdrant, or Milvus works identically in this same Celery pattern, since only the RagLeap construction inside get_rag() changes. Nothing about Celery integration is pgvector-specific.

Full runnable version: [examples/05_celery_background_tasks.py](https://github.com/antonyrag/ragleap-core/blob/main/packages/ragleap-rag/examples/05_celery_background_tasks.py

Clone this wiki locally