""" 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"}, )