Universal and extensible RAG module with standardized interfaces and adapters.
- Alexander Ivanov
- email: VeryComplexAndLongName@gamil.com
- Telegram: @alexander_ivan0v
- Storage architecture is PostgreSQL + Qdrant only.
- New combined provider:
postgres+qdrant(PostgreSQL metadata + Qdrant vectors). - Adaptive document pipeline supports semantic subtype classification with hybrid scoring:
- rules-based scoring
- optional LLM scoring (
ollamaoropenai_compat) - weighted merge and confidence threshold fallback
- Document subtype is persisted in PostgreSQL metadata (
documents,document_versions) and propagated into chunk metadata/tags. - Added infrastructure compose files for local development:
docker-compose.postgres.ymldocker-compose.qdrant.ymldocker-compose.infra.yml
- One internal chunk contract across vector stores.
- Standardized ingestion pipeline: cleaning -> chunking -> embedding -> upsert.
- Adaptive document pipeline: detection -> normalization -> strategy-aware chunking.
- Standard retrieval APIs with semantic/hybrid strategies.
- First-class interoperability with PromptOrchestrator pipelines.
- Extensible migration framework and quality evaluation utilities.
Supported provider kinds in create_provider:
postgres+qdrant(recommended)postgresql+qdrantpostgres_qdrantpgvector/postgres/postgresql(legacy)qdrant(legacy)
- Start infrastructure:
docker compose -f docker-compose.infra.yml up -d- Configure environment:
export RAG_POSTGRES_DSN="postgresql://rag_user:rag_password@localhost:5432/rag_db"
export RAG_QDRANT_URL="http://localhost:6333"
export RAG_QDRANT_COLLECTION="rag_chunks"PowerShell:
$env:RAG_POSTGRES_DSN = "postgresql://rag_user:rag_password@localhost:5432/rag_db"
$env:RAG_QDRANT_URL = "http://localhost:6333"
$env:RAG_QDRANT_COLLECTION = "rag_chunks"- Ingest and search:
from ragflow_orchestrator.factory import create_provider
from ragflow_orchestrator.orchestrator import RAGOrchestrator
from ragflow_orchestrator.embedding import HashEmbedder
from ragflow_orchestrator.presets import document_preset
provider = create_provider(
"postgres+qdrant",
dsn="postgresql://rag_user:rag_password@localhost:5432/rag_db",
qdrant_url="http://localhost:6333",
qdrant_collection="rag_chunks",
)
preset = document_preset()
orchestrator = RAGOrchestrator(
provider=provider,
embedder=HashEmbedder(dimensions=256),
chunker=preset.chunker,
cleaner=preset.cleaner,
)
orchestrator.ingest(
source_id="doc-1",
raw_text="RAG orchestration standardizes ingestion and retrieval.",
metadata={"tenant_id": "t1", "language": "en", "doctype": "note"},
)
hits = orchestrator.search("How does orchestration help?", top_k=3)
for hit in hits:
print(hit.score, hit.chunk.id, hit.chunk.text)from ragflow_orchestrator import (
ConfigStore,
EmbeddingConfig,
ModuleConfig,
PipelineConfig,
ProviderConfig,
RAGOrchestratorFactory,
)
store = ConfigStore(
ModuleConfig(
provider=ProviderConfig(
kind="postgres+qdrant",
params={
"dsn": "postgresql://rag_user:rag_password@localhost:5432/rag_db",
"qdrant_url": "http://localhost:6333",
"qdrant_collection": "rag_chunks",
},
),
embedding=EmbeddingConfig(
provider="ollama",
model="nomic-embed-text:latest",
options={"base_url": "http://localhost:11434", "timeout_seconds": 60},
),
pipeline=PipelineConfig(preset="document"),
)
)
orchestrator = RAGOrchestratorFactory.from_config_store(store)Subtype classification is integrated into ingestion and versioned metadata pipeline.
Main behavior:
- If subtype is missing, classifier predicts it from content and metadata.
- Final subtype and confidence are attached to:
- document metadata
- version metadata
- chunk metadata/tags
- Fallback subtype is applied when confidence is below threshold.
Config fields in ModuleConfig.subtype_classification:
enabledfallback_subtypeconfidence_thresholdrules_weightllm_weightallowed_subtypesllmsettings:provider:none | ollama | openai_compatmodelbase_urlapi_key_envtimeout_secondstemperature
Default document preset routes content by detected type.
Supported types include:
pdfdocxxlsxhtmlmarkdownjsonxmlcsvtxtcodeunsupported
Detection can use extension hints, magic bytes, and content-type metadata.
Examples in examples/ now use PostgreSQL + Qdrant only:
examples/basic_usage.pyexamples/query_rag.pyexamples/template_ingestion.pyexamples/evaluate_retrieval.py
Each example reads environment variables:
RAG_POSTGRES_DSNRAG_QDRANT_URLRAG_QDRANT_COLLECTION
docker compose -f docker-compose.postgres.yml up -dServices:
postgresonlocalhost:5432pgadminonlocalhost:5050
docker compose -f docker-compose.qdrant.yml up -dService:
qdrantonlocalhost:6333(HTTP),localhost:6334(gRPC)
docker compose -f docker-compose.infra.yml up -dServices:
postgrespgadminqdrant
Enable local collector:
docker compose -f docker-compose.otel.yml up -dFiles:
docker-compose.otel.ymlobservability/otel-collector-config.yamlobservability/signoz-dashboard-ragflow.yaml
pip install -e .Optional extras:
pip install -e .[qdrant]
pip install -e .[pgvector]
pip install -e .[hf]
pip install -e .[all]ruff check .
mypy src tests scripts
pytest -qDefaults:
QDRANT_URL=http://localhost:6333PGVECTOR_DSN=postgresql+psycopg://postgres:N0th1ing@localhost:5432/app
Run preflight:
python scripts/preflight_check.pyRun preflight + integration tests:
python scripts/run_preflight_and_integration.pyUse PromptStyleRAGProviderAdapter to expose retrieve(query, limit) style retrieval for PromptOrchestrator flows while keeping ragflow_orchestrator ingestion/storage responsibilities.
src/ragflow_orchestrator/: package sourceexamples/: usage samplesscripts/: runnable demos and utility scriptstests/: test suitedatasets/: evaluation datasets
See LICENSE.
