A production-ready AI boilerplate with unified adapter patterns for LLMs, RAG, and intelligent routing
Build AI applications faster. FAIForge provides a complete foundation with multi-provider LLM support, RAG pipelines, streaming, function calling, and intelligent model routingβall with built-in observability and Docker deployment.
I built this while exploring different LLM providers and found myself repeatedly solving the same infrastructure problems:
- Provider switching - Rewriting code every time I wanted to test a different model
- Cost tracking - No visibility into per-request costs across providers
- Observability - Difficulty debugging AI interactions without proper logging
- Deployment - Setting up Docker, security headers, CORS each time
- RAG complexity - Implementing chunking, embeddings, vector stores from scratch
- Reliability - No automatic failover when providers go down
The adapter pattern solves this. Now I can compare GPT-4o vs Claude with just a config change, implement RAG with pluggable components, and have automatic failover when providers fail.
Quick Links: Features β’ Quick Start β’ Architecture β’ API Docs β’ RAG System β’ Deployment
- OpenAI (GPT-4o, GPT-4o-mini)
- Anthropic (Claude Opus 4, Claude Sonnet 4.5)
- Google Gemini (gemini-2.0-flash, gemini-1.5-pro/flash)
- Cohere (Command R+, Command R)
- Ollama (Local models - Llama 3, Mistral, Phi-3, any Ollama model)
- vLLM (GPU-accelerated local serving - any HuggingFace model)
- Unified adapter pattern - switch providers with one line
- Streaming (SSE) - Real-time token streaming for responsive UX
- Function Calling - Native tool use support for OpenAI & Anthropic
- Structured Outputs - JSON mode for reliable parsing
- Model Fallbacks - Automatic failover when providers fail
- Smart Routing - Route requests based on complexity/cost rules
- Circuit Breaker - Auto-disable unhealthy providers
- Semantic Caching - Cache similar queries to reduce costs & latency
- 4 Vector Databases - Pinecone, Weaviate, Qdrant, ChromaDB
- 2 Embedding Providers - OpenAI, HuggingFace (local)
- 4 Chunking Strategies - Recursive, semantic, token-based, fixed-size
- Hybrid Search - BM25 + semantic with RRF/weighted fusion
- Cross-Encoder Reranker - Post-retrieval reranking (
use_rerank=true) - RAG-embedded Chat -
use_rag=trueinjects context into any chat completion - Document Management - List and delete ingested chunks via API
- Async Ingestion -
background=truereturns job ID immediately
- LLM Judge - 0β10 AI scoring of any response
- RAG Metrics - Faithfulness, answer relevancy, context precision/recall (Ragas-first, LLM-judge fallback)
- Prompt A/B Testing - ABRouter with round-robin and weighted-random routing
- "Rate This" UI - Thumbs up/down + AI judge button on every chat message
- Prometheus metrics -
/metricsendpoint for Grafana/alerting - Structured JSON logging - Machine-parseable logs with correlation IDs
- Automatic cost tracking - Per-request pricing for all providers
- Provider health checks - Circuit breaker status monitoring
- API Key Auth - Bearer token authentication; set
FAIFORGE_API_KEYSto enable - Rate Limiting - Per-key sliding window; 429 +
Retry-Afterheader - Zero-config dev mode - Auth/rate limiting auto-disabled when keys not set
- YAML-based config - No hardcoded values
- Environment overrides - Different configs for dev/staging/prod
- Fallback chains - Configurable provider failover sequences
- Routing rules - Define model selection logic in config
- 12-factor app compliant
- One-command setup -
docker-compose up - Multi-stage builds - Optimized image sizes (~350MB total)
- Health monitoring - Auto-restart on failure
- Production-ready - Non-root user, security headers
- FastAPI backend - Modern, async Python
- React + TypeScript frontend - 4-tab UI (Chat, RAG, Stats, Evals)
- Chat tab - Multi-model selector, streaming, RAG toggle, collapsible source citations, "Rate This" AI judge panel
- RAG tab - Document ingest, hybrid/semantic/BM25 search, document browser with per-chunk deletion
- Stats tab - Live cache stats, RAG corpus stats, cache clear
- Evals tab - Feedback log, A/B experiment stats
- Nginx reverse proxy - Production-grade serving
- API documentation - Auto-generated OpenAPI/Swagger
- Docker & Docker Compose
- OpenAI API key (required)
- Anthropic, Gemini, or Cohere API keys (optional)
git clone https://github.com/fiddyrod/faiforge.git
cd faiforge
# Add your API keys
cp backend/.env.example backend/.env
nano backend/.env # Add your keys (see Environment Variables section)docker-compose up -dThat's it! π
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
# Health check
curl http://localhost:8000/health
# List models
curl http://localhost:8000/v1/models
# Chat completion
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Hello!"}],
"model": "gpt-4o-mini"
}'
# Streaming response
curl -X POST "http://localhost:8000/v1/chat/completions?stream=true" \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Tell me a joke"}],
"model": "gpt-4o-mini"
}'βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FAIForge v2.5 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββ β
β β Browser β β
β ββββββββ¬βββββββ β
β β HTTP β
β β β
β βββββββββββββββββββββββββββββββββββ β
β β Frontend (React + Nginx) β β
β β Port: 3000 (4 tabs) β β
β β Chat β RAG β Stats β Evals β β
β ββββββββ¬βββββββββββββββββββββββββββ β
β β Proxy /v1/* β backend:8000 β
β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Backend (FastAPI) - Port: 8000 ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β β Middleware β ββ
β β β β’ API Key Auth (Bearer) β’ Rate Limiting (per-key) β ββ
β β βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββ ββ
β β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β β API Layer β ββ
β β β β’ Streaming (SSE) β’ Function Calling β ββ
β β β β’ Structured Outputs β’ RAG-embedded Chat β ββ
β β βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββ ββ
β β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β β Smart Router + Fallback Adapter β ββ
β β β β’ Query-based routing β’ Circuit breaker β ββ
β β β β’ Retry with backoff β’ Provider failover β ββ
β β βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββ ββ
β β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β β LLM Adapters (6 providers) β ββ
β β β ββββββββββ ββββββββββ ββββββββββ ββββββββββ β ββ
β β β βOpenAI β βAnthropicβ βGemini β βCohere β β ββ
β β β ββββββββββ ββββββββββ ββββββββββ ββββββββββ β ββ
β β β ββββββββββ ββββββββββ β ββ
β β β βOllama β β vLLM β β ββ
β β β β(local) β β (GPU) β β ββ
β β β ββββββββββ ββββββββββ β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β β RAG Pipeline β ββ
β β β Embeddings β Chunking β Vector Store β ββ
β β β + Hybrid Search (BM25+semantic) + Reranker β ββ
β β β Pinecone β Weaviate β Qdrant β ChromaDB β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β β β Evals β ββ
β β β LLM Judge β’ RAG Metrics β’ A/B Testing β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Observability: Prometheus /metrics β’ JSON logs β’ Cost trackingβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Frontend (/frontend)
- React 18 + TypeScript
- Tailwind CSS styling
- Vite build system
- Nginx production serving
Backend (/backend)
- FastAPI async framework
- Pydantic validation
- Multi-provider adapters
- Structured logging
LLM Adapters (/backend/core/inference/adapters)
- Unified interface for all providers
- Streaming support (SSE)
- Function/tool calling
- Structured outputs (JSON mode)
Fallback & Routing (/backend/core/inference)
fallback.py- FallbackAdapter with circuit breakerregistry.py- Model registry with routing support- Config-driven fallback chains
Semantic Cache (/backend/core/cache)
semantic.py- SemanticCache with embedding similaritybackends/- Memory (dev) and Redis (production) backends- Configurable similarity threshold and TTL
RAG System (/backend/core/rag)
- Embedding adapters (OpenAI, HuggingFace)
- Chunking strategies (recursive, semantic, token, fixed)
- Vector store adapters (Pinecone, Weaviate, Qdrant, Chroma)
- Pipeline orchestration
Configuration (/backend/core/config)
app.yaml- Application settingsmodels.yaml- Model definitionsrouting.yaml- Fallback chains & routing rulesrag.yaml- RAG pipeline configuration
models:
gpt-4o-mini:
adapter: openai
model: gpt-4o-mini
claude-sonnet:
adapter: anthropic
model: claude-sonnet-4-5-20250929
tiny-llama:
adapter: vllm
model: TinyLlama/TinyLlama-1.1B-Chat-v1.0fallback_chains:
default:
models: [gpt-4o-mini, claude-sonnet, ollama/phi3] # local as final fallback
retry:
max_retries: 3
base_delay: 1.0
circuit_breaker:
threshold: 5
recovery: 300
high_quality:
models: [gpt-4o, claude-opus, gpt-4o-mini]
local_only:
models: [ollama/llama3, ollama/mistral, ollama/phi3]
routing:
enabled: true
default_chain: default
rules:
- condition: has_tools
fallback_chain: high_quality
- condition: max_tokens > 2000
fallback_chain: high_quality
# Semantic caching (reduces API costs)
cache:
enabled: true
backend: memory # "memory" for dev, "redis" for prod
similarity_threshold: 0.95
ttl: 3600 # 1 hour
redis:
url: "redis://localhost:6379"embeddings:
default: openai
adapters:
openai:
model: text-embedding-3-small
huggingface:
model: all-MiniLM-L6-v2
chunking:
default: recursive
adapters:
recursive:
chunk_size: 512
overlap: 50
vector_stores:
default: chroma
adapters:
chroma:
collection: documents
pinecone:
index: faiforge# Required
OPENAI_API_KEY=sk-...
# LLM Providers (optional β models skipped if key not set)
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=...
COHERE_API_KEY=...
# Enterprise (optional β disabled when not set)
FAIFORGE_API_KEYS=key1,key2,key3 # Bearer token auth
FAIFORGE_RATE_LIMIT_REQUESTS=60 # requests per window (default: 60)
FAIFORGE_RATE_LIMIT_WINDOW=60 # window in seconds (default: 60)
# Infrastructure
ENV=production # development | production
LOAD_VLLM=false # Enable GPU local models
PINECONE_API_KEY=... # For Pinecone vector storeGET /health
# Response: {"status": "healthy", "models_loaded": 4}GET /v1/health/providers
# Response: {"status": "ok", "providers": {...circuit breaker status...}}GET /v1/cache/stats
# Response: {"enabled": true, "backend": "memory", "hit_rate": 0.85, "cache_size": 150}POST /v1/cache/clear
# Response: {"status": "ok", "entries_cleared": 150}GET /v1/models
# Response: {"models": [...], "fallback_chains": [...], "all": [...]}POST /v1/chat/completions
Content-Type: application/json
{
"messages": [{"role": "user", "content": "Hello!"}],
"model": "gpt-4o-mini",
"temperature": 0.7,
"max_tokens": 500
}POST /v1/chat/completions?stream=true
# Returns: Server-Sent Events (SSE) streamPOST /v1/chat/completions
{
"messages": [{"role": "user", "content": "What's the weather?"}],
"model": "gpt-4o-mini",
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}]
}POST /v1/chat/completions
{
"messages": [{"role": "user", "content": "Extract: John is 25"}],
"model": "gpt-4o-mini",
"response_format": {"type": "json_object"}
}POST /v1/rag/ingest
Content-Type: application/json
{
"documents": [
{"text": "Your document content here...", "source": "my-doc.txt"}
]
}
# Response: {"status": "ok", "chunks_created": 12, "documents_ingested": 1}POST /v1/rag/query
Content-Type: application/json
{
"query": "What is the main topic?",
"top_k": 5,
"search_mode": "hybrid" # "hybrid" | "semantic" | "bm25"
}
# Response: {"results": [{"text": "...", "source": "...", "score": 0.92, "semantic_score": 0.89, "bm25_score": 0.74}]}GET /v1/rag/stats
# Response: {"total_chunks": 42, "total_documents": 3, "hybrid_search": {"enabled": true, "fusion_method": "rrf"}}GET /v1/rag/documents
DELETE /v1/rag/documents/{chunk_id}# Start in background
POST /v1/rag/ingest?background=true
# Response: {"job_id": "uuid", "status": "pending"}
# Poll status
GET /v1/rag/jobs/{job_id}
# Response: {"job_id": "...", "status": "done", "result": {...}}POST /v1/chat/completions?use_rag=true
# Retrieves top-5 relevant chunks, injects as system context
# Response includes: {"content": "...", "sources": [{"content": "...", "score": 0.92}]}# LLM Judge score
POST /v1/evals/judge
{"messages": [...], "response": "...", "criteria": "helpfulness"}
# Submit feedback
POST /v1/evals/feedback
{"message_id": "...", "rating": 1, "comment": "..."}
# Get feedback log
GET /v1/evals/feedback
# Run RAG metrics
POST /v1/evals/rag
{"question": "...", "answer": "...", "contexts": [...], "ground_truth": "..."}
# A/B experiments
POST /v1/evals/ab/experiments
GET /v1/evals/ab/experiments/{id}/statsGET /metrics
# Returns Prometheus-format metrics: request counts, latency, token usage, costsFull API docs: http://localhost:8000/docs
FAIForge includes a complete RAG (Retrieval-Augmented Generation) system with pluggable components.
| Component | Options |
|---|---|
| Embeddings | OpenAI (text-embedding-3-small/large), HuggingFace (all-MiniLM-L6-v2, local) |
| Chunking | Recursive (smart splitting), Semantic (similarity-based), Token-based (LLM-aware), Fixed-size |
| Vector Stores | ChromaDB (embedded), Pinecone (managed), Qdrant (self-hosted), Weaviate (open-source) |
| Mode | Description |
|---|---|
semantic |
Dense vector search via embeddings - best for conceptual similarity |
bm25 |
Sparse keyword retrieval (Okapi BM25) - best for exact term matching |
hybrid |
BM25 + semantic fused with RRF (Reciprocal Rank Fusion) - best overall |
from core.rag import RAGPipeline, RAGRegistry, SearchMode, HybridConfig
# Initialize with hybrid search enabled
registry = RAGRegistry()
pipeline = RAGPipeline(
embedding_adapter=registry.get_embedding("openai"),
chunking_adapter=registry.get_chunking("recursive"),
vector_store=registry.get_vector_store("chroma"),
hybrid_config=HybridConfig(enabled=True, semantic_weight=0.6, bm25_weight=0.4)
)
# Ingest documents
await pipeline.ingest_documents(documents)
# Query with hybrid search (default)
results = await pipeline.query("What is the main topic?", top_k=5)
# Query with specific search mode
results = await pipeline.query("exact keyword match", top_k=5, search_mode=SearchMode.BM25)The RAG system is also exposed via REST endpoints - see the API Reference section for /v1/rag/ingest, /v1/rag/query, and /v1/rag/stats.
- Create adapter class inheriting from
LLMAdapter - Implement
complete()andcomplete_stream()methods - Handle
toolsandresponse_formatparameters - Register in
registry.pyand configure inmodels.yaml
Currently supported: OpenAI, Anthropic, Google Gemini, Cohere, Ollama, vLLM Easy to add: Mistral AI, any OpenAI-compatible API
- Create adapter inheriting from
VectorStoreAdapter - Implement
add(),search(),delete()methods - Register in RAG registry
Currently supported: ChromaDB, Pinecone, Qdrant, Weaviate
docker-compose up -d
docker-compose logs -f
docker-compose downAWS ECS / Fargate - Use task definitions with environment variables Google Cloud Run - Deploy as separate services Railway / Render / Fly.io - One-click deployment with GitHub
| Category | Feature | Status | Description |
|---|---|---|---|
| Foundation | Streaming (SSE) | β Done | Real-time token streaming |
| Foundation | Function Calling | β Done | Native tool use (OpenAI/Anthropic) |
| Foundation | Structured Outputs | β Done | JSON mode for reliable parsing |
| Infra | Model Fallbacks | β Done | Auto-failover with circuit breaker |
| Infra | Smart Routing | β Done | Query-based model selection |
| Infra | Semantic Caching | β Done | Redis + In-Memory backends |
| RAG | Vector Databases | β Done | Pinecone, Weaviate, Qdrant, ChromaDB |
| RAG | Embeddings | β Done | OpenAI, HuggingFace (local) |
| RAG | Chunking | β Done | Recursive, semantic, token, fixed |
| RAG | Hybrid Search | β Done | BM25 + semantic search with RRF fusion |
| Edge AI | Ollama Adapter | β Done | Local inference (Llama3, Mistral, Phi-3) |
| Evals | RAG Evaluation | β Done | Ragas + LLM-judge fallback (faithfulness, relevancy, precision, recall) |
| Evals | LLM Response Eval | β Done | LLMJudge (0-10 scorer) + "Rate This" UI |
| Evals | Prompt A/B Testing | β Done | ABRouter with round-robin & weighted-random |
| Observability | Prometheus | β Done | /metrics endpoint, Prometheus-compatible |
| Adapters | Gemini Adapter | β Done | gemini-2.0-flash, gemini-1.5-pro/flash |
| Adapters | Cohere Adapter | β Done | Command R+, Command R |
| Enterprise | API Key Auth | β Done | Bearer token; disabled when keys unset |
| Enterprise | Rate Limiting | β Done | Per-key sliding window, 429 + Retry-After |
| Enterprise | Async Ingestion | β Done | background=true + job polling |
| Agentic | MCP Integration | π Planned | Model Context Protocol |
| Agentic | Agent Framework | π Planned | LangGraph/tool-using agents |
| Agentic | Human-in-the-loop | π Planned | Approval workflows |
| Observability | LangSmith/W&B | π Planned | Tracing integration |
| Edge AI | llama.cpp/ONNX | π Planned | Quantized model support |
| Multimodal | Vision Support | π Planned | GPT-4o, Gemini Vision |
| Multimodal | Audio Processing | π Planned | Speech/audio input |
| Governance | Prompt Injection Defense | π Planned | Security hardening |
| Governance | PII Masking | π Planned | Data privacy |
| Governance | Content Moderation | π Planned | Guardrails |
MIT License - see LICENSE for details.
This project is open-source and available for use in personal or commercial projects. Feel free to fork and adapt for your own needs!
Built with: FastAPI, React, Ollama, vLLM, Docker, Tailwind CSS, Pydantic, Nginx, Prometheus
Vector stores: ChromaDB, Pinecone, Qdrant, Weaviate
β Star this repo if you find it useful!
FAIForge v2.5 - Production-ready AI infrastructure for modern applications π