Cambiar el proveedor del modelo: OpenAI, Anthropic, Bedrock, Ollama
Corre el mismo crew con cuatro backends de modelo distintos cambiando solo una variable de entorno. Comparas costo, latencia, privacidad y fricción de setup. Confirmas que el agente es independiente del proveedor.
Costo estimado: free a poco según el proveedor
Aparece en: Agentic AI desde cero para Backend y Cloud Developers
Por qué este lab existe
Tu crew_setup.py del Lab 4 instancia el LLM así:
llm = LLM(
model="groq/llama-3.3-70b-versatile",
api_key=os.environ["GROQ_API_KEY"],
temperature=0.3,
)
Funciona. Pero si mañana tu cliente exige que los datos no salgan de su VPC (Groq es cloud público) o si el bill crece y quieres probar un modelo más barato, tienes que tocar el archivo donde están los agentes para cambiar dónde corre el modelo. La identidad de los agentes (roles, goals, backstories) y la elección del proveedor viven mezcladas.
CrewAI usa por debajo litellm, una librería que abstrae más de 100 proveedores detrás de la misma interfaz. Cambiar de proveedor es cambiar el string del modelo y, a veces, las credenciales. El refactor de este lab te permite hacer ese cambio con una sola variable de entorno, sin tocar crew_setup.py ni tasks.py.
Duración: ~60 min · Nivel: Intermediate · Costo: gratis a poco según el proveedor.
Lo que vas a tener al terminar
- Un
llm_factory.pyque decide qué LLM instanciar leyendo la env varLLM_PROVIDER. - Un
crew_setup.pymodificado que pide el LLM al factory en vez de hardcodearlo. - Cuatro corridas validadas del mismo crew: Groq (default del Lab 4), OpenAI, Anthropic y Ollama local. Bedrock como opcional con AWS account.
- Una tabla comparativa real con costo por 1M tokens, dónde corre, fricción del setup y notas de calidad observada.
Qué vas a aprender
- Aplicar Factory pattern para desacoplar el agente del proveedor del modelo.
- Distinguir las tres categorías de cómo se accede a un LLM desde Python: dialecto OpenAI-compatible, SDK nativo, gateway agregador.
- Configurar Amazon Bedrock con credenciales IAM y entender por qué su setup es distinto.
- Comparar trade-offs reales de cuatro proveedores sobre el mismo caso de uso.
Conceptos clave
Tres categorías de cómo un cliente Python le habla a un LLM
Qué es: la diferencia entre las tres categorías es lo que determina cuánto código tienes que escribir por proveedor:
- Dialecto OpenAI-compatible. El proveedor expone el endpoint en el mismo formato JSON que OpenAI. Cliente único (el SDK
openai), cambia solo elbase_urly la key. Ejemplos: Groq, Cerebras, OpenRouter, Together. Visto en el Lab 1. - SDK nativo. El proveedor tiene su propio SDK con su propio formato. Ejemplos: Anthropic (
anthropic), Amazon Bedrock (boto3con clientebedrock-runtime). El payload, los nombres de los campos y la forma de las respuestas son distintos. - Gateway agregador. Una librería que envuelve las dos categorías anteriores y expone una sola interfaz uniforme. El más usado es litellm. CrewAI lo trae como dependencia, por eso
groq/llama-3.3-70b-versatilefunciona sin que tú escribas el cliente.
Mini-ejemplo: tres caminos posibles para hablarle a Claude desde Python.
# 1. SDK nativo (formato propio de Anthropic)
from anthropic import Anthropic
client = Anthropic(api_key=...)
client.messages.create(model="claude-3-5-haiku-20241022", ...)
# 2. Dialecto OpenAI-compatible: no aplica a Anthropic.
# Anthropic no expone su API en formato OpenAI; necesitas un gateway.
# 3. Gateway (litellm directo, o vía CrewAI como en este lab)
from litellm import completion
completion(model="anthropic/claude-3-5-haiku-20241022", ...)
Factory pattern para el LLM
Qué es: un Factory (también fábrica en español) es una función que centraliza la decisión de qué objeto instanciar. En vez de que crew_setup.py decida directamente “uso Groq”, le pide al factory “dame el LLM configurado”. El factory lee LLM_PROVIDER del entorno y devuelve la instancia correcta. Cambiar de proveedor pasa a ser una variable de entorno, no un edit de código.
Mini-ejemplo:
# llm_factory.py
def get_llm():
provider = os.environ.get("LLM_PROVIDER", "groq")
if provider == "groq":
return LLM(model="groq/llama-3.3-70b-versatile", ...)
if provider == "openai":
return LLM(model="gpt-4o-mini", ...)
...
Para profundizar: el Factory pattern viene de Design Patterns (Gamma, Helm, Johnson y Vlissides, 1994). En su forma original es una clase abstracta con métodos para crear familias de objetos. Acá usamos la versión simplificada (una función con
if/elif), que es suficiente cuando el set de proveedores es chico y conocido. Si crece, conviene mover a un dictPROVIDERS = \{"groq": _make_groq, ...\}o a una clase con polimorfismo.
Mapa visual
LLM_PROVIDER=groq ┐
LLM_PROVIDER=openai │
LLM_PROVIDER=anthropic │── env var ─▶ llm_factory.get_llm() ─▶ LLM(...)
LLM_PROVIDER=bedrock │ │
LLM_PROVIDER=ollama ┘ ▼
crew_setup.py
(researcher, writer, reviewer)
│
▼
main.py: crew.kickoff()
crew_setup.py no sabe qué proveedor está activo. Tampoco lo saben tasks.py ni main.py. El “swap point” es una sola env var. Esa es la propiedad que demuestra que el agente es independiente del proveedor del modelo.
Punto de partida
Antes de refactorizar, verifica que el Lab 4 esté funcionando.
cd agentic-ai-lab
source .venv/bin/activate
python main.py
Respuesta esperada: el crew corre los tres agentes con Groq y produce un post final.
Si falla, regresa al Lab 4.
Sobre las versiones y los modelos
Validado al updatedAt: 2026-05-16:
crewai: mismo de Lab 4.litellmviene como dependencia transitiva.boto3: requerido solo si vas a probar Bedrock. Última en pypi.org/project/boto3.- Modelos (verifica la lista vigente antes de correr; los proveedores cambian la oferta cada pocos meses):
- Groq:
llama-3.3-70b-versatile(mismo del Lab 1 al Lab 4). - OpenAI:
gpt-4o-mini(platform.openai.com/docs/models). - Anthropic:
claude-3-5-haiku-20241022(docs.anthropic.com/en/docs/about-claude/models). - Bedrock:
anthropic.claude-3-5-haiku-20241022-v1:0(lista en la consola de Bedrock, varía por región). - Ollama:
llama3.2(lista local conollama list).
- Groq:
Si un modelo fue deprecado al momento que corres el lab, los proveedores suelen indicar el reemplazo en su página de modelos.
Paso 1. Refactor a llm_factory.py
Archivo: llm_factory.py (NUEVO)
import os
from dotenv import load_dotenv
from crewai import LLM
load_dotenv()
def get_llm():
"""Instancia el LLM según LLM_PROVIDER. Default: groq."""
provider = os.environ.get("LLM_PROVIDER", "groq").lower()
if provider == "groq":
return LLM(
model="groq/llama-3.3-70b-versatile",
api_key=os.environ["GROQ_API_KEY"],
temperature=0.3,
)
if provider == "openai":
return LLM(
model="gpt-4o-mini",
api_key=os.environ["OPENAI_API_KEY"],
temperature=0.3,
)
if provider == "anthropic":
return LLM(
model="anthropic/claude-3-5-haiku-20241022",
api_key=os.environ["ANTHROPIC_API_KEY"],
temperature=0.3,
)
if provider == "bedrock":
return LLM(
model="bedrock/anthropic.claude-3-5-haiku-20241022-v1:0",
aws_region_name=os.environ.get("AWS_REGION", "us-east-1"),
temperature=0.3,
)
if provider == "ollama":
return LLM(
model="ollama/llama3.2",
base_url=os.environ.get("OLLAMA_BASE_URL", "http://localhost:11434"),
temperature=0.3,
)
raise ValueError(f"LLM_PROVIDER={provider!r} no soportado")
Notas:
- Default =
groq, para que la corrida del Lab 4 siga funcionando sin tocar nada más. - Bedrock no recibe
api_keycomo string: usa las credenciales AWS configuradas en el shell (env vars o~/.aws/credentials). - Ollama lee
OLLAMA_BASE_URLcon fallback a localhost. Útil si en algún momento corres Ollama en otra máquina. - Si pasas un valor no soportado en
LLM_PROVIDER, falla conValueErroren vez de intentar invocar y recibir un error confuso del proveedor.
Archivo: crew_setup.py (MODIFICADO, solo el bloque del llm)
Reemplaza:
llm = LLM(
model="groq/llama-3.3-70b-versatile",
api_key=os.environ["GROQ_API_KEY"],
temperature=0.3,
)
Por:
from llm_factory import get_llm
llm = get_llm()
El resto del archivo (los tres agentes) queda igual.
Probar:
python main.py
Respuesta esperada: el crew sigue corriendo con Groq (default), produce el mismo post final que en el Lab 4. Si así es, el refactor no rompió nada.
Paso 2. Swap a OpenAI
- Crea cuenta en platform.openai.com y genera una API key (requiere agregar crédito; no hay free tier).
- Agrega al
.env:
OPENAI_API_KEY=sk-tu-valor-aqui
LLM_PROVIDER=openai
- Corre:
python main.py
Respuesta esperada: misma estructura de output, modelo distinto. En los logs de litellm ves ahora api.openai.com en vez de api.groq.com. El post final viene de gpt-4o-mini.
Coste: a la fecha de validación,
gpt-4o-miniestá en ~$0.15 / 1M input + ~$0.60 / 1M output. Una corrida del crew (~5k tokens) cuesta fracciones de centavo.
Paso 3. Swap a Anthropic
- Crea cuenta en console.anthropic.com y genera una API key. Anthropic requiere agregar crédito; los $5 iniciales alcanzan para muchas corridas.
- Agrega al
.env:
ANTHROPIC_API_KEY=sk-ant-tu-valor-aqui
LLM_PROVIDER=anthropic
- Corre:
python main.py
Respuesta esperada: mismo crew, mismo flujo, ahora con Claude 3.5 Haiku. La calidad del post tiende a ser distinta: Claude suele ser más verboso en revisión. Si te molesta, ajusta el expected_output de review_task (vuelve al Lab 4 para editarlo).
Paso 4. Swap a Amazon Bedrock
Bedrock es un servicio AWS. Tienes tres requisitos previos: pedir acceso al modelo, tener credenciales AWS válidas y tener boto3 instalado (litellm lo usa por debajo).
-
Habilita acceso al modelo Claude en Bedrock:
- Consola AWS → Amazon Bedrock → Model access.
- Solicita acceso a
Claude 3.5 Haikuen la región que vas a usar. La aprobación para Anthropic en Bedrock suele ser inmediata o de minutos.
-
Configura credenciales AWS (si todavía no las tienes):
aws configure
aws sts get-caller-identity # confirma que las credenciales funcionan
- Instala boto3:
pip install boto3
- Agrega al
.env:
AWS_REGION=us-east-1
LLM_PROVIDER=bedrock
- Corre:
python main.py
Respuesta esperada: el crew corre con Claude 3.5 Haiku, pero servido por Bedrock. La primera corrida tarda un poco más (cold start del modelo en Bedrock). Fíjate que en el .env no aparece BEDROCK_API_KEY: la autenticación va por las credenciales AWS estándar.
Si te sale
AccessDeniedException: no aprobaron el acceso al modelo, o tu identidad IAM no tienebedrock:InvokeModel. La política mínima del IAM es:{ "Effect": "Allow", "Action": "bedrock:InvokeModel", "Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-haiku-20241022-v1:0" }
Paso 5. Swap a Ollama local
Ollama corre modelos en tu máquina, sin proveedor en la nube. Los datos no salen de tu laptop. Costo cero. Latencia depende de tu hardware.
- Instala Ollama desde ollama.com/download.
- Descarga el modelo y arranca el daemon:
ollama pull llama3.2
ollama serve # corre en background, escucha en :11434
- Agrega al
.env:
LLM_PROVIDER=ollama
- Corre:
python main.py
Respuesta esperada: el crew corre 100% local. La calidad de llama3.2 (3B parámetros) es notablemente más baja que los modelos cloud anteriores: el post tiende a ser más genérico y a veces no respeta el formato pedido. Es el trade-off por correr sin nube en hardware modesto.
Para acercarte a la calidad de los modelos cloud, prueba
ollama pull llama3.1:70boollama pull qwen2.5:32b. Necesitas hardware adecuado (~40 GB de RAM o una GPU con buena VRAM).
Paso 6. Tabla comparativa de los cinco proveedores
Después de correr el crew con cada proveedor vas a tener datos propios. Esta es la lectura validada al updatedAt: 2026-05-16:
| Proveedor | Modelo de la corrida | Coste 1M tokens (in / out) | Dónde corre | Setup | Notas |
|---|---|---|---|---|---|
| Groq | Llama 3.3 70B | $0 (free tier) | Cloud (LPU propio) | Email + key | El más rápido. Free tier holgado pero no apto para producción. |
| OpenAI | gpt-4o-mini | $0.15 / $0.60 | Cloud público | Cuenta + crédito | El más barato de los SaaS comparables. Calidad decente. |
| Anthropic | Claude 3.5 Haiku | $1.00 / $5.00 | Cloud público | Cuenta + crédito | Mejor calidad subjetiva en revisión. Más caro por token. |
| Bedrock | Claude 3.5 Haiku | igual a Anthropic | AWS (tu región) | IAM + acceso al modelo | Datos no salen de tu cuenta AWS. Setup con más fricción. |
| Ollama | Llama 3.2 (3B) | $0 | Local (tu máquina) | Instalar + pull | Datos no salen de tu red. Calidad limitada por el hardware. |
Cómo leerla:
- Para prototipos sin restricciones: Groq (gratis y rápido).
- Para producción con presupuesto ajustado: OpenAI gpt-4o-mini.
- Para calidad alta en revisión y escritura: Anthropic (o Bedrock con el mismo modelo).
- Para datos sensibles que no pueden salir de AWS: Bedrock.
- Para datos que no pueden salir de tu red local: Ollama.
Errores comunes
Error 1. KeyError: 'OPENAI_API_KEY' al hacer swap
Síntoma: cambias LLM_PROVIDER=openai pero olvidas agregar la key del nuevo proveedor en .env. Python explota al instanciar el LLM.
Causa raíz: el factory hace os.environ["X"] sin fallback. Es a propósito: si falta la credencial, mejor fallar rápido (en el constructor) que enviar la request y recibir un 401 confuso.
Corrección: cada vez que cambies LLM_PROVIDER, asegúrate de que la key correspondiente esté presente en .env.
Error 2. litellm.exceptions.AuthenticationError con Bedrock
Síntoma: corres con LLM_PROVIDER=bedrock y litellm responde AuthenticationError: Could not connect to AWS Bedrock.
Causa raíz: no tienes credenciales AWS válidas en el shell, o aws configure no se ha corrido.
Corrección: verifica primero que el CLI tiene credenciales activas:
aws sts get-caller-identity
Si esto falla, configura las credenciales antes de seguir.
Error 3. Ollama responde “connection refused”
Síntoma: con LLM_PROVIDER=ollama la corrida falla con httpcore.ConnectError: All connection attempts failed.
Causa raíz: el daemon de Ollama no está corriendo (ollama serve no fue ejecutado, o se detuvo).
Corrección:
ollama serve # déjalo corriendo en una terminal aparte
# en macOS también sirve abrir la app de Ollama desde el dock
Buenas prácticas
- Configuración por entorno, no por código. El factory lee
LLM_PROVIDERdel entorno. Esto te permite tener el mismo binario corriendo en dev contra Groq y en producción contra Bedrock sin un soloifen el dominio. Ref: 12-Factor App · Config, aplicado desde el Lab 1. - Mismo
expected_outputpara todos los proveedores. Distintos modelos tienen sesgos distintos: Claude tiende a ser verboso, Llama-3.2-3B improvisa formato, gpt-4o-mini se queda corto. Si quieres comparar calidad de forma justa, no cambies las tasks entre proveedores: el control va siempre enexpected_output. - Mide costo por corrida, no solo por token. Una corrida del crew gasta tokens en 3 agentes y en la coordinación interna que CrewAI hace por debajo. El número que importa para tu negocio es
costo total de una kickoff completa, nocosto por 1M tokens del modelo. Loggea ambos. Ref: el patrónlast_usagedel Lab 2 escalado alresultado.token_usagedel Crew (Lab 4).
Estado del proyecto al finalizar
agentic-ai-lab/
├── .venv/
├── .env ← MODIFICADO (LLM_PROVIDER + keys de los proveedores que probaste)
├── .gitignore
├── call_llm.py ← sin cambios
├── tools.py ← sin cambios
├── agent.py ← sin cambios
├── llm_factory.py ← NUEVO
├── crew_setup.py ← MODIFICADO (usa get_llm() del factory)
├── tasks.py ← sin cambios
├── main.py ← sin cambios
└── summary.md ← sin cambios
Checklist:
- Cambiar
LLM_PROVIDERen.envcorre el crew contra un backend distinto sin tocarcrew_setup.py. - Probaste al menos dos proveedores y comparaste sus outputs.
- Bedrock funciona con credenciales AWS estándar (sin api_key en
.env). - Ollama corre el crew con datos que no salen de tu máquina.
¿Qué viene en el Lab 6?
Hasta acá todo corre en tu laptop. Si quieres que el crew sirva tráfico real, persista logs, se autentique con IAM y escale sin que mantengas tu propia infra, necesitas llevarlo a la nube. En el Lab 6 vas a desplegar el sistema a Amazon Bedrock + AgentCore Runtime, el entorno serverless oficial de AWS para correr agentes. Vas a empaquetar la app, crear el IAM role del agente, exponer un endpoint y leer los logs de cada agent step en CloudWatch.
Referencias
Documentación oficial
- litellm · Providers: lista completa y syntax de modelos por proveedor.
- OpenAI · Models
- Anthropic · Models
- AWS Bedrock · Foundation Models
- Ollama · Library
Libros canónicos
- Gamma, E., Helm, R., Johnson, R. & Vlissides, J. Design Patterns: Elements of Reusable Object-Oriented Software (1994): origen del Factory pattern aplicado en este lab.
Specs y estándares
- 12-Factor App · Config: rationale para usar variables de entorno como switch de proveedor.
Repositorios y librerías
- BerriAI/litellm: el gateway que CrewAI usa por debajo. Su catálogo
model_prices_and_context_window.jsones referencia útil para coste por token. - boto3: SDK oficial de AWS para Python; litellm lo usa para hablar con Bedrock.