# Kill switch de gasto API para agentes LLM: detén el coste antes del proveedor

> Para frenar el gasto de un agente LLM, reserva el coste máximo antes de cada llamada de pago y bloquea cuando el gasto confirmado más las reservas no deje margen. Si falta el recibo de uso, conserva la reserva y concilia antes de reanudar.

- URL: https://blog.laozhang.ai/es/posts/llm-agent-api-spend-kill-switch
- Published: 2026-06-14
- Updated: 2026-10-07
- Author: LaoZhang AI Team (https://blog.laozhang.ai/es/about)
- Topic: Guías de API
- Tags: Agentes LLM, Control de costes API, Presupuestos, AI Gateway

---
Para detener el gasto descontrolado de un agente LLM, **bloquea la siguiente llamada de pago antes de enviarla al proveedor**. La aplicación debe comprobar y reservar su coste máximo en una sola operación: gasto confirmado + reservas pendientes + nueva reserva ≤ presupuesto. Si no cabe, devuelve una parada que el agente no pueda convertir en otro reintento, otro subagente o un cambio de clave.

El bloqueo protege las llamadas futuras. Las ya enviadas pueden seguir generando costes. Por eso, si un stream se interrumpe o no llega el recibo de uso, conserva su reserva y deja la tarea pendiente de conciliación. Volver a empezar con un identificador nuevo no debe devolver el presupuesto consumido.

Los límites duros del proveedor también son útiles. La [guía actual de OpenAI](https://developers.openai.com/api/docs/guides/spend-limits) permite activarlos para organizaciones y proyectos, aunque su aplicación no es instantánea. Combina ese respaldo con un control propio cuando necesites limitar una tarea, repartir presupuesto entre subagentes o cubrir varias rutas de pago.

## Qué tiene que controlar el freno de gasto

Un *kill switch* es el componente que puede rechazar una solicitud antes de iniciar otro trabajo facturable. Colócalo donde se autoriza el envío, con una identidad presupuestaria resuelta por la aplicación. Si el agente dispone de una ruta directa al proveedor que evita ese componente, el control está incompleto.

Incluye el planificador, los evaluadores, los subagentes y las herramientas que llaman modelos o servicios de pago. Incluye también los reintentos automáticos del SDK y las rutas alternativas del proxy: una llamada lógica puede convertirse en varios intentos facturables. Puedes reservar cada intento por separado o un máximo para una secuencia realmente acotada; no basta con contabilizar la primera solicitud del agente.

Mantén las claves, los importes autorizados, la identidad del equipo y las tarifas fuera del contenido que decide el modelo. Un argumento generado como `budget_id: "otro-equipo"` o `estimated_cost: 0` no autoriza ese gasto. La aplicación autentica al llamador, identifica el presupuesto padre y calcula la reserva para la ruta que va a ejecutar.

| Control | Qué limita | Qué falta para contener el gasto |
| --- | --- | --- |
| Máximo de iteraciones | Pasos o turnos según el entorno | Los costes y las llamadas ocultas dentro de cada paso |
| Máximo de salida | La salida permitida en una llamada | La entrada, otros conceptos de cobro y las llamadas sucesivas |
| Límite de solicitudes o tokens por minuto | El ritmo de uso | El importe acumulado durante la tarea |
| Alerta monetaria | La notificación al alcanzar un umbral | Un rechazo efectivo antes de seguir gastando |
| Reserva monetaria previa | La admisión de otra llamada dentro del presupuesto | Una estimación completa y un registro compartido que sobreviva a fallos |

Un límite diario puede contener una tarea que se descontrola hoy; uno mensual controla el gasto acumulado del equipo. Aplica ambos si esa es tu política, comprobando y reservando todos los límites pertinentes juntos. No permitas que la reserva diaria quede aprobada si la mensual se rechaza. Si el registro compartido no está disponible, detén las admisiones; un saldo local nuevo no sustituye ese estado.

[Databricks describe su uso de presupuestos diarios y mensuales](https://www.databricks.com/es/blog/how-databricks-manages-its-own-coding-agent-spend-unity-ai-gateway-budgets) y distingue la confirmación humana de un aumento diario de las excepciones temporales aprobadas. Esa decisión de una persona bajo una política no equivale a autorizar al modelo a elevar su propio límite. Los importes de su relato son ilustrativos y no acreditan su gasto interno real ni una garantía de conciliación instantánea.

## Calcula una reserva que cubra la llamada completa

La reserva debe ser una cota superior defendible para la solicitud que vas a enviar. No uses el coste medio de las últimas llamadas ni una predicción del modelo como si fueran un máximo.

Para texto, parte de una entrada contada o acotada por código de confianza y de una salida máxima que la ruta realmente respete. Añade los conceptos facturables que correspondan: lectura y escritura de caché, razonamiento, imágenes, audio, búsquedas u otras herramientas de pago. Mantén las unidades, la moneda, la versión de tarifa y el modelo resuelto junto a la reserva. Un cambio de ruta exige volver a calcularla.

Por ejemplo, supongamos **tarifas inventadas**, solo para hacer la cuenta: 2 USD por millón de tokens de entrada y 10 USD por millón de salida. Con un máximo de 1.600 tokens de entrada y 600 de salida, sin otros cargos:

- Entrada: 1.600 × 2 / 1.000.000 = 0,0032 USD.
- Salida: 600 × 10 / 1.000.000 = 0,0060 USD.
- Reserva: 0,0092 USD, o 9.200 microUSD.

Si el presupuesto restante es 0,0080 USD, rechaza la llamada antes del envío. Si no conoces la tarifa, el máximo de entrada o un cargo relevante, rechaza por `missing_cost_bound`; no sustituyas el dato desconocido por cero. En producción conviene trabajar con unidades monetarias enteras y redondear las estimaciones hacia arriba.

El contador de tokens debe corresponder al modelo y al contenido enviados. Contar caracteres no garantiza ese máximo. Y una caché puede reducir el precio sin volver gratuitas todas las entradas: la [documentación de Anthropic](https://platform.claude.com/docs/en/api/rate-limits) distingue `input_tokens`, tokens de lectura de caché y tokens de escritura. Un token excluido de cierto límite de ritmo no queda por ello excluido de la facturación.

## Reserva, envía y concilia sin abrir una carrera

Guarda el límite del periodo, el gasto confirmado y las reservas de llamadas en curso en un registro compartido. **La comprobación y el aumento de la reserva son una sola operación atómica.** Leer el saldo con un `GET` y escribirlo después con un `SET` permite que varios trabajadores gasten el mismo margen.

Imagina un presupuesto de 0,025 USD y cuatro solicitudes que necesitan 0,0092 USD cada una. Si todas leen primero el mismo saldo, todas pueden concluir que caben. Una reserva atómica admite solo dos mientras permanezcan pendientes: 0,0184 USD reservados. La tercera se bloquea aunque todavía no haya llegado ningún recibo de uso.

![Reserva del coste máximo antes de enviar la llamada y conciliación posterior en un registro compartido.](https://blog.laozhang.ai/posts/es/llm-agent-api-spend-kill-switch/img/reserve-call-reconcile.webp)

Una transacción de base de datos o un script Lua en Redis puede implementar esa decisión. [Redis garantiza la ejecución atómica de sus scripts](https://redis.io/docs/latest/develop/programmability/eval-intro/), pero eso no crea una transacción con la llamada HTTP al proveedor, no garantiza la persistencia del registro y no prueba la reversión de escrituras previas ante cualquier error del script. Valida los datos antes de modificar el saldo y define la recuperación del almacenamiento.

Cada reserva necesita una identidad estable de solicitud, asociada al presupuesto, periodo, ruta y contenido autorizado. Si llega otra vez el mismo identificador, recupera su estado; no envíes otra llamada por defecto. Si llega con otro contenido, rechaza el conflicto. Cuando un recibo válido confirma el coste, mueve ese importe al gasto confirmado y libera únicamente el sobrante. Conciliar dos veces el mismo recibo no debe cobrar ni liberar dos veces.

| Estado de la solicitud | Tratamiento de su reserva | Próxima acción permitida |
| --- | --- | --- |
| Rechazada antes de admitirla | No se crea | Entregar resultado parcial o pedir una decisión autorizada |
| Reservada y pendiente de envío | Se conserva | Enviar una vez; liberar si se acredita que no se envió |
| Enviada, con uso aún pendiente | Se conserva | Esperar o consultar un recibo mediante el conciliador |
| Resultado de cobro desconocido | Se conserva; bloquear si no puede mantenerse una cota fiable | Conciliar antes de repetir o reanudar |
| Coste confirmado | Se carga el coste real y se libera el sobrante | Continuar solo dentro del margen restante |
| Coste superior a la reserva | Se registra todo el coste real y se congela el presupuesto | Investigar la estimación y autorizar la recuperación |

Un timeout, una cancelación solicitada o un error del proveedor no demuestran por sí solos que el coste sea cero. Libera una reserva completa cuando tengas evidencia fiable de que no se envió o de que no se cobró. Si el cobro real supera la cota, registra la verdad y detén nuevas admisiones: la estimación ha fallado. No puedes presentar después ese caso como una factura que nunca superó el límite.

Asocia la conciliación al periodo original. Una respuesta que llega después de medianoche no debe descargar el coste en un presupuesto nuevo y borrar el consumo anterior. Tampoco hagas caducar silenciosamente una reserva de una llamada cuyo cobro sigue pendiente.

## Un ejemplo ejecutable con proveedor falso

El siguiente programa usa solo la biblioteca estándar de Python. Puedes guardarlo como `presupuesto_demo.py` y ejecutarlo con `python3 presupuesto_demo.py`. La política y la ruta son constantes de confianza de la demostración; el proveedor falso devuelve un importe inventado. No hay claves, red, SDK ni facturas reales.

La clase protege las reservas entre hilos del **mismo proceso** mediante `Lock`. Marca la solicitud en curso antes de ejecutar el proveedor, evita repetir un identificador y congela nuevas llamadas cuando falta el uso. Conserva el importe real aunque supere la reserva.

```python
from concurrent.futures import ThreadPoolExecutor
from threading import Lock

# Hipótesis: microUSD; 1 USD = 1_000_000 microUSD.
# Tarifas inventadas para el ejemplo: 2 y 10 USD por millón de tokens.
POLICY = {"scope": "equipo-demo", "period": "2026-10",
          "cap": 25_000, "input_max": 1_600, "output_max": 600,
          "input_rate": 2, "output_rate": 10}
UPPER = (POLICY["input_max"] * POLICY["input_rate"]
         + POLICY["output_max"] * POLICY["output_rate"])
BINDING = (POLICY["scope"], POLICY["period"], "ruta-demo", "payload-v1")

class Stop(Exception):
    pass

class Ledger:
    def __init__(self, cap):
        self.cap, self.actual, self.held = cap, 0, 0
        self.rows, self.frozen, self.lock = {}, None, Lock()

    def admit(self, rid, binding, upper):
        with self.lock:
            if rid in self.rows:
                if self.rows[rid]["binding"] != binding:
                    raise Stop("request_id_conflict")
                raise Stop("duplicate_request")
            if self.frozen:
                raise Stop(self.frozen)
            if not isinstance(upper, int) or upper <= 0:
                raise Stop("missing_cost_bound")
            if self.actual + self.held + upper > self.cap:
                raise Stop("over_budget")
            self.rows[rid] = {"binding": binding, "upper": upper,
                              "state": "inflight", "cost": None}
            self.held += upper

    def unknown(self, rid):
        with self.lock:
            row = self.rows[rid]
            if row["state"] == "inflight":
                row["state"] = "unknown"
                if self.frozen is None:
                    self.frozen = "usage_pending"

    def settle(self, rid, cost):
        with self.lock:
            row = self.rows[rid]
            if not isinstance(cost, int) or cost < 0:
                raise Stop("invalid_receipt")
            if row["state"] == "settled":
                if row["cost"] != cost:
                    self.frozen = "receipt_conflict"
                    raise Stop(self.frozen)
                return "settled"
            self.held -= row["upper"]
            self.actual += cost
            row.update(state="settled", cost=cost)
            if cost > row["upper"]:
                self.frozen = "cost_overrun"
            elif self.frozen == "usage_pending" and not any(
                r["state"] == "unknown" for r in self.rows.values()
            ):
                self.frozen = None
            return self.frozen or "settled"

def guarded(ledger, rid, provider):
    try:
        ledger.admit(rid, BINDING, UPPER)
    except Stop as error:
        return {"status": str(error), "retryable": False}
    try:
        cost = provider()  # Solo un proveedor falso local en esta demostración.
        status = ledger.settle(rid, cost)
        return {"status": status, "retryable": False}
    except Exception:
        ledger.unknown(rid)
        return {"status": "usage_pending", "retryable": False}

calls = []
def fake_ok():
    calls.append("called")
    return 3_000

low = Ledger(8_000)
assert guarded(low, "no-cabe", fake_ok)["status"] == "over_budget"
assert calls == []

normal = Ledger(POLICY["cap"])
assert guarded(normal, "a", fake_ok)["status"] == "settled"
assert guarded(normal, "a", fake_ok)["status"] == "duplicate_request"
normal.settle("a", 3_000)  # Recibo repetido: no cobra dos veces.
assert (len(calls), normal.actual, normal.held) == (1, 3_000, 0)
try:
    normal.admit("a", ("otro-payload",), UPPER)
    raise AssertionError("Debía rechazar la identidad reutilizada")
except Stop as error:
    assert str(error) == "request_id_conflict"

parallel = Ledger(POLICY["cap"])
def attempt(i):
    try:
        parallel.admit(str(i), BINDING, UPPER)
        return True
    except Stop:
        return False
with ThreadPoolExecutor(max_workers=4) as pool:
    admitted = list(pool.map(attempt, range(4)))
assert sum(admitted) == 2 and parallel.held == 18_400

def fake_timeout():
    calls.append("uncertain")
    raise TimeoutError("Sin recibo de uso")
pending = Ledger(POLICY["cap"])
assert guarded(pending, "b", fake_timeout)["status"] == "usage_pending"
count = len(calls)
assert guarded(pending, "c", fake_ok)["status"] == "usage_pending"
assert len(calls) == count and pending.held == UPPER
pending.settle("b", 4_000)  # Conciliador de confianza, recibo simulado.
assert pending.actual == 4_000 and pending.held == 0

excess = Ledger(POLICY["cap"])
assert guarded(excess, "d", lambda: 30_000)["status"] == "cost_overrun"
assert excess.actual == 30_000 and excess.frozen == "cost_overrun"
assert guarded(excess, "e", fake_ok)["status"] == "cost_overrun"
print("OK: bloqueo, duplicados, reservas paralelas, incertidumbre y exceso")
```

Ejecutamos este programa localmente. Con una reserva de 9.200 microUSD y un límite de 8.000, el contador del proveedor falso quedó en cero. Cuatro reservas simultáneas sobre 25.000 microUSD admitieron dos y retuvieron 18.400. Repetir una solicitud conciliada no volvió a ejecutar el proveedor; repetir su recibo no duplicó el cargo. El timeout conservó la reserva y bloqueó la siguiente llamada. Un coste simulado de 30.000 microUSD quedó registrado y congeló nuevas admisiones.

![Prueba sintética de bloqueo antes del envío, reserva mantenida ante uso desconocido y congelación por exceso](https://blog.laozhang.ai/posts/es/llm-agent-api-spend-kill-switch/img/no-provider-call-test.webp)

Estas comprobaciones validan esas ramas del programa. **No acreditan una factura máxima, un almacén duradero ni coordinación entre procesos.** Al reiniciarlo se pierde su registro en memoria; no lo uses como control de producción sin sustituir esa parte. El ejemplo tiene una ruta y una huella de contenido fijas: una integración real debe vincular la solicitud al contenido normalizado, versión de tarifa y presupuesto autenticado. Su `settle` representa un conciliador de confianza, no una herramienta que el modelo pueda invocar con un importe elegido.

Antes de sustituir el proveedor falso, resuelve también la separación entre la reserva y el envío. Persiste un estado previo al envío, realiza la transición a «enviado» una sola vez y recupera los casos de caída en ese intervalo. Si puedes demostrar que una reserva no llegó a enviarse, libérala mediante una operación idempotente. Si no puedes demostrarlo, conserva el estado incierto. Un registro presupuestario y la idempotencia del receptor son controles distintos.

## Qué ofrecen hoy OpenAI, Anthropic y las pasarelas

Comprueba el alcance y el momento de contabilización de cada producto. Un campo llamado «presupuesto» puede avisar, rechazar futuras solicitudes o detener una sesión después de consumir el umbral; esos efectos no son intercambiables.

| Producto y control documentado | Qué puede detener | Condición que cambia la decisión |
| --- | --- | --- |
| [OpenAI: límite duro de organización o proyecto](https://developers.openai.com/api/docs/guides/spend-limits) | Solicitudes afectadas al alcanzar el gasto registrado | Debe estar activado **Enforce a hard limit**; la aplicación no es instantánea y puede producir un pequeño exceso |
| [Anthropic: límite del nivel de servicio o límite fijado por el usuario](https://platform.claude.com/docs/en/api/rate-limits) | Uso de la organización sujeto a ese límite | Los errores difieren según el límite alcanzado; no todos son un 429 transitorio |
| [Cloudflare AI Gateway: reglas de gasto](https://developers.cloudflare.com/ai-gateway/features/spend-limits/) | Solicitudes que atraviesan la pasarela y superan una regla aplicable | El coste se registra después de completar la solicitud y hay consistencia eventual |
| [LiteLLM Proxy: presupuestos globales, de equipo, miembro, usuario o clave](https://docs.litellm.ai/docs/proxy/users) | El tráfico sujeto al presupuesto configurado | El alcance, la ventana y la versión importan; esa documentación no acredita una reserva atómica estricta |
| [LiteLLM: presupuesto por sesión de agente](https://docs.litellm.ai/docs/a2a_iteration_budgets) | La siguiente llamada una vez contabilizado el consumo de la sesión | Se acumula tras la respuesta; el identificador de traza y la caducidad del contador no sustituyen el presupuesto padre |

### OpenAI sí permite un límite duro; una alerta sigue siendo una alerta

La [guía actual de límites de gasto de OpenAI](https://developers.openai.com/api/docs/guides/spend-limits) permite activar **Enforce a hard limit** en la organización o en un proyecto. El primero se aplica al tráfico de todos sus proyectos; el segundo, al tráfico facturado al proyecto. Una alerta envía una notificación y mantiene el tráfico.

Al alcanzar un límite duro, las solicitudes afectadas reciben 429 con `organization_spend_limit_exceeded` o `project_spend_limit_exceeded`. La guía advierte que el estado tarda en propagarse y el gasto registrado puede superar ligeramente el importe configurado. El límite mensual de uso aprobado por OpenAI es otro control distinto.

Por tanto, utiliza el límite duro como respaldo de cuenta o proyecto. El control propio sigue siendo necesario para una tarea con presupuesto menor, varios proveedores o reservas de llamadas pendientes. Un 429 por ese código de gasto no se resuelve haciendo más intentos sobre el mismo presupuesto agotado.

### Anthropic distingue el límite impuesto y el que configura el usuario

Según la [documentación de límites de Anthropic](https://platform.claude.com/docs/en/api/rate-limits), alcanzar el techo mensual del nivel de servicio puede devolver 429 `rate_limit_error`, sin `retry-after`, con `enforced_spend_limit_reached` en los detalles de Messages. Un límite de gasto configurado por el usuario, inferior al techo del nivel, devuelve 400 `invalid_request_error` en el caso documentado.

Clasifica el error por su cuerpo, producto y condición; no deduzcas «reintentar» solo del estado HTTP. Los límites de espacios de trabajo de Claude Code tienen un comportamiento documentado aparte, y la facturación mediante AWS también exige comprobar su ruta. Una regla escrita para la API directa no debe aplicarse a todos esos casos sin distinguirlos.

### Cloudflare y LiteLLM necesitan conocer su alcance real

[Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/features/spend-limits/) comprueba las reglas aplicables antes de enviar la solicitud y puede bloquear con 429. Sin embargo, registra el coste después de completarla, utiliza un cálculo de mejor esfuerzo y advierte sobre la consistencia eventual y los excesos en ráfagas concurrentes. La regla puede frenar las siguientes solicitudes sin reservar el máximo de todas las que ya están en curso.

Una dimensión de usuario tampoco es una frontera de confianza si el propio agente elige su valor. Resuelve esa identidad en la aplicación. Si una regla provoca un cambio a un modelo más barato, la nueva ruta sigue siendo de pago y debe caber en el presupuesto global.

En [LiteLLM Proxy](https://docs.litellm.ai/docs/proxy/users), revisa qué presupuesto se aplica a tu clave, equipo y miembro, y cuándo se reinicia. La documentación señala un cambio desde v1.95 en las claves de equipo: deja de aplicarles el presupuesto personal del propietario interno como antes; un presupuesto por miembro del equipo cumple otra función. Un reinicio del contador tampoco reduce una factura ya generada.

Los [presupuestos de iteraciones y sesiones de LiteLLM](https://docs.litellm.ai/docs/a2a_iteration_budgets) contabilizan el coste después de las llamadas y comprueban el acumulado antes de la siguiente; sus contadores tienen un TTL predeterminado de una hora. No interpretes una traza nueva o la caducidad como autorización para gastar otra vez. Conserva un presupuesto padre duradero. La guía presenta indicaciones diferentes sobre dónde configurar algunos controles; confirma la ubicación en tu versión antes de copiar una configuración como si estuviera validada.

## Devuelve el trabajo parcial y cierra el bucle

Cuando el control rechaza otra llamada, el llamador debe salir de la ejecución pagada y guardar lo útil. El modelo puede explicar el bloqueo con los datos ya disponibles, pero no debe necesitar otra llamada de pago para decidir si respeta la parada.

Por ejemplo, una salida del controlador puede ser:

```json
{
  "task_id": "informe-17",
  "status": "partial",
  "reason": "over_budget",
  "retryable": false,
  "budget_scope": "equipo-demo",
  "period": "2026-10",
  "saved_result": "borrador-validado-17",
  "pending_requests": [],
  "allowed_next_actions": ["return_partial_result", "request_authorized_resume"]
}
```

Si falta el uso de una llamada enviada, utiliza una razón como `usage_pending` y conserva su identificador entre las pendientes. Deja de programar subagentes, cancela el trabajo pendiente que aún no se ha enviado y evita los reintentos internos. Solicitar la cancelación de una llamada en curso no certifica que se haya detenido ni que su coste desaparezca.

Una reanudación autorizada debe conservar el resultado parcial, el consumo anterior y las reservas pendientes. Registra quién la autorizó, el ámbito, el nuevo importe si procede, el motivo y la caducidad de una excepción temporal. La aplicación comprueba esa autorización; el modelo no puede fabricarla ni borrar el saldo cambiando de tarea, traza, proveedor o clave.

Reducir el alcance o escoger una ruta más barata puede ser una decisión válida, pero debe ser explícita y respetar la calidad necesaria para el trabajo. Si el problema es además una repetición sin avance, la [guía para detener un agente atrapado en un bucle de herramientas](https://blog.laozhang.ai/es/posts/ai-agent-tool-loop) explica cómo reconocer el progreso y recuperar operaciones sin duplicarlas. El freno monetario limita cuánto puedes gastar; no confirma que la tarea esté completada.

## Preguntas frecuentes

### ¿Un presupuesto de proyecto de OpenAI basta para parar el gasto?

Puede rechazar tráfico si activas **Enforce a hard limit**, según la [guía actual de OpenAI](https://developers.openai.com/api/docs/guides/spend-limits). Una alerta sola no lo hace, y la aplicación del límite duro puede admitir un pequeño exceso mientras se propaga. Para limitar una tarea concreta y contar llamadas en curso, añade una reserva previa en tu aplicación.

### ¿Debo reintentar todos los errores 429 con una espera?

No. Un 429 por [límite de gasto de OpenAI](https://developers.openai.com/api/docs/guides/spend-limits) o por el [techo mensual documentado de Anthropic](https://platform.claude.com/docs/en/api/rate-limits) no se corrige esperando unos segundos y repitiendo. Identifica el código y su condición. Incluso ante un error transitorio, un nuevo intento de pago debe pasar por el presupuesto y resolver el coste incierto del anterior.

### ¿Puedo liberar la reserva al cerrar un stream?

Solo si el cierre aporta evidencia suficiente del coste o de la ausencia de cobro. Una desconexión del cliente no deshace el trabajo del proveedor. Si falta el recibo, conserva la reserva, marca la solicitud como pendiente y concilia antes de recuperar ese margen.

### ¿Cada subagente puede tener su propio presupuesto?

Sí, siempre que también consuma del presupuesto padre. Comprueba y reserva ambos en la misma decisión atómica. Dar a cada subagente un saldo independiente permite superar el límite global aunque ninguno supere el suyo.

### ¿Un TTL o un periodo nuevo permite continuar automáticamente?

Solo permite aplicar la política del nuevo periodo cuando realmente corresponde. No borra llamadas anteriores cuyo cobro sigue pendiente. Mantén la reserva y el recibo asociados a su periodo original; una sesión nueva tampoco autoriza a eludir una tarea detenida.

### ¿La prueba con un proveedor falso demuestra que nunca habrá exceso en la factura?

No. Demuestra el comportamiento del código y de los casos simulados. La garantía real exige cotas de coste completas, todas las rutas de pago bajo control, reservas duraderas y atómicas, conciliación fiable y recuperación de fallos. Si una cota falla, registra el importe verdadero y congela nuevas llamadas.

## Fuentes

Páginas externas que cita esta guía, en el orden en que aparecen. Última actualización: 2026-10-07.

- [guía actual de OpenAI](https://developers.openai.com/api/docs/guides/spend-limits) (developers.openai.com)
- [Databricks describe su uso de presupuestos diarios y mensuales](https://www.databricks.com/es/blog/how-databricks-manages-its-own-coding-agent-spend-unity-ai-gateway-budgets) (databricks.com)
- [documentación de Anthropic](https://platform.claude.com/docs/en/api/rate-limits) (platform.claude.com)
- [Redis garantiza la ejecución atómica de sus scripts](https://redis.io/docs/latest/develop/programmability/eval-intro/) (redis.io)
- [Cloudflare AI Gateway: reglas de gasto](https://developers.cloudflare.com/ai-gateway/features/spend-limits/) (developers.cloudflare.com)
- [LiteLLM Proxy: presupuestos globales, de equipo, miembro, usuario o clave](https://docs.litellm.ai/docs/proxy/users) (docs.litellm.ai)
- [LiteLLM: presupuesto por sesión de agente](https://docs.litellm.ai/docs/a2a_iteration_budgets) (docs.litellm.ai)
