TaxaRAGbiodiversity Q&A

How it works

System architecture

The architecture is taxon-centric rather than chunk-centric. Metadata for accepted names, synonyms, source URLs, and canonical IDs is copied onto every chunk, while two parallel indexes represent different evidence units. The router decides both the retrieval index and whether the question must first be resolved to a canonical taxon and filtered by that ID.

flowchart LR
  classDef meta fill:#eef4f8,stroke:#5b7890,color:#1e3446
  classDef chunk fill:#ffffff,stroke:#c8d1dc,color:#15212e
  classDef index fill:#fcf8ee,stroke:#b8731f,color:#6c4410
  classDef route fill:#e6f1f6,stroke:#0f6b8f,color:#0a5572
  classDef llm fill:#e8f5ee,stroke:#14855a,color:#0d5e40
  classDef guard fill:#f7ecf0,stroke:#b6253b,color:#7d1c2b

  subgraph D[Taxon-centered data layer]
    M[(Canonical metadata
accepted ID · accepted name
synonyms · source URL)]:::meta S[Section chunks
one named section per species
distribution · habitat · biology · IUCN · uses]:::chunk T[Morphology evidence chunks
sentence-level trait evidence
dorsal · anal · jaw · scale · leaf · petal]:::chunk M --> S M --> T end S --> SI[(Section TF-IDF index)]:::index T --> MI[(Morphology TF-IDF index)]:::index M --> A[(Synonym alias index
name to canonical taxon ID)]:::meta Q([User question]):::route --> R{Router
classify intent}:::route R --> N[name_resolution]:::route R --> MT[morphology_trait]:::route R --> SF[species_fact]:::route R --> SP[species_profile]:::route R --> GS[general_search]:::route N --> A MT -. resolve species when mentioned .-> A SF --> A SP --> A A --> F[Canonical taxon filter
species_id / taxon_id]:::guard F --> SI F --> MI MT --> MI SF --> SI SP --> SI GS --> SI SI --> E["Retrieved numbered chunks
1, 2, 3 ..."]:::llm MI --> E N --> E E --> G["LLM grounded answer
every factual sentence cites [N]"]:::llm G --> U[UI evidence cards
citation linked to source chunk]:::llm
Overall RAG architecture. The same taxon can appear in both indexes, but every chunk carries canonical metadata. Species-specific routes resolve names before retrieval and filter evidence to the canonical taxon.

Fish pipeline · FishBase

Single-source extraction: every fish record is scraped from FishBase species pages, with one section chunk per FishBase section and sentence-level morphology evidence pulled from the descriptive sections.

flowchart TB
  classDef src fill:#e6f1f6,stroke:#0f6b8f,color:#0a5572
  classDef proc fill:#ffffff,stroke:#c8d1dc,color:#15212e
  classDef store fill:#fcf8ee,stroke:#b8731f,color:#7a4f15
  classDef out fill:#e8f5ee,stroke:#14855a,color:#0d5e40

  A([FishBase species pages]):::src --> B[Scraper + synonym fetch]:::proc
  B --> C[(Species records · JSONL)]:::store
  C --> D[Section chunker]:::proc
  C --> E[Morphology evidence extractor]:::proc
  D --> F[(Section-aware TF-IDF index)]:::store
  E --> G[(Morphology evidence TF-IDF index)]:::store
  F --> R[Unified retrieval]:::out
  G --> R
      
Fish pipeline. One source (FishBase), two chunk types, two indexes per domain.

Botany pipeline · WCVP + POWO + WFO

Multi-source extraction joined on a single taxonomic backbone. WCVP supplies the authoritative accepted names and synonyms; POWO and WFO each contribute descriptive prose, then are concatenated into one section index and one morphology index per pipeline, just like the fish side.

flowchart TB
  classDef src fill:#e6f1f6,stroke:#0f6b8f,color:#0a5572
  classDef proc fill:#ffffff,stroke:#c8d1dc,color:#15212e
  classDef store fill:#fcf8ee,stroke:#b8731f,color:#7a4f15
  classDef out fill:#e8f5ee,stroke:#14855a,color:#0d5e40

  W([WCVP Darwin Core Archive]):::src --> WI[Backbone extractor
family-stratified sampling]:::proc P([POWO Kew]):::src --> PI[Description scraper]:::proc WF([World Flora Online]):::src --> WFI[Description scraper]:::proc WI --> J[Join on taxon ID]:::proc PI --> J J --> JC[(Canonical taxa · JSONL)]:::store JC --> SC[Section chunker]:::proc JC --> MC[Morphology evidence extractor]:::proc WFI --> WFC[WFO section + morphology chunks]:::proc SC --> MS[(Multi-source section index)]:::store WFC --> MS MC --> MM[(Multi-source morphology index)]:::store WFC --> MM MS --> R2[Unified retrieval]:::out MM --> R2
Botany pipeline. WCVP is the canonical backbone; POWO and WFO are descriptive enrichment layers, concatenated at the chunk level (multisource).

Shared query routing

Both domains share the same classifier and retrieval routes. The router decides which index to query based on the question shape, so trait questions hit morphology evidence, name queries hit synonyms, and species-fact questions resolve the taxon first before retrieving section evidence.

flowchart TD
  Q([User question])
  Q --> C1{Synonym or
accepted-name intent?} C1 -->|yes| R1[name_resolution] C1 -->|no| C2{Trait terms or
numeric ranges?} C2 -->|yes| R2[morphology_trait] C2 -->|no| C3{Species + section
keyword?} C3 -->|yes| R3[species_fact] C3 -->|no| C4{Profile-style
'tell me about'?} C4 -->|yes| R4[species_profile] C4 -->|no| R5[general_search] classDef route fill:#e6f1f6,stroke:#0f6b8f,color:#0a5572 class R1,R2,R3,R4,R5 route
Query routing. The classifier picks the retrieval strategy before any chunks are scored.

Grounded generation

Retrieved chunks are numbered and passed to the LLM with strict citation rules: every factual sentence must end with [N] referring to a numbered evidence chunk. Uncited paragraphs in the streamed answer are flagged in the UI. Cache hits return instantly from a fingerprint of the question + retrieved-chunk set.