Optimización de prompts para agentes de IA (sin romper producción)

Optimiza prompts de forma segura: versionado, tests de regresión, budgets de coste/latencia y rollouts. Incluye ejemplos en Python + JS.
En esta página
  1. Problema (el “cambio pequeño” que te cuesta una semana)
  2. Por qué esto falla en producción
  3. Diagrama: pipeline seguro de prompts
  4. Código real: versiona prompts como código (Python + JS)
  5. Fallo real (con números)
  6. Trade-offs
  7. Cuándo NO optimizar prompts
  8. Checklist (copy-paste)
  9. Config segura por defecto (YAML)
  10. Implementar en OnceOnly (opcional)
  11. FAQ (3–5)
  12. Páginas relacionadas (3–6 links)

Problema (el “cambio pequeño” que te cuesta una semana)

Tocas un prompt porque el agente suena raro.

En dev parece bien.

En producción:

  • tool calls/run suben poco a poco (nadie mira)
  • la latencia se duplica con carga
  • el agente empieza a ignorar stop conditions
  • un edge case raro se vuelve un incidente diario

Optimizar prompts es ingeniería, no copywriting. Si lo tratas como “edito texto hasta que suene mejor”, vas a shippear regresiones.

Por qué esto falla en producción

En prod, un prompt está pegado a:

  • schemas de tools (renombras un campo y el modelo se pierde)
  • budgets (inflación de tokens = loops caros)
  • stop reasons (sin querer, incentivas “un intento más”)
  • variación externa (search cambia, APIs flaky, rate limits)

La parte incómoda: no puedes optimizar prompts de forma segura sin un harness. No tiene que ser fancy. Tiene que ser consistente.

Diagrama: pipeline seguro de prompts

Código real: versiona prompts como código (Python + JS)

Mínimo viable:

  • cada prompt tiene una prompt_id estable (hash o versión)
  • cada run loguea prompt_id
  • rollback = un switch de config
PYTHON
import hashlib
from dataclasses import dataclass
from typing import Any, Dict


def prompt_id(text: str) -> str:
    return hashlib.sha256(text.encode("utf-8")).hexdigest()[:12]


@dataclass(frozen=True)
class Prompt:
    name: str
    version: str
    text: str

    @property
    def id(self) -> str:
        return f"{self.name}:{self.version}:{prompt_id(self.text)}"


class Logger:
    def event(self, name: str, fields: Dict[str, Any]) -> None: ...


def build_system_prompt(p: Prompt) -> str:
    return (
        "You are a production agent. You must follow tool policies and budgets.\n"
        "Always stop with a stop_reason.\n\n"
        f"[prompt_id={p.id}]\n"
        + p.text.strip()
    )


def run_agent(task: str, *, prompt: Prompt, logger: Logger, budgets: Dict[str, Any]) -> Dict[str, Any]:
    build_system_prompt(prompt)
    logger.event("agent_start", {"prompt_id": prompt.id, "budget": budgets})
    return {"output": "ok", "prompt_id": prompt.id, "stop_reason": "finish"}


PROMPTS = {
    "support:v12": Prompt("support", "v12", "Answer using KB. If unsure, ask a clarifying question."),
    "support:v13": Prompt("support", "v13", "Answer using KB. Cite tool results. If unsure, ask a clarifying question."),
}

ACTIVE_PROMPT = PROMPTS["support:v13"]
JAVASCRIPT
import crypto from "node:crypto";

export function promptId(text) {
  return crypto.createHash("sha256").update(text, "utf8").digest("hex").slice(0, 12);
}

export function makePrompt({ name, version, text }) {
  const id = `${name}:${version}:${promptId(text)}`;
  return { name, version, text, id };
}

export function buildSystemPrompt(prompt) {
  return [
    "You are a production agent. You must follow tool policies and budgets.",
    "Always stop with a stop_reason.",
    "",
    "[prompt_id=" + prompt.id + "]",
    prompt.text.trim(),
  ].join("\n");
}

export function runAgent(task, { prompt, logger, budgets }) {
  buildSystemPrompt(prompt);
  logger.event("agent_start", { prompt_id: prompt.id, budget: budgets });
  return { output: "ok", prompt_id: prompt.id, stop_reason: "finish" };
}

const PROMPTS = {
  "support:v12": makePrompt({ name: "support", version: "v12", text: "Answer using KB. If unsure, ask a clarifying question." }),
  "support:v13": makePrompt({ name: "support", version: "v13", text: "Answer using KB. Cite tool results. If unsure, ask a clarifying question." }),
};

