diff --git a/.env.example b/.env.example index 953d9f4..ab62818 100644 --- a/.env.example +++ b/.env.example @@ -9,6 +9,7 @@ FLASK_ENV=production AI_MODEL=gpt-3.5-turbo # 模型名称,例如: gpt-4, claude-3-sonnet-20240229, gemini-pro AI_API_KEY= # API密钥 # AI_API_BASE= # 可选:自定义API端点 +# AI_CUSTOM_PROVIDER= # 可选:自定义端点的API格式(如 'openai',用于兼容OpenAI格式的自定义端点) # AI_TEMPERATURE=0.7 # 可选:温度参数(0-1) # AI_MAX_TOKENS=500 # 可选:最大token数 @@ -21,6 +22,12 @@ AI_API_KEY= # API密钥 # Gemini: gemini-pro, gemini-1.5-pro # 更多模型请参考: https://docs.litellm.ai/docs/providers +# 自定义端点示例(使用兼容OpenAI格式的API调用Gemini模型): +# AI_MODEL=gemini-pro +# AI_API_KEY=your_api_key_here +# AI_API_BASE=https://your-custom-endpoint.com/v1 +# AI_CUSTOM_PROVIDER=openai # 指定使用OpenAI格式的API调用 + # 默认用户配置 # Docker首次启动时会自动创建此用户 DEFAULT_USERNAME=admin diff --git a/backend/ai_service.py b/backend/ai_service.py index 0fd6546..d5edfe4 100644 --- a/backend/ai_service.py +++ b/backend/ai_service.py @@ -12,24 +12,31 @@ class AIService: - OpenAI (gpt-3.5-turbo, gpt-4等) - Anthropic Claude (claude-3-opus, claude-3-sonnet等) - Google Gemini (gemini-pro等) + - 自定义端点(兼容OpenAI格式的API) - 其他LiteLLM支持的所有模型 """ # 获取AI配置 self.model = os.getenv('AI_MODEL', 'gpt-3.5-turbo') self.api_key = os.getenv('AI_API_KEY', os.getenv('OPENAI_API_KEY')) # 兼容旧配置 self.api_base = os.getenv('AI_API_BASE') # 可选:自定义API端点 + self.custom_llm_provider = os.getenv('AI_CUSTOM_PROVIDER') # 可选:自定义端点的API格式(如 'openai') self.temperature = float(os.getenv('AI_TEMPERATURE', '0.7')) self.max_tokens = int(os.getenv('AI_MAX_TOKENS', '500')) # 设置环境变量供LiteLLM使用 if self.api_key: + # 如果使用自定义端点,优先使用OPENAI_API_KEY(兼容OpenAI格式的端点) + if self.api_base and self.custom_llm_provider == 'openai': + os.environ['OPENAI_API_KEY'] = self.api_key # 根据模型类型设置相应的环境变量 - if self.model.startswith('gpt-'): + elif self.model.startswith('gpt-'): os.environ['OPENAI_API_KEY'] = self.api_key elif self.model.startswith('claude-'): os.environ['ANTHROPIC_API_KEY'] = self.api_key elif self.model.startswith('gemini-'): - os.environ['GEMINI_API_KEY'] = self.api_key + # 如果没有设置自定义provider,使用默认的Gemini API Key + if not self.custom_llm_provider: + os.environ['GEMINI_API_KEY'] = self.api_key # LiteLLM会自动处理其他模型的API密钥 def polish_description(self, description): @@ -67,6 +74,10 @@ class AIService: if self.api_base: kwargs["api_base"] = self.api_base + # 如果设置了自定义provider(用于兼容OpenAI格式的自定义端点) + if self.custom_llm_provider: + kwargs["custom_llm_provider"] = self.custom_llm_provider + # 使用LiteLLM统一接口调用 response = completion(**kwargs) diff --git a/test_ai_config.py b/test_ai_config.py new file mode 100644 index 0000000..65aad81 --- /dev/null +++ b/test_ai_config.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +""" +AI服务配置测试脚本 + +测试不同的AI服务配置是否正确工作,包括自定义端点支持 +""" + +import os +import sys +from dotenv import load_dotenv + +# 添加backend目录到路径 +sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'backend')) + +from ai_service import AIService + +def test_configuration(): + """测试AI服务配置""" + print("=" * 60) + print("AI服务配置测试") + print("=" * 60) + + # 加载环境变量 + load_dotenv() + + # 创建AI服务实例 + ai = AIService() + + # 显示配置信息 + print(f"\n当前配置:") + print(f" 模型: {ai.model}") + print(f" API密钥: {'已配置' if ai.api_key and ai.api_key != 'your_api_key_here' else '未配置'}") + print(f" 自定义端点: {ai.api_base if ai.api_base else '未设置'}") + print(f" 自定义Provider: {ai.custom_llm_provider if ai.custom_llm_provider else '未设置'}") + print(f" 温度: {ai.temperature}") + print(f" 最大Token数: {ai.max_tokens}") + + # 获取模型信息 + model_info = ai.get_model_info() + print(f"\n模型信息:") + print(f" 服务商: {model_info['provider']}") + print(f" 可用性: {'是' if model_info['available'] else '否'}") + + # 显示使用场景说明 + print(f"\n配置说明:") + + if ai.custom_llm_provider == 'openai' and ai.api_base: + print(" ✓ 检测到自定义OpenAI格式端点配置") + print(" → 将使用OpenAI兼容格式调用API") + print(f" → 端点: {ai.api_base}") + print(f" → 模型: {ai.model}") + elif ai.model.startswith('gemini-') and not ai.custom_llm_provider: + print(" ✓ 使用原生Gemini API") + print(" → 需要设置 GEMINI_API_KEY 或 AI_API_KEY") + elif ai.model.startswith('claude-'): + print(" ✓ 使用原生Claude API") + print(" → 需要设置 ANTHROPIC_API_KEY 或 AI_API_KEY") + elif ai.model.startswith('gpt-'): + print(" ✓ 使用原生OpenAI API") + print(" → 需要设置 OPENAI_API_KEY 或 AI_API_KEY") + + # 环境变量检查 + print(f"\n环境变量检查:") + env_vars = { + 'AI_MODEL': os.getenv('AI_MODEL'), + 'AI_API_KEY': '已设置' if os.getenv('AI_API_KEY') else '未设置', + 'AI_API_BASE': os.getenv('AI_API_BASE', '未设置'), + 'AI_CUSTOM_PROVIDER': os.getenv('AI_CUSTOM_PROVIDER', '未设置'), + 'OPENAI_API_KEY': '已设置' if os.getenv('OPENAI_API_KEY') else '未设置', + 'ANTHROPIC_API_KEY': '已设置' if os.getenv('ANTHROPIC_API_KEY') else '未设置', + 'GEMINI_API_KEY': '已设置' if os.getenv('GEMINI_API_KEY') else '未设置', + } + + for key, value in env_vars.items(): + print(f" {key}: {value}") + + print("\n" + "=" * 60) + + # 测试AI功能(如果配置了API密钥) + if ai.is_available(): + print("\n是否要测试AI润色功能? (y/n): ", end='') + try: + choice = input().strip().lower() + if choice == 'y': + test_text = "完成项目文档" + print(f"\n测试文本: {test_text}") + print("正在调用AI服务...") + + try: + result = ai.polish_description(test_text) + print(f"\n润色结果: {result}") + print("\n✓ AI服务测试成功!") + except Exception as e: + print(f"\n✗ AI服务测试失败: {e}") + except KeyboardInterrupt: + print("\n跳过测试") + else: + print("\nAI服务未配置或配置不正确,跳过功能测试") + + print("\n配置示例:") + print("\n1. 使用原生Gemini API:") + print(" AI_MODEL=gemini-pro") + print(" AI_API_KEY=your_gemini_api_key") + + print("\n2. 使用OpenAI格式的自定义端点调用Gemini:") + print(" AI_MODEL=gemini-pro") + print(" AI_API_KEY=your_api_key") + print(" AI_API_BASE=https://your-endpoint.com/v1") + print(" AI_CUSTOM_PROVIDER=openai") + + print("\n3. 使用原生OpenAI API:") + print(" AI_MODEL=gpt-3.5-turbo") + print(" AI_API_KEY=your_openai_api_key") + + print("\n" + "=" * 60) + +if __name__ == '__main__': + test_configuration()