Skip to main content
skill CX Codex

model-deployment — Claude Code skill: ship ML models to prod

A skill for getting a trained model into production: FastAPI server, Docker, Kubernetes, monitoring and drift detection. Useful once the model works and serving does not.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add secondsky/claude-skills --skill model-deployment -a claude-code
Open on GitHub

What model-deployment does

The skill walks the path from model.pkl to a running pod. It ships a FastAPI app template with /predict and /health endpoints, a Dockerfile on python:3.12-slim, and the commands to build the image, push it to a registry and roll it out with kubectl apply. A pre-deploy checklist covers validation on the test set, documented endpoints, authentication, model versioning and a rollback procedure.

Most of the content is about where these deploys break. Skip health checks and the load balancer keeps sending traffic to dead pods, returning 503s. Forget to copy the model into the image, or put it at the wrong path, and the container dies with FileNotFoundError. Leave resource limits unset and Kubernetes kills the pod through OOMKiller. Nobody measures drift, so degradation surfaces as user complaints. Each case comes with code: liveness and readiness probes, MODEL_PATH as an environment variable, Pydantic input validation, and a ModelMonitor class that logs predictions and latencies.

You need FastAPI, Pydantic, joblib, numpy and Docker. If your model is not loadable through joblib, expect to rewrite the server template around your own loader.

What it helps with

  • stand up a FastAPI server that serves model predictions
  • package a model and its code into a Docker image
  • configure liveness and readiness probes in Kubernetes
  • catch model drift before users notice
  • roll back a bad model release

Example prompts for the agent

  • Deploy my trained model: build a FastAPI server with /predict and /health
  • Write a Dockerfile for the model and show the build and push commands
  • Set up drift monitoring for the model in production

How to install model-deployment

1Skills CLI (Vercel)

npx skills add secondsky/claude-skills --skill model-deployment -a claude-code

2Manually: put the files in place

~/.claude/skills/model-deployment/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/model-deployment/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about model-deployment

How do I install model-deployment in Claude?

Run npx skills add secondsky/claude-skills --skill model-deployment -a claude-code. The skill lands in ~/.claude/skills/model-deployment/SKILL.md.

What does model-deployment do?

It takes a model from model.pkl to a Kubernetes pod: FastAPI server, Dockerfile, health probes, drift monitoring and a rollback plan.

What do I need for this skill to work?

FastAPI, Pydantic, joblib and numpy for the server, plus Docker for the image. The model has to load through joblib, otherwise you adapt the server template.

Source text

SKILL.md · MIT
---
name: model-deployment
description: Deploy ML models with FastAPI, Docker, Kubernetes. Use for serving predictions, containerization, monitoring, drift detection, or encountering latency issues, health check failures, version conflicts.
license: MIT
metadata:
  keywords: "model deployment, FastAPI, Docker, Kubernetes, ML serving, model monitoring, drift detection, A/B testing, CI/CD, mlops, production ml, model versioning, health checks, Prometheus, containerization, rolling updates, blue-green deployment, canary deployment, model registry"
---

# ML Model Deployment

Deploy trained models to production with proper serving and monitoring.

## Deployment Options

| Method | Use Case | Latency |
|--------|----------|---------|
| REST API | Web services | Medium |
| Batch | Large-scale processing | N/A |
| Streaming | Real-time | Low |
| Edge | On-device | Very low |

## FastAPI Model Server

```python
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np

app = FastAPI()
model = joblib.load('model.pkl')

class PredictionRequest(BaseModel):
    features: list[float]

class PredictionResponse(BaseModel):
    prediction: float
    probability: float

@app.get('/health')
def health():
    return {'status': 'healthy'}

@app.post('/predict', response_model=PredictionResponse)
def predict(request: PredictionRequest):
    features = np.array(request.features).reshape(1, -1)
    prediction = model.predict(features)[0]
    probability = model.predict_proba(features)[0].max()
    return PredictionResponse(prediction=prediction, probability=probability)
```

## Docker Deployment

```dockerfile
FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY model.pkl .
COPY app.py .

EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
```

## Model Monitoring

```python
class ModelMonitor:
    def __init__(self):
        self.predictions = []
        self.latencies = []

    def log_prediction(self, input_data, prediction, latency):
        self.predictions.append({
            'input': input_data,
            'prediction': prediction,
            'latency': latency,
            'timestamp': datetime.now()
        })

    def detect_drift(self, reference_distribution):
        # Compare current predictions to reference
        pass
```

