Primera fase: se construyen las funciones para las primeras 12 preguntas

This commit is contained in:
Mongar28
2025-10-30 11:05:14 -05:00
parent e2b027026d
commit 878ff1e9f3
16 changed files with 1953 additions and 0 deletions

3
llm/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
"""
Archivo __init__.py para marcar el directorio como un paquete Python.
"""

78
llm/config.py Normal file
View File

@@ -0,0 +1,78 @@
"""
Módulo para la configuración de modelos de lenguaje.
Este módulo proporciona clases para manejar la configuración
de diferentes modelos de lenguaje de manera estructurada.
"""
from typing import Dict, Any, Optional
class LLMConfig:
"""
Clase para manejar la configuración de los modelos de lenguaje.
Esta clase encapsula todos los parámetros necesarios para crear
un modelo de lenguaje, facilitando su gestión y reutilización.
"""
def __init__(
self,
provider: str,
model_name: Optional[str] = None,
temperature: float = 0.0,
**kwargs
):
"""
Inicializa una configuración para un modelo de lenguaje.
Args:
provider: Proveedor del modelo (openai, anthropic)
model_name: Nombre del modelo específico (opcional)
temperature: Temperatura para la generación (default: 0.0)
**kwargs: Parámetros adicionales específicos del modelo
"""
self.provider = provider
self.model_name = model_name
self.temperature = temperature
self.extra_params = kwargs
def as_dict(self) -> Dict[str, Any]:
"""
Convierte la configuración a un diccionario.
Returns:
Diccionario con todos los parámetros de configuración
"""
config = {
"temperature": self.temperature,
}
# Añadir el nombre del modelo si está definido
if self.model_name:
config["model_name"] = self.model_name
# Añadir parámetros adicionales
config.update(self.extra_params)
return config
@classmethod
def default_openai(cls) -> 'LLMConfig':
"""
Crea una configuración predeterminada para OpenAI.
Returns:
Configuración predeterminada para OpenAI
"""
return cls(provider="openai", model_name="o4-mini")
@classmethod
def default_anthropic(cls) -> 'LLMConfig':
"""
Crea una configuración predeterminada para Anthropic.
Returns:
Configuración predeterminada para Anthropic
"""
return cls(provider="anthropic", model_name="claude-3-5-haiku-20241022")

110
llm/context.py Normal file
View File

@@ -0,0 +1,110 @@
"""
Módulo que implementa el contexto del patrón Strategy para modelos de lenguaje.
Este módulo contiene la clase LLMContext que mantiene una referencia a la
estrategia actual y delega en ella la creación del modelo de lenguaje.
"""
from typing import Dict, Any, Optional
from .strategies import (
LLMStrategy,
OpenAIO4MiniStrategy,
OpenAIGPT41MiniStrategy,
AnthropicHaikuStrategy,
AnthropicSonnet37Strategy,
AnthropicHaiku45Strategy,
)
from .config import LLMConfig
class LLMContext:
"""
Contexto que utiliza diferentes estrategias para crear modelos de lenguaje.
Esta clase es el punto central de interacción con el sistema de modelos.
Mantiene una referencia a la estrategia actual y delega la creación
del modelo a dicha estrategia.
"""
def __init__(self):
"""
Inicializa el contexto con las estrategias disponibles.
"""
# Mapeo de proveedores y modelos a estrategias
self._strategies = {
"openai": {
"o4-mini": OpenAIO4MiniStrategy(),
"gpt-4.1-mini": OpenAIGPT41MiniStrategy(),
},
"anthropic": {
"claude-3-5-haiku-20241022": AnthropicHaikuStrategy(),
"claude-sonnet-4-5": AnthropicSonnet37Strategy(),
"claude-haiku-4-5": AnthropicHaiku45Strategy(),
},
}
self._current_strategy: Optional[LLMStrategy] = None
self._config: Optional[Dict[str, Any]] = None
def set_strategy(self, config: LLMConfig) -> None:
"""
Establece la estrategia actual basada en la configuración.
Args:
config: Configuración del modelo
Raises:
ValueError: Si el proveedor o modelo no están soportados
"""
provider = config.provider.lower()
# Verificar que el proveedor es válido
if provider not in self._strategies:
raise ValueError(f"Proveedor no soportado: {provider}")
# Si se especificó un modelo, usarlo
if config.model_name:
model_name = config.model_name
if model_name not in self._strategies[provider]:
raise ValueError(f"Modelo no soportado para {provider}: {model_name}")
self._current_strategy = self._strategies[provider][model_name]
else:
# Si no se especificó un modelo, usar el primero disponible
self._current_strategy = next(iter(self._strategies[provider].values()))
# Guardar la configuración
self._config = config.as_dict()
def get_llm(self):
"""
Crea y devuelve un modelo de lenguaje usando la estrategia actual.
Returns:
Instancia del modelo de lenguaje
Raises:
ValueError: Si no se ha establecido una estrategia
"""
if not self._current_strategy:
raise ValueError("No se ha establecido una estrategia")
return self._current_strategy.create_llm(self._config)
def register_strategy(
self, provider: str, model_name: str, strategy: LLMStrategy
) -> None:
"""
Registra una nueva estrategia.
Args:
provider: Nombre del proveedor (openai, anthropic)
model_name: Nombre del modelo
strategy: Instancia de la estrategia a registrar
"""
provider = provider.lower()
# Crear el diccionario del proveedor si no existe
if provider not in self._strategies:
self._strategies[provider] = {}
# Registrar la estrategia
self._strategies[provider][model_name] = strategy

