Promptfoo es un test runner basado en configuración para prompts y modelos. Defines una matriz de prompts, providers y casos de prueba en YAML, validas las salidas con asserts y ves un diff lado a lado. Así un cambio de prompt pasa por CI como cualquier otro código, en vez de revisarlo a ojo una vez y mandarlo a producción. Acá va qué es, cuándo conviene más que tu propio script de eval o una plataforma alojada, un quickstart que puedes pegar en un repo hoy mismo y las concesiones reales que trae: los graders no deterministas y el costo.

En resumen
- Promptfoo corre una matriz de prompts x providers x casos de prueba desde un archivo YAML, aplica los asserts y arma una comparación lado a lado que entiendes a la primera.
- Le da a tus prompts una suite de regresión. Cambias el prompt, corres los casos y ves exactamente qué salidas cambiaron y si siguen pasando, en vez de fiarte de un par de revisiones a ojo.
- Es una CLI más un visor web local. Sin cuenta, sin servidor, sin SDK que aprender. Lo apuntas a tus archivos de prompt y tus providers, y listo.
- Usa asserts duros (contains, regex, JSON schema, is-json) para todo lo que puedas verificar de forma mecánica. Deja las rúbricas calificadas por LLM para la calidad realmente subjetiva, porque el juez no es determinista y te puede tumbar el build.
- La victoria más barata del primer día: comparar dos modelos en TUS tareas, con costo y latencia reales por celda, antes de casarte con uno en producción.
Los prompts son código que llega directo a los usuarios, pero la mayoría de los equipos los edita a ciegas. Ajustas una frase, revisas una o dos salidas a ojo, despliegas, y te enteras por una queja de que el cambio rompió algo en otro caso totalmente distinto. El problema es de fondo. Los prompts no tienen suite de pruebas, así que no hay nada que correr antes de mandarlos. Promptfoo llena ese hueco con la respuesta más aburrida posible: un archivo de config, un test runner y un diff. Acá va qué es Promptfoo realmente, cuándo vale la pena frente a un script de eval hecho a mano o una plataforma de evals alojada, un quickstart que pegas en un repo en cinco minutos y las concesiones que duelen, sobre todo el grader LLM no determinista que, usado sin cuidado, te tumba el build sin razón real.
01 · Qué es en realidad
Promptfoo es dos cosas en un mismo binario: un test runner para prompts y modelos, y un visor local que muestra los resultados como una grilla. Describes el trabajo en un config YAML (qué prompts, qué providers, qué casos de prueba) y Promptfoo corre cada combinación y compara la salida contra los asserts que declaraste.
La forma fácil de pensarlo es como una hoja de cálculo. Las filas son tus casos de prueba, cada uno con sus propias variables de entrada. Las columnas son las combinaciones de prompt-y-provider que estás probando. Cada celda es una salida del modelo con su pasa/falla y su costo. Abres el visor y lees toda la matriz de un golpe: qué entradas se rompieron, qué modelo sale más barato, dónde divergen dos prompts.
- Un prompt es un archivo de plantilla o un string inline con «{{variables}}» que se rellenan en cada caso de prueba.
- Un provider es un endpoint de modelo, por ejemplo anthropic:claude-opus-4-8, y puedes listar varios para compararlos cara a cara.
- Un test es una fila: un conjunto de valores de variables más los asserts que esa salida tiene que cumplir.
- Un assert es el chequeo: coincidencia exacta, contains, regex, is-json, validación contra un JSON schema, similitud semántica (similar) o una llm-rubric calificada por otro modelo.
Esa es toda la superficie. Todo lo demás (la integración con CI, el visor web, la generación de datasets) se apoya en ese núcleo de config-más-asserts.
Nota
Promptfoo es open-source (licencia MIT) y corre entero en tu máquina desde la CLI. No hay cuenta que crear y no sale nada hacia ningún lado salvo las llamadas a la API del modelo que tus pruebas hacen de verdad. Eso lo hace seguro para meterlo en un repo privado y correrlo en CI sin atarte a ningún proveedor. Un plus real cuando la alternativa es pasar tus prompts por un dashboard alojado.
02 · Por qué importa
El valor central es una suite de regresión para prompts. Una vez que tus prompts importantes tienen casos de prueba, cambiar uno deja de ser un salto al vacío. Editas, corres la suite y el diff te dice exactamente qué salidas cambiaron y si siguen pasando. Un cambio que rompió en silencio el caso de clasificar reembolsos ahora sale en rojo antes de llegar a un usuario, no después.
El segundo valor es comparar modelos en tus propias tareas. Los benchmarks públicos te dicen cómo le va a un modelo con los problemas de otra gente. No te dicen nada de los tuyos. Listar dos providers en el mismo config y correr tus casos reales te da una grilla pareja (accuracy, costo y latencia por celda) sobre el trabajo que de verdad haces. Cuando sale un modelo nuevo, volver a correr la suite es la forma honesta de decidir si te conviene cambiar.
Atrapar los fallos que se esconden
La mayoría de las regresiones de prompt no son crashes. Son una respuesta segura pero equivocada que, vista sola, parece estar bien. Un prompt que resumía limpio empieza a comerse la conclusión. Un clasificador que devolvía { "label": "urgent" } empieza a envolverlo en prosa. Ninguno lanza un error. Simplemente se degradan en silencio. Los asserts duros los atrapan de forma mecánica: verifica que la salida sea is-json, que contains el id del ticket, que cumpla un schema. El test falla en el instante en que la forma se desvía.
Consejo
Empieza escribiendo casos de prueba para tus peores incidentes pasados. Cada "el prompt antes hacía X y de repente dejó de hacerlo" es un caso de regresión listo para usar. Codificar los bugs con los que ya te quemaste es el camino más rápido a una suite que valga la pena, y de paso documenta qué se supone que el prompt debe hacer.
03 · Cuándo usarlo (y cuándo no)
Usa Promptfoo cuando:
- Un prompt importa en producción y lo cambias más de una vez: cualquier cosa de cara al usuario, cualquier cosa en un flujo que genera ingresos.
- Estás eligiendo entre modelos, o decidiendo si adoptar uno más nuevo, y quieres basar la decisión en tus tareas y no en un leaderboard.
- Quieres que los cambios de prompt pasen por code review y CI como el resto de tu código, con un check que falla cuando una salida se regresa.
Usa otra cosa cuando:
- Es un prompt de usar y tirar. Un prompt que vas a correr una vez y descartar no necesita suite de regresión. No le montes andamiaje a un script.
- Necesitas tracing completo de producción, no evals antes del deploy. Promptfoo prueba prompts antes de que salgan, contra un dataset fijo. Si lo que de verdad necesitas es observar el tráfico en vivo (cada prompt, completion y tool call en producción), ese es el trabajo de una herramienta de tracing, como Langfuse, no de Promptfoo. Son complementarias: evals antes, trazas después.
- Tu set de pruebas es realmente enorme y lo comparte todo un equipo. A gran escala, con mucha gente curando datasets y revisando resultados en conjunto, la base de datos y los controles de acceso de una plataforma de evals alojada quizá valgan lo que cuestan. Para alguien que construye solo o un equipo pequeño, el flujo local de YAML-y-CLI es más liviano y más que suficiente.
04 · Quickstart
Promptfoo corre con npx, así que no hay nada que instalar de forma global. Genera un config, apúntalo a tu prompt y tus providers, y córrelo. Primero define la API key de tu modelo en el entorno. Para Anthropic es ANTHROPIC_API_KEY. Nunca la subas al repo. Tómala de tu secrets manager (en nuestro stack, vaulting estilo Infuse, no un .env subido al repo).
export ANTHROPIC_API_KEY="..." # de tu secrets manager, no de un archivo commiteado
npx promptfoo@latest init # genera promptfooconfig.yaml
Ahora edita el config. El ejemplo de abajo prueba un archivo de prompt contra un provider en dos casos, mezclando un assert duro con una rúbrica. Ojo: los chequeos duros (contains, is-json) no necesitan llamar al modelo para calificar, mientras que la llm-rubric levanta un segundo modelo para juzgar. Ten presente esa diferencia tanto por costo como por inestabilidad.
prompts:
- file://prompts/classify.txt
providers:
- anthropic:claude-opus-4-8
tests:
- vars:
input: "quiero un reembolso del pedido 4471"
assert:
- type: is-json
- type: contains
value: "4471"
- vars:
input: "¿dónde está mi paquete?"
assert:
- type: llm-rubric
value: "Clasifica el mensaje como consulta de envío/estado, no de reembolso."
Corre la matriz y abre el visor para leer la grilla:
npx promptfoo@latest eval # corre cada prompt x provider x test
npx promptfoo@latest view # abre el visor web local
En CI, ese mismo comando eval es tu compuerta. Termina con código distinto de cero cuando un assert falla, así que un prompt regresado bloquea el merge igual que un test unitario que falla. Engánchalo al mismo workflow que corre tus demás checks y, a partir de ahí, un cambio de prompt necesita la suite en verde para entrar.
Importante
Cada corrida de eval hace llamadas reales y facturadas a la API, y un assert llm-rubric las duplica, porque llama a un modelo para generar la salida y a otro para calificarla. Una matriz grande (muchos prompts x muchos providers x muchos casos, cada uno con rúbrica) te puede dejar una factura sorpresa en una sola corrida. Mantén la matriz ligera, apóyate en los asserts duros y reserva las rúbricas para los casos que de verdad necesitan juicio subjetivo.
05 · Las concesiones que nadie pone en el README
Los gotchas honestos, en el orden en que suelen morder.
Los asserts calificados por LLM no son deterministas. La mayor trampa de todas. Una llm-rubric le pide a un modelo que juzgue la salida, y ese juez puede dar un veredicto distinto con la misma entrada de una corrida a otra. Si te apoyas en eso para todo, tu build parpadea en rojo sobre código que está bien, y eso entrena a todo el mundo a ignorar la suite. Ese es el peor resultado posible para un test en el que querías confiar. La solución es disciplina. Fija con asserts duros todo lo que puedas (is-json, contains, regex, schema) y reserva la rúbrica para la calidad que de verdad es subjetiva y no se puede expresar como un chequeo mecánico. Un juez inestable que falla uno de cada veinte casos es peor que no tener test en ese caso, porque te tumba la confianza en los diecinueve que sí son sólidos.
El costo escala con la matriz, sin que te des cuenta. La grilla se multiplica: prompts por providers por casos de prueba, y se duplica otra vez en cualquier fila con rúbrica. Es fácil escribir un config que se ve razonable pero cuesta plata real cada vez que CI lo corre. Vigila las dimensiones, cachea donde puedas y no corras la suite completa en cada commit trivial si la puedes acotar a los cambios de prompt.
Los asserts duros solo revisan la forma, no la verdad. Un contains o un chequeo de schema verifica que la salida tenga la forma correcta, no que la respuesta sea correcta. Un clasificador puede devolver JSON válido con la etiqueta equivocada y pasar limpio por is-json. Los asserts duros son necesarios y baratos, pero combínalos con unas pocas rúbricas o revisiones humanas bien elegidas en los casos donde lo que importa es que la respuesta sea correcta, no su formato.
Una suite en verde vale lo que valen sus casos. Promptfoo prueba exactamente lo que le dices y nada más. Si a tu dataset se le escapa un modo de fallo, la suite sigue en verde mientras ese modo se rompe en producción. Trata el set de pruebas como un artefacto vivo: cada incidente nuevo se convierte en un caso nuevo, igual que agregarías un test de regresión después de arreglar un bug en código normal.
Promptfoo es la herramienta que quiero tener lista antes de la segunda vez que toco un prompt importante, no después de que un mal cambio ya salió. Es deliberadamente poco glamoroso, un config, un runner, un diff, y ese es justo el punto. Convierte "creo que este prompt sigue bien" en "la suite está en verde". Solo úsalo con los ojos abiertos respecto al grader: los asserts duros son tu columna vertebral, las rúbricas son una herramienta filosa para un trabajo muy puntual, y cada corrida gasta plata de verdad.
Puntos clave
- Promptfoo le da a los prompts lo que el código ya tiene: una suite de regresión. Define una matriz de prompt x provider x test en YAML, valida las salidas con asserts y lee el diff de pasa/falla antes de mandar a producción.
- Los asserts duros (is-json, contains, regex, JSON schema) son tu columna vertebral. Son deterministas, baratos y atrapan los cambios de forma. Reserva la rúbrica calificada por LLM para la calidad realmente subjetiva, porque el juez no es determinista y te puede tumbar el build.
- Es una CLI open-source autocontenida más un visor local. Sin cuenta, sin servidor, corre con npx. Fácil de meter en un repo privado y de bloquear un merge hasta que la suite esté en verde.
- Úsalo para comparar modelos en TUS tareas con costo y latencia reales por celda, sobre todo al decidir si adoptar un modelo más nuevo.
- Cada corrida gasta plata real de API y una llm-rubric duplica las llamadas por fila. Mantén la matriz ligera y recuerda que una suite en verde vale lo que valen sus casos. Codifica cada incidente pasado como un test nuevo.
Preguntas frecuentes
¿En qué se diferencia Promptfoo de escribir mi propio script de eval?
Un script hecho a mano funciona bien hasta que deja de funcionar: terminas reinventando la matriz de pruebas, los tipos de assert (contains, regex, JSON schema, similitud semántica, llm-rubric), el visor lado a lado, la contabilidad de costo y latencia, y los códigos de salida para CI. Promptfoo te da todo eso de fábrica desde un solo archivo YAML, con una grilla web local para leer los resultados. Para un chequeo de usar y tirar, un script está bien. Pero en cuanto quieres más de un prompt, más de un modelo, o un resultado que vas a re-correr en CI, el runner basado en configuración te ahorra mantener tu propio harness.
¿Los asserts calificados por LLM son lo bastante confiables para bloquear un build?
Solo para los casos indicados, y nunca como tu única línea de defensa. Una llm-rubric le pide a un modelo que juzgue la salida, y ese juicio no es determinista. La misma entrada puede pasar en una corrida y fallar en la siguiente, lo que te pone CI en rojo sobre código que está bien y entrena al equipo a ignorar los fallos. Usa asserts duros (is-json, contains, regex, JSON schema) para todo lo que puedas expresar de forma mecánica, y reserva la rúbrica para la calidad realmente subjetiva. Si no te queda otra que bloquear con una rúbrica, escríbela acotada y específica, y asume que es una señal más blanda que un chequeo de schema.
¿Correr Promptfoo cuesta plata? ¿Cómo mantengo la factura baja?
Sí. Cada corrida de eval hace llamadas reales y facturadas a la API de los providers que listes, y un assert llm-rubric más o menos duplica las llamadas de esa fila, porque genera la salida y luego la califica. El costo escala con la matriz: prompts por providers por casos. Para mantenerlo bajo, apóyate en los asserts duros (que no necesitan una llamada para calificar), mantén la matriz ligera, cachea donde puedas y acota las corridas de CI a los cambios de prompt en vez de correr la suite completa en cada commit trivial.
¿Puedo usar Promptfoo para comparar dos modelos, no solo dos prompts?
Sí, y es uno de los mejores usos desde el primer día. Lista varios providers en el mismo config (por ejemplo anthropic:claude-opus-4-8 junto a otro modelo) y corre tus casos de prueba reales contra todos. Obtienes una grilla pareja con accuracy, costo y latencia por celda, sobre TUS tareas en vez de un benchmark público. Cuando sale un modelo más nuevo, volver a correr la suite es la forma honesta de decidir si cambiar realmente ayuda a tu carga de trabajo, antes de mandarlo a producción.
¿Promptfoo reemplaza el tracing u observabilidad de producción?
No. Resuelven mitades distintas del problema y se complementan bien. Promptfoo corre evals antes de mandar a producción, contra un dataset fijo, para atrapar regresiones y comparar opciones. Una herramienta de tracing como Langfuse registra lo que de verdad pasó en producción: cada prompt, completion, tool call, conteo de tokens y costo, como una traza en vivo. Usa las evals para decidir qué mandar y las trazas para entender qué fue lo que mandaste. Querer una no es excusa para saltarte la otra.
¿Necesito una cuenta o un servidor para correrlo?
No. Promptfoo es una CLI open-source que corre entera en tu máquina, normalmente con npx y sin instalación global. No hay cuenta que crear y nada sale de tu entorno salvo las llamadas a la API del modelo que tus pruebas hacen. El visor web es un servidor local que Promptfoo levanta para que leas la grilla de resultados en el navegador. Ese montaje autocontenido y sin proveedor externo es justo lo que lo hace fácil de meter en un repo privado y en un pipeline de CI.
¿Prefieres que lo hagamos por ti?
Esto mismo lo construimos para negocios como el tuyo. La primera conversación es gratis y sin compromiso.
Escríbenos por WhatsAppPrimera conversación gratis. Te responde el fundador.
Recursos relacionados

