MÓDULO 17 · SERVERLESS AI · 25 MIN

La misma llamada en tres nubes

Las tres llamadas hacen exactamente lo mismo —mandar un prompt, recibir texto— y ninguna se parece a las otras. Lo que cambia no es el modelo: es quién define el formato del cuerpo, qué nombra el identificador y de dónde sale la credencial. Tres detalles pequeños que se pagan enteros el día que hay que portar código de una nube a otra.
01 — Las tres formas
El mismo prompt, escrito de tres maneras

AWS Bedrock — un cliente genérico de AWS, y el cuerpo en JSON crudo:

bedrock = boto3.client(service_name='bedrock-runtime', region_name='us-east-1')

body = json.dumps({
    "anthropic_version": "bedrock-2023-05-31",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": prompt}]
})

response = bedrock.invoke_model(modelId='anthropic.claude-...', body=body)
texto = json.loads(response['body'].read())['content'][0]['text']

Azure OpenAI — el SDK de OpenAI, con otra clase y un endpoint propio:

client = AzureOpenAI(api_key=..., api_version="2024-02-15-preview",
                    azure_endpoint="https://<recurso>.openai.azure.com/")

response = client.chat.completions.create(
    model=DEPLOYMENT_NAME,          # ojo: NO es el nombre del modelo
    messages=messages
)
texto = response.choices[0].message.content

Vertex AI — inicialización global con proyecto y región, y objetos propios:

vertexai.init(project=PROJECT_ID, location="us-central1")

model = GenerativeModel("gemini-...")
response = model.generate_content(prompt, generation_config={...})
texto = response.text
02 — Las tres trampas
Dónde se rompe al portar
NubeLa trampaCómo se manifiesta
BedrockEl cuerpo lo define el proveedor del modelo, no AWS: de ahí anthropic_versionCambiar de Claude a Llama exige reescribir el JSON entero, no solo el modelId
Azure OpenAImodel= es el nombre de tu deployment, no del modeloUn despliegue que funciona en desarrollo falla en producción: los nombres de deployment no coinciden
Vertex AIProyecto y región viven en un init() global, no en la llamadaCambiar de región es tocar la inicialización; un modelo puede no existir en tu región

La primera es la que más sorprende. Bedrock parece una API de AWS y en realidad es un sobre: por fuera es invoke_model, por dentro va el formato nativo del proveedor. Por eso el cuerpo lleva una versión con nombre de Anthropic dentro de una llamada de boto3. Es coherente —permite exponer modelos de terceros sin traducirlos— y significa que «cambiar de modelo en Bedrock» no es cambiar una cadena.

La segunda es la que más tiempo cuesta depurar, porque el error no dice lo que pasa: pides un deployment que no existe y recibes un mensaje que suena a modelo no encontrado. Que la clave del SDK se llame model y contenga otra cosa es una trampa de diseño heredada de mantener compatibilidad con el SDK de OpenAI.

// en Azure, model= no es el modelo: es el nombre que TÚ le pusiste al deployment
03 — La credencial
Clave estática o identidad de la nube

Las tres ofrecen las dos vías, y la diferencia es la misma que ya aparecía entre las dos puertas de los modelos de Google en el Módulo 8:

Clave estáticaIdentidad de la nube
AWSClaves de acceso en el entornoRol de IAM asumido por el recurso
Azureapi_keyAzure AD / Entra ID, con proveedor de token
GoogleAPI key (solo en la puerta de AI Studio)Cuenta de servicio o credenciales por defecto
Qué implicaUn secreto que rotar y que se filtra en un commitNada que guardar; permisos revocables al instante

La segunda columna es la que se usa en producción, y no por purismo: una credencial que no existe como cadena no se puede filtrar, y los permisos se retiran desde la consola sin desplegar nada. El coste es que el código deja de funcionar fuera de la nube — lo cual, en un servicio desplegado ahí, no es un problema.

Auditoría Tres cadenas del código de la guía llevan una fecha incrustada y ninguna se comenta: "anthropic_version": "bedrock-2023-05-31" en el cuerpo de Bedrock, api_version="2024-02-15-preview" en el cliente de Azure — nótese el preview — y los identificadores de modelo con su fecha de release (claude-3-sonnet-20240229-v1:0, gemini-1.5-pro-001). ¿Qué pasa cuando una versión de API en preview deja de estarlo, y sigue siendo esa la que debes pasar? Y una pregunta de método: ¿por qué la guía fija esas versiones a mano en vez de dejar que el SDK use la actual? Merece la pena entender qué se rompe al subirlas, porque es exactamente el tipo de cadena que nadie toca hasta que falla.
Para hacer
Escribir la misma función dos veces

Implementa preguntar(prompt) -> str contra dos de las tres nubes, con la misma firma y el mismo comportamiento. No hace falta que ambas funcionen: basta con escribirlas.

Lo que buscas es la lista de lo que no se puede unificar detrás de esa firma: el formato del cuerpo, el significado del identificador, dónde viven proyecto y región, cómo se pide la credencial. Esa lista es, literalmente, el coste de portar tu código el día que alguien proponga cambiar de proveedor.