Tu prueba pasó el lunes: misma entrada, mismo código y temperature=0. El martes falló sin cambios en tu aplicación. La aserción esperaba una cadena exacta, pero el modelo devolvió la misma respuesta con una redacción ligeramente distinta. El agente funciona; tu suite de pruebas no.
.
Por qué temperature=0 no significa determinismo
La temperatura controla cómo el modelo selecciona el siguiente token. Con temperature=0, el modelo elige el token más probable, lo que parece reproducible. Sin embargo, esa configuración no garantiza resultados idénticos.
La causa está debajo del modelo:
- Las operaciones de punto flotante en GPU no son asociativas: el orden de las sumas puede modificar mínimamente el resultado.
- Esa diferencia puede cambiar cuál token queda en primer lugar.
- El orden de ejecución puede depender de cómo el proveedor agrupa solicitudes, del hardware, de la región o de la versión del kernel.
- Los proveedores pueden cambiar GPUs, bibliotecas de inferencia o cuantización de pesos.
Una y cómo se propagan. La salida no determinista de un LLM es una de las formas más rápidas de crearlas.
No intentes resolverlo capturando más texto en snapshots. Haz lo contrario: desacopla la prueba de la redacción variable.
Prueba estructura y significado, no texto exacto
Un agente de soporte puede confirmar un reembolso de muchas maneras, pero una respuesta válida debería mantener los mismos hechos:
- Importe del reembolso.
- ID del pedido.
- Estado de la operación.
Cambia esta pregunta:
¿El modelo dijo exactamente esta frase?
Por esta:
¿La respuesta tiene la forma correcta, los campos necesarios y valores válidos?
Estas son las estrategias más útiles.
1. Valida la respuesta con un esquema JSON
Si tu agente devuelve datos estructurados, define un esquema y valida cada respuesta contra él.
Por ejemplo, un resultado de reembolso podría exigir:
{
"type": "object",
"required": ["order_id", "status", "amount"],
"properties": {
"order_id": {
"type": "string",
"pattern": "^ORD-[0-9]+$"
},
"status": {
"type": "string",
"enum": ["refunded", "pending", "denied"]
},
"amount": {
"type": "number",
"minimum": 0
}
},
"additionalProperties": false
}
Este enfoque detecta fallos que sí importan:
- Falta un campo obligatorio.
- El modelo devuelve prosa en lugar de JSON.
- Un objeto está anidado incorrectamente.
- Un campo tiene un tipo inválido.
- El estado contiene un valor no permitido.
Carga el esquema de respuesta en cubre cómo capturar esos esquemas de herramientas y validarlos.
3. Usa rangos numéricos en lugar de valores exactos
Para números generados o calculados por el modelo, valida límites razonables en lugar de una cifra exacta.
Por ejemplo, para el total de un carrito:
assert response["total"] >= 0
assert response["total"] <= cart_subtotal + max_shipping + max_taxes
Este tipo de prueba detecta errores relevantes:
- Un total negativo.
- Un importe desproporcionadamente alto.
- Un total de cero para un carrito con productos.
También sirve para:
- Puntuaciones de confianza.
- Número de artículos.
- Presupuestos de latencia.
- Uso de tokens.
- Límites de gasto.
Elige el rango más amplio que siga detectando un fallo real.
4. Verifica campos obligatorios y campos prohibidos
Dos comprobaciones simples ofrecen mucha cobertura:
- Las claves necesarias existen y no son
null. - Las claves sensibles o internas no aparecen.
Ejemplo para una respuesta de soporte:
required_fields = {"resolution", "ticket_id", "status"}
for field in required_fields:
assert field in response
assert response[field] is not None
forbidden_fields = {"internal_notes", "raw_prompt"}
for field in forbidden_fields:
assert field not in response
Estas aserciones no dependen de cómo se redacte el texto. Además, ayudan a evitar fugas de privacidad si el modelo incluye información que no debe llegar al usuario.
5. Usa verificaciones semánticas y umbrales para texto libre
A veces la salida debe ser prosa. En ese caso, valida propiedades estables del texto.
Por ejemplo:
assert order_id in response_text
assert len(response_text) <= 500
blocked_phrases = ["contraseña", "instrucciones internas", "raw prompt"]
for phrase in blocked_phrases:
assert phrase.lower() not in response_text.lower()
Si necesitas comprobar significado, compara la salida con una respuesta de referencia mediante similitud de incrustaciones y exige un umbral:
assert cosine_similarity(response_embedding, expected_embedding) >= 0.85
Usa esta técnica como una puerta amplia, no como una garantía de precisión factual. Puede detectar que la respuesta se desvió del tema, pero no sustituye validaciones estructurales, de tipos y de rango.
6. Captura rangos, no snapshots de texto completo
Los snapshots siguen siendo útiles si congelas solo los elementos estables:
- Conjunto de claves.
- Tipos.
- Valores enumerados.
- Rangos numéricos.
- Campos obligatorios.
En lugar de guardar una respuesta completa como esta:
{
"message": "Tu reembolso de $42.00 ha sido procesado correctamente."
}
Captura el contrato:
{
"required_keys": ["message", "status", "amount"],
"status": ["refunded", "pending", "denied"],
"amount": {
"minimum": 0,
"maximum": 10000
}
}
Así, el snapshot falla por un cambio estructural que merece revisión, no por un sinónimo.
El estado y la memoria complican las pruebas
Las técnicas anteriores asumen una entrada y una salida. Los agentes con memoria añaden otra fuente de variación.
Una respuesta puede depender de:
- Documentos recuperados.
- Datos guardados en turnos previos.
- Resúmenes de la conversación.
- Orden de los mensajes anteriores.
Dos ejecuciones de la misma conversación pueden divergir porque la recuperación ordenó documentos de otra manera o porque un resumen anterior influyó en el razonamiento posterior. El explicador sobre para configurar simulacros con cuerpos de respuesta estables y combinarlos con validaciones de esquema. Esto forma parte de las pruebas de IA agéntica, donde simulación y aserción trabajan juntas.
Dónde encaja Apidog y dónde no
Es importante definir el alcance de la herramienta.
Apidog es una plataforma para diseño, pruebas y simulación de APIs. No es:
- Un framework de agentes.
- Un host de modelos.
- Un runtime de agentes.
- Una plataforma de evaluación u observabilidad.
- Un sistema que construya, ejecute u orqueste el razonamiento del agente.
Su encaje está en la capa API con la que el agente se comunica.
Puedes usarlo para:
Validar contratos de respuestas API del agente:
- Esquemas JSON.
- Campos obligatorios y prohibidos.
- Tipos.
- Rangos numéricos.
- Forma de llamadas a herramientas.
Simular dependencias externas:
- Respuestas fijas.
- Errores controlados.
- Casos límite reproducibles.
La brecha que cubre Apidog es el contrato de solicitudes y respuestas, no el modelo que las genera.
Prueba el contrato, no la redacción
El no determinismo no es un error que se elimine con una configuración. Es una propiedad de ejecutar modelos de lenguaje, y temperature=0 no lo desactiva.
Para construir una suite fiable:
- Valida esquemas.
- Comprueba tipos y claves requeridas.
- Bloquea campos prohibidos.
- Usa rangos para valores numéricos.
- Prueba la forma de las llamadas a herramientas.
- Simula dependencias externas.
- Inicializa la memoria del agente.
- Aserciona invariantes de estado.
El resultado es una suite más útil: permanece en verde cuando solo cambia la redacción y falla cuando el contrato realmente se rompe.
Esta semana, elige una aserción inestable de tu suite y sustitúyela por una validación de esquema o de rango. Usa Apidog para validar las respuestas de tu agente contra un contrato y simular las dependencias que hacen repetibles tus pruebas.
SOCIAL SHARE CARD GENERATOR