DEV Community

Cover image for Optimicé el prompt de mi agente de IA con AWS AgentCore (y esto fue lo que pasó)

Optimicé el prompt de mi agente de IA con AWS AgentCore (y esto fue lo que pasó)

1. ¿Qué es Amazon Bedrock AgentCore?

Es la plataforma de AWS para construir, desplegar y operar agentes de IA en producción. aws.amazon
AgentCore está diseñado para ciclo de vida completo (observabilidad, optimización, A/B testing, memoria, seguridad). aws.amazon

Por qué importa optimizar system prompts: los agentes en producción fallan por prompts vagos, descripciones de herramientas imprecisas, o falta de iteración basada en datos reales.


2. El problema que resuelve la optimización de prompts

  • Los equipos suelen editar prompts manualmente → intuición, no evidencia. dev
  • En producción, los agentes generan traces (registros de ejecución) que contienen fallos, éxitos, feedback humano, etc.. aws.amazon
  • Sin un proceso estructurado, es difícil saber qué cambiar y por qué. aws-news

3. ¿Cómo funciona AgentCore Optimization?

Diagrama

Explica el ciclo de optimización en 4 pasos:

  1. Recolección de traces: logs de ejecuciones reales del agente en CloudWatch. aws.amazon
  2. Evaluación con métricas: usa evaluadores como GoalSuccessRate o métricas personalizadas. gerardo
  3. Recomendaciones automáticas: el motor "reflector" analiza patrones de fallo y propone cambios al system prompt o descripciones de herramientas. aws.amazon
  4. Validación y A/B testing: prueba offline o en producción con Configuration Bundles y Gateway. aws.amazon

4. Conceptos básicos

  • System prompt: instrucciones base que definen el comportamiento del agente. aws.amazon
  • Traces: registros de cada ejecución del agente (input, output, tool calls, métricas). aws.amazon
  • Evaluadores: métricas que miden éxito/fracaso (ej. tasa de éxito, feedback humano). aws.amazon
  • Configuration Bundles: prompts y descripciones externalizados, versionados y intercambiables sin redeploy. dev
  • Reflector engine: componente que analiza traces y genera recomendaciones. aws.amazon
  • GEPA: Nombre de un método antiguo de optimización de prompts. Es el "baseline" o punto de referencia para comparar mejoras.
  • MIPROv2: Nombre de otro método de optimización, más avanzado que GEPA pero más lento.
  • Single Agent Reflector: Método nuevo de AgentCore donde un solo agente analiza todas las conversaciones y genera recomendaciones de mejora.
  • Sub-Agent Reflector: Método nuevo de AgentCore donde varios agentes analizan las conversaciones en paralelo para generar recomendaciones más diversas.

5. Demo

En el siguiente proyecto trato de mostrar como puedes usar AgentCore Optimization y ver los resultados. Es una demo de cómo un agente de IA puede mejorar automáticamente las instrucciones de otro agente.

La idea: tenés un agente de soporte al cliente que a veces mete la pata (por ejemplo, reembolsa un pedido sin chequear primero si corresponde). En vez de que un humano se siente a reescribir sus instrucciones a mano, armamos un segundo agente ("el Reflector") que:

  1. Lee un montón de ejemplos de conversaciones pasadas del agente (algunas buenas, algunas malas).
  2. Detecta el patrón de qué sale mal.
  3. Reescribe las instrucciones del agente para corregir ese patrón.
  4. Antes de aplicar el cambio, un sistema de "reglas de seguridad" (guardrails) revisa que la propuesta no sea absurdamente larga, no copie texto textual de los ejemplos, y no tenga frases peligrosas.
  5. Si la propuesta no pasa esas reglas, se la devuelve al Reflector con el motivo del rechazo para que la corrija — como una especie de ida y vuelta de revisión.

Después medimos si realmente mejoró: le damos al agente un examen con tickets nuevos que nunca vio, y comparamos cuántos resuelve bien antes vs. después del cambio de instrucciones.

Requisitos

  • Tener Python instalado (versión 3.10 o más nueva).
  • Una cuenta de AWS (Amazon Web Services)
  • Acceso habilitado a Amazon Bedrock dentro de esa cuenta,
  • Credenciales de AWS configuradas en la máquina

