La Mentalidad de Ingeniería de IA: Qué Cambia Cuando Construyes con LLMs
La ingeniería de IA no es solo ingeniería de software con un modelo adjunto. Los bucles de retroalimentación, los modos de fallo y las señales de calidad son fundamentalmente diferentes. Así es como debes pensar al respecto.
Un tipo diferente de ingeniería
La ingeniería de software tradicional es determinista en su esencia. Dada la misma entrada, esperas la misma salida. Las pruebas son binarias: pasan o fallan. Las implementaciones funcionan o no.
La ingeniería de IA rompe esta suposición. Cuando integras un LLM en un sistema de producción, estás trabajando con un componente que es:
- No determinista: el mismo prompt puede producir diferentes salidas
- Costoso por llamada: órdenes de magnitud más caro que una consulta a una base de datos
- Latencia variable: los tiempos de respuesta varían de milisegundos a decenas de segundos
- Opaco: no puedes inspeccionar el "razonamiento" de una manera depurable
- Evolutivo: el comportamiento del modelo cambia con actualizaciones que no controlas
Esto no significa que la ingeniería de IA sea más difícil o más fácil que la ingeniería tradicional. Significa que las habilidades, los patrones y los instintos son diferentes.
El problema de la evaluación
En el software tradicional, escribes una prueba:
expect(calculateTax(100, 'CA')).toBe(7.25)
En la ingeniería de IA, el equivalente es mucho más difícil:
const response = await llm.complete('Summarize this article...')
// What does "correct" mean here?
// How do you assert quality programmatically?
Este es el desafío central. Necesitas frameworks de evaluación que sean lo suficientemente rigurosos para detectar regresiones, pero lo suficientemente flexibles para adaptarse a la variación natural en las salidas del modelo.
El patrón que mejor funciona en la práctica es la evaluación basada en rúbricas: define un conjunto de criterios, puntúa las salidas según esos criterios y haz un seguimiento de las puntuaciones a lo largo del tiempo.
interface EvaluationRubric {
criteria: EvaluationCriterion[]
passingScore: number
}
interface EvaluationCriterion {
name: string
description: string
weight: number
scorer: (input: string, output: string) => Promise<number>
}
const summarizationRubric: EvaluationRubric = {
criteria: [
{
name: 'completeness',
description: 'Covers all key points from the source',
weight: 0.3,
scorer: async (input, output) => {
// Extract key entities from input, check coverage in output
const keyPoints = await extractKeyPoints(input)
const covered = keyPoints.filter((p) =>
output.toLowerCase().includes(p.toLowerCase())
)
return covered.length / keyPoints.length
},
},
{
name: 'conciseness',
description: 'Significantly shorter than the original',
weight: 0.2,
scorer: async (input, output) => {
const ratio = output.length / input.length
if (ratio < 0.2) return 1.0
if (ratio < 0.4) return 0.7
return 0.3
},
},
{
name: 'accuracy',
description: 'No hallucinated facts',
weight: 0.5,
scorer: async (input, output) => {
// Use a separate model call to check factual consistency
return await checkFactualConsistency(input, output)
},
},
],
passingScore: 0.75,
}
Este enfoque te proporciona un número que puedes rastrear, sobre el que puedes configurar alertas y usar en CI. No es perfecto, pero es mucho mejor que la revisión manual o ninguna evaluación en absoluto.
La ingeniería de prompts es diseño de API
Trata tus prompts como interfaces, no como cadenas de texto. Un prompt es el contrato API entre la lógica de tu aplicación y el modelo. Merece el mismo rigor que cualquier otra API.
interface PromptTemplate<TInput, TOutput> {
name: string
version: string
template: (input: TInput) => string
parser: (raw: string) => TOutput
examples: Array<{ input: TInput; expectedOutput: TOutput }>
}
const classifyIntent: PromptTemplate<
{ message: string },
{ intent: string; confidence: number }
> = {
name: 'classify-intent',
version: '2.1',
template: ({ message }) => `Classify the user intent for the following message.
Respond with a JSON object containing "intent" and "confidence" (0-1).
Valid intents: question, feedback, complaint, request, other
Message: "${message}"
JSON response:`,
parser: (raw) => {
const parsed = JSON.parse(raw.trim())
return {
intent: parsed.intent,
confidence: Math.min(1, Math.max(0, parsed.confidence)),
}
},
examples: [
{
input: { message: 'How do I reset my password?' },
expectedOutput: { intent: 'question', confidence: 0.95 },
},
],
}
Versionar los prompts, probarlos con ejemplos y tratar el análisis de salida como una preocupación de primera clase son las prácticas que separan los sistemas de IA de producción de los prototipos.
La ecuación del costo
Las llamadas a LLM son costosas. Un sistema que realiza una llamada de clase GPT-4 por cada interacción de usuario tendrá costos de infraestructura que escalan linealmente con el tráfico, a diferencia de los sistemas tradicionales donde los costos escalan sub-linealmente con el almacenamiento en caché y la optimización.
Las estrategias clave:
Caché agresivamente. Si dos usuarios hacen preguntas semánticamente similares, la respuesta probablemente sea la misma. El almacenamiento en caché semántico —utilizando la similitud de embeddings para detectar entradas equivalentes— puede reducir el volumen de llamadas entre un 30% y un 60%.
Usa el modelo más pequeño que funcione. GPT-4 no siempre es necesario. Para tareas de clasificación, extracción y formato, los modelos más pequeños son más rápidos, más baratos y a menudo igual de precisos.
Procesa en lotes cuando sea posible. Muchos proveedores de LLM ofrecen APIs de procesamiento por lotes con descuentos significativos. Si tu caso de uso tolera cierta latencia, el procesamiento por lotes puede reducir los costos en un 50% o más.
Precalcula donde puedas. Si estás utilizando un LLM para generar descripciones de productos, hazlo una vez en el momento de la publicación, no en cada vista de página.
Los modos de fallo son diferentes
Los sistemas tradicionales fallan con excepciones, tiempos de espera y códigos de error. Los sistemas de IA tienen un modo de fallo más sutil: devuelven algo que parece correcto pero no lo es.
Esto significa que necesitas barreras de seguridad:
async function safeLLMCall<T>(
prompt: string,
parser: (raw: string) => T,
validator: (result: T) => boolean,
retries = 2
): Promise<T | null> {
for (let attempt = 0; attempt <= retries; attempt++) {
try {
const raw = await llm.complete(prompt)
const parsed = parser(raw)
if (validator(parsed)) {
return parsed
}
// Output parsed but failed validation — retry with adjusted prompt
continue
} catch {
// Parse failure — retry
continue
}
}
return null // All attempts failed — fall back gracefully
}
La función validator es clave. Codifica tu lógica de negocio sobre cómo debe ser una salida válida. Sin ella, estás confiando completamente en el modelo, y esa confianza siempre debe ser verificada.
Qué significa esto para tu equipo
Si estás integrando IA en un sistema de producción, tu equipo necesita desarrollar nuevas habilidades:
- Comodidad con salidas probabilísticas. No todas las respuestas serán perfectas. Define explícitamente qué es "suficientemente bueno".
- Desarrollo impulsado por la evaluación. Escribe evaluaciones antes de escribir prompts, tal como escribirías pruebas antes del código.
- Conciencia de costos. Cada ingeniero debe comprender el costo por llamada y el costo total por característica.
- Degradación elegante. Cada característica impulsada por IA debe tener una alternativa no-IA.
La ingeniería de IA es ingeniería real. Simplemente requiere un conjunto diferente de instintos.
Próximo en esta serie: construyendo un sistema RAG de producción que realmente funcione.
Artículos Relacionados

Gasté $500 en una Semana en Codificación Asistida por IA. Esto es lo que Aprendí sobre Cómo No Hacerlo.
Contextos grandes, modo MAX, Opus 4.6 Thinking — las herramientas de codificación de IA más potentes son también las más caras. Después de una factura brutal, descubrí cómo obtener el 90% del rendimiento con el 20% del costo.

El programador de líneas ha muerto. ¡Viva el ingeniero!
Escribir código línea por línea ya no es el trabajo. El trabajo es dirigir agentes: saber qué construir, cómo descomponerlo y cómo guiar la IA hacia la solución correcta. La habilidad que importa ahora es el juicio de ingeniería, no la velocidad de escritura.

La creación es barata ahora. La creatividad es el foso.
La IA hizo que la producción fuera rápida y casi gratuita. Cualquiera puede crear una aplicación, generar contenido, lanzar un producto. El recurso escaso ya no es la ejecución, sino la idea que vale la pena ejecutar. La persona más creativa de la sala acaba de convertirse en la más peligrosa.