Introducció

A la nostra infraestructura de IA amb K3s, LiteLLM fa de passarel·la central de models: un proxy que unifica múltiples proveïdors de models darrere d’una única API compatible amb OpenAI. Combinat amb el Model Context Protocol (MCP), es converteix en l’esquema vertebral de la comunicació entre agents i models. Aquest post documenta la nostra configuració de producció i les lliçons apreses al llarg del camí.

Resum de l’arquitectura

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Hermes     │────▶│   LiteLLM    │────▶│   NVIDIA     │
│   Agents     │     │   Gateway    │     │   Nemotron   │
└──────────────┘     │              │     └──────────────┘
┌──────────────┐     │  (port 4000) │     ┌──────────────┐
│   Cron Jobs  │────▶│              │────▶│   Mistral    │
└──────────────┘     └──────────────┘     └──────────────┘
┌──────────────┐           ▲               ┌──────────────┐
│   Webhooks   │───────────┘               │   OpenAI     │
└──────────────┘   Endpoint MCP           └──────────────┘
                    /mcp

Desplegament de LiteLLM a K3s

Configuració

El nostre desplegament de LiteLLM fa servir una configuració de llista de models que enruta les peticions a diferents proveïdors segons la tasca:

# litellm-config.yaml
model_list:
  # Model principal per a tasques de codi
  - model_name: hermes-coder
    litellm_params:
      model: nvidia/nemotron-3-ultra-550b-a55b
      api_base: https://integrate.api.nvidia.com/v1
      api_key: ${NVIDIA_API_KEY}
      timeout: 7200

  # Models Mistral per a recerca i anàlisi
  - model_name: mistral-reasoning
    litellm_params:
      model: mistral/devstral-latest
      api_base: https://api.mistral.ai/v1
      api_key: ${MISTRAL_API_KEY}
      timeout: 3600

  # Model lleuger per a tasques ràpides
  - model_name: hermes-lean
    litellm_params:
      model: nvidia/nemotron-3-nano-omni-30b-a3b-reasoning
      api_base: https://integrate.api.nvidia.com/v1
      api_key: ${NVIDIA_API_KEY}
      timeout: 7200

Manifiest de Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: litellm-gateway
  namespace: ia-services-payed
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: litellm
  template:
    metadata:
      labels:
        app: litellm
        version: main-stable
    spec:
      containers:
      - name: litellm
        image: ghcr.io/anthropics/litellm:main-stable
        ports:
        - containerPort: 4000
        env:
        - name: MODEL_LIST
          valueFrom:
            secretKeyRef:
              name: litellm-config
              key: model-list.yaml
        - name: PROXY_SERVER_KEY
          valueFrom:
            secretKeyRef:
              name: litellm-secrets
              key: api-key
        - name: HTTP_TIMEOUT
          value: "7200"
        - name: REQUEST_TIMEOUT
          value: "3600"
        - name: LOG_PII
          value: "false"
        resources:
          requests:
            memory: "2Gi"
            cpu: "500m"
          limits:
            memory: "4Gi"
            cpu: "1"
        livenessProbe:
          httpGet:
            path: /health
            port: 4000
          initialDelaySeconds: 30
          periodSeconds: 15
        readinessProbe:
          httpGet:
            path: /health
            port: 4000
          initialDelaySeconds: 10
          periodSeconds: 10
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: litellm
  namespace: ia-services-payed
spec:
  selector:
    app: litellm
  ports:
  - port: 4000
    targetPort: 4000
  type: ClusterIP

Integració de MCP

Configuració del endpoint MCP

LiteLLM exposa l’endpoint MCP a http://litellm.ia-services-payed.svc.cluster.local:4000/mcp. Els agents i els treball programats (cron jobs) s’hi connecten per accedir a eines i models:

# Exemple de connexió de client MCP
from mcp import ClientConnection

# Connexió a través del DNS del servei de K3s
connection = await ClientConnection.connect(
    "litellm.ia-services-payed.svc.cluster.local",
    port=4000,
    path="/mcp",
)

# Llistar les eines disponibles
tools = await connection.list_tools()
for tool in tools:
    print(f"{tool.name}: {tool.description[:80]}...")

Registre del servidor MCP

Cada servidor MCP es registra amb la passarel·la de LiteLLM:

# Registrar un nou servidor MCP
curl -X POST http://litellm.ia-services-payed.svc.cluster.local:4000/mcp/register \
  -H "Authorization: Bearer ${LITE...KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "kubernetes-mcp",
    "url": "http://mcp-k8s.forgejo-runners.svc.cluster.local:8080/mcp",
    "timeout": 300
  }'