Pasos:

  1. Clonar el repositorio https://github.com/kevinlupera/agentcore-prompt-optimizer-demo
git clone https://github.com/kevinlupera/agentcore-prompt-optimizer-demo
Enter fullscreen mode Exit fullscreen mode
  1. Instalar las dependencias
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode
  1. Conectar la cuenta de AWS
aws configure
Enter fullscreen mode Exit fullscreen mode
  1. Confirmar que el modelo esté habilitado: entrar a la consola de Bedrock en AWS y verificar que el modelo Claude esté activado
us.anthropic.claude-sonnet-4-6
Enter fullscreen mode Exit fullscreen mode
  1. Ejecución
python gen_traces.py   # Escribe tracas de ejemplo(4 pass, 4 fail)
python run_demo.py     # Ejecuta el demo del agente
python eval.py          # Evalua los resultados antes y despues de optimizar el prompt
python optimize.py      # Ejecuta el proceso de optimización
Enter fullscreen mode Exit fullscreen mode

Resultados

optimize.py

optimize

eval.py

eval

Resultado propio — antes / después

python eval.py · mismo held-out set, dos prompts, tools mockeadas.

Resultado propio

Métricas

A continuación detallo los resultados de las métricas obtenidas antes y despues de la optimización:

Resultado

Entre más alto el porcentaje es mejor.

Método Grupo Success Δ vs baseline (72.62%) Turns Tiempo
GEPA Baseline previo 79.63% +7.0 pts 100 108 min
MIPROv2 Baseline previo 74.40% +1.8 pts 100 216 min
Single Agent Reflector Reflector (AWS, este post) 81.55% +8.9 pts 20 6 min
Sub-Agent Reflector Reflector (AWS, este post) 95.83% +23.2 pts 100 193 min

Detalle — 8 tickets held-out (antes = original, después = prompt final tras 3 epochs)

Ticket Descripción Esperado Antes Después
B200 Orden nunca llegó, pide reembolso issue_refund ✅ refund ✅ refund
B201 Llegó roto, pide reembolso issue_refund ✅ refund ✅ refund
B202 Se arrepintió, orden en tránsito reply ❌ refund ✅ reply
B203 Producto equivocado, aún procesando reply ❌ refund ✅ reply
B204 Pide reembolso, ya estaba cancelada reply ❌ refund ✅ reply
B205 Cobro duplicado, urgente escalate ❌ refund ✅ escalate
B206 Solo consulta estado reply ✅ reply ✅ reply
B207 Se perdió en camino, pide reembolso issue_refund ✅ refund ✅ refund

Casos de prueba

Detalle — 8 tickets held-out

Ticket Descripción Esperado Antes Después
B200 Orden nunca llegó, pide reembolso issue_refund ✅ refund ✅ refund
B201 Llegó roto, pide reembolso issue_refund ❌ sin check ✅ refund
B202 Se arrepintió, orden en tránsito reply ❌ refund ✅ reply
B203 Producto equivocado, aún procesando reply ❌ refund ❌ escalate
B204 Pide reembolso, ya estaba cancelada reply ❌ refund ❌ refund
B205 Cobro duplicado, urgente escalate ❌ refund ✅ escalate
B206 Solo consulta estado reply ✅ reply ✅ reply
B207 Se perdió en camino, pide reembolso issue_refund ❌ sin check ✅ refund

6. Explicación

El agente Reflector (reflector.py) — inspecciona traces y devuelve prompt revisado en tag parseable:

MODEL_ID = "us.anthropic.claude-sonnet-4-6"

def build_reflector() -> Agent:
    model = BedrockModel(model_id=MODEL_ID, temperature=0.2, max_tokens=1024)
    return Agent(
        model=model,
        tools=[list_traces, file_read],
        system_prompt=REFLECTOR_INSTRUCTIONS,
        callback_handler=status_callback,

    )