131
llm/strategies.py Normal file
View File

@@ -0,0 +1,131 @@
"""
Módulo que define la interfaz de estrategia y las implementaciones concretas
para diferentes modelos de lenguaje (LLM).
"""
from abc import ABC, abstractmethod
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from typing import Any, Dict, Optional
from dotenv import load_dotenv
load_dotenv()
# 1.Interfaz de la estrategia
class LLMStrategy(ABC):
"""Interfaz para todas las estrategias de modelos de lenguaje.
Esta clase define la interfaz commún que todas las estrategias
concretas deben implementar.
"""
@abstractmethod
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> Any:
"""Crea una instancia de modelo de lenguaje según la configuración.
Args:
config: Diccionario con la configuración del modelo.
Returns:
Instancia del modelo de lenguaje.
"""
pass
class OpenAIO4MiniStrategy(LLMStrategy):
"""Estrategia para el modelo OpenAI o4-mini"""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatOpenAI:
"""
Implementación concreta para crear un modelo OpenAI o4-mini
Args:
config: Configuración opcional para el modelo (no utilizada)
Returns:
ChatOpenAI: Instancia del modelo o4-mini
"""
# Para o4-mini solo pasamos el nombre del modelo sin parámetros adicionales
return ChatOpenAI(model="o4-mini")
class OpenAIGPT41MiniStrategy(LLMStrategy):
"""Estrategia para el modelo OpenAI GPT-4.1-mini."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatOpenAI:
"""
Implementación concreta para crear un modelo OpenAI GPT-4.1-mini.
Args:
config: Configuración opcional para el modelo
Returns:
ChatOpenAI: Una instancia del modelo gpt-4.1-mini
"""
config = config or {}
temperature = config.get("temperature", 0.0)
return ChatOpenAI(
model="gpt-4.1-mini",
temperature=temperature,
**{k: v for k, v in config.items() if k != "temperature"},
)
class AnthropicHaikuStrategy(LLMStrategy):
"""Estrategia para el modelo Anthropic Claude 3.5 Haiku."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatAnthropic:
"""
Implementación concreta para crear un modelo Anthropic Claude 3.5 Haiku.
Args:
config: Configuración opcional para el modelo
Returns:
ChatAnthropic: Una instancia del modelo claude-3-5-haiku
"""
config = config or {}
temperature = config.get("temperature", 0.0)
return ChatAnthropic(
model="claude-3-5-haiku-20241022",
temperature=temperature,
**{k: v for k, v in config.items() if k != "temperature"},
)
class AnthropicSonnet37Strategy(LLMStrategy):
"""Estrategia para el modelo Anthropic Claude 4.5 Sonnet."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatAnthropic:
"""
Implementación concreta para crear un modelo Anthropic Claude 4.5 Sonnet.
Args:
config: Configuración opcional para el modelo (no utilizada)
Returns:
ChatAnthropic: Una instancia del modelo claude-sonnet-4-5
"""
return ChatAnthropic(model="claude-sonnet-4-5")
class AnthropicHaiku45Strategy(LLMStrategy):
"""Estrategia para el modelo Anthropic Claude Haiku 4-5."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatAnthropic:
"""
Implementación concreta para crear un modelo Anthropic Claude Haiku 4-5.
Args:
config: Configuración opcional para el modelo
Returns:
ChatAnthropic: Una instancia del modelo claude-haiku-4-5
"""
config = config or {}
temperature = config.get("temperature", 0.0)
return ChatAnthropic(
model="claude-haiku-4-5", # <-- Nombre exacto del modelo
temperature=temperature,
**{k: v for k, v in config.items() if k != "temperature"},
)