This repository demonstrates an LLM application with model fallback, monitoring, and testing.
- FastAPI Application: REST API for LLM interactions with cascade fallback
- LiteLLM Proxy: Unified interface for multiple LLM providers (OpenAI, Gemini, OpenRouter)
- MLflow: Experiment tracking and prompt tracing
- Docker and Docker Compose
- uv
- API keys for:
- Groq (required for the primary Qwen model)
- OpenAI, Gemini, and OpenRouter (optional routes)
-
Setup environment:
cp env.example .env # Edit .env with your API keys uv sync --frozen -
Start services:
docker compose up -d --build --wait
-
Access services:
- API: http://localhost:8000
- LiteLLM: http://localhost:8001
- MLflow UI: http://localhost:5001
POST /generate
Content-Type: application/json
{
"prompt": "Your prompt here",
"model": "groq-qwen-primary",
"temperature": 0.7
}GET /modelsGET /health- Primary:
groq-qwen-primary(qwen/qwen3.6-27b) - Fallback:
groq-gpt-oss-backup(openai/gpt-oss-20b)
The other provider routes remain available explicitly when their keys are configured.
All LLM calls are tracked with:
- Input/Output parameters
- Token usage and latency
- Success/Failure status
- Request metadata and trace status
Access the MLflow UI at http://localhost:5001
.
├── docker-compose.yml # Service definitions
├── litellm-config.yaml # LiteLLM model configuration
├── env.example # Template for environment variables
├── pyproject.toml # Python dependencies managed by uv
├── uv.lock # Validated dependency lock
├── tests/ # Integration tests
├── mlflow-data/ # MLflow experiment data
└── src/
└── api/ # FastAPI application
├── main.py # API endpoints
└── Dockerfile # API container setup
Tests run through the locked uv environment:
uv run --frozen pytestdocker compose downdocker compose logs -f- MLflow data:
./mlflow-data - Test coverage reports:
./htmlcov
The Makefile provides a set of commands to manage the environment and run tests. Here are the available commands:
Note:
jqis required to parse the API responses.
# Check API health
make api-test
# List available models
make api-models
# Generate text with fallback model
make api-generate PROMPT="What is the capital of France?"
# Generate text specifically with Gemini
make api-generate-gemini PROMPT="Explain quantum computing in simple terms"