xz-rag 0.1.1

Multi-channel Retrieval-Augmented Generation engine
Documentation

xz-rag

Multi-channel Retrieval-Augmented Generation engine for the 小竹 AI ecosystem.

Build composable RAG pipelines with multiple retrieval channels, RRF fusion, query preprocessing (HYDE), optional reranking, and LLM generation.

Architecture

xz-rag coordinates a pluggable retrieval pipeline:

Query → [Preprocessing] → Channel Executors → [Normalize] → [RRF Fusion] → [Rerank] → [Context Build] → [Generate]
                              │
           ┌──────────────────┼──────────────────┐
      Semantic             BM25              Metadata            Graph
   (vector search)    (full-text via     (structured         (knowledge
                       tantivy)           filters)            graph)

Channels

Channel Feature Backend Purpose
Semantic default any Embedder + SemanticSearch impl Dense vector similarity search
BM25 bm25 tantivy Sparse keyword retrieval
Metadata default any MetadataStore impl Structured field filtering
Graph default any KnowledgeGraphSearch impl Entity-relation traversal

Pipeline stages

  1. Query preprocessing -- HYDE (hypothetical document generation) or query expansion, both powered by xz-provider (feature hyde).
  2. Multi-channel retrieval -- each channel runs independently, configured with per-channel weight and top_k.
  3. Score normalization -- min-max normalization equalizes scores across heterogeneous channels.
  4. RRF fusion -- reciprocal rank fusion (RRFusion) merges results by rank position, smoothing out score distribution differences.
  5. Reranking -- optional cross-encoder reranking via xz-rerank (feature rerank) with Cohere/Jina support.
  6. Context assembly -- token-budget-aware context window with configurable citation formatting.
  7. Generation -- optional LLM response via xz-provider (feature llm-generation), with streaming support.

Features

Feature Default Description
bm25 no BM25 full-text search via tantivy
rerank no Cross-encoder reranking via xz-rerank
hyde no HYDE query expansion and query variation generation
llm-generation no LLM integration via xz-provider for retrieve_and_generate
caching no In-memory result caching via moka
query-expansion no Alias for hyde (same provider dep)

Usage

Basic retrieval with DefaultRagEngine

use std::sync::Arc;
use xz_rag::{
    DefaultRagEngine, RagEngine,
    channels::semantic::{Embedder, SemanticSearch, SemanticChannelExecutor},
    pipeline::channel::{ChannelConfig, ChannelPipeline},
    types::retrieval::RetrieveRequest,
};

// Provide your embedder and vector store implementations
let embedder: Arc<dyn Embedder> = Arc::new(MyEmbedder);
let store: Arc<dyn SemanticSearch> = Arc::new(MyVectorStore);

let engine = DefaultRagEngine::builder()
    .embedder(embedder)
    .semantic_store(store)
    .pipeline(
        ChannelPipeline::new(vec![
            ChannelConfig::semantic(0.6, 10).with_min_score(0.2),
            ChannelConfig::metadata(0.4, 5),
        ])
        .with_rrf_k(60),
    )
    .build();

let request = RetrieveRequest::builder("what is RAG?")
    .channels(vec![
        ChannelConfig::semantic(0.6, 10),
        ChannelConfig::metadata(0.4, 5),
    ])
    .top_k(15)
    .build();

let result = engine.retrieve(&request).await?;
println!("got {} hits from {} channels",
    result.hits.len(), result.channel_report.len());

With HYDE and reranking

Enable features in Cargo.toml:

[dependencies]
xz-rag = { version = "0.1", features = ["hyde", "rerank", "llm-generation"] }
use xz_rag::types::retrieval::{QueryPreprocessing, RetrieveRequest};

let request = RetrieveRequest::builder("explain attention mechanism")
    .channels(vec![ChannelConfig::semantic(1.0, 20)])
    .query_preprocessing(QueryPreprocessing::Hyde)
    .top_k(10)
    .build();

// engine built with .reranker(...) and .provider(...)
let response = engine.retrieve_and_generate(&rag_request).await?;
println!("{}", response.answer);

YAML/JSON configuration

engine:
  name: "my-rag"
channels:
  semantic:
    weight: 0.5
    top_k: 10
    min_score: 0.1
  bm25:
    weight: 0.3
    top_k: 8
  metadata:
    weight: 0.2
    top_k: 5
fusion:
  algorithm: "rrf"
  rrf_k: 60
  normalize_scores: true
reranking:
  enabled: true
context:
  max_context_tokens: 4096
  citation_format: "numeric"

Load via RagConfig::from_file() and build the engine:

use xz_rag::types::config::RagConfig;

let config: RagConfig = serde_yaml::from_str(&yaml_str)?;
let engine = config.build_engine()?;

Streaming generation

use futures::StreamExt;
use xz_rag::types::rag::RagStreamEvent;

let mut stream = engine.retrieve_and_generate_stream(&request).await?;
while let Some(event) = stream.next().await {
    match event? {
        RagStreamEvent::GenerationStarted { context_chunks, .. } => {
            eprintln!("context: {} chunks", context_chunks);
        }
        RagStreamEvent::ContentDelta { delta } => print!("{}", delta),
        RagStreamEvent::Done { citations, .. } => println!("\n[Done]"),
    }
}

Modules

  • engine -- DefaultRagEngine and its builder
  • channels -- per-retriever channel executors (semantic, bm25, metadata, graph)
  • pipeline -- channel orchestration, RRF fusion, score normalization
  • context -- token budget management and citation formatting
  • preprocessing -- HYDE and query expansion
  • generation -- LLM response generation via xz-provider
  • indexing -- document chunking (fixed, recursive, separator-based)
  • types -- shared types (configs, requests, responses, chunk metadata)
  • cache -- optional in-memory result caching
  • error -- typed RAG errors

Crate features

All optional components are feature-gated. The default crate is lightweight with only semantic and metadata channels. Turn on bm25, rerank, hyde, llm-generation, or caching as needed.

License

MIT OR Apache-2.0