Estratègia d’enrutament multi-model

Regles d’enrutament

Usem un enfocament d’enrutament per nivells:

Tipus de tasca Model principal Alternativa Justificació
Generació de codi hermes-coder (Nemotron) devstral Nemotron destaca en codi
Recerca/anàlisi devstral nemotron-35b El raonament de Mistral
Tasques ràpides nemotron-3-nano devstral Ràpid i econòmic
Raonament complex devstral hermes-coder El millor raonament global
Escripció creativa hermes-coder devstral Qualitat d’estil

Enrutament basat en l’estat de salut

LiteLLM enruta automàticament cap als models sans:

# Si el model principal no està sà, LiteLLM fa servir l'alternativa
# Comprovar l'estat del model
import httpx

async def check_model_health(model_name: str) -> bool:
    try:
        async with httpx.AsyncClient(timeout=5.0) as client:
            response = await client.post(
                f"{API_BASE}/v1/models",
                headers={"Authorization": f"Bearer {API_KEY}"},
            )
            return response.status_code == 200
    except httpx.TimeoutException:
        return False
    except httpx.RequestError:
        return False

Lliçons operatives

Lliçó 1: la configuració dels temps d’espera importa

L’API de NVIDIA pot ser lenta amb els models grans. Configurem:

HTTP_TIMEOUT=7200s  # 2 hores — per a la càrrega del model
REQUEST_TIMEOUT=3600s  # 1 hora — per a peticions individuals

Sense aquests valors, les peticions superen el temps d’espera durant l’arrancada en fred del model.

Lliçó 2: limitació de taxa a la capa de proxy

Configura els límits de taxa de LiteLLM per impedir que un sol consumidor desbordi el backend:

model_aliases:
  "nvidia/nemotron-3-ultra-550b-a55b": "nemotron-35b"

litellm_settings:
  model_fallbacks:
    "nemotron-35b": ["nemotron-35b", "devstral-large"]
  num_retries: 3
  retry_after: 5

Lliçó 3: registre i observabilitat

Habilita el registre estructurat per a la depuració:

litellm_settings:
  success_callback: ["langsmith", "opentelemetry"]
  failure_callback: ["langsmith", "opentelemetry"]
  cache: true
  cache_params:
    type: "redis"
    host: "redis-monitoring.svc.cluster.local"
    port: 6379

Consideracions de seguretat

Gestió de claus d’API

Mai codifiquis claus d’API en text pla. Fes servir secrets de Kubernetes:

# Crear el secret a partir de variables d'entorn existents
kubectl create secret generic litellm-secrets \
  --from-literal=api-key="${PROXY_SERVER_KEY}" \
  --namespace=ia-services-payed

kubectl create secret generic litellm-config \
  --from-file=model-list.yaml \
  --namespace=ia-services-payed

Polítiques de xarxa

Restringeix qui pot accedir a la passarel·la de LiteLLM:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: litellm-ingress
  namespace: ia-services-payed
spec:
  podSelector:
    matchLabels:
      app: litellm
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: forgejo-runners
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: cicd
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: flux-system
    ports:
    - port: 4000
  policyTypes:
  - Ingress

Monitorització de LiteLLM

Mètriques clau a seguir:

  1. Latència de la petició — P50, P95, P99 per model
  2. Ús de tokens — entrada/sortida per model i consumidor
  3. Taxa d’error — per codi d’estat i tipus d’error
  4. Estat del model — temps actiu i temps de resposta per backend
  5. Taxa d’encerts de cau — eficàcia de la cau de respostes

Consultes del panell de Grafana (Prometheus):

# Taxa de peticions per model
rate(litellm_proxy_request_count[5m])

# Latència mitjana per model
litellm_proxy_latency_seconds / 1000

# Taxa d'error
sum(rate(litellm_proxy_request_error_count[5m])) / sum(rate(litellm_proxy_request_count[5m]))

Conclusió

LiteLLM + MCP proporciona una passarel·la de models robusta i escalable per a infraestructures de IA basades en K3s. Les principals conclusions:

  • Configura temps d’espera generosos per a la càrrega del model
  • Fes ús de secrets de Kubernetes per a la gestió de claus d’API
  • Implementa alternatives de model basades en l’estat de salut
  • Monitoritza l’ús de tokens i la latència per model
  • Restringeix l’accés amb NetworkPolicies

Amb aquestes pràctiques en el seu lloc, la teva passarel·la de models gestiona la complexitat de l’enrutament multi-model mentre els teus agents se centren en les seves tasques reals.