## Deployment Checklist

- [ ] Model validated on test set
- [ ] API endpoints documented
- [ ] Health check endpoint
- [ ] Authentication configured
- [ ] Logging and monitoring setup
- [ ] Model versioning in place
- [ ] Rollback procedure documented

## Quick Start: Deploy Model in 6 Steps

```bash
# 1. Save trained model
import joblib
joblib.dump(model, 'model.pkl')

# 2. Create FastAPI app (see references/fastapi-production-server.md)
# app.py with /predict and /health endpoints

# 3. Create Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py model.pkl ./
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
EOF

# 4. Build and test locally
docker build -t model-api:v1.0.0 .
docker run -p 8000:8000 model-api:v1.0.0

# 5. Push to registry
docker tag model-api:v1.0.0 registry.example.com/model-api:v1.0.0
docker push registry.example.com/model-api:v1.0.0

# 6. Deploy to Kubernetes
kubectl apply -f deployment.yaml
kubectl rollout status deployment/model-api
```

## Known Issues Prevention

### 1. No Health Checks = Downtime
**Problem**: Load balancer sends traffic to unhealthy pods, causing 503 errors.

**Solution**: Implement both liveness and readiness probes:
```python
# app.py
@app.get("/health")  # Liveness: Is service alive?
async def health():
    return {"status": "healthy"}

@app.get("/ready")  # Readiness: Can handle traffic?
async def ready():
    try:
        _ = model_store.model  # Verify model loaded
        return {"status": "ready"}
    except:
        raise HTTPException(503, "Not ready")
```

```yaml
# deployment.yaml
livenessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 30
readinessProbe:
  httpGet:
    path: /ready
    port: 8000
  initialDelaySeconds: 5
```

### 2. Model Not Found Errors in Container
**Problem**: `FileNotFoundError: model.pkl` when container starts.

**Solution**: Verify model file is copied in Dockerfile and path matches:
```dockerfile
# ❌ Wrong: Model in wrong directory
COPY model.pkl /app/models/  # But code expects /app/model.pkl

# ✅ Correct: Consistent paths
COPY model.pkl /models/model.pkl
ENV MODEL_PATH=/models/model.pkl

# In Python:
model_path = os.getenv("MODEL_PATH", "/models/model.pkl")
```

### 3. Unhandled Input Validation = 500 Errors
**Problem**: Invalid inputs crash API with unhandled exceptions.

**Solution**: Use Pydantic for automatic validation:
```python
from pydantic import BaseModel, Field, validator

class PredictionRequest(BaseModel):
    features: List[float] = Field(..., min_items=1, max_items=100)

    @validator('features')
    def validate_finite(cls, v):
        if not all(np.isfinite(val) for val in v):
            raise ValueError("All features must be finite")
        return v

# FastAPI auto-validates and returns 422 for invalid requests
@app.post("/predict")
async def predict(request: PredictionRequest):
    # Request is guaranteed valid here
    pass
```

### 4. No Drift Monitoring = Silent Degradation
**Problem**: Model performance degrades over time, no one notices until users complain.

**Solution**: Implement drift detection (see references/model-monitoring-drift.md):
```python
monitor = ModelMonitor(reference_data=training_data, drift_threshold=0.1)

@app.post("/predict")
async def predict(request: PredictionRequest):
    prediction = model.predict(features)
    monitor.log_prediction(features, prediction, latency)

    # Alert if drift detected
    if monitor.should_retrain():
        alert_manager.send_alert("Model drift detected - retrain recommended")

    return prediction
```

### 5. Missing Resource Limits = OOM Kills
**Problem**: Pod killed by Kubernetes OOMKiller, service goes down.

**Solution**: Set memory/CPU limits and requests:
```yaml
resources:
  requests:
    memory: "512Mi"  # Guaranteed
    cpu: "500m"
  limits:
    memory: "1Gi"    # Max allowed
    cpu: "1000m"

# Monitor actual usage:
kubectl top pods
```

### 6. No Rollback Plan = Stuck on Bad Deploy
**Problem**: New model version has bugs, no way to revert quickly.

