Un Solo Parámetro de IA Me Costó $54 al Mes
Pensé que mi migración a Cloud Run había sido perfecta, hasta que un solo parámetro de IA —temperature en 0.7 en lugar de 0— causó un 30% de llamadas fallidas a la API y me costó $54 al mes en tokens desperdiciados.
Confié en Claude para ayudarme a migrar de AWS Lambda a Google Cloud Run. La migración salió perfecta: los servicios se desplegaron, los flujos de trabajo se ejecutaron y los usuarios estaban contentos. Luego revisé nuestras facturas de API y casi me caigo de la silla.
*Esta es la parte 3 de mi serie de ingeniería de DIALØGUE. Si te perdiste las anteriores: [Parte 1: Introducción a DIALØGUE] y [Parte 2: De la Publicidad a la Ingeniería] sientan las bases.*
Esta es la historia de lo que pasa cuando dejas que la IA escriba código de producción sin ser explícito sobre las restricciones de ese entorno. Spoiler: "hacer que funcione" y "hacer que esté listo para producción" son peticiones muy distintas.
La Migración Que Salió Demasiado Bien
Después de lidiar con AWS Lambda durante meses (cold starts, límites de capas, todo el paquete), decidí migrar todo a Google Cloud Run. Como desarrollador pragmático (léase: perezoso), reclute a Claude como mi compañero de programación.
"Ayúdame a migrar estas funciones Lambda a Cloud Run," le dije. "Aquí está el código existente."
Claude lo entregó de maravilla. Dockerfiles limpios, configuraciones de servicio correctas, Cloud Workflows funcionando. La migración tomó un solo día en lugar de las semanas que esperaba. ¡Estaba encantado!
Todo se desplegó sin problemas. Los servicios arrancaron rápido. Los usuarios creaban podcasts sin inconvenientes. Éxito, ¿no?
Entonces noté algo raro en nuestros logs:
```
[ERROR] Segment generation failed: Unexpected token in JSON
[RETRY] Attempting segment generation again...
[SUCCESS] Segment generated successfully
```
Alrededor del 30% de nuestras llamadas a la IA fallaban en el primer intento pero tenían éxito en el reintento. No era el fin del mundo: ¡mi lógica de reintentos funcionaba! Los usuarios no notaban ningún problema. Pero vaya, esas llamadas extra a la API se iban acumulando.
La Investigación: ¿La Culpa es de la Migración?
Mi primer pensamiento fue que algo salió mal durante la migración. ¿Quizás el nuevo entorno de Cloud Run era diferente? ¿Problemas de red en el contenedor? Pasé horas comparando las configuraciones de AWS y GCP.
Todo parecía idéntico. Mismos prompts, misma lógica de reintentos, mismo manejo de errores. Entonces, ¿por qué de repente estábamos recibiendo respuestas JSON malformadas?
Luego empecé a comparar el código real. Esto es lo que encontré:
Versión AWS Lambda (funcionando bien durante meses):
```python
response = anthropic.messages.create(
model="claude-3-7-sonnet-20250219",
temperature=0, # Deterministic for JSON
response_format=\{"type": "json_object"\}, # JSON mode
system="You are a JSON generation assistant. Output only valid JSON.",
messages=[\{"role": "user", "content": prompt\}]
)
```
Versión GCP Cloud Run (migración de Claude):
```python
response = anthropic.messages.create(
model="claude-3-7-sonnet-20250219",
temperature=0.7, # <-- ¿Espera, qué?
messages=[\{"role": "user", "content": prompt\}]
)
```
Ahí estaba. Temperature 0.7.
"¡Pero es un valor predeterminado razonable!" podrías decir. Y tendrías razón. Para escritura creativa, exploración, lluvia de ideas: 0.7 tiene todo el sentido. ¿Pero para generar JSON estructurado? Es un desastre.
La Prueba del Delito: JSON Creativo
Después de añadir un logging detallado para capturar las respuestas reales de la IA, encontré exactamente lo que estaba pasando. Esto es lo que Claude devolvía a temperature 0.7:
```
Here's the podcast segment you requested:
\{
"title": "The Rise of AI Podcasting",
"content": "Welcome back, listeners! Today we're diving into something really fascinating...",
"duration": 120
\}
I hope this segment captures what you were looking for!
```
¿Ves el problema? Claude estaba siendo creativo con el formato de respuesta. A veces solo JSON, a veces JSON con comentarios útiles, a veces JSON envuelto en bloques de código markdown. A temperature 0.7, improvisaba como un músico de jazz cuando yo necesitaba un metrónomo.
El Punto Ciego de la Programación en Pareja con IA
El caso es este: cuando trabajas con IA como compañero de programación, es increíblemente buena para hacer que el código funcione, pero no necesariamente optimiza para las preocupaciones de producción a menos que se lo pidas explícitamente.
Cuando dije "migra esta función Lambda a Cloud Run", Claude se centró en los requisitos de la migración:
- ✅ Que funcione en Cloud Run
- ✅ Manejar los mismos inputs y outputs
- ✅ Mantener la misma funcionalidad
- ❌ Optimizar para eficiencia en producción
Claude eligió temperature 0.7 porque es un "valor predeterminado razonable" para aplicaciones de IA. ¡Y lo es! Para la mayoría de los casos de uso, 0.7 da un buen equilibrio entre creatividad y consistencia.
Pero esto es lo que aprendí: **La IA no conoce tus restricciones específicas de producción a menos que se las cuentes.**
Mi código original de AWS usaba temperature 0 Y el modo JSON porque había aprendido (a las malas) que la generación de JSON necesita tanto salidas deterministas como formato explícito. Pero durante la migración, nunca dije explícitamente "esto es para la generación de datos estructurados" ni "mantén todas las optimizaciones específicas para JSON."
Así que Claude escribió código perfectamente funcional con valores predeterminados sensatos. El problema no era la IA, eran mis requisitos incompletos.
La Corrección: Ser Específico con la IA
Una vez que identifiqué el problema, volví a Claude con mejores requisitos:
"Ayúdame a corregir este código. Es para la generación de JSON en producción. Necesito un 100% de fiabilidad, cero creatividad. Usa temperature 0 y cualquier otra optimización para datos estructurados."
Claude sugirió de inmediato:
```python
response = anthropic.messages.create(
model="claude-3-5-sonnet",
temperature=0, # Deterministic outputs
response_format=\{"type": "json_object"\}, # JSON mode
system="You are a JSON generation assistant. Output only valid JSON.",
messages=[\{"role": "user", "content": prompt\}]
)
```
¡Espera, Claude eliminó el modo JSON que teníamos! (¡Esto es lo que pasa cuando no mencionas explícitamente cada requisito de producción durante la migración!)
La tasa de éxito saltó del 70% al 99.9%. ¿El 0.1% restante? Timeouts de red. No se le puede echar la culpa a Claude por esos.
¿La diferencia? Esta vez fui explícito sobre las restricciones de producción. No pedí solo una migración, pedí código optimizado para producción y enfocado en la fiabilidad.
El Coste Real de los Valores "Razonables" Predeterminados
Déjame desglosar lo que este ajuste de temperature "razonable" nos costó realmente:
- **Generaciones diarias de podcasts**: ~200
- **Tasa de fallos**: 30% que requieren reintentos
- **Llamadas extra a la API por día**: 60 llamadas fallidas que necesitan reintento
- **Desperdicio mensual**: ~1.800 llamadas innecesarias a la API
- **Precio de Claude 3.7 Sonnet**: $3 input + $15 output por millón de tokens
- **Tokens promedio por llamada**: ~2.000 input + 1.500 output
- **Coste por reintento**: ~$0.03 por intento fallido
- **Exceso mensual**: ~$54 en llamadas innecesarias a la API
Pero el coste real no fueron solo los $54 al mes. Cada reintento añadía de 3 a 5 segundos al tiempo de generación. Los usuarios esperaban más, mis instancias de Cloud Run arrancaban con mayor frecuencia y yo quemaba cuota más rápido.
¿Lo más irónico? Todo esto sucedió porque confié en la IA para tomar decisiones de producción sin darle el contexto de producción. Un caso clásico de "funciona" versus "funciona de manera eficiente."
Lo Que Aprendí Sobre la Programación en Pareja con IA
1. Sé Explícito Sobre los Requisitos de Producción
"Hacer que funcione" te da código funcional. "Hacer que funcione eficientemente en producción con estas restricciones" te da código optimizado. La IA es excelente para resolver el problema que describes, no el problema que tienes en mente.
2. La IA Usa Valores Predeterminados "Razonables", No "Óptimos"
Temperature 0.7 es razonable para la mayoría de las aplicaciones de IA. Pero los sistemas de producción a menudo necesitan optimizaciones específicas como temperature 0 Y el modo JSON. La IA no las preservará a menos que las menciones explícitamente.
3. La Revisión de Código También Aplica al Código Generado por IA
El hecho de que la IA lo haya escrito no significa que esté listo para producción. Debería haberlo detectado durante la revisión del código, pero estaba tan centrado en si la migración funcionaba que no audité los parámetros.
4. El Contexto Importa Más de lo que Crees
Mi código original de AWS tenía temperature 0 Y el modo JSON por buenas razones, aprendidas a través de una experiencia dolorosa. Durante la migración, ese contexto se perdió porque no lo mencioné explícitamente. Ahora documento el "por qué" detrás de cada parámetro y característica.
Mi Nuevo Flujo de Trabajo de Programación en Pareja con IA
Ahora cuando trabajo con IA en código de producción, soy mucho más explícito sobre las restricciones:
**Antes:**
"Migra esta función Lambda a Cloud Run"
**Ahora:**
"Migra esta función Lambda a Cloud Run. Esto es para la generación de JSON en producción: prioriza la fiabilidad sobre la creatividad. Usa temperature 0, el modo JSON si está disponible, y cualquier otra optimización para la salida de datos estructurados."
Aquí está la configuración optimizada para producción que Claude me ayudó a construir:
```python
def get_ai_json_response(prompt: str) -> dict:
"""Production-optimized JSON generation with AI"""
response = anthropic.messages.create(
model="claude-sonnet-4-20250514",
temperature=0, # Zero creativity for structured data
response_format=\{"type": "json_object"\}, # Force JSON mode
system="You are a JSON generation assistant. Output only valid JSON.",
messages=[\{
"role": "user",
"content": f"{prompt\}\n\nRespond with valid JSON only."
}]
)
# Explicit error handling for production
try:
return json.loads(response.content[0].text)
except json.JSONDecodeError as e:
logger.error(f"JSON parse failed: \{e\}")
logger.error(f"Raw response: {response.content[0].text}")
raise
```
¿La diferencia? Le di a la IA el contexto que necesitaba para optimizar mi caso de uso específico.
Los Resultados
Un 30% menos en costes de API, un 40% más rápido en generación. Todo a partir de una conversación en la que fui realmente específico sobre lo que significaba "listo para producción."
¿Lo gracioso? Incluso nuestra generación de diálogo "creativa" usa temperature 0. Resulta que determinista no significa aburrido: significa fiable. Las conversaciones siguen sonando naturales porque los prompts y la investigación de contenido aportan la variedad, no las fluctuaciones aleatorias de temperature.
Resulta que la programación en pareja con IA funciona estupendamente cuando recuerdas que sigue siendo programación: la precisión en los requisitos te da precisión en los resultados.
¿Alguna vez has tenido un asistente de IA que tomara una decisión "razonable" que resultó ser completamente equivocada para tu caso de uso? Me encantaría escuchar tus anécdotas: sospecho que a todos nos han mordido los valores predeterminados sensatos en algún momento :)
Un abrazo,
Chandler
¿Quieres crear tus propios podcasts de IA con JSON válido garantizado? Prueba DIALØGUE: ¡2 créditos gratis para empezar! :P
Parte 3 de la Serie de Ingeniería de DIALØGUE. Todavía aprendiendo que "hacer que funcione" y "hacer que funcione eficientemente" son peticiones completamente distintas. Sigue más aventuras de programación en pareja con IA en chandlernguyen.com.
**Próxima entrega**: Llegando en unos 7 días: "De 3 Minutos a 500ms: El Bug de Registro que No Tenía Ningún Sentido"





