Módulo 4: Chain-of-Thought y Razonamiento
4. CoT para Tareas Específicas
Descripción
Cada tipo de tarea tiene un estilo de razonamiento óptimo. Un buen prompt de CoT para aritmética no sirve igual para debugging de código. En esta cápsula encontrarás templates de CoT optimizados para cinco tipos de tareas: math/arithmetic, razonamiento lógico, análisis de código, verificación factual, y problemas de múltiples restricciones.
Tiempo estimado: 75-90 minutos
Por Qué el Dominio Importa en CoT
Un template de CoT genérico como "Piensa paso a paso" activa el razonamiento, pero no le dice cómo razonar en ese dominio. Los problemas matemáticos requieren pasos operación por operación. Los problemas de lógica requieren identificar premisas formalmente. El debugging de código requiere trazar la ejecución.
Diseñar templates específicos por dominio produce:
- Razonamiento más consistente y en el formato esperado
- Menor probabilidad de saltar pasos críticos
- Output más fácil de parsear programáticamente
- Mayor accuracy en benchmarks específicos
Dominio 1: Math / Aritmética
Template Base
from openai import OpenAI
client = OpenAI()
MATH_COT = """Resuelve el problema matemático paso a paso.
Para cada paso:
- Escribe qué operación estás haciendo
- Muestra el cálculo
- Escribe el resultado intermedio
Al final escribe: "Respuesta final: [número con unidades]"
Problema: {problema}
"""
def resolver_math(problema: str) -> dict:
"""Resuelve un problema matemático con CoT estructurado."""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": MATH_COT.format(problema=problema)}],
temperature=0,
max_tokens=700
)
output = response.choices[0].message.content
import re
match = re.search(r'Respuesta final:\s*(.+)', output, re.IGNORECASE)
respuesta_final = match.group(1).strip() if match else None
return {
"razonamiento": output,
"respuesta_final": respuesta_final
}
Template Avanzado: Algebra con Variables
ALGEBRA_COT = """Resuelve el problema algebraico siguiendo esta estructura:
1. VARIABLES: Define qué representa cada variable (ej: x = edad de Ana)
2. ECUACIONES: Escribe las ecuaciones del sistema
3. RESOLUCIÓN: Despeja paso a paso
4. VERIFICACIÓN: Sustituye los valores y confirma que se cumplen las ecuaciones
5. RESPUESTA: Escribe la respuesta en lenguaje natural
Problema: {problema}
"""
def resolver_algebra(problema: str) -> str:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": ALGEBRA_COT.format(problema=problema)}],
temperature=0,
max_tokens=800
)
return response.choices[0].message.content
# Ejemplos de problemas algebraicos
PROBLEMAS_ALGEBRA = [
"María tiene 3 veces la edad de Juan. En 10 años, la suma de sus edades será 60. ¿Qué edad tiene cada uno ahora?",
"Se mezclan 2 litros de solución al 30% con X litros al 60% para obtener una solución al 40%. ¿Cuántos litros son X?",
"Un tren A sale de Madrid a 120 km/h. Un tren B sale 30 min después en la misma dirección a 150 km/h. ¿Cuándo alcanza B a A?",
]
if __name__ == "__main__":
for p in PROBLEMAS_ALGEBRA:
print(f"\nProblema: {p}")
print(resolver_algebra(p))
print("-" * 60)
Template: Probabilidad
PROBABILITY_COT = """Resuelve el problema de probabilidad paso a paso.
Estructura requerida:
1. ESPACIO MUESTRAL: ¿Cuál es el universo de posibilidades?
2. EVENTO: ¿Qué evento calculamos?
3. CONTEO: ¿Cuántos casos favorables y totales hay?
4. PROBABILIDAD: P(evento) = casos_favorables / casos_totales
5. VERIFICACIÓN: ¿La probabilidad está entre 0 y 1? ¿Tiene sentido?
Problema: {problema}
"""
if __name__ == "__main__":
p = "En una bolsa hay 5 bolas rojas, 3 azules y 2 verdes. Si sacas 2 bolas sin reposición, ¿cuál es la probabilidad de que ambas sean rojas?"
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": PROBABILITY_COT.format(problema=p)}],
temperature=0, max_tokens=500
)
print(response.choices[0].message.content)
# Respuesta esperada: P = C(5,2)/C(10,2) = 10/45 = 2/9 ≈ 0.222
Dominio 2: Razonamiento Lógico
Template: Validez de Argumentos
LOGIC_VALIDITY_COT = """Analiza la validez lógica del argumento usando esta estructura:
1. PREMISAS: Lista todas las premisas numeradas
2. CONCLUSIÓN: Identifica la conclusión que se quiere probar
3. FORMA LÓGICA: Escribe el argumento en forma simbólica (∀, ∃, →, ¬, ∧, ∨)
4. ANÁLISIS: ¿La conclusión se sigue necesariamente de las premisas?
- Si es válido: ¿Qué regla de inferencia aplica? (modus ponens, modus tollens, silogismo)
- Si es inválido: ¿Cuál es la falacia? ¿Existe un contraejemplo?
5. VEREDICTO: VÁLIDO o INVÁLIDO, con justificación de una línea
Argumento: {argumento}
"""
def analizar_validez(argumento: str) -> dict:
"""Analiza si un argumento lógico es válido."""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": LOGIC_VALIDITY_COT.format(argumento=argumento)}],
temperature=0,
max_tokens=600
)
output = response.choices[0].message.content
import re
veredicto_match = re.search(r'VEREDICTO:\s*(VÁLIDO|INVÁLIDO)', output, re.IGNORECASE)
return {
"analisis_completo": output,
"es_valido": veredicto_match.group(1).upper() == "VÁLIDO" if veredicto_match else None
}
# Argumentos de prueba con respuestas conocidas
ARGUMENTOS_TEST = [
# Válidos
("Si llueve, el suelo se moja. Llueve. Por lo tanto el suelo se moja.", True),
("Todos los humanos son mortales. Sócrates es humano. Por lo tanto Sócrates es mortal.", True),
("Si no hay red, la app falla. La app no falla. Por lo tanto hay red.", True),
# Inválidos
("Si llueve, el suelo se moja. El suelo está mojado. Por lo tanto llueve.", False),
("Algunos perros son peligrosos. Rex es un perro. Por lo tanto Rex es peligroso.", False),
("Si trabajo duro, tendré éxito. No tengo éxito. Por lo tanto no trabajé duro.", False),
]
if __name__ == "__main__":
correctos = 0
for argumento, esperado in ARGUMENTOS_TEST:
resultado = analizar_validez(argumento)
obtenido = resultado["es_valido"]
correcto = obtenido == esperado
if correcto:
correctos += 1
estado = "✓" if correcto else "✗"
print(f"{estado} Esperado: {esperado}, Obtenido: {obtenido}")
print(f" Argumento: {argumento[:60]}...")
print(f"\nAccuracy: {correctos}/{len(ARGUMENTOS_TEST)}")
Template: Razonamiento de Sentido Común
COMMON_SENSE_COT = """Razona sobre la situación usando conocimiento de sentido común.
Estructura:
1. SITUACIÓN: Resume la situación en 1-2 oraciones
2. CONOCIMIENTO RELEVANTE: ¿Qué conocimiento del mundo aplica?
3. INFERENCIAS: ¿Qué se puede inferir lógicamente?
4. RESTRICCIONES: ¿Hay suposiciones implícitas o restricciones?
5. RESPUESTA: La conclusión más razonable
Pregunta: {pregunta}
"""
PREGUNTAS_SENTIDO_COMUN = [
"Si Sarah está en una habitación oscura y encuentra un interruptor, ¿qué debería hacer primero?",
"Un restaurante tiene cola de 45 minutos. Los comensales que están esperando, ¿probablemente quieren ir o no quieren ir al restaurante?",
"Tu teléfono tiene 3% de batería y necesitas hacer una llamada urgente. ¿Qué debes hacer primero?",
]
Dominio 3: Análisis y Debugging de Código
Template: Debug Exhaustivo
CODE_DEBUG_COT = """Analiza y debuggea el siguiente código Python siguiendo estos pasos:
1. QUÉ HACE EL CÓDIGO: Describe brevemente el propósito del código
2. TRAZA DE EJECUCIÓN: Simula la ejecución línea por línea para el input dado (o el caso que causa el error)
3. IDENTIFICACIÓN DEL ERROR: ¿En qué línea falla y por qué? Tipo de error exacto.
4. CAUSA RAÍZ: ¿Por qué existe este error? (edge case no manejado, tipo incorrecto, etc.)
5. CORRECCIÓN: Código corregido
6. CASOS ADICIONALES: ¿Hay otros edge cases que también fallarían?
Código a analizar:
```python
{codigo}
{contexto_adicional} """
def debug_codigo_exhaustivo(codigo: str, contexto: str = "") -> dict: """ Realiza un análisis exhaustivo de código con CoT.
Args:
codigo: El código Python a analizar
contexto: Información adicional (ej: "El error ocurre con input=[]")
Returns:
dict con análisis completo y código corregido
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": CODE_DEBUG_COT.format(
codigo=codigo,
contexto_adicional=contexto or ""
)
}
],
temperature=0,
max_tokens=900
)
output = response.choices[0].message.content
import re
# Extraer el código corregido del bloque de código
codigo_match = re.search(r'```python\n(.*?)```', output, re.DOTALL)
codigo_corregido = codigo_match.group(1).strip() if codigo_match else None
return {
"analisis": output,
"codigo_corregido": codigo_corregido
}
Ejemplos para probar
CODIGOS_CON_BUGS = [ (""" def fibonacci(n): if n == 0: return 0 if n == 1: return 1 return fibonacci(n-1) + fibonacci(n-2)
Este código funciona pero tiene un problema grave de rendimiento
print(fibonacci(40)) # Muy lento """, "El código es correcto pero no eficiente"),
("""
def encontrar_duplicados(lista): duplicados = [] for i in range(len(lista)): for j in range(len(lista)): if i != j and lista[i] == lista[j]: if lista[i] not in duplicados: duplicados.append(lista[i]) return duplicados
print(encontrar_duplicados([1, 2, 3, 2, 1, 4])) """, "Busca duplicados"),
("""
class Pila: def init(self): self.elementos = []
def apilar(self, elemento):
self.elementos.append(elemento)
def desapilar(self):
return self.elementos.pop(0) # LIFO
def esta_vacia(self):
return len(self.elementos) == 0
p = Pila() p.apilar(1) p.apilar(2) p.apilar(3) print(p.desapilar()) # Debería ser 3, no 1 """, "Implementación de pila LIFO"), ]
if name == "main": for codigo, descripcion in CODIGOS_CON_BUGS: print(f"\n=== {descripcion} ===") resultado = debug_codigo_exhaustivo(codigo, descripcion) print(resultado["analisis"]) print("\n--- Código corregido ---") if resultado["codigo_corregido"]: print(resultado["codigo_corregido"])
### Template: Revisión de Código (Code Review)
```python
CODE_REVIEW_COT = """Realiza una revisión de código profesional siguiendo estos criterios:
1. FUNCIONALIDAD: ¿El código hace lo que se supone?
2. EDGE CASES: Lista los casos límite no manejados
3. RENDIMIENTO: ¿Hay ineficiencias? ¿Cuál es la complejidad O()?
4. LEGIBILIDAD: ¿El código es claro? ¿Nombres descriptivos?
5. SEGURIDAD: ¿Hay vulnerabilidades potenciales?
6. SUGERENCIAS: Lista de mejoras priorizadas (alta/media/baja)
Código a revisar:
```python
{codigo}
"""
---
## Dominio 4: Verificación Factual
### Template: Verificar contra Contexto
```python
FACTUAL_VERIFY_COT = """Verifica si la afirmación es correcta basándote en el contexto proporcionado.
Estructura:
1. AFIRMACIÓN: Escribe claramente qué se afirma
2. EVIDENCIA EN CONTEXTO: ¿Qué dice el contexto exactamente sobre esto?
3. ANÁLISIS: ¿La afirmación es consistente con la evidencia?
- Si hay evidencia directa: cítala
- Si hay evidencia indirecta: explica la inferencia
- Si no hay evidencia: indícalo
4. VEREDICTO: CORRECTO / INCORRECTO / NO PUEDE VERIFICARSE
5. CONFIANZA: Alta / Media / Baja (y por qué)
Contexto:
{contexto}
Afirmación a verificar: {afirmacion}
"""
def verificar_afirmacion(contexto: str, afirmacion: str) -> dict:
"""
Verifica una afirmación contra un contexto dado.
Útil para: RAG, fact-checking, QA sobre documentos.
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": FACTUAL_VERIFY_COT.format(
contexto=contexto,
afirmacion=afirmacion
)
}
],
temperature=0,
max_tokens=500
)
output = response.choices[0].message.content
import re
veredicto_match = re.search(
r'VEREDICTO:\s*(CORRECTO|INCORRECTO|NO PUEDE VERIFICARSE)',
output, re.IGNORECASE
)
confianza_match = re.search(r'CONFIANZA:\s*(Alta|Media|Baja)', output, re.IGNORECASE)
return {
"analisis": output,
"veredicto": veredicto_match.group(1) if veredicto_match else "DESCONOCIDO",
"confianza": confianza_match.group(1) if confianza_match else "Desconocida"
}
# Ejemplo de uso en RAG
CONTEXTO_EMPRESA = """
TechCorp fue fundada en 2018 por Ana García y Roberto Martínez en Barcelona.
La empresa tiene 250 empleados y opera en 12 países de Europa y América Latina.
En 2023, facturó €45 millones, un crecimiento del 28% respecto a 2022.
Su producto principal es una plataforma SaaS de gestión de inventarios.
El CEO actual es Ana García, quien también es cofundadora.
"""
AFIRMACIONES_TEST = [
("TechCorp fue fundada en 2018", True),
("TechCorp tiene más de 300 empleados", False),
("El producto de TechCorp es una app móvil", False),
("TechCorp opera en Asia", None), # No puede verificarse
("Ana García es cofundadora y CEO", True),
]
if __name__ == "__main__":
for afirmacion, esperado in AFIRMACIONES_TEST:
resultado = verificar_afirmacion(CONTEXTO_EMPRESA, afirmacion)
print(f"\nAfirmación: {afirmacion}")
print(f"Veredicto: {resultado['veredicto']} (confianza: {resultado['confianza']})")
Dominio 5: Problemas Multi-Restricción
Template: Satisfacción de Restricciones
MULTI_CONSTRAINT_COT = """Resuelve el problema cumpliendo TODAS las restricciones dadas.
Estructura:
1. LISTA DE RESTRICCIONES: Enumera cada restricción claramente
2. ANÁLISIS DE COMPATIBILIDAD: ¿Hay restricciones que puedan entrar en conflicto?
3. ESTRATEGIA: ¿Cómo abordar la búsqueda de solución?
4. SOLUCIÓN CANDIDATA: Propón una solución
5. VERIFICACIÓN: Para CADA restricción, confirma que la solución la cumple con ✓ o ✗
6. RESPUESTA FINAL: La solución verificada o "No existe solución" si hay conflicto
Problema: {problema}
Restricciones:
{restricciones}
"""
def resolver_multi_constraint(problema: str, restricciones: list[str]) -> dict:
"""
Resuelve un problema con múltiples restricciones.
Args:
problema: Descripción del problema
restricciones: Lista de restricciones que deben cumplirse
Returns:
dict con solución verificada y check de cada restricción
"""
restricciones_texto = "\n".join(f"- {r}" for r in restricciones)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": MULTI_CONSTRAINT_COT.format(
problema=problema,
restricciones=restricciones_texto
)
}
],
temperature=0,
max_tokens=900
)
output = response.choices[0].message.content
# Contar cuántas restricciones se verificaron con ✓
checkmarks = output.count("✓")
crossmarks = output.count("✗")
return {
"solucion_completa": output,
"restricciones_cumplidas": checkmarks,
"restricciones_fallidas": crossmarks,
"todas_cumplidas": crossmarks == 0 and checkmarks == len(restricciones)
}
# Ejemplo: Programación de reunión
problema_reunion = "Programar una reunión de 2 horas para 4 personas"
restricciones_reunion = [
"La reunión debe ser entre 9:00 y 18:00",
"Ana no puede los lunes",
"Beto solo puede martes y jueves",
"Carlos tiene bloqueado 12:00-14:00 todos los días",
"Diana tiene reunion fija los miércoles de 10:00-12:00",
"La sala de conferencias solo está libre martes y jueves",
]
if __name__ == "__main__":
resultado = resolver_multi_constraint(problema_reunion, restricciones_reunion)
print(resultado["solucion_completa"])
print(f"\nRestricciones cumplidas: {resultado['restricciones_cumplidas']}")
print(f"Restricciones fallidas: {resultado['restricciones_fallidas']}")
Template: Optimización con Restricciones
OPTIMIZATION_COT = """Encuentra la solución que MAXIMIZA/MINIMIZA el objetivo dado, cumpliendo todas las restricciones.
Estructura:
1. OBJETIVO: ¿Qué se optimiza? ¿Maximizar o minimizar?
2. VARIABLES DE DECISIÓN: ¿Qué variables podemos controlar?
3. RESTRICCIONES: Listar cada una formalmente
4. ESPACIO DE BÚSQUEDA: ¿Cuántas soluciones posibles hay?
5. CANDIDATOS: Evalúa 2-3 opciones concretas
6. COMPARACIÓN: Tabla con valor del objetivo para cada candidato
7. SOLUCIÓN ÓPTIMA: La que mejor cumple el objetivo respetando restricciones
8. VERIFICACIÓN: Confirmar que la solución óptima cumple todas las restricciones
Problema de optimización: {problema}
"""
PROBLEMAS_OPTIMIZACION = [
"""
Tienes $10,000 para invertir. Puedes elegir entre:
- Bonos del gobierno: 4% anual, riesgo mínimo
- Acciones tecnológicas: 12% esperado, 30% de probabilidad de perder todo
- Bienes raíces: 7% anual, requiere mínimo $8,000
Restricciones: Máximo 50% en un solo activo. Mínimo 20% en activos de bajo riesgo.
Objetivo: Maximizar el retorno esperado ajustado por riesgo.
""",
"""
Una fábrica puede producir mesas (ganancia $50/u) o sillas (ganancia $30/u).
Restricciones:
- Madera disponible: 1200 unidades (mesa requiere 8u, silla requiere 4u)
- Horas trabajo: 480h (mesa requiere 4h, silla requiere 2h)
- Mínimo 20 mesas por pedido pendiente
¿Cuántas mesas y sillas producir para maximizar ganancia?
"""
]
Tabla Comparativa: Templates por Dominio
| Dominio | Pasos clave del razonamiento | Formato de respuesta | Verificación |
|---|---|---|---|
| Aritmética | Operación → cálculo → resultado intermedio | Número + unidades | Backward check |
| Álgebra | Variables → ecuaciones → despeje | Valor(es) de variables | Sustituir en ecuaciones |
| Lógica | Premisas → forma simbólica → inferencia | VÁLIDO/INVÁLIDO | Contraejemplo |
| Código debug | Traza → error → causa raíz | Código corregido | Ejecutar o trazar |
| Verificación factual | Afirmación → evidencia → análisis | CORRECTO/INCORRECTO | Confianza |
| Multi-restricción | Lista → compatibilidad → candidato | Solución + checks ✓/✗ | Por cada restricción |
| Optimización | Objetivo → espacio → candidatos | Solución óptima | Verificar restricciones |
Implementación: Sistema Multi-Dominio
from enum import Enum
from dataclasses import dataclass
from openai import OpenAI
client = OpenAI()
class TipoProbema(Enum):
MATEMATICA = "matematica"
ALGEBRA = "algebra"
LOGICA = "logica"
CODIGO = "codigo"
VERIFICACION = "verificacion"
MULTI_RESTRICCION = "multi_restriccion"
OPTIMIZACION = "optimizacion"
GENERAL = "general"
@dataclass
class ResultadoCoT:
tipo: TipoProbema
problema: str
razonamiento: str
respuesta_final: str | None
tokens_usados: int
TEMPLATES: dict[TipoProbema, str] = {
TipoProbema.MATEMATICA: MATH_COT,
TipoProbema.ALGEBRA: ALGEBRA_COT,
TipoProbema.LOGICA: LOGIC_VALIDITY_COT,
TipoProbema.CODIGO: CODE_DEBUG_COT,
TipoProbema.VERIFICACION: FACTUAL_VERIFY_COT,
TipoProbema.MULTI_RESTRICCION: MULTI_CONSTRAINT_COT,
TipoProbema.OPTIMIZACION: OPTIMIZATION_COT,
TipoProbema.GENERAL: "{problema}\n\nPiensa paso a paso.",
}
def detectar_tipo_automatico(problema: str) -> TipoProbema:
"""
Detecta el tipo de problema usando el LLM para clasificar.
Alternativa: usar reglas basadas en keywords.
"""
prompt_clasificacion = f"""
Clasifica el siguiente problema en una de estas categorías:
- matematica: aritmética, porcentajes, fracciones
- algebra: ecuaciones, variables, sistemas de ecuaciones
- logica: argumentos, premisas, validez lógica
- codigo: debugging, revisión de código Python
- verificacion: verificar si una afirmación es correcta dado un contexto
- multi_restriccion: encontrar solución que cumpla múltiples restricciones
- optimizacion: maximizar/minimizar algo sujeto a restricciones
- general: otros
Responde solo con la categoría, sin más texto.
Problema: {problema[:300]}
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt_clasificacion}],
temperature=0,
max_tokens=20
)
tipo_str = response.choices[0].message.content.strip().lower()
try:
return TipoProbema(tipo_str)
except ValueError:
return TipoProbema.GENERAL
def resolver_dominio_especifico(
problema: str,
tipo: TipoProbema | None = None,
**kwargs
) -> ResultadoCoT:
"""
Resuelve un problema usando el template específico para su dominio.
Args:
problema: El problema a resolver
tipo: Tipo de problema (si None, se detecta automáticamente)
**kwargs: Parámetros adicionales para el template (contexto, restricciones, etc.)
Returns:
ResultadoCoT con análisis completo
"""
if tipo is None:
tipo = detectar_tipo_automatico(problema)
template = TEMPLATES[tipo]
# Construir el prompt según el tipo
if tipo == TipoProbema.VERIFICACION:
contexto = kwargs.get("contexto", "")
prompt = template.format(contexto=contexto, afirmacion=problema)
elif tipo == TipoProbema.MULTI_RESTRICCION:
restricciones = kwargs.get("restricciones", [])
restricciones_texto = "\n".join(f"- {r}" for r in restricciones)
prompt = template.format(problema=problema, restricciones=restricciones_texto)
else:
try:
prompt = template.format(problema=problema, **kwargs)
except KeyError:
prompt = f"{problema}\n\nPiensa paso a paso."
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0,
max_tokens=900
)
output = response.choices[0].message.content
import re
respuesta_match = re.search(
r'(?:Respuesta(?:\s+final)?|VEREDICTO|SOLUCIÓN ÓPTIMA)[:\s]+(.+?)(?:\n|$)',
output, re.IGNORECASE
)
return ResultadoCoT(
tipo=tipo,
problema=problema,
razonamiento=output,
respuesta_final=respuesta_match.group(1).strip() if respuesta_match else None,
tokens_usados=response.usage.total_tokens
)
# Demo del sistema
if __name__ == "__main__":
casos_prueba = [
("¿Cuánto es 17% de $350?", TipoProbema.MATEMATICA, {}),
("Todos los gatos son felinos. Felix es un gato. ¿Qué podemos concluir?", TipoProbema.LOGICA, {}),
("def suma(a, b):\n return a - b\nprint(suma(3, 4))", TipoProbema.CODIGO, {}),
]
for problema, tipo, kwargs in casos_prueba:
resultado = resolver_dominio_especifico(problema, tipo, **kwargs)
print(f"\n=== Tipo: {resultado.tipo.value} ===")
print(f"Respuesta final: {resultado.respuesta_final}")
print(f"Tokens: {resultado.tokens_usados}")
Troubleshooting por Dominio
Matemáticas: Errores de Cálculo en Pasos Intermedios
# ❌ Problema: El modelo hace 17 × 23 = 390 (error de cálculo)
# ✅ Solución: Pedir verificación del paso
MATH_COT_CON_VERIFICACION = """Resuelve el problema matemático.
Para cada operación:
1. Escribe la operación
2. Calcula el resultado
3. Verifica brevemente que es correcto
Problema: {problema}
"""
Lógica: Confusión con Doble Negación
# ❌ Problema: "No es cierto que Juan NO sea culpable" se interpreta incorrectamente
# ✅ Solución: Pedir conversión explícita a forma afirmativa
LOGIC_NEGATION_COT = """Antes de analizar el argumento, convierte todas las negaciones dobles a forma afirmativa.
"No es cierto que no X" → "X"
"No es falso que X" → "X"
Luego analiza la validez.
Argumento: {argumento}
"""
Código: El Modelo No Sigue la Ejecución Real
# ❌ Problema: El modelo "asume" qué hace el código sin seguir línea a línea
# ✅ Solución: Pedir traza explícita con valores
CODE_TRACE_COT = """Traza la ejecución línea por línea, mostrando el estado de TODAS las variables.
Formato de traza:
Línea N | variable1=valor1, variable2=valor2 | Comentario
Código:
```python
{codigo}
Input de prueba: {input_prueba} """
### Verificación Factual: Confusión con Información No Proporcionada
```python
# ❌ Problema: El modelo usa conocimiento del entrenamiento, no el contexto dado
# ✅ Solución: Instrucción explícita de solo usar contexto
STRICT_FACTUAL_COT = """IMPORTANTE: Solo usa la información del contexto proporcionado.
No uses tu conocimiento general. Si la información no está en el contexto,
escribe "NO PUEDE VERIFICARSE" aunque creas conocer la respuesta.
Contexto: {contexto}
Afirmación: {afirmacion}
Verifica paso a paso.
"""
Ejercicios
Ejercicio 1: Template para problemas de probabilidad condicional
Diseña un template CoT para resolver: "En una clase, 60% de los estudiantes son mujeres. El 70% de las mujeres aprueba el examen, y el 50% de los hombres aprueba. ¿Qué porcentaje del total aprueba?"
Ver solución
CONDITIONAL_PROB_COT = """Resuelve el problema de probabilidad condicional usando la Ley de Probabilidad Total.
Estructura:
1. DEFINIR GRUPOS: Identifica los subgrupos o particiones
2. PROBABILIDADES DADAS: Lista P(grupo) y P(evento|grupo) para cada grupo
3. LEY DE PROBABILIDAD TOTAL: P(evento) = Σ P(evento|grupo_i) × P(grupo_i)
4. CÁLCULO: Sustituye y calcula
5. VERIFICACIÓN: ¿La probabilidad está entre 0% y 100%?
Problema: {problema}
"""
problema = """
En una clase, 60% de los estudiantes son mujeres. El 70% de las mujeres
aprueba el examen, y el 50% de los hombres aprueba. ¿Qué porcentaje del total aprueba?
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": CONDITIONAL_PROB_COT.format(problema=problema)}],
temperature=0, max_tokens=500
)
print(response.choices[0].message.content)
# Respuesta esperada:
# P(mujeres) = 0.60, P(hombres) = 0.40
# P(aprueba|mujer) = 0.70
# P(aprueba|hombre) = 0.50
# P(aprueba) = 0.70×0.60 + 0.50×0.40 = 0.42 + 0.20 = 0.62 = 62%
Ejercicio 2: Diseñar CoT para análisis de complejidad algorítmica
Crea un template que ayude al modelo a calcular la complejidad O() de un algoritmo.
Ver solución
COMPLEXITY_COT = """Analiza la complejidad temporal del código dado.
Estructura:
1. IDENTIFICAR BUCLES: Lista todos los bucles (for, while) y su rango
2. BUCLES ANIDADOS: ¿Hay bucles dentro de bucles? Multiplica las complejidades
3. RECURSIÓN: Si hay recursión, escribe la ecuación de recurrencia T(n)
4. OPERACIONES DOMINANTES: ¿Cuál es la operación que más se repite?
5. COMPLEJIDAD FINAL: O(?) y justificación
6. COMPLEJIDAD ESPACIAL: O(?) para memoria
Código:
```python
{codigo}
"""
Ejemplo de uso
codigo_ejemplo = """ def encontrar_par_suma(arr, objetivo): for i in range(len(arr)): for j in range(i+1, len(arr)): if arr[i] + arr[j] == objetivo: return (arr[i], arr[j]) return None """
response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": COMPLEXITY_COT.format(codigo=codigo_ejemplo)}], temperature=0, max_tokens=400 ) print(response.choices[0].message.content)
Esperado: O(n²) temporal, O(1) espacial
</details>
### Ejercicio 3: CoT para evaluación de riesgo de crédito
Diseña un template CoT para decidir si otorgar un préstamo a un solicitante.
<details>
<summary>Ver solución</summary>
```python
CREDIT_RISK_COT = """Evalúa el riesgo crediticio del solicitante y recomienda si otorgar o no el préstamo.
Estructura:
1. INGRESOS Y CAPACIDAD DE PAGO
- Ingreso mensual: {ingreso}
- Cuota propuesta: {cuota}
- Ratio cuota/ingreso: calcular (ideal < 30%)
2. HISTORIAL CREDITICIO
- Score: {score} (>700: bueno, 600-700: regular, <600: malo)
- Deudas actuales: {deudas_actuales}
3. GARANTÍAS
- Colateral ofrecido: {colateral}
- Relación garantía/préstamo: calcular
4. FACTORES DE RIESGO
- Lista factores que aumentan riesgo
- Lista factores que reducen riesgo
5. DECISIÓN: APROBAR / RECHAZAR / APROBAR_CON_CONDICIONES
6. JUSTIFICACIÓN: Razón principal de la decisión
Datos del solicitante: {datos_solicitante}
"""
datos = {
"ingreso": "$5,000/mes",
"cuota": "$1,200/mes",
"score": 680,
"deudas_actuales": "$8,000",
"colateral": "Automóvil valuado en $15,000",
"datos_solicitante": "Empleado estable 3 años, solicita $20,000 a 24 meses"
}
print(CREDIT_RISK_COT.format(**datos))
Ejercicio 4: Comparar templates de verificación factual
Prueba FACTUAL_VERIFY_COT y STRICT_FACTUAL_COT con el mismo contexto y afirmación. ¿En qué casos difieren?
Ver solución
contexto = """
El producto X tiene las siguientes características:
- Precio: $299
- Garantía: 1 año
- Disponible en: rojo, azul, verde
- Peso: 1.5 kg
"""
afirmaciones_test = [
"El producto X cuesta menos de $300", # Verificable, correcto
"El producto X está disponible en negro", # Verificable, incorrecto
"El producto X es el más vendido del mercado", # No puede verificarse con contexto
]
for afirmacion in afirmaciones_test:
print(f"\nAfirmación: {afirmacion}")
# Template estándar (puede usar conocimiento externo)
r1 = verificar_afirmacion(contexto, afirmacion)
print(f"Estándar: {r1['veredicto']} ({r1['confianza']})")
# Template estricto (solo contexto)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": STRICT_FACTUAL_COT.format(
contexto=contexto, afirmacion=afirmacion
)}],
temperature=0, max_tokens=300
)
print(f"Estricto: {response.choices[0].message.content[-100:]}")
Diferencia clave: Para "el más vendido del mercado", el template estándar podría dar opinión basada en conocimiento general del modelo, mientras el template estricto forzará "NO PUEDE VERIFICARSE".
Ejercicio 5: Template para problemas de programación dinámica
Diseña un template CoT que guíe al modelo a resolver problemas clásicos de programación dinámica (ej: la mochila, Fibonacci, LCS).
Ver solución
DP_COT = """Resuelve el problema usando programación dinámica.
Estructura:
1. SUBPROBLEMAS: ¿Cómo se descompone el problema en subproblemas más pequeños?
2. ESTADO: ¿Qué define un estado? (variables que cambian en la recursión)
3. TRANSICIÓN: ¿Cómo se calcula dp[estado] a partir de estados anteriores?
4. CASO BASE: ¿Cuáles son los valores iniciales?
5. TABLA DP: Completa la tabla para inputs pequeños (mostrar matriz)
6. RESULTADO: ¿En qué celda está la respuesta final?
7. CÓDIGO: Implementa la solución
Problema: {problema}
"""
problema_mochila = """
Mochila 0/1: Tienes una mochila con capacidad 7 kg.
Objetos disponibles:
- Objeto A: peso=2, valor=3
- Objeto B: peso=3, valor=4
- Objeto C: peso=4, valor=5
- Objeto D: peso=5, valor=6
¿Qué objetos llevar para maximizar el valor total sin exceder la capacidad?
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": DP_COT.format(problema=problema_mochila)}],
temperature=0, max_tokens=900
)
print(response.choices[0].message.content)
# Respuesta óptima: A + B + C = 2+3+4=9kg... no, A+B+D=2+3+5=10...
# Óptimo: A+C = 2+4=6kg, valor=8. O A+B=5kg, valor=7. O B+C=7kg, valor=9. → B+C es óptimo
Resumen
- Math/Aritmética: Pasos operación por operación, resultado intermedio explícito, verificación backward
- Lógica: Premisas formales → forma simbólica → regla de inferencia → veredicto
- Código: Traza de ejecución línea a línea → identificación de error → corrección → edge cases
- Verificación factual: Afirmación explícita → evidencia en contexto → veredicto + confianza
- Multi-restricción: Lista restricciones → candidato → verificar cada restricción con ✓/✗
- Optimización: Objetivo → variables → candidatos → comparación → solución óptima verificada