const ACTIVE_PROMPT = PROMPTS["support:v13"];

Fallo real (con números)

“Mejoramos” un prompt de soporte añadiendo una instrucción larga de “sé exhaustivo”.

Nada crasheó. Pero el modelo hizo lo que pedimos: se volvió exhaustivo.

Impacto en 36h:

  • p95 tokens/run: 7.5k → 14.2k
  • avg tool calls/run: 4 → 11
  • spend: +$620
  • on-call: ~2h para demostrar que era el prompt

Arreglo:

  1. capear budgets (steps/tool calls/tokens)
  2. invariantes en golden tasks: max tool calls + max tokens por run
  3. hacer “exhaustivo” condicional (solo si falta un tool result)

Trade-offs

  • Mejor calidad suele costar más. Si no lo mides, lo pagas.
  • Prompts cortos son rápidos pero a veces inseguros.
  • Contratos explícitos son feos y sobrevivibles.

Cuándo NO optimizar prompts

No intentes “optimizar” para tapar:

  • budgets inexistentes (/es/governance/budget-controls)
  • validación de tools (/es/tools/input-validation)
  • logging (/es/observability-monitoring/agent-logging)
  • tests (/es/testing-evaluation/unit-testing-agents)

Si el agente es inestable, los cambios de prompt solo mueven el problema.

Checklist (copy-paste)

  • [ ] prompt_id estable en cada run
  • [ ] Golden tasks (10–50) del tráfico real
  • [ ] Invariantes: stop_reason, bound de tool_calls, bound de tokens
  • [ ] Canary rollout + rollback switch
  • [ ] Monitor: spend/run, tool_calls/run, latency/run
  • [ ] 1 golden task por incidente

Config segura por defecto (YAML)

YAML
prompts:
  active: "support:v13"
  rollback: "support:v12"
  require_prompt_id: true
testing:
  golden_tasks:
    - id: "kb_lookup"
      expect_stop_reason: "finish"
      max_tool_calls: 6
      max_tokens: 9000
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
observability:
  log_prompt_id: true
  alert_on_token_spike: true

Implementar en OnceOnly (opcional)

Implementar en OnceOnly
Asegura cambios de prompt con budgets + stop reasons + logging.
Usar en OnceOnly
# onceonly-python: budgets + safe rollout guardrails
import os
from onceonly import OnceOnly

client = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"])
agent_id = "support-bot"

# Set budgets/limits before you ship prompt changes
client.gov.upsert_policy({
    "agent_id": agent_id,
    "max_actions_per_hour": 200,
    "max_spend_usd_per_day": 50.0,
    "max_calls_per_tool": {"kb.search": 6},
    "allowed_tools": ["kb.search", "send_email"],
})

# After rollout, watch for spend/tool spikes
m = client.gov.agent_metrics(agent_id, period="day")
print("actions=", m.total_actions, "spend_usd=", m.total_spend_usd)

FAQ (3–5)

¿Debería A/B testear prompts en producción?
Solo si puedes hacer rollback rápido y monitorizas spend/run y tool_calls/run. Si no, es un incidente controlado.
¿Cuántas golden tasks necesito?
Empieza con 10–20 tareas del tráfico real. Añade una por incidente. Llegarás a 50 de forma natural.
¿Qué debo comprobar en tests de prompt?
Stop reasons, número de tool calls, paradas por budget y constraints simples. No el texto exacto.
¿Un prompt puede reemplazar guardrails?
No. El prompt cambia la probabilidad. Los guardrails cambian lo posible.
⏱️ 4 min de lecturaActualizado Mar, 2026Dificultad: ★★☆
Integrado: control en producciónOnceOnly
Guardrails para agentes con tool-calling
Lleva este patrón a producción con gobernanza:
  • Presupuestos (pasos / topes de gasto)
  • Permisos de herramientas (allowlist / blocklist)
  • Kill switch y parada por incidente
  • Idempotencia y dedupe
  • Audit logs y trazabilidad
Mención integrada: OnceOnly es una capa de control para sistemas de agentes en producción.
Autor

Esta documentación está curada y mantenida por ingenieros que despliegan agentes de IA en producción.

El contenido es asistido por IA, con responsabilidad editorial humana sobre la exactitud, la claridad y la relevancia en producción.

Los patrones y las recomendaciones se basan en post-mortems, modos de fallo e incidentes operativos en sistemas desplegados, incluido durante el desarrollo y la operación de infraestructura de gobernanza para agentes en OnceOnly.