CCDV-F · Selección y optimización de modelos
Haiku, Sonnet u Opus con evidencia, y migrar sin romper
Un clasificador que rutea cientos de miles de tickets por mes corre en Opus desde el lanzamiento y es la línea más grande de la factura. Otro equipo cambió solo el ID del modelo y ahora cada pedido devuelve 400. Elegir y cambiar de modelo son decisiones de ingeniería: se toman con datos y se prueban antes de publicar.
Elegir con evidencia
El compromiso entre calidad, latencia y costo (quality/latency/cost tradeoff) se resuelve por tarea, no por empresa:
| Familia | Cuándo conviene |
|---|---|
| Haiku | Alto volumen y tareas acotadas: clasificar, rutear, extraer campos, subagentes simples. El más rápido y barato |
| Sonnet | El punto medio: la mayoría de las aplicaciones, agentes y código de complejidad normal |
| Opus | Razonamiento difícil, tareas agénticas largas, problemas donde el error cuesta caro |
La regla: empezá por el modelo más chico que podría alcanzar, corré tu set de evaluación (eval set) con casos etiquetados y subí de familia solo si hay una brecha medida. Si Haiku queda dentro del margen acordado, el ahorro en costo y latencia es directo. El modelo grande “por las dudas” cuesta más y responde más lento sin ganancia demostrada.
Antes de cambiar de familia, mirá las otras perillas: bajar el nivel de esfuerzo en el mismo modelo, el modo rápido si el problema es la velocidad de salida, o la Message Batches API si el trabajo puede esperar.
Cuando el modelo nuevo rompe algo
Un cambio que rompe (breaking change) entre versiones aparece de dos formas: un error 400 invalid_request_error apenas cambiás el ID, o un comportamiento distinto con el mismo prompt. Los más comunes al pasar a los modelos actuales:
- Prellenado del asistente (assistant prefill): terminar el pedido con un mensaje del asistente que empieza la respuesta (por ejemplo, una llave
{para forzar JSON). Los modelos nuevos lo rechazan: “la conversación tiene que terminar con un mensaje del usuario”. Para JSON, el reemplazo es la salida estructurada. - Parámetros de muestreo:
temperature,top_pytop_kdevuelven error. Se sacan y el comportamiento se guía con el prompt. - Pensamiento con
budget_tokens: se reemplaza por pensamiento adaptativo y nivel de esfuerzo. - Otras opciones que algunos modelos dejaron de aceptar, como forzar una herramienta con
tool_choiceo desactivar el pensamiento condisabled. - Cambios sin error: nuevos
stop_reasonque hay que manejar (refusal,model_context_window_exceeded), otro tokenizador que cuenta más tokens para el mismo texto, y niveles de esfuerzo con otros valores por defecto.
Ante un 400, leé el mensaje: dice qué parámetro sobra. Reintentar no sirve, porque el pedido es inválido. Y cambiar a otra familia tampoco: las versiones nuevas de todas las familias comparten esos cambios.
Migrar con método
- Leé la guía de migración del modelo de destino.
- Ajustá el código: sacá lo que ya no se acepta y reemplazalo por su equivalente.
- Corré el set de evaluación y compará calidad, latencia y
usagecontra el modelo actual. - Publicá en forma gradual, con el ID anterior listo para volver atrás.
Ciclo de vida de los modelos
Los modelos pasan por activo, legado (legacy), obsoleto (deprecated, con fecha de retiro y reemplazo recomendado) y retirado. Después del retiro de modelos (model retirement), los pedidos a ese ID fallan. Anthropic avisa con anticipación, así que la migración se planifica, no se improvisa el día del corte.
Las trampas típicas
- Usar el modelo más caro para todo sin haber probado otro.
- Reintentar con backoff un 400 que aparece al cambiar el ID.
- Quedarse para siempre en el modelo viejo en lugar de adaptar el código.
- Cambiar de familia esperando que acepte lo que la nueva versión rechaza.
- Publicar la migración sin correr el set de evaluación.
En el examen
Si el escenario habla de costo o latencia en una tarea simple y nadie probó otro modelo, la respuesta es correr el set existente con uno más chico. Si habla de un 400 después de cambiar el ID, buscá la opción que reemplaza la función que ya no existe (prefill por salida estructurada, budget_tokens por esfuerzo) y vuelve a correr la evaluación.
Pregunta rápida
Una pregunta del simulacro sobre este dominio. Cuenta para tu progreso.
A healthcare scheduling start-up extracts appointment details from patient emails as JSON. To make the model start its answer with JSON, the code has always ended each request with a short assistant message containing a single opening brace, then concatenated that brace with the returned text before parsing.
The team changed only the model ID to move from an older Sonnet model to the newest one. In staging, every extraction request now fails immediately with HTTP 400 and an invalid_request_error whose message says the conversation must end with a user message.
A developer suggests wrapping the call in retries, since the old model ID still works and the error might be a rollout issue. Another wants to move to the Opus family.
The release is planned for next week, and the team already has an eval set of 300 emails.
What is the best way to complete the migration?