**Solution**: Tag images with versions, keep previous deployment:
```bash
# Deploy with version tag
kubectl set image deployment/model-api model-api=registry/model-api:v1.2.0

# If issues, rollback to previous
kubectl rollout undo deployment/model-api

# Or specify version
kubectl set image deployment/model-api model-api=registry/model-api:v1.1.0
```

### 7. Synchronous Prediction = Slow Batch Processing
**Problem**: Processing 10,000 predictions one-by-one takes hours.

**Solution**: Implement batch endpoint:
```python
@app.post("/predict/batch")
async def predict_batch(request: BatchPredictionRequest):
    # Process all at once (vectorized)
    features = np.array(request.instances)
    predictions = model.predict(features)  # Much faster!
    return {"predictions": predictions.tolist()}
```

### 8. No CI/CD Validation = Deploy Bad Models
**Problem**: Deploying model that fails basic tests, breaking production.

**Solution**: Validate in CI pipeline (see references/cicd-ml-models.md):
```yaml
# .github/workflows/deploy.yml
- name: Validate model performance
  run: |
    python scripts/validate_model.py \
      --model model.pkl \
      --test-data test.csv \
      --min-accuracy 0.85  # Fail if below threshold
```

## Best Practices

- **Version everything**: Models (semantic versioning), Docker images, deployments
- **Monitor continuously**: Latency, error rate, drift, resource usage
- **Test before deploy**: Unit tests, integration tests, performance benchmarks
- **Deploy gradually**: Canary (10%), then full rollout
- **Plan for rollback**: Keep previous version, document procedure
- **Log predictions**: Enable debugging and drift detection
- **Set resource limits**: Prevent OOM kills and resource contention
- **Use health checks**: Enable proper load balancing

## When to Load References

Load reference files for detailed implementations:

- **FastAPI Production Server**: Load `references/fastapi-production-server.md` for complete production-ready FastAPI implementation with error handling, validation (Pydantic models), logging, health/readiness probes, batch predictions, model versioning, middleware, exception handlers, and performance optimizations (caching, async)

- **Model Monitoring & Drift**: Load `references/model-monitoring-drift.md` for ModelMonitor implementation with KS-test drift detection, Jensen-Shannon divergence, Prometheus metrics integration, alert configuration (Slack, email), continuous monitoring service, and dashboard endpoints

- **Containerization & Deployment**: Load `references/containerization-deployment.md` for multi-stage Dockerfiles, model versioning in containers, Docker Compose setup, A/B testing with Nginx, Kubernetes deployments (rolling update, blue-green, canary), GitHub Actions CI/CD, and deployment checklists

- **CI/CD for ML Models**: Load `references/cicd-ml-models.md` for complete GitHub Actions pipeline with model validation, data validation, automated testing, security scanning, performance benchmarks, automated rollback, and deployment strategies

© secondsky · MIT · secondsky/claude-skills

Similar skills

Everything for AI and ML →

From the same set94

bun-macros A skill that covers running JavaScript during bundling and inlining the result. Useful when a version string, git hash or file belongs in the build, not the runtime. CX Codex +1 385installs bun-nuxt A skill that tells the agent how to run Nuxt 3 on Bun: scripts, Nitro preset, server routes and deployment. Useful when you want off Node. CX Codex +1 387installs multi-ai-consultant A skill that pulls in outside AIs when Claude is stuck on a bug or weighing an architecture call. Their answers get merged into one review. CX Codex +1 384installs graphql-implementation A skill for building GraphQL APIs: schema, resolvers, error codes and N+1 protection. Useful when moving off REST or adding real-time subscriptions. CX Codex +1 380installs cloudflare-agents A skill for building AI agents on Cloudflare Workers with tools, MCP and LLM providers. Useful when the agent runs inside a worker. CX Codex +1 378installs cloudflare-mcp-server A skill for building MCP servers on Cloudflare Workers: tools, resources, prompts and transport choices. Useful when you write your own server for an AI agent. CX Codex +1 375installs thesys-generative-ui A skill that teaches your agent to build React components from plain-language prompts with the Thesys SDK. Handy when you want a UI sketched out from a description. CX Codex +1 371installs maz-ui This skill teaches your agent Maz-UI v4: 50+ components, composables and directives for Vue 3 and Nuxt 3. Handy when you build forms, dialogs or data tables. CX Codex +1 369installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor