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:
- Latència de la petició — P50, P95, P99 per model
- Ús de tokens — entrada/sortida per model i consumidor
- Taxa d’error — per codi d’estat i tipus d’error
- Estat del model — temps actiu i temps de resposta per backend
- 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.