Ragas: evalúa tu RAG con honestidad en vez de medirlo a ojo
Cada cambio que le metes a tu RAG, tamaño de chunk, embedder, reranker, prompt, es una adivinanza hasta que le pones un número encima. Ragas puntúa fidelidad, relevancia de la respuesta y precisión/recall del contexto para que separes los problemas de recuperación de los de generación y respaldes tus cambios con un delta. Aquí te explico qué es, cuándo conviene frente a armarlo tú mismo o usar una suite de evals más pesada, un quickstart listo para pegar, y las concesiones honestas de poner un modelo a calificar a otro modelo.

Arma evals para tus agentes antes de confiar en ellos
Cada cambio de prompt en un agente que no puedes medir es una apuesta a ciegas. Una eval no es más que un test para sistemas no deterministas: un dataset pequeño y honesto, graders que corren en cada cambio y un pass rate que te dice al instante si tu "ajustito" rompió algo que ya funcionaba.

Langfuse: tracing open-source para apps LLM
Langfuse es un almacén de trazas con UI, auto-hospedable, para apps LLM: registra cada prompt, completion, tool call, conteo de tokens, costo y latencia como una traza anidada, más versiones de prompts y scores de evals. Es la diferencia entre depurar un agente de verdad y andar adivinando con puros prints, solo que el self-host ahora pide Postgres Y ClickHouse, y eso te cambia las cuentas en un solo VPS.