Un lote de humo de 2 pedidos contra la Batch API confirmó el camino completo
—crear, consultar estado, recoger, normalizar— y dejó dos cosas a corregir:
- El costo estimado se redondeaba a 2 decimales, así que un trabajo chico
informaba US$ 0.0. Pasa a 4 decimales: en una prueba de humo importa saber
que gastaste algo, no que gastaste nada.
- cache_read_input_tokens quedó en 0. La causa es que el mínimo cacheable de
Opus 5 son 512 tokens y el prompt de sistema de la prueba tenía 86: la marca
cache_control no hace nada por debajo de ese umbral, y no avisa. Queda
documentado en el código y en la config, con cómo detectarlo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Etapa 3 del plan. Se elige la Batch API sobre llamadas sueltas porque cuesta
la mitad y generar un dataset no es sensible a la latencia: es exactamente su
caso de uso. A cambio el trabajo es asincrónico y puede tardar horas, así que
todo el estado vive en disco y es reanudable — matar el proceso, perder la
conexión o reiniciar el servidor no pierde nada ni gasta de nuevo.
Cuatro decisiones que sostienen eso:
- El custom_id se deriva del hash del contenido del pedido. El trabajo queda
idempotente: re-generar la misma especificación produce los mismos IDs, así
que lo ya resuelto se reconoce y no se vuelve a pagar.
- Los resultados se indexan por custom_id, nunca por posición. La API los
devuelve en cualquier orden, y emparejarlos por índice mezcla las respuestas
en silencio; un dataset mal alineado es peor que uno vacío porque parece
correcto. El cliente falso de los tests los invierte a propósito.
- Los fallos se registran en errors.jsonl con su motivo en vez de descartarse,
y --retry-failed reenvía solo esos.
- El prompt de sistema compartido va marcado para caché: es idéntico entre
miles de pedidos, y a ~0,1x del precio de entrada deja de contar.
Los lotes se persisten después de cada envío y no al final, para que una caída
a mitad de camino no deje lotes huérfanos sin registrar.
El SDK de anthropic se importa de forma perezosa y queda como extra opcional:
el servidor de entrenamiento no lo necesita y el paquete importa sin él.
21 tests nuevos (92 en total), todos contra un cliente falso — lo que hay que
verificar es el harness, no el SDK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>