Módulo 3: Detectar Hallucinations en Código
Módulo 3: Detectar Hallucinations en Código
Módulo 3: Detectar Hallucinations en Código
Descripción de la cápsula
Un bug causa un error. Un typo causa un crash. Pero una hallucination — código que parece perfectamente correcto, pasa tu revisión visual, incluso pasa el linter, y solo falla cuando ejecutas — es el error más peligroso que AI puede generar. En este módulo vas a aprender a detectar hallucinations en código antes de que lleguen a producción.
Este módulo cierra la Phase 1 de la guía. En el módulo 1 construiste awareness sobre la confianza en AI code. En el módulo 2 desarrollaste mental models para supervisar output de AI. Ahora aplicas todo eso al caso más crítico: código que se ve bien pero referencia algo que no existe.
Si puedes detectar hallucinations, has dado el salto más importante de esta guía. Code review, debugging, y todo lo que viene en las Phases 2 y 3 son refinamientos de una habilidad que ya tienes.
Contexto del Módulo
¿Dónde estamos?
Esta es la Guía #6 del Claude Code Agentic Development Path. Los módulos 1 y 2 construyeron tus frameworks mentales — awareness sobre confianza en AI code y mental models para supervisar output. Este módulo es donde esos frameworks se ponen a prueba contra el error más sutil.
¿Hacia dónde vamos?
Este módulo cierra la Phase 1: Entender el Problema. Después de esto, la Phase 2 te da herramientas concretas: code review profesional (módulo 4), patrones de error comunes (módulo 5), y debugging con Claude Code (módulo 6). Pero esas herramientas son más efectivas si primero puedes detectar lo invisible — las hallucinations.
¿Por qué esto importa tanto?
Piensa en los tipos de errores que AI puede generar:
Errores de sintaxis
└── El linter los detecta → Riesgo bajo
Errores de lógica
└── Los tests los detectan → Riesgo medio
Errores de diseño
└── Code review los detecta → Riesgo medio-alto
Hallucinations
└── Se ven correctas visualmente
└── Pasan el linter (en lenguajes dinámicos)
└── Pasan code review visual
└── Solo fallan en runtime
└── A veces, solo fallan en runtime ESPECÍFICO
└── → Riesgo ALTO
Las hallucinations son el caso más peligroso porque son el más difícil de detectar. Y son exactamente lo que los LLMs producen con más frecuencia cuando trabajan con APIs, librerías, y funciones específicas.
La Diferencia Crítica: Bugs vs Hallucinations
Antes de avanzar, necesitas distinguir claramente entre un bug y una hallucination. La distinción importa porque cambia cómo buscas el error y cómo lo corriges.
Un bug es un error de implementación
# Bug: el developer quiso calcular el promedio pero dividió por el número incorrecto
def average(numbers):
return sum(numbers) / (len(numbers) + 1) # Error: debería ser len(numbers)
El developer sabía que sum() y len() existen. Los usó correctamente. Simplemente se equivocó en la fórmula. El fix es cambiar + 1 por nada. El concepto de la función es correcto, la implementación tiene un error puntual.
Una hallucination es una invención
# Hallucination: el LLM inventó una función que no existe
from sklearn.metrics import roc_auc_multiclass # No existe en sklearn
score = roc_auc_multiclass(y_true, y_pred) # Nunca funcionaría
Aquí no hay un error de implementación — hay una invención. roc_auc_multiclass no existe. El LLM generó un nombre que suena real basándose en patrones (roc_auc_score existe, multiclass es un concepto real), pero combinó ambos en algo que nunca fue real.
La tabla de diferencias
| Aspecto | Bug | Hallucination |
|---|---|---|
| Origen | Error humano o de AI en implementación | Invención de algo que no existe |
| APIs usadas | Reales | Inventadas o incorrectas |
| Detección | Tests, debugging | Verificación contra documentación |
| Fix | Corregir la lógica | Reemplazar con lo que realmente existe |
| Ejemplo | if x > 0 cuando debería ser >= | requests.get(url, verify_ssl=True) |
| Peligro | Variable (depende del bug) | Alto (se ve correcto, pasa review visual) |
Esta distinción es pragmática, no académica. En la práctica, cuando encuentres un error en código AI, pregúntate: "¿usó algo que no existe?" Si la respuesta es sí, es una hallucination. Si usó todo correctamente pero la lógica es incorrecta, es un bug.
Qué Es una Hallucination en Código
Definición precisa
Una hallucination en código es código que:
- Es sintácticamente correcto (no causa error de parseo)
- Parece semánticamente válido (se ve como si hiciera algo real)
- Referencia algo que no existe o funciona diferente a lo que aparenta
La clave está en el punto 3. No es un bug — es una invención. El LLM generó algo que suena correcto pero no corresponde a la realidad.
Ejemplos rápidos para calibrar
| Esto NO es una hallucination | Esto SÍ es una hallucination |
|---|---|
import os (existe) | from fastapi.security import OAuth2TokenValidator (no existe) |
requests.get(url, verify=True) (parámetro correcto) | requests.get(url, verify_ssl=True) (parámetro inventado) |
pd.DataFrame.to_json(orient="records") (valor válido) | pd.DataFrame.to_json(orient="dict") (valor inventado) |
| Bug en lógica de negocio (error del programador) | Función validate_email que solo checa @ (invención) |
Observa el patrón: las hallucinations se parecen a lo correcto. verify_ssl suena como algo que debería existir — pero el parámetro real es verify. orient="dict" suena razonable — pero los valores válidos son "records", "index", "columns", "values", "table", "split".
Por Qué los LLMs Hallucinan Código
La mecánica del problema
Los LLMs no consultan documentación cuando generan código. No ejecutan pip install para verificar que un import existe. No abren la API reference para confirmar un parámetro. Generan texto probable basado en patrones que vieron durante el entrenamiento.
Esto tiene consecuencias específicas para código:
Lo que hace un developer humano:
1. "Necesito validar JWT"
2. Abre docs de PyJWT
3. Lee la signature de jwt.decode()
4. Escribe: jwt.decode(token, key, algorithms=["HS256"])
Lo que hace un LLM:
1. "Necesito validar JWT"
2. Ha visto miles de ejemplos con jwt.decode()
3. Recuerda patrones como "verify", "algorithms", "key"
4. Combina patrones probables
5. Genera: jwt.decode(token, algorithms=["HS256"], verify=True)
← "verify=True" es un parámetro que suena real pero no existe
← El parámetro real es options={"verify_signature": True}
El LLM no está "equivocándose." Está generando la combinación más probable de tokens basada en lo que vio. Y verify=True es una combinación que suena perfectamente razonable — solo que no existe en PyJWT.
Las 4 razones principales de hallucinations en código
1. Mezcla de versiones de APIs
Los LLMs fueron entrenados con código de múltiples versiones de la misma librería. Cuando generan código, pueden mezclar la API de la v1 con la de la v3.
# El LLM vio código de Pydantic v1 y v2
# Puede generar esto — que mezcla ambos:
from pydantic import BaseModel, validator # v1 style
class User(BaseModel):
email: str
@validator("email") # v1 decorator
def validate_email(cls, v):
# Pero usa model_dump() que es v2
return v
user = User(email="test@test.com")
data = user.model_dump() # v2 method — con validator de v1
2. Invención de funciones que "deberían existir"
Si un patrón es común en un dominio, el LLM puede inventar una función que encaje en ese patrón aunque no exista.
# sklearn tiene roc_auc_score para binary classification
from sklearn.metrics import roc_auc_score # ✅ Existe
# El LLM razona: "si existe roc_auc_score,
# debe existir una versión multiclass"
from sklearn.metrics import roc_auc_multiclass # ❌ No existe
# Lo real: roc_auc_score con multi_class="ovr" parameter
3. Parámetros que suenan lógicos
Los LLMs inventan parámetros que encajan con el naming convention de una librería pero no existen.
# requests usa verify para SSL verification
requests.get(url, verify=True) # ✅ Correcto
# El LLM genera algo que suena más descriptivo:
requests.get(url, verify_ssl=True) # ❌ No existe
# "verify_ssl" suena más claro que "verify",
# pero requests usa "verify"
4. Lógica que parece implementar algo pero no lo hace
El LLM genera una función con un nombre descriptivo pero la implementación es incorrecta o incompleta.
def validate_email(email: str) -> bool:
"""Validates that the email address is properly formatted."""
return "@" in email # ← Esto NO es validación de email
# Acepta: "@", "@@@@", "no-domain@", "@no-local"
# Una validación real usa regex o una librería como email-validator
El Impacto Real de las Hallucinations
Escenarios que ocurren en producción
Las hallucinations no son un problema teórico. Son errores que llegan a producción y causan impacto real:
Escenario 1: Import falso en deploy
├── Claude Code genera: from fastapi.security import OAuth2TokenValidator
├── Developer acepta sin verificar
├── El linter local no lo detecta (Python no verifica imports estáticos)
├── Push a GitHub → CI/CD ejecuta tests → Tests no cubren ese import
├── Deploy a producción
├── Primera request que toca auth → ImportError → 500 Error
├── Impacto: downtime hasta que alguien identifica el import falso
└── Costo: 30 minutos a 2 horas de downtime
Escenario 2: Parámetro silenciosamente ignorado
├── Claude Code genera: requests.get(url, verify_ssl=False)
├── Developer piensa que deshabilitó SSL verification para testing
├── El código funciona (verify_ssl es ignorado, verify=True por default)
├── Developer sube a producción con "verify_ssl=False" pensando
│ que reactivará SSL verification después
├── En producción, SSL SIEMPRE estuvo activo (el parámetro nunca funcionó)
├── Impacto: ninguno inmediato (por suerte), pero confusión futura
└── Costo: horas de debugging cuando alguien intenta desactivar SSL
Escenario 3: Lógica de seguridad fabricada
├── Claude Code genera: función de hash de password con SHA-256
├── Developer acepta porque SHA-256 es un algoritmo conocido
├── La función es correcta sintácticamente pero insegura para passwords
├── Pasa code review visual, pasa tests (los tests solo verifican
│ que la función produce un hash, no que sea seguro)
├── Deploy a producción con passwords hasheados con SHA-256
├── 6 meses después: breach, base de datos comprometida
├── Atacante hace rainbow table attack en horas (SHA-256 es muy rápido)
├── Impacto: compromiso de datos de usuarios
└── Costo: incalculable (legal, reputacional, financiero)
El patrón que conecta los 3 escenarios
En los 3 casos, el código:
- Fue generado por AI
- Se veía correcto visualmente
- No fue verificado contra la realidad (documentación, ejecución, best practices)
- El error era detectable con las herramientas adecuadas
Este módulo te da esas herramientas. No para eliminar el riesgo (ninguna herramienta lo elimina al 100%), sino para reducirlo drásticamente.
Objetivo Profesional
Al final de este módulo podrás:
- ✅ Definir "hallucination en código" con precisión técnica
- ✅ Clasificar hallucinations en 4 tipos: imports falsos, APIs inventadas, parámetros incorrectos, lógica fabricada
- ✅ Detectar imports de paquetes o módulos que no existen
- ✅ Detectar APIs con parámetros incorrectos o inexistentes
- ✅ Detectar lógica que compila pero no hace lo que dice hacer
- ✅ Usar herramientas para verificar: type checkers, linters, quick tests, documentación oficial
- ✅ Encontrar al menos 4 de 5 hallucinations en el ejercicio práctico
Progresión del Módulo
Mapa del Módulo
| Cápsula | Tema | Qué aprenderás |
|---|---|---|
| 02 | Tipos de Hallucinations | Taxonomía completa: imports, APIs, parámetros, lógica — con ejemplos sutiles |
| 03 | Hallucinations en Imports y APIs | Cómo detectar imports falsos y APIs con signatures inventadas |
| 04 | Hallucinations en Lógica | Código que "se ve correcto" pero implementa lógica incorrecta |
| 05 | Herramientas de Detección | Type checkers, linters, quick tests, documentación oficial |
| 06 | Ejercicio: Detectar Hallucinations | 5 snippets con hallucinations ocultas — ¿puedes encontrarlas todas? |
Flujo de aprendizaje
Primero entenderás la taxonomía completa de hallucinations con ejemplos sutiles de cada tipo (cápsula 02). Después profundizarás en las hallucinations de imports y APIs — las más comunes — con técnicas específicas para detectarlas (cápsula 03). Luego abordarás las hallucinations en lógica — las más peligrosas porque pasan incluso los linters estáticos (cápsula 04). Con esa base, aprenderás las herramientas que actúan como red de seguridad cuando tu ojo falla (cápsula 05). Finalmente, pondrás todo a prueba con 5 snippets que contienen hallucinations reales de dificultad progresiva (cápsula 06).
Troubleshooting
Problema 1: "No estoy seguro de cuándo algo es hallucination vs cuándo es solo una forma diferente de hacer lo mismo"
Causa: Algunas variaciones son estilísticas (válidas), otras son hallucinations. La línea puede ser confusa.
Solución: La regla: si cambiar el código por la "forma correcta" cambia el comportamiento, es una hallucination. Si ambas formas producen el mismo resultado, es variación estilística. Ejemplo: from json import JSONDecodeError vs json.JSONDecodeError — ambas funcionan, es variación. from json.exceptions import JSONDecodeError — no funciona, es hallucination.
Problema 2: "¿Los LLMs hallucinan más en ciertas librerías que en otras?"
Causa: Sí. Las librerías con APIs que cambian entre versiones o con naming conventions ambiguos generan más hallucinations.
Solución: Librerías de alto riesgo para hallucinations: Pydantic (v1 vs v2), SQLAlchemy (1.x vs 2.x), sklearn (APIs extensas), FastAPI (confusión con Starlette). Librerías de bajo riesgo: módulos estándar de Python, requests (API estable), pytest. Ajusta tu nivel de verificación según la librería.
Problema 3: "¿Puedo usar Claude Code para verificar si su propio código tiene hallucinations?"
Causa: Sí puedes, pero con precaución. Claude Code puede identificar muchos de sus propios errores si le preguntas directamente.
Solución: Puedes preguntar: "¿Este import existe en FastAPI?" o "¿Cuáles son los parámetros reales de requests.get()?" Pero verifica la respuesta con herramientas (python -c, docs). Un LLM puede hallucinar sobre sus propias hallucinations. Las herramientas son la fuente de verdad.
Conexión con Proyecto
Ejercicio de este módulo
Vas a recibir 5 snippets de código con una hallucination oculta en cada uno. Tu trabajo es encontrar las 5. La dificultad es progresiva: 1 obvia, 2 medias, 2 sutiles. El benchmark es encontrar al menos 4 de 5.
Conexión con el proyecto integrador (Módulo 8)
El proyecto integrador del módulo 8 incluye hallucinations intencionalmente plantadas en un codebase FastAPI completo. Las técnicas que aprendes en este módulo son exactamente las que necesitas para encontrarlas. La diferencia: aquí trabajas con snippets aislados; en el módulo 8, las hallucinations están escondidas en un codebase con múltiples archivos interconectados.
Límites: Qué NO Se Cubre en Este Módulo
- ❌ Code review completo — Eso es el módulo 4. Aquí nos enfocamos exclusivamente en hallucinations.
- ❌ Bugs en lógica de negocio — Si la función implementa algo incorrecto pero usa APIs reales, es un bug, no una hallucination.
- ❌ Security holes — Eso es el módulo 5. Un endpoint sin auth es un security hole, no una hallucination.
- ❌ Debugging de errores — Eso es el módulo 6. Aquí detectas hallucinations antes de que causen errores.
- ❌ Alucinaciones en texto/comentarios — Nos enfocamos en código ejecutable, no en docstrings o comentarios incorrectos.
Evidencia de Éxito
Al terminar este módulo, sabrás que tuviste éxito si:
- ✅ Puedes explicar por qué los LLMs hallucinan código (generan texto probable, no código verificado)
- ✅ Clasificas correctamente hallucinations en sus 4 tipos
- ✅ Ante un import desconocido, tu primer instinto es verificar que existe
- ✅ Ante un parámetro de API, verificas contra la documentación oficial
- ✅ Puedes detectar funciones que dicen hacer algo pero su implementación no corresponde
- ✅ Tienes un toolkit de herramientas para verificar código sospechoso
- ✅ Encontraste al menos 4 de 5 hallucinations en el ejercicio
El Tono de Este Módulo: Detective
Este módulo tiene un tono diferente a los anteriores. Los módulos 1 y 2 fueron de reflexión y frameworks. Este módulo es de detección. Piensa en ti como un detective entrenando el ojo para ver lo que otros no ven.
Las hallucinations peligrosas son las que se ven bien. Las obvias (import unicorn_magic) no importan — nadie las aceptaría. Las que importan son las sutiles: from fastapi.security import OAuth2TokenValidator se ve tan real que un developer con experiencia podría no cuestionar que existe. Lo que parece correcto a primera vista es justamente donde está el peligro.
Qué cambia después de este módulo
Antes de este módulo, tu proceso con código AI probablemente se ve así:
Claude Code genera código
└── "Se ve bien" → Acepto
Después de este módulo, tu proceso será:
Claude Code genera código
├── ¿Imports que no reconozco? → Verificar con python -c
├── ¿Parámetros de API que no he usado antes? → Verificar con docs
├── ¿Funciones de seguridad/validación? → Verificar implementación
├── ¿Lógica que debería usar una librería estándar? → Comparar
└── Todo verificado → Acepto con confianza
La diferencia no es que desconfíes de todo — es que sabes dónde mirar. Un developer que puede detectar hallucinations trabaja más rápido (no más lento) porque sabe qué verificar y qué confiar. No revisa cada línea — revisa las que importan.
Tu ventaja después de este módulo: cada vez que Claude Code genere un import, un API call, o una función de librería, tu instinto será verificar lo que no reconoces. No porque desconfíes de AI — sino porque sabes que la verificación es un skill profesional que separa al developer ordinario del excepcional.
Resumen
- Las hallucinations en código son el error más peligroso de AI-generated code porque se ven correctas
- Los LLMs no verifican lo que generan — producen texto probable, no código comprobado
- Las hallucinations se clasifican en 4 tipos: imports falsos, APIs inventadas, parámetros incorrectos, lógica fabricada
- Las hallucinations peligrosas son las sutiles — las que se parecen a lo real
- Este módulo cierra la Phase 1: combina awareness (módulo 1) y mental models (módulo 2) con el caso más crítico
- Al terminar, tendrás un toolkit de detección y habrás probado tu habilidad con 5 snippets reales
Recursos Adicionales
- Anthropic — Claude Code Documentation - Documentación oficial de Claude Code y sus capacidades
- arXiv — Code Hallucinations in Large Language Models - Investigación sobre hallucinations específicas en generación de código
- GitHub Blog — AI Code Generation Research - Estudios sobre calidad de código generado por AI
- Python Package Index (PyPI) - Verificar que un paquete Python existe antes de confiar en un import
- FastAPI Official Documentation - Referencia para verificar APIs de FastAPI
Siguiente cápsula: Tipos de Hallucinations — la taxonomía completa con ejemplos sutiles de cada categoría.
Debugging & Code Review with Claude Code — Módulo 3, Cápsula 01 Claude Code Agentic Development Path — Guía #6 de 11