Skip to content

Data flow — RAG path

Status: Implemented (v2)

This page describes how a knowledge question flows through the agent graph, from user query to cited answer.


Sequence

The router is not a LangGraph node — it is the conditional edge route_after_intent() in router.py, evaluated immediately after the intent node. The RAG node retrieves chunks only; LLM synthesis happens in the report node.

sequenceDiagram
    actor U as Engineer
    participant API as FastAPI
    participant LG as LangGraph
    participant I as Intent node
    participant Q as Qdrant
    participant RN as RAG node
    participant RP as Report node
    participant LLM as LLM

    U->>API: POST /ask
    API->>LG: invoke(CAEState)
    LG->>I: user_query
    I->>LG: intent (keyword or LLM)
    Note over LG: conditional edge: knowledge / setup / scripting → RAG

    LG->>RN: user_query
    RN->>Q: vector search + metadata filters
    Q-->>RN: child chunks + parent_text
    RN->>LG: retrieved_docs

    LG->>RP: user_query + retrieved_docs
    RP->>LLM: synthesize answer with context (if API key set)
    LLM-->>RP: draft answer
    RP->>LG: final_answer, citations
    LG-->>API: final state
    API-->>U: JSON response

Without an API key, the report node uses deterministic markdown assembly instead of calling the LLM.


Ingestion path

Documents are chunked before indexing:

  1. Parent chunks — larger sections (up to ~1200 chars) stored for context.
  2. Child chunks — smaller overlapping units (~512 chars) used for search.
  3. Each child carries parent_id and parent_text in the Qdrant payload.

On retrieval, the system searches child embeddings but returns parent context for the LLM prompt — better table and section coherence.

Code: rag/chunking.py, rag/ingest.py, scripts/ingest.py


Vector search + metadata filters

Layer Mechanism Status
Vector sentence-transformers embeddings (multilingual-e5-base) Implemented
Metadata filter doc_type, material payload filters Implemented
Parent expansion parent_text from child hit Implemented
Full-text / BM25 Not implemented

Offline fallback

When CAEC_QDRANT_URL is empty, InMemoryRetriever seeds demo KB chunks. Keyword intent still routes to RAG; citations come from seeded documents.