¿Por Qué Evaluar Aplicaciones LLM?
A diferencia del software tradicional donde los tests verifican resultados exactos, las aplicaciones LLM producen respuestas no deterministas. Necesitas estrategias de evaluación especializadas para asegurar que tu app de IA sea precisa, útil y segura antes de desplegar a producción.
⚠️ Qué Puede Salir Mal
- Alucinación: El modelo inventa hechos que suenan convincentes
- Deriva de Relevancia: Las respuestas no corresponden a la pregunta
- Contexto Ignorado: RAG recupera documentos pero el modelo los ignora
- Inconsistencia: La misma pregunta obtiene respuestas muy diferentes
- Seguridad: El modelo produce contenido dañino o sesgado
Evaluación Manual con Casos de Prueba
interface CasoPrueba {
entrada: string;
temasEsperados: string[];
noDebeContener: string[];
}
const casosPrueba: CasoPrueba[] = [
{
entrada: "¿Qué es React?",
temasEsperados: ["biblioteca UI", "componentes", "JavaScript"],
noDebeContener: ["Angular", "Vue"],
},
{
entrada: "Explica los volúmenes de Docker",
temasEsperados: ["almacenamiento persistente", "contenedores", "montaje"],
noDebeContener: ["máquinas virtuales"],
},
];
async function ejecutarEvaluacion(chain: any) {
const resultados = [];
for (const caso of casosPrueba) {
const response = await chain.invoke({ input: caso.entrada });
const respuesta = (response.answer || response.content).toLowerCase();
const temasCubiertos = caso.temasEsperados.filter(
(tema) => respuesta.includes(tema.toLowerCase())
);
const noDeseadosEncontrados = caso.noDebeContener.filter(
(termino) => respuesta.includes(termino.toLowerCase())
);
resultados.push({
entrada: caso.entrada,
aprobado: temasCubiertos.length === caso.temasEsperados.length
&& noDeseadosEncontrados.length === 0,
cobertura: `${temasCubiertos.length}/${caso.temasEsperados.length}`,
});
}
return resultados;
}
Evaluación LLM-como-Juez
Usa un LLM poderoso para evaluar la calidad de las respuestas de otro LLM.
import { ChatOpenAI } from "@langchain/openai";
import { z } from "zod";
const EvalSchema = z.object({
relevancia: z.number().min(1).max(5).describe("Qué tan relevante es la respuesta"),
precision: z.number().min(1).max(5).describe("Qué tan precisa factualmente"),
completitud: z.number().min(1).max(5).describe("Qué tan completa es"),
razonamiento: z.string().describe("Explicación breve de las puntuaciones"),
});
const juez = new ChatOpenAI({ modelName: "gpt-4", temperature: 0 })
.withStructuredOutput(EvalSchema);
async function evaluarRespuesta(pregunta: string, respuesta: string) {
return await juez.invoke(`
Eres un evaluador experto. Puntúa esta respuesta de IA en escala 1-5.
Pregunta: ${pregunta}
Respuesta de IA: ${respuesta}
Puntúa cada dimensión 1-5:
- Relevancia: ¿La respuesta aborda la pregunta?
- Precisión: ¿Los hechos son correctos?
- Completitud: ¿La respuesta es completa?
`);
}
Suite de Tests Automatizados
// evaluacion.test.ts
import { describe, it, expect } from "vitest";
describe("Calidad de Cadena IA", () => {
it("debería responder preguntas de React con precisión", async () => {
const result = await miCadena.invoke({ input: "¿Qué son los hooks de React?" });
const evaluacion = await evaluarRespuesta("¿Qué son los hooks de React?", result);
expect(evaluacion.relevancia).toBeGreaterThanOrEqual(4);
expect(evaluacion.precision).toBeGreaterThanOrEqual(4);
});
it("no debería alucinar en respuestas RAG", async () => {
const result = await cadenaRAG.invoke({ input: "¿Política de reembolso?" });
const evalRAG = await evaluarRAG(
"¿Política de reembolso?",
result.sourceDocuments.map((d: any) => d.pageContent),
result.answer
);
expect(evalRAG.alucinacion).toBe(false);
expect(evalRAG.fidelidad).toBeGreaterThanOrEqual(4);
});
});
LangSmith para Monitoreo en Producción
# Configurar trazado de LangSmith
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=tu-api-key-langsmith
export LANGCHAIN_PROJECT=mi-proyecto
// ¡Los trazos se capturan automáticamente — no se necesitan cambios en el código!
const result = await miCadena.invoke(
{ input: "¿Cómo funcionan los volúmenes de Docker?" },
{
metadata: {
userId: "usuario-123",
feature: "chat",
environment: "produccion",
},
tags: ["produccion", "v2.1"],
}
);
// En el dashboard de LangSmith puedes:
// - Ver el trazo completo de cada paso
// - Ver uso de tokens y latencia por paso
// - Filtrar por tags, metadatos y tiempo
// - Comparar diferentes versiones de modelos
💡 Puntos Clave
- • Las apps LLM necesitan evaluación especializada — los tests unitarios tradicionales no son suficientes
- • LLM-como-Juez usa un modelo poderoso para evaluar la salida de otro modelo
- • La evaluación RAG verifica fidelidad (sin alucinación) y calidad de recuperación
- • Construye suites de tests automatizados que se ejecuten en cada despliegue
- • LangSmith proporciona trazabilidad, monitoreo y depuración en producción