""" LLM 工厂模块 提供统一的 LLM 客户端构建接口 """ from typing import Optional from contextlib import contextmanager import os @contextmanager def temp_env_vars(vars_dict): """临时设置环境变量的上下文管理器""" old_values = {} for key, value in vars_dict.items(): old_values[key] = os.environ.get(key) os.environ[key] = value try: yield finally: for key, old_value in old_values.items(): if old_value is None: os.environ.pop(key, None) else: os.environ[key] = old_value def build_deepseek(api_key: str, model: str, temperature: float): """构建 DeepSeek LLM""" from langchain_deepseek import ChatDeepSeek return ChatDeepSeek(api_key=api_key, model=model, temperature=temperature) def build_openai(api_key: str, model: str, temperature: float): """构建 OpenAI LLM""" from langchain_openai import ChatOpenAI return ChatOpenAI(api_key=api_key, model=model, temperature=temperature) def build_tongyi(api_key: str, model: str, temperature: float): """构建通义千问 LLM""" try: from langchain_community.chat_models import ChatTongyi return ChatTongyi(api_key=api_key, model=model, model_kwargs={"temperature": temperature}) except Exception: from langchain_aliyun import ChatTongyi # type: ignore return ChatTongyi(api_key=api_key, model=model, temperature=temperature) def build_groq(api_key: str, model: str, temperature: float): """构建 Groq LLM""" from langchain_groq import ChatGroq return ChatGroq(api_key=api_key, model=model, temperature=temperature) def build_moonshot(api_key: str, model: str, temperature: float): """构建 Moonshot (Kimi) LLM""" try: from langchain_moonshot import ChatMoonshot # type: ignore return ChatMoonshot(api_key=api_key, model=model, temperature=temperature) except Exception: from langchain_community.chat_models import MoonshotChat # type: ignore return MoonshotChat(api_key=api_key, model=model, temperature=temperature) def build_doubao(api_key: str, temperature: float): """构建豆包 LLM""" try: from modules.chat_doubao import create_chat_doubao return create_chat_doubao(api_key=api_key, temperature=temperature) except ImportError as e: raise ValueError(f"豆包初始化失败:缺少依赖库。请运行:pip install 'volcengine-python-sdk[ark]'。错误:{e}") except Exception as e: raise ValueError(f"豆包初始化失败:{e}。请确保 API Key 格式为:access_key:secret_key:endpoint_id") def build_wenxin(api_key: str, model: str, temperature: float): """构建文心一言 LLM""" parts = api_key.split(":") if len(parts) != 2: raise ValueError("文心一言 API Key 格式错误,应为:app_key:app_secret(用冒号分隔)") app_key, app_secret = parts # 优先使用 langchain-community 的千帆接口(已包含在依赖中) try: from langchain_community.chat_models import QianfanChatEndpoint with temp_env_vars({"QIANFAN_AK": app_key, "QIANFAN_SK": app_secret}): return QianfanChatEndpoint( model=model if model else "ernie-bot-turbo", temperature=temperature, ) except ImportError: # 备选方案:尝试 langchain-wenxin try: from langchain_wenxin import ChatWenxin return ChatWenxin( baidu_api_key=app_key, baidu_secret_key=app_secret, model=model if model else "ernie-bot-turbo", temperature=temperature, ) except ImportError as e: raise ValueError(f"文心一言初始化失败:缺少依赖库。请运行:pip install qianfan(或使用已安装的 langchain-community)。错误:{e}") except Exception as e: raise ValueError(f"文心一言初始化失败:{e}") # Provider 映射表 PROVIDER_BUILDERS = { "DeepSeek": lambda api_key, model, temp: build_deepseek(api_key, model, temp), "OpenAI (GPT)": lambda api_key, model, temp: build_openai(api_key, model, temp), "Tongyi (通义千问)": lambda api_key, model, temp: build_tongyi(api_key, model, temp), "Groq": lambda api_key, model, temp: build_groq(api_key, model, temp), "Moonshot (Kimi)": lambda api_key, model, temp: build_moonshot(api_key, model, temp), "豆包(字节跳动)": lambda api_key, model, temp: build_doubao(api_key, temp), "文心一言(百度)": lambda api_key, model, temp: build_wenxin(api_key, model, temp), } def build_llm(provider: str, api_key: str, model: str, temperature: float): """ 统一的 LLM 构建接口 Args: provider: 提供商名称 api_key: API Key model: 模型名称 temperature: 温度参数 Returns: LLM 实例 Raises: ValueError: 不支持的提供商或初始化失败 """ builder = PROVIDER_BUILDERS.get(provider) if builder is None: raise ValueError(f"不支持的 LLM 提供商: {provider}") return builder(api_key, model, temperature) def get_supported_providers(): """获取支持的提供商列表""" return list(PROVIDER_BUILDERS.keys()) def get_default_model(provider: str) -> str: """获取提供商的默认模型""" defaults = { "DeepSeek": "deepseek-chat", "OpenAI (GPT)": "gpt-4o-mini", "Tongyi (通义千问)": "qwen-max", "Groq": "llama3-70b-8192", "Moonshot (Kimi)": "moonshot-v1-128k", "豆包(字节跳动)": "", "文心一言(百度)": "ernie-bot-turbo", } return defaults.get(provider, "")