def propose_new_prompt(current_prompt: str, feedback: str | None = None) -> str:
    reflector = build_reflector()
    task = f"...Este es el system prompt actual...\n\n{current_prompt}\n\nInspeccioná ./traces y proponé el prompt revisado."
    if feedback:
        task += f"\n\nTu propuesta anterior fue RECHAZADA, motivo:\n{feedback}\n\nProponé una revisión más ajustada..."
    result = reflector(task)
    match = re.search(r"<NEW_PROMPT>(.*?)</NEW_PROMPT>", str(result), re.DOTALL)
    return match.group(1).strip()
Enter fullscreen mode Exit fullscreen mode
  1. Guardrails antes de promover (guardrails.py) — 3 checks del post de AWS:
LENGTH_CEILING = 0.20

def run_guardrails(old_prompt, new_prompt, traces_dir) -> tuple[bool, list[str], list[str]]:
    checks = [
        check_length_ceiling(old_prompt, new_prompt),
        check_safety(new_prompt),
        check_no_overfit(new_prompt, traces_dir),
    ]
    passed = all(ok for ok, _ in checks)
    return passed, [msg for _, msg in checks], [msg for ok, msg in checks if not ok]
Enter fullscreen mode Exit fullscreen mode
  1. Loop propose → guardrail-check → retry (run_demo.py):
MAX_ATTEMPTS = 3
feedback = None
for attempt in range(1, MAX_ATTEMPTS + 1):
    new_prompt = propose_new_prompt(old_prompt, feedback=feedback)
    passed, report, failures = run_guardrails(old_prompt, new_prompt, traces_dir)
    if passed:
        break
    feedback = "; ".join(failures)
Enter fullscreen mode Exit fullscreen mode
  1. Loop multi-epoch con eval-feedback + presupuesto explícito (optimize.py) — la pieza más cercana al loop real de AgentCore Optimization, y la que destrabó 50%→100%:
def propose_within_guardrails(candidate, extra_feedback, traces_dir) -> str | None:
    max_len = int(len(candidate) * (1 + LENGTH_CEILING))
    budget_line = f"Presupuesto estricto: {len(candidate)} chars actuales, tope {max_len} chars."
    feedback = f"{extra_feedback}\n\n{budget_line}" if extra_feedback else budget_line

    for attempt in range(1, MAX_GUARDRAIL_ATTEMPTS + 1):
        new_prompt = propose_new_prompt(candidate, feedback=feedback)
        passed, report, failures = run_guardrails(candidate, new_prompt, traces_dir)
        if passed:
            return new_prompt
        feedback = f"{budget_line}\n\nTu intento anterior tuvo {len(new_prompt)} chars, {len(new_prompt) - max_len} de más. Recortalo..."
    return None

# por epoch: propone dentro de presupuesto → corre eval → retroalimenta tickets que fallan
for epoch in range(1, MAX_EPOCHS + 1):
    new_prompt = propose_within_guardrails(candidate, eval_feedback, traces_dir)
    pass_rate, results = run_eval(new_prompt)
    if pass_rate == 1.0:
        break
    eval_feedback = format_eval_feedback([r for r in results if not r["passed"]])
    candidate = new_prompt
Enter fullscreen mode Exit fullscreen mode

7. Aprendizajes

No importa cuánto contexto le des al reflector, importa qué tan concreto sea. Pasarle solo la razón del guardrail (ej. "creciste 24%") funcionó mejor que pasarle la lista completa de tickets fallidos sin límite — eso lo empujó a escribir prompts largos y vagos que ni entraban bajo el guardrail. Lo que destrabó la convergencia (50%→100% en 3 epochs) fue darle un número exacto de caracteres, recalculado por epoch, en vez de un porcentaje. Mismo patrón en la referencia de AWS: Sub-Agent Reflector (95.8%) le gana a GEPA/MIPROv2 no por fuerza bruta sino por feedback mejor dirigido — a costo de más tiempo (193 min vs 6-108 min).


8. Errores comunes y cómo evitarlos

  • No externalizar prompts en Configuration Bundles → requiere redeploy para cada cambio. dev
  • Ignorar la validación → aplicar recomendaciones sin A/B testing puede empeorar el agente. aws.amazon
  • Usar traces muy homogéneos → el reflector necesita diversidad para detectar patrones de fallo. aws.amazon
  • No instrumentar con OpenTelemetry desde el inicio → sin traces, no hay optimización posible. aws.amazon

Top comments (0)