Tabla de Contenidos
En el artículo del Optimization Loop de AgentCore dejé que AWS reescribiera el system prompt de mi agente DevOps. La recomendación fue buena, pero tuvo un efecto que en ese momento no medí: el prompt creció. El optimizador conservó todo lo que yo había escrito y le agregó dos bloques nuevos.
La documentación de Advanced Prompt Optimization lo reconoce: por defecto optimiza solo por calidad, sin ninguna restricción de longitud, y un prompt optimizado puede terminar más largo que el original. Más largo significa más tokens de entrada en cada llamada y, potencialmente, más tiempo hasta el primer token.
El 20 de octubre de 2026 AWS anunció una opción para eso, shortenPrompt, que le pide al optimizador un prompt más corto que el original y con un puntaje igual o mejor. Si no lo encuentra, te devuelve el tuyo.
Quería responder una pregunta concreta: ¿cuánto me ahorra acortar un prompt que ya funciona, y a partir de qué volumen vale la pena? Para eso usé el prompt real del clasificador de mi agente de noticias, las 205 clasificaciones que hizo en producción como referencia y tres modelos objetivo. El resultado no fue el que esperaba, y tampoco por las razones que esperaba.
📌 TL;DR — Lo que encontré
- En las seis optimizaciones (tres modelos, con y sin
shortenPrompt), el prompt que devolvió el servicio es idéntico al original, carácter por carácter.compressionRatio = 1.0en los tres modelos.- Un job reportó +45% de mejora (0.575 → 0.833) para ese prompt idéntico. La causa: 12 inferencias fallidas del lado original, con cero tokens, puntuadas como 0.
- Otro job terminó en
CompletedconSUCCESSaunque el optimizador falló en 684 de 689 llamadas. Solo lo vi en las métricas de error de CloudWatch.- Aun con el 30% de recorte del ejemplo del anuncio, a mi volumen (~267 llamadas al mes) el job tardaría entre 9 y 55 años en pagarse.
- El mismo prompt con la misma noticia mide 1,621 tokens en Haiku 5.5, 1,132 en Haiku 4.5 y 917 en Nova 2 Lite. El servicio lo cuenta como 600 en los tres.
Qué Es Advanced Prompt Optimization y Qué Agrega shortenPrompt
Advanced Prompt Optimization es el optimizador completo de Bedrock, distinto del OptimizePrompt simple. Le entregas un archivo JSONL con tus plantillas (variables con doble llave, {{variable}}), hasta 100 muestras de evaluación por plantilla y un método de evaluación: el juez por defecto, criterios en texto libre (steeringCriteria), un LLM como juez con tu rúbrica, o un Lambda propio. El servicio corre un ciclo de inferencia, evaluación y reescritura sobre cada modelo objetivo y te devuelve un prompt optimizado por modelo. Un job acepta hasta 10 plantillas y 5 modelos, y la documentación habla de 15 a 20 minutos para un prompt con pocas muestras y de varias horas para muchas. Mis jobs tardaron 14 y 29 minutos.
shortenPrompt se activa por plantilla, dentro del JSONL, no en la llamada a la API:
{
"version": "bedrock-2026-05-14",
"templateId": "news-classifier-shorten",
"promptTemplate": "...",
"optimizationConfig": { "shortenPrompt": true },
"customEvaluationMetricLabel": "clasificacion_vs_produccion",
"evaluationMetricLambdaArn": "arn:aws:lambda:us-east-1:<cuenta>:function:apo-news-classification-evaluator",
"evaluationSamples": [ "..." ]
}
La lógica de retorno es simple: el prompt acortado se devuelve solo si es más corto y puntúa al menos igual que el original. Si falla cualquiera de las dos condiciones, recibes tu prompt original con compressionRatio = 1.0. El ratio es optimizedTokenCount / originalTokenCount, medido sobre la plantilla y no sobre el prompt con las variables sustituidas.
Sobre el costo, la documentación dice que no hay un cargo propio del servicio: pagas los tokens que consume. La página de precios da la fórmula: unas 16 × N inferencias del modelo objetivo por plantilla, donde N es el número de muestras, más el optimizador (hoy Claude Sonnet 4.6) con 101 × (3700 + 0.35 × P) tokens de entrada, donde P son los tokens de tu plantilla. Los tokens de salida del optimizador no tienen fórmula.
El Experimento
El prompt: el clasificador de mi agente de noticias
Mi agente procesa el RSS de AWS tres veces al día. Desde finales de septiembre el modelo ya no calcula la relevancia: solo clasifica cada noticia en un tema (topic_tier) y un tipo de cambio (change_type), y una rúbrica con pesos editables calcula la nota de 0 a 10. Si la nota llega a 6 se genera un post; si llega a 7, la noticia entra al newsletter.
Elegí este prompt por tres razones. Tiene una respuesta objetiva, así que se puede evaluar sin un juez subjetivo. Corre todos los días, así que tiene un volumen real contra el cual calcular el ahorro. Y ya era compacto, unos 1,900 caracteres: si el shortening encuentra algo que recortar aquí, lo encontrará en casi cualquier prompt. Un fragmento:
topic_tier: el tema al que pertenece el servicio o la capacidad (elige el más específico):
• genai_agentes: Bedrock, IA generativa, agentes, MCP, Amazon Quick, AgentCore, SageMaker AI
• serverless_core: Lambda, Step Functions, API Gateway, EventBridge, DynamoDB
...
change_type: qué tipo de cambio anuncia la noticia (juzga el cambio, no el servicio):
• nueva_capacidad: una función o servicio que antes no existía
• mejora: una mejora incremental de algo que ya existía (límites, rendimiento, integraciones)
...
La referencia: lo que decidió producción
No etiqueté nada a mano. La referencia de cada noticia es la clasificación que hizo producción, guardada en DynamoDB: 205 noticias clasificadas entre el 30 de septiembre y el 22 de octubre de 2026. Partí el conjunto de forma determinística, por hash del ID: 60 noticias para el optimizador y 145 de holdout que nunca ve.
Con esta referencia no mido si el prompt acortado acierta más, sino si se comporta igual que el actual. Para un acortamiento me parece la pregunta correcta: busco un prompt más barato que no rompa nada, es decir, una prueba de regresión. La desventaja es que si producción se equivocaba, el optimizador aprende a repetir el error.
El evaluador: un Lambda determinístico
Advanced Prompt Optimization ofrece cuatro formas de evaluar, y descarté tres. El juez por defecto califica exactitud, completitud y Expression Quality, y este último criterio premia respuestas cortas, así que habría optimizado la brevedad de la salida en lugar de la clasificación. Los steeringCriteria son demasiado vagos para una tarea con respuesta exacta. Un LLM como juez agrega costo, porque el juez lee prompt, respuesta y referencia en cada evaluación, y suma su propio ruido a algo que se resuelve comparando dos valores.
Me quedé con un Lambda. El contrato que exige el servicio es simple: recibes {"preds": [...], "golds": [...]} y devuelves {"score": float, "scores": [...]}, más alto es mejor. Mi regla: si la salida no es un JSON válido con todas las claves y valores permitidos, la muestra vale 0; si lo es, suma 0.5 por acertar el tema y 0.5 por acertar el tipo de cambio.
def compute_score(preds, golds):
"""Contrato JSON obligatorio; 0.5 por topic_tier correcto y 0.5 por change_type correcto."""
scores = [score_one(p, g) for p, g in zip(preds, golds)]
return {"score": sum(scores) / len(scores) if scores else 0.0, "scores": scores}
El servicio lee el docstring como descripción de la métrica y revisa el código completo antes de usarlo. Esa revisión me costó el primer job; lo cuento en los gotchas.
La plantilla: qué puede tocar el optimizador y qué no
En producción el prompt va como system, la noticia como mensaje de usuario, y la salida usa Structured Outputs. Advanced Prompt Optimization recibe una sola plantilla de texto y no acepta structured outputs, así que el contrato JSON tiene que vivir dentro del prompt. Lo protegí con <advpo:exclude>: el optimizador puede reescribir las instrucciones de clasificación, pero no la noticia ni el formato de salida.
<advpo:exclude>Noticia a clasificar:
Título: {{title}}
Descripción: {{description}}
Responde ÚNICAMENTE con un objeto JSON, sin texto antes ni después, con exactamente estas claves:
change_type, topic_tier, topic, reason, keyPoints (lista de textos) y emojis (lista de textos).
En topic_tier y change_type usa solo las claves listadas arriba.</advpo:exclude>
En el mismo job puse dos copias idénticas de la plantilla, una optimizada solo por calidad (el comportamiento por defecto) y otra con shortenPrompt: true, para compararlas en las mismas condiciones.
Tres modelos y dos cuentas
Esta parte del diseño cambió sobre la marcha. Desde el 8 de octubre, mi agente consume Claude Haiku 5.5 por la API de Anthropic, no por Bedrock. Advanced Prompt Optimization solo optimiza modelos de Bedrock, y mi cuenta de trabajo no puede invocar Haiku 5.5 en Bedrock. La cuenta que sí puede no tenía enviado el formulario de casos de uso de Anthropic, así que ahí no corría Haiku 4.5.
Terminé corriendo un job por cuenta, con los mismos datos y el mismo evaluador: Claude Haiku 5.5 (el modelo de producción) en una, y Claude Haiku 4.5 (el de producción hasta el 8 de octubre) más Amazon Nova 2 Lite en la otra. Nova es el modelo que dejé en marzo porque no soportaba structured outputs; como Advanced Prompt Optimization trabaja con texto plano, aquí esa limitación no importa. Ese mismo formulario faltante terminó afectando también el job de Haiku 5.5, como explico en el Hallazgo 3.
Hipótesis, escritas antes de ver resultados
Seguí el mismo método de los artículos anteriores: antes de leer el resultado de los jobs escribí cada hipótesis con el criterio que la refutaría.
- H1 — El shortening encuentra algo que recortar. Al menos un modelo devuelve
compressionRatio < 0.9. Se refuta si los tres devuelven 1.0 o un ratio mayor a 0.9. - H2 — El prompt acortado se comporta igual en el holdout. La diferencia de score contra el original, en el mismo modelo, queda dentro del piso de ruido. Se refuta si cae por debajo de ese piso.
- H3 — A mi volumen, el ahorro no paga el job. Con ~267 llamadas al mes, el ahorro mensual no cubre el costo del job en menos de 12 meses en ningún modelo. Se refuta si algún modelo recupera el costo en un año o menos.
- H4 — Los prompts optimizados no son portables. El prompt optimizado para un modelo pierde más que el piso de ruido al correrlo en otro. Se refuta si rinden igual en los tres modelos.
📋 Desviaciones registradas: (1) el diseño original usaba solo Nova 2 Lite, porque Haiku 5.5 no estaba disponible en Bedrock en mi cuenta de trabajo; (2) pasé a tres modelos repartidos en dos cuentas; (3) el job corre Haiku 5.5 con su configuración por defecto, que piensa, distinta de la de producción (ver gotchas); (4) los dos primeros jobs fallaron por el validador de código del Lambda; (5) detuve un job con el evaluador viejo, y su ventana se cruza unos minutos con el job bueno de esa cuenta, lo que infla un poco los costos medidos ahí; (6) mi línea base del holdout corrió en paralelo con el job de Haiku 4.5.
Todo el código está en github.com/codecr/bedrock-prompt-shortening: scripts numerados del 01 al 07, el evaluador y el cleanup.
Línea Base: Cuánto Difiere el Prompt de Sí Mismo
Antes de mirar ningún prompt optimizado corrí el original sobre las 145 noticias del holdout, dos veces en cada modelo. La segunda corrida es importante porque el modelo no es determinístico: si dos variantes difieren menos de lo que el prompt original difiere de sí mismo, esa diferencia no significa nada. Haiku 5.5 corrió como en producción, sin thinking y con esfuerzo bajo.
| Modelo | Score vs producción | Contrato JSON | Coincide consigo mismo | Tokens in / out | TTFT mediana | Costo por 1,000 llamadas |
|---|---|---|---|---|---|---|
| Claude Haiku 5.5 | 0.848 | 100% | 133/145 (91.7%) | 1,621 / 334 | 1.11 s | $0.36 |
| Claude Haiku 4.5 | 0.840 | 100% | 128/145 (88.3%) | 1,132 / 284 | 0.66 s | $2.81 |
| Amazon Nova 2 Lite | 0.760 | 100% | 140/145 (96.6%) | 917 / 191 | 0.47 s | $0.83 |
Nova es el más estable y el que menos coincide con producción: repite su respuesta el 96.6% de las veces, pero ser consistente no lo hace más exacto. Haiku 5.5 no llega a 1.0 ni contra referencias que en su mayoría generó él mismo, porque en producción corre con system prompt separado y structured outputs, y cambiar la forma de llamar al modelo ya mueve el resultado. Y el piso de ruido es alto: el mismo prompt cambia la clasificación de entre 5 y 17 noticias de 145 entre una corrida y otra. Una mejora menor que eso no se distingue del azar.
Un dato de negocio: con la rúbrica activa, la clasificación de Haiku 5.5 cambia la decisión de generar un post en 10 de las 145 noticias respecto de lo que decidió producción. Ese margen de error ya existe hoy en mi pipeline, y no lo había medido.
🔢 ProTip #1: El mismo texto no mide lo mismo en todos los modelos. Mi prompt con la misma noticia son 1,621 tokens en Haiku 5.5 contra 1,132 en Haiku 4.5: un 43% más. Antes de calcular cuánto te ahorra recortar un prompt, mide sus tokens en el modelo donde va a correr. Y no uses el
originalTokenCountdel job para eso: el servicio contó mi plantilla como 600 tokens en los tres modelos, con un conteo propio que no es el del tokenizador que te cobra.
Hallazgo 1: Seis Optimizaciones, Cero Cambios
Este es el resultado completo de los dos jobs. «Idéntico» significa idéntico carácter por carácter al original, una vez quitadas las etiquetas <advpo:exclude>, que el servicio siempre elimina.
| Modelo | Plantilla | Score original → “optimizado” | compressionRatio | Inferencias fallidas (orig / opt) | ¿Cambió el prompt? |
|---|---|---|---|---|---|
| Haiku 5.5 | calidad | 0.808 → 0.850 | — | 0 / 0 | No |
| Haiku 5.5 | shorten | 0.825 → 0.825 | 1.0 | 0 / 0 | No |
| Haiku 4.5 | calidad | 0.575 → 0.833 | — | 12 / 0 | No |
| Haiku 4.5 | shorten | 0.625 → 0.625 | 1.0 | 13 / 13 | No |
| Nova 2 Lite | calidad | 0.708 → 0.708 | — | 1 / 1 | No |
| Nova 2 Lite | shorten | 0.708 → 0.708 | 1.0 | 0 / 0 | No |
H1 queda refutada: ningún modelo devolvió un ratio menor a 1.0. Pero de las seis filas, solo las dos de Nova son un resultado limpio.
En Nova 2 Lite el optimizador trabajó, el modelo respondió casi todas las inferencias y el servicio no encontró un prompt mejor ni uno más corto que puntuara igual. Para un prompt que ya era compacto, evaluado con un criterio estricto, es una respuesta razonable: no había nada que recortar sin perder calidad. Cuando devuelve el original, el servicio copia la medición del original en las métricas «optimizadas», y por eso las dos columnas son iguales hasta el último decimal.
Haiku 4.5 y Haiku 5.5 no son casos limpios, por dos razones distintas que el resultado del job no menciona.
Hallazgo 2: El +45% que No Existió
Volvamos a la tercera fila. Para Haiku 4.5, optimizando solo por calidad, el resumen del job reporta que el score subió de 0.575 a 0.833, un 45%, y el tiempo promedio hasta el primer token bajó de 1.12 s a 0.60 s. El prompt “optimizado” es idéntico al original.
Revisé el archivo de resultados muestra por muestra. Del lado original, 12 de las 60 inferencias volvieron vacías: respuesta en blanco, inputTokens: 0, outputTokens: 0, latencia cero. El evaluador recibió un texto vacío, que no es un JSON válido, y lo puntuó 0. Del lado «optimizado» no falló ninguna. La mejora sale completa de esas 12 llamadas fallidas.
Las métricas de Bedrock en CloudWatch muestran qué pasó: en la ventana del job, Haiku 4.5 registró 607 errores de servidor (InvocationServerErrors). Una parte puede ser mía: mi línea base del holdout corrió 230 llamadas contra el mismo modelo en paralelo, y mi cliente reintentaba los 5xx. Pero las 25 inferencias vacías del job son del job. La cuota no fue el problema: Haiku 4.5 tiene 10,000 solicitudes por minuto en esa cuenta.
En esa misma fila hay otro detalle. Aun excluyendo las 12 fallidas, el original saca 0.719 contra 0.833 para el mismo texto en el mismo job. Es el mismo piso de ruido de la línea base, ahora dentro del job: con 60 muestras y un modelo que coincide consigo mismo el 88% de las veces, dos mediciones del mismo prompt difieren por más de 10 puntos.
🚨 ProTip #2: No le creas al
averageScoredel resumen. Antes de aceptar un prompt optimizado, haz dos cosas que el servicio no hace por ti: compara el texto del prompt contra el original (en mis seis casos era idéntico), y cuenta endataset[]cuántas muestras tienenoutputTokens: 0. Una inferencia fallida entra al promedio como un 0.0 más, y en mi caso produjo una mejora de 45% sobre un prompt que no cambió. El script05_fetch_results.pydel repo hace las dos verificaciones.
Hallazgo 3: SUCCESS Sin Optimizador
El job de Haiku 5.5 terminó en Completed, con las dos entradas en SUCCESS, sin errores en el archivo de resultados y con un +5% de mejora en la plantilla de calidad (0.808 → 0.850) para, otra vez, un prompt idéntico al original. Ese +5% es del tamaño de lo que el mismo prompt varía consigo mismo: en mi línea base, Haiku 5.5 cambió la clasificación de 12 de 145 noticias entre dos corridas. Por sí solo no dice nada. El problema estaba en las métricas del optimizador.
Haiku 5.5 hizo 1,925 inferencias en la ventana del job. La fórmula de precios predice 16 × 60 × 2 = 1,920: el modelo objetivo trabajó exactamente lo esperado. Pero el optimizador, Claude Sonnet 4.6, registró 689 invocaciones y 684 errores de cliente (InvocationClientErrors), con apenas 7,756 tokens de entrada en total. En la otra cuenta, el mismo optimizador consumió 2.49 millones de tokens.
La causa la encontré invocando Sonnet 4.6 a mano en esa cuenta: “Model use case details have not been submitted for this account”. Es el mismo formulario de Anthropic que me impedía usar Haiku 4.5 ahí. El optimizador corre con mis credenciales, no con un rol del servicio, y mi cuenta no podía invocarlo. El job no lo detectó al crearse ni lo reportó en failureMessage o en las entradas del resultado. Evaluó el prompt original, no pudo generar candidatos y me lo devolvió con SUCCESS.
Este tipo de falla es difícil de detectar porque el resultado se ve normal. Si no hubiera revisado CloudWatch para calcular costos, habría escrito que Haiku 5.5 no encontró nada que recortar.
🔍 ProTip #3: Advanced Prompt Optimization no usa un rol de servicio: invoca los modelos objetivo, el optimizador y tu Lambda con las credenciales de quien crea el job (Forward Access Session). Antes de lanzar un job, verifica que tu cuenta pueda invocar Claude Sonnet 4.6 con una llamada de prueba. El servicio valida al crear el job que puedas invocar los modelos objetivo (“No inference API is accessible for model”), pero no valida el optimizador. Y después de cada job, revisa
InvocationClientErrorsdeus.anthropic.claude-sonnet-4-6en las métricas de Bedrock de CloudWatch.
Hallazgo 4: ¿Habría Valido la Pena?
Ningún prompt cambió, así que no hay ahorro medido. Aun así, la pregunta original se puede responder con los costos reales de los jobs, suponiendo que el shortening hubiera logrado lo del ejemplo del anuncio: compressionRatio = 0.7, un 30% menos de tokens en la plantilla.
Según CloudWatch, los jobs consumieron:
| Modelo | Rol en el job | Invocaciones | Tokens in / out | Costo |
|---|---|---|---|---|
| Claude Sonnet 4.6 | Optimizador (4 pares) | 384 | 2,488,824 / 262,585 | $12.55 |
| Claude Haiku 4.5 | Objetivo | 3,396 | 3,152,146 / 766,911 | $7.69 |
| Amazon Nova 2 Lite | Objetivo | 2,811 | 2,673,178 / 553,897 | $2.41 |
| Claude Haiku 5.5 | Objetivo | 1,925 | 3,107,401 / 1,021,435 | $0.90 |
| Claude Sonnet 4.6 | Optimizador fallido (2 pares) | 689 | 7,756 / 2,733 | $0.07 |
Total: $23.61, más alrededor de $1.40 de la validación en el holdout. Las cifras de Haiku 4.5 y Nova incluyen unos minutos del job que detuve, así que un job limpio sale algo más barato. El optimizador es la parte más cara: unos $3.14 por cada par plantilla-modelo.
Con esos datos calculé el costo de optimizar una plantilla para un modelo y lo que ahorraría al mes a mi volumen real (205 noticias en 23 días, unas 267 llamadas al mes), con el 30% de recorte sobre los 600 tokens de la plantilla:
| Modelo | Costo del job (1 plantilla) | Ahorro al mes | Se paga en | Llamadas al mes para pagarlo en un mes |
|---|---|---|---|---|
| Claude Haiku 5.5 | $3.48 | $0.0053 | 55 años | 175,955 |
| Claude Haiku 4.5 | $5.83 | $0.0529 | 9 años | 29,453 |
| Amazon Nova 2 Lite | $3.93 | $0.0159 | 21 años | 66,168 |
H3 se confirma con mucho margen. La tabla muestra además que acortar rinde más en el modelo más caro: Haiku 4.5 cuesta 10 veces más por token de entrada que Haiku 5.5 en Bedrock. En el modelo de producción, que es el más barato, acortar importa menos. Mi tabla subestima un poco el ahorro en Haiku 5.5, porque calcula sobre los 600 tokens que cuenta el servicio y no sobre los que cobra su tokenizador; aun corrigiendo eso, el orden de magnitud no cambia.
Esto no significa que el shortening no sirva, sino que la cuenta depende más del volumen que del porcentaje de recorte. Con unas 30,000 llamadas al mes en Haiku 4.5, o unas 176,000 en Haiku 5.5, el job se paga en un mes. Con 267, no se paga.
Sobre la latencia, el otro beneficio que menciona el anuncio, no tengo nada que medir: sin un prompt más corto no hay diferencia de TTFT. La mejora que muestra el resumen del job (1.12 s → 0.60 s en Haiku 4.5) son dos mediciones del mismo texto, tomadas mientras el modelo devolvía errores de servidor; no se las atribuyo al prompt.
Lo que la Documentación No Te Dice
Además de los hallazgos anteriores, estos son los gotchas que me costaron un job o un buen rato.
🧪 ProTip #4: En
modelConfigurations, el campoadditionalModelRequestFieldssolo aceptatopK. Intenté pasarthinking: disabledyoutput_config.effort: lowpara Haiku 5.5, como lo corro en producción, y el job se rechazó al crearse: “contains unsupported keys: [output_config, thinking]. Supported keys: [topK]”. El optimizador ajusta el prompt para Haiku 5.5 con su configuración por defecto, que usa thinking: en una muestra de 12 noticias eso fue un 57% más de tokens de salida y 0.75 s más de latencia que la configuración de producción, con el mismo score. En la práctica optimizas para una configuración distinta de la que vas a correr.
🛑 ProTip #5: El servicio revisa el código de tu Lambda evaluador antes de usarlo, y lo rechaza si encuentra algo que considera peligroso. Mi primer job falló con “Metric code validation failed: Uses potentially dangerous builtin: compile()” por un
re.compile(): el análisis no distingue el método deredel builtincompile. Usare.match(patron, texto)directamente. El job tampoco falla al crearse: falla unos tres minutos después, con unfailureMessagegenérico que te manda al archivo de resultados en S3, donde está el motivo real por entrada.
⏱️ ProTip #6: Los estados terminales de un job son
Completed,Failed,StoppedyPartiallyCompleted. El loop de espera del sample oficial solo considera los tres primeros, así que con un resultado parcial se queda esperando para siempre.
También encontré algunas diferencias entre la guía de usuario y la API real:
- La operación de borrado es
BatchDeleteAdvancedPromptOptimizationJob, en singular (la guía usa el plural), y devuelveadvancedPromptOptimizationJobs[]yerrors[]. - La respuesta de
ListAdvancedPromptOptimizationJobsusa la clavejobSummaries, no la que muestra el ejemplo de la guía. - El parámetro de cifrado se llama
encryptionKeyArn, noencryptionConfig. - La página de evaluación pide una resource-based policy para que
bedrock.amazonaws.cominvoque tu Lambda; la de prerrequisitos dice que el servicio lo invoca con tus credenciales. Yo configuré las dos cosas.
Veredicto de las Hipótesis
| Hipótesis | Resultado |
|---|---|
| H1 — El shortening encuentra algo que recortar | Refutada. compressionRatio = 1.0 en los tres modelos. El único resultado limpio, Nova 2 Lite, devolvió el original. |
| H2 — El prompt acortado se comporta igual en el holdout | No se pudo probar. No hubo prompt acortado. |
| H3 — A mi volumen, el ahorro no paga el job | Confirmada. Ni siquiera con un 30% de recorte hipotético: entre 9 y 55 años. |
| H4 — Los prompts optimizados no son portables | No se pudo probar. Los seis prompts “optimizados” son el original. |
Dos de las cuatro hipótesis quedaron sin probar. La matriz de portabilidad que tenía preparada no tenía sentido con seis prompts iguales, así que no la corrí.
Límites del Experimento
- Una plantilla, un dominio. Mi prompt ya era compacto y la tarea tiene respuesta exacta. Con un prompt largo y redundante, el shortening probablemente sí recortaría. No corrí ese control positivo, así que no puedo separar «el servicio no recorta» de «mi prompt no tenía nada que recortar». El caso de Nova sugiere lo segundo.
- La referencia es producción, no la verdad. Mido regresión, no exactitud.
- 60 muestras y un solo job por modelo. No sé cuánto varía el optimizador entre corridas del mismo job.
- Haiku 5.5 se optimizó con una configuración distinta a la de producción, y su job no tuvo optimizador funcional. Ese resultado no cuenta.
- Haiku 4.5 tuvo errores de servidor durante el job, y mi propia línea base corría en paralelo contra el mismo modelo.
- Producción no corre en Bedrock sino en la API de Anthropic, así que aunque el prompt hubiera cambiado, llevarlo a producción habría sido otro experimento.
- La decisión humana no sirve como segunda referencia: de las noticias del dataset con post, 133 fueron aprobados y solo 3 rechazados.
Conclusión
Volvamos a la pregunta del inicio: ¿cuánto me ahorra acortar un prompt que ya funciona?
En mi caso, nada, por dos razones. Mi prompt ya era compacto, y el único resultado limpio del experimento devolvió el original. Y aun si lo hubiera recortado un 30%, a 267 llamadas al mes el ahorro sería de centavos por año contra un job de varios dólares. Acortar prompts es una optimización de volumen, y conviene hacer la cuenta antes de lanzar el job: tokens ahorrados por llamada, por llamadas al mes, por precio por token, contra unos $3 a $6 por plantilla y modelo.
Lo que más me sirvió del ejercicio fue ver cómo reporta el servicio. En un día obtuve un +45% de mejora que salió de inferencias fallidas contadas como cero, y un SUCCESS de un job cuyo optimizador nunca pudo ejecutarse. Ninguno de los dos casos aparece en el resultado del job. Los encontré comparando el texto del prompt devuelto y revisando las métricas de error de CloudWatch.
Me pasó algo parecido con el A/B test del Optimization Loop: el número que reporta un optimizador hay que verificarlo por fuera antes de tomar una decisión con él.
🚀 ProTip Final: Antes de optimizar un prompt por costo, calcula el punto de equilibrio con tu volumen real y el precio del modelo donde corre. Si no se paga en un año, no tiene sentido correrlo por costo; córrelo solo si tienes un problema de calidad que resolver. Y si lo corres, revisa tres cosas antes de aceptar el resultado: si el texto cambió, cuántas inferencias volvieron vacías y si el optimizador registró errores en CloudWatch.
¿Ya mediste cuántas llamadas al mes hacen tus prompts de producción? ¿Tu volumen está en la escala donde esta cuenta sí importa? Si alguien está viendo ahorros reales con el shortening, me interesa mucho saber con qué volumen — los comentarios están abiertos.
¡Nos vemos en el próximo artículo! 🚀
Recursos Oficiales 📚
- Anuncio: Advanced Prompt Optimization now supports prompt shortening (20 de octubre de 2026)
- Shorten prompts
- How Advanced Prompt Optimization works
- Prepare your input dataset
- Define evaluation methods (incluye el contrato del Lambda evaluador)
- Selective optimization:
<advpo:optimize>y<advpo:exclude> - Create and manage optimization jobs
- View and interpret results
- Prerequisites (permisos y Forward Access Session)
- Quotas
- API Reference: CreateAdvancedPromptOptimizationJob
- Amazon Bedrock pricing (fórmula del Advanced Prompt Optimizer)
- Sample oficial: aws-samples/amazon-bedrock-samples, advanced-prompt-optimization
Preguntas frecuentes
¿Qué hace la opción shortenPrompt de Bedrock Advanced Prompt Optimization?
Le pide al optimizador un prompt más corto que el original y que puntúe al menos igual en tu evaluación. Se activa por plantilla en el archivo JSONL de entrada con optimizationConfig.shortenPrompt: true, no en la llamada a la API. Si el optimizador no encuentra un prompt que cumpla las dos condiciones, devuelve el original con compressionRatio 1.0. El ratio es optimizedTokenCount / originalTokenCount, medido sobre la plantilla. Fue anunciada el 20 de octubre de 2026.
¿Cuánto cuesta correr un job de Advanced Prompt Optimization?
No hay un cargo propio del servicio: pagas los tokens del modelo objetivo, del optimizador (Claude Sonnet 4.6) y las invocaciones de tu Lambda evaluador. En mi experimento, con 60 muestras por plantilla, el modelo objetivo hizo unas 16 inferencias por muestra, como dice la fórmula de la página de precios, y el optimizador consumió unos 2.5 millones de tokens de entrada para cuatro pares plantilla-modelo. Los jobs costaron en total unos 23.6 dólares medidos en CloudWatch.
¿Por qué un job de Advanced Prompt Optimization puede reportar una mejora sin cambiar el prompt?
Porque el resumen compara dos mediciones distintas, y las inferencias fallidas del modelo objetivo se puntúan como 0.0. En mi job de Claude Haiku 4.5, 12 de las 60 inferencias del prompt original volvieron vacías, con cero tokens, y el averageScore pasó de 0.575 a 0.833 para un prompt optimizado idéntico al original. Revisa en dataset[] cuántas muestras tienen outputTokens igual a 0 y compara el texto del prompt antes de creerle al resumen.
¿Qué permisos necesita Advanced Prompt Optimization?
No usa un rol de servicio. El job invoca los modelos objetivo, el optimizador y tu Lambda con las credenciales de quien lo crea (Forward Access Session). Tu cuenta tiene que poder invocar Claude Sonnet 4.6, que es el optimizador, incluido haber enviado el formulario de casos de uso de Anthropic. En una cuenta donde eso faltaba, 684 de 689 llamadas del optimizador fallaron y el job terminó igual en Completed con SUCCESS.
Inicia la conversación