更新环境配置,支持多种AI服务提供商(华为和硅基流动),增强API调用的灵活性和可配置性,同时更新文档以反映新的配置选项和使用说明。

This commit is contained in:
python 2025-12-10 10:05:45 +08:00
parent cd27bb4bd0
commit 11be119ffc
5 changed files with 447 additions and 94 deletions

58
.env
View File

@ -1,18 +1,68 @@
# 华为大模型API配置必需
# ========== AI服务提供商配置 ==========
# 选择使用的AI服务提供商
# 可选值: 'huawei' 或 'siliconflow'
# 默认值: 'siliconflow'
AI_PROVIDER=siliconflow
# ========== 华为大模型API配置 ==========
# 当 AI_PROVIDER=huawei 时使用以下配置
# API端点地址
HUAWEI_API_ENDPOINT=http://10.100.31.26:3001/v1/chat/completions
# API密钥
HUAWEI_API_KEY=sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186
HUAWEI_API_TIMEOUT=900
# 模型名称
HUAWEI_MODEL=DeepSeek-R1-Distill-Llama-70B
# 数据库配置
# API超时配置
# 开启思考模式时,响应时间会显著增加,需要更长的超时时间
# 默认180秒3分钟
HUAWEI_API_TIMEOUT=180
# API最大token数配置
# 开启思考模式时模型可能生成更长的响应需要更多的token
# 默认12000
HUAWEI_API_MAX_TOKENS=12000
# ========== 硅基流动API配置 ==========
# 当 AI_PROVIDER=siliconflow 时使用以下配置
# API端点地址默认值通常不需要修改
SILICONFLOW_URL=https://api.siliconflow.cn/v1/chat/completions
# API密钥必需
SILICONFLOW_API_KEY=sk-pgujibohpenkomkwlufexmqzyckglgogdiubfplgqxkfqgfu
# 模型名称(默认值,通常不需要修改)
SILICONFLOW_MODEL=Qwen/Qwen2.5-72B-Instruct
# API超时配置
# 默认120秒
SILICONFLOW_API_TIMEOUT=120
# API最大token数配置
# 默认2000
SILICONFLOW_API_MAX_TOKENS=2000
# ========== 数据库配置 ==========
DB_HOST=152.136.177.240
DB_PORT=5012
DB_USER=finyx
DB_PASSWORD=6QsGK6MpePZDE57Z
DB_NAME=finyx
# ========== MinIO配置可选文档生成功能需要 ==========
MINIO_ENDPOINT=minio.datacubeworld.com:9000
MINIO_ACCESS_KEY=JOLXFXny3avFSzB0uRA5
MINIO_SECRET_KEY=G1BR8jStNfovkfH5ou39EmPl34E4l7dGrnd3Cz0I
MINIO_BUCKET=finyx
MINIO_SECURE=true
# ========== 服务配置 ==========
# 服务端口
PORT=7500
# 调试模式true/false
DEBUG=False

View File

@ -1,4 +1,12 @@
# 华为大模型API配置必需
# ========== AI服务提供商配置 ==========
# 选择使用的AI服务提供商
# 可选值: 'huawei' 或 'siliconflow'
# 默认值: 'siliconflow'
AI_PROVIDER=siliconflow
# ========== 华为大模型API配置 ==========
# 当 AI_PROVIDER=huawei 时使用以下配置
# API端点地址
HUAWEI_API_ENDPOINT=http://10.100.31.26:3001/v1/chat/completions
@ -8,9 +16,53 @@ HUAWEI_API_KEY=sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186
# 模型名称
HUAWEI_MODEL=DeepSeek-R1-Distill-Llama-70B
# 数据库配置
# API超时配置
# 开启思考模式时,响应时间会显著增加,需要更长的超时时间
# 默认180秒3分钟
HUAWEI_API_TIMEOUT=180
# API最大token数配置
# 开启思考模式时模型可能生成更长的响应需要更多的token
# 默认12000
HUAWEI_API_MAX_TOKENS=12000
# ========== 硅基流动API配置 ==========
# 当 AI_PROVIDER=siliconflow 时使用以下配置
# API端点地址默认值通常不需要修改
SILICONFLOW_URL=https://api.siliconflow.cn/v1/chat/completions
# API密钥必需
SILICONFLOW_API_KEY=sk-pgujibohpenkomkwlufexmqzyckglgogdiubfplgqxkfqgfu
# 模型名称(默认值,通常不需要修改)
SILICONFLOW_MODEL=Qwen/Qwen2.5-72B-Instruct
# API超时配置
# 默认120秒
SILICONFLOW_API_TIMEOUT=120
# API最大token数配置
# 默认2000
SILICONFLOW_API_MAX_TOKENS=2000
# ========== 数据库配置 ==========
DB_HOST=152.136.177.240
DB_PORT=5012
DB_USER=finyx
DB_PASSWORD=6QsGK6MpePZDE57Z
DB_NAME=finyx
# ========== MinIO配置可选文档生成功能需要 ==========
MINIO_ENDPOINT=minio.datacubeworld.com:9000
MINIO_ACCESS_KEY=JOLXFXny3avFSzB0uRA5
MINIO_SECRET_KEY=G1BR8jStNfovkfH5ou39EmPl34E4l7dGrnd3Cz0I
MINIO_BUCKET=finyx
MINIO_SECURE=true
# ========== 服务配置 ==========
# 服务端口
PORT=7500
# 调试模式true/false
DEBUG=False

View File

@ -6,7 +6,10 @@
- ✅ AI解析接口 (`/api/ai/extract`) - 从输入文本中提取结构化字段
- ✅ 字段配置管理 - 从数据库读取字段配置
- ✅ 支持华为大模型DeepSeek-R1-Distill-Llama-70B
- ✅ 支持多种AI服务提供商
- 华为大模型DeepSeek-R1-Distill-Llama-70B
- 硅基流动DeepSeek-V3.2-Exp
- ✅ 可通过配置灵活切换AI服务提供商
- ✅ Web测试界面 - 可视化测试解析功能
## 项目结构
@ -69,20 +72,30 @@ copy .env.example .env
cp .env.example .env
```
编辑 `.env` 文件,填入你的API密钥
编辑 `.env` 文件,填入你的配置
```env
# 华为大模型API配置必需已内置默认值如需修改可调整
# API端点地址
# ========== AI服务提供商配置 ==========
# 选择使用的AI服务提供商
# 可选值: 'huawei' 或 'siliconflow'
# 默认值: 'siliconflow'
AI_PROVIDER=siliconflow
# ========== 华为大模型API配置当 AI_PROVIDER=huawei 时使用) ==========
HUAWEI_API_ENDPOINT=http://10.100.31.26:3001/v1/chat/completions
# API密钥
HUAWEI_API_KEY=sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186
# 模型名称
HUAWEI_MODEL=DeepSeek-R1-Distill-Llama-70B
HUAWEI_API_TIMEOUT=180
HUAWEI_API_MAX_TOKENS=12000
# 数据库配置(已默认配置,如需修改可调整)
# ========== 硅基流动API配置当 AI_PROVIDER=siliconflow 时使用) ==========
SILICONFLOW_URL=https://api.siliconflow.cn/v1/chat/completions
SILICONFLOW_API_KEY=your_siliconflow_api_key_here
SILICONFLOW_MODEL=deepseek-ai/DeepSeek-V3.2-Exp
SILICONFLOW_API_TIMEOUT=120
SILICONFLOW_API_MAX_TOKENS=2000
# ========== 数据库配置 ==========
DB_HOST=152.136.177.240
DB_PORT=5012
DB_USER=finyx
@ -90,6 +103,13 @@ DB_PASSWORD=6QsGK6MpePZDE57Z
DB_NAME=finyx
```
**AI服务提供商选择说明**
- **华为大模型**:设置 `AI_PROVIDER=huawei`,并配置 `HUAWEI_API_KEY``HUAWEI_API_ENDPOINT`
- **硅基流动**:设置 `AI_PROVIDER=siliconflow`(默认值),并配置 `SILICONFLOW_API_KEY`
如果配置的AI服务不完整系统会自动尝试使用另一个可用的服务。
**华为大模型API调用示例**
```bash

View File

@ -31,7 +31,12 @@ class AIService:
"""AI服务类"""
def __init__(self):
# 华为大模型配置(必需)
# ========== AI服务提供商选择 ==========
# 通过环境变量 AI_PROVIDER 选择使用的AI服务
# 可选值: 'huawei' 或 'siliconflow',默认为 'siliconflow'
self.ai_provider_config = os.getenv('AI_PROVIDER', 'siliconflow').lower()
# ========== 华为大模型配置 ==========
self.huawei_api_endpoint = os.getenv('HUAWEI_API_ENDPOINT', 'http://10.100.31.26:3001/v1/chat/completions')
self.huawei_api_key = os.getenv('HUAWEI_API_KEY', 'sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186')
self.huawei_model = os.getenv('HUAWEI_MODEL', 'DeepSeek-R1-Distill-Llama-70B')
@ -39,16 +44,39 @@ class AIService:
# API超时配置
# 开启思考模式时,响应时间会显著增加,需要更长的超时时间
# 可以通过环境变量 HUAWEI_API_TIMEOUT 自定义默认180秒3分钟
self.api_timeout = int(os.getenv('HUAWEI_API_TIMEOUT', '180'))
self.huawei_api_timeout = int(os.getenv('HUAWEI_API_TIMEOUT', '180'))
# API最大token数配置
# 开启思考模式时模型可能生成更长的响应需要更多的token
# 可以通过环境变量 HUAWEI_API_MAX_TOKENS 自定义默认12000
self.api_max_tokens = int(os.getenv('HUAWEI_API_MAX_TOKENS', '12000'))
self.huawei_api_max_tokens = int(os.getenv('HUAWEI_API_MAX_TOKENS', '12000'))
# ========== 硅基流动配置 ==========
self.siliconflow_url = os.getenv('SILICONFLOW_URL', 'https://api.siliconflow.cn/v1/chat/completions')
self.siliconflow_api_key = os.getenv('SILICONFLOW_API_KEY', '')
self.siliconflow_model = os.getenv('SILICONFLOW_MODEL', 'deepseek-ai/DeepSeek-V3.2-Exp')
# API超时配置
self.siliconflow_api_timeout = int(os.getenv('SILICONFLOW_API_TIMEOUT', '120'))
# API最大token数配置
self.siliconflow_api_max_tokens = int(os.getenv('SILICONFLOW_API_MAX_TOKENS', '2000'))
# 确定使用的AI服务
self.ai_provider = self._determine_ai_provider()
# 根据选择的提供商设置当前使用的超时和token配置
if self.ai_provider == 'huawei':
self.api_timeout = self.huawei_api_timeout
self.api_max_tokens = self.huawei_api_max_tokens
elif self.ai_provider == 'siliconflow':
self.api_timeout = self.siliconflow_api_timeout
self.api_max_tokens = self.siliconflow_api_max_tokens
else:
# 默认值
self.api_timeout = 120
self.api_max_tokens = 2000
# 初始化AI日志记录器
if AI_LOGGER_AVAILABLE:
try:
@ -60,11 +88,48 @@ class AIService:
self.ai_logger = None
def _determine_ai_provider(self) -> str:
"""确定使用的AI服务提供商仅支持华为大模型"""
if self.huawei_api_endpoint and self.huawei_api_key:
return 'huawei'
"""
确定使用的AI服务提供商
根据 AI_PROVIDER 环境变量配置选择支持 'huawei' 'siliconflow'
"""
# 根据配置选择服务提供商
if self.ai_provider_config == 'huawei':
# 检查华为大模型配置是否完整
if self.huawei_api_endpoint and self.huawei_api_key:
print(f"[AI服务] 使用华为大模型: {self.huawei_model}")
return 'huawei'
else:
print(f"[AI服务] 警告: 配置为使用华为大模型,但配置不完整,尝试使用硅基流动")
# 如果华为配置不完整,尝试使用硅基流动
if self.siliconflow_api_key and self.siliconflow_url:
print(f"[AI服务] 使用硅基流动: {self.siliconflow_model}")
return 'siliconflow'
else:
return 'none'
elif self.ai_provider_config == 'siliconflow':
# 检查硅基流动配置是否完整
if self.siliconflow_api_key and self.siliconflow_url:
print(f"[AI服务] 使用硅基流动: {self.siliconflow_model}")
return 'siliconflow'
else:
print(f"[AI服务] 警告: 配置为使用硅基流动,但配置不完整,尝试使用华为大模型")
# 如果硅基流动配置不完整,尝试使用华为大模型
if self.huawei_api_endpoint and self.huawei_api_key:
print(f"[AI服务] 使用华为大模型: {self.huawei_model}")
return 'huawei'
else:
return 'none'
else:
return 'none'
# 未知的配置值,尝试自动检测
print(f"[AI服务] 警告: 未知的AI_PROVIDER配置值 '{self.ai_provider_config}',尝试自动检测")
if self.siliconflow_api_key and self.siliconflow_url:
print(f"[AI服务] 自动选择硅基流动: {self.siliconflow_model}")
return 'siliconflow'
elif self.huawei_api_endpoint and self.huawei_api_key:
print(f"[AI服务] 自动选择华为大模型: {self.huawei_model}")
return 'huawei'
else:
return 'none'
def extract_fields(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
"""
@ -78,80 +143,207 @@ class AIService:
提取的字段字典格式: {field_code: field_value}
"""
if self.ai_provider == 'none':
raise Exception("未配置华为大模型服务,请设置 HUAWEI_API_KEY 和 HUAWEI_API_ENDPOINT")
raise Exception("未配置AI服务请设置 AI_PROVIDER 环境变量('huawei''siliconflow'并配置相应的API密钥")
if self.ai_provider == 'huawei':
return self._extract_with_huawei(prompt, output_fields)
elif self.ai_provider == 'siliconflow':
return self._extract_with_siliconflow(prompt, output_fields)
else:
raise Exception(f"未知的AI服务提供商: {self.ai_provider}")
def _extract_with_siliconflow(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
"""
使用硅基流动API提取字段已不再使用仅保留用于参考
系统仅支持华为大模型不再支持自动回退
使用硅基流动API提取字段临时启用
"""
# 生成会话ID用于关联同一次调用的请求和响应
session_id = f"session_{int(time.time() * 1000)}"
payload = {
"model": self.siliconflow_model,
"messages": [
{
"role": "system",
"content": "你是一个专业的数据提取助手。请从输入文本中提取结构化信息并严格按照JSON格式返回结果。\n\n⚠️ 核心要求(必须严格遵守):\n\n1. 字段提取要求:\n - 如果文本中明确提到信息(如性别、年龄、职务、职级、线索来源等),必须提取,绝对不能设为空字符串\n - 性别字段target_gender如果文本中出现\"\"\"\"\"男性\"\"女性\"\"先生\"\"女士\"等任何表示性别的词汇,必须提取并转换为\"\"\"\",不能为空\n - 职级字段target_professional_rank如果文本中提到\"正处级\"\"副处级\"\"正科级\"等,必须提取,不能为空\n - 线索来源字段clue_source如果文本中提到\"举报\"\"群众举报\"\"来信\"等,必须提取,不能为空\n\n2. 字段名格式要求(严格禁止错误):\n - 必须使用\"target_professional_rank\",禁止使用\"_professional_rank\"或任何下划线前缀\n - 必须使用\"clue_source\",禁止使用\"_source\"\"source\"或任何下划线前缀\n - 必须使用\"target_organization\",禁止使用\"target_organisation\"(英式拼写)\n - 所有字段名必须严格按照JSON示例中的字段编码不能随意修改\n\n3. JSON格式要求\n - 只返回JSON对象不要包含任何其他文字、思考过程、markdown代码块标记或```json标记\n - 所有字段名必须使用双引号\n - 必须返回所有要求的字段即使值为空字符串也要包含在JSON中\n - JSON格式必须完整且有效不能有语法错误\n\n4. 提取逻辑:\n - 逐字逐句仔细阅读输入文本,不要遗漏任何信息\n - 对于性别、职级、线索来源等关键字段,请特别仔细查找\n - 如果文本中明确提到某个信息,必须提取出来,不能设为空"
},
{
"role": "user",
"content": prompt
}
],
"temperature": 0.2,
"max_tokens": self.siliconflow_api_max_tokens
}
headers = {
"Authorization": f"Bearer {self.siliconflow_api_key}",
"Content-Type": "application/json"
}
# 记录请求信息(发送请求前)
api_request_info = {
"endpoint": self.siliconflow_url,
"model": self.siliconflow_model,
"messages": payload["messages"],
"temperature": payload.get("temperature"),
"max_tokens": payload.get("max_tokens"),
}
if self.ai_logger:
self.ai_logger.log_request_only(prompt, api_request_info, session_id)
print(f"[AI服务] 正在调用硅基流动API...")
extracted_data = None
error_message = None
try:
payload = {
"model": self.siliconflow_model,
"messages": [
{
"role": "system",
"content": "你是一个专业的数据提取助手能够从文本中准确提取结构化信息。请严格按照JSON格式返回结果。"
},
{
"role": "user",
"content": prompt
}
],
"temperature": 0.3,
"max_tokens": 2000
}
headers = {
"Authorization": f"Bearer {self.siliconflow_api_key}",
"Content-Type": "application/json"
}
response = requests.post(
self.siliconflow_url,
json=payload,
headers=headers,
timeout=30
timeout=self.siliconflow_api_timeout
)
if response.status_code != 200:
raise Exception(f"API调用失败: {response.status_code} - {response.text}")
error_message = f"API调用失败: {response.status_code} - {response.text}"
# 记录错误
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=None,
extracted_data=None,
error=error_message,
session_id=session_id
)
raise Exception(error_message)
result = response.json()
# 提取AI返回的内容
if 'choices' in result and len(result['choices']) > 0:
content = result['choices'][0]['message']['content']
raw_content = result['choices'][0]['message']['content']
# 尝试解析JSON
try:
# 如果返回的是代码块提取JSON部分
if '```json' in content:
json_start = content.find('```json') + 7
json_end = content.find('```', json_start)
content = content[json_start:json_end].strip()
elif '```' in content:
json_start = content.find('```') + 3
json_end = content.find('```', json_start)
content = content[json_start:json_end].strip()
# 调试打印原始返回内容前500字符
print(f"[AI服务] API返回的原始内容前500字符: {raw_content[:500]}")
extracted_data = json.loads(content)
return extracted_data
except json.JSONDecodeError:
# 如果不是JSON尝试从文本中提取
return self._parse_text_response(content, output_fields)
# 清理内容
content = raw_content
# 尝试解析JSON使用增强的修复机制
extracted_data = self._extract_json_from_text(content)
if extracted_data:
print(f"[AI服务] JSON解析成功提取到 {len(extracted_data)} 个字段")
print(f"[AI服务] 原始字段名: {list(extracted_data.keys())}")
# 规范化字段名并映射到正确的字段编码
normalized_data = self._normalize_field_names(extracted_data, output_fields)
print(f"[AI服务] 规范化后的字段名: {list(normalized_data.keys())}")
# 打印关键字段的值用于调试
for key in ['target_name', 'target_gender', 'target_age', 'target_date_of_birth']:
if key in normalized_data:
print(f"[AI服务] 规范化后 {key} = '{normalized_data[key]}'")
# 规范化日期格式
normalized_data = self._normalize_date_formats(normalized_data, output_fields)
# 后处理从已有信息推断缺失字段传入原始prompt以便从输入文本中提取
normalized_data = self._post_process_inferred_fields(normalized_data, output_fields, prompt)
# 打印后处理后的关键字段
for key in ['target_name', 'target_gender', 'target_age', 'target_date_of_birth', 'target_organization', 'target_position']:
if key in normalized_data:
print(f"[AI服务] 后处理后 {key} = '{normalized_data[key]}'")
# 即使提取的字段不完整,也返回结果(更宽容的处理)
if any(v for v in normalized_data.values() if v): # 至少有一个非空字段
print(f"[AI服务] 返回提取的数据(包含 {sum(1 for v in normalized_data.values() if v)} 个非空字段)")
# 记录成功的对话
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=result,
extracted_data=normalized_data,
error=None,
session_id=session_id
)
return normalized_data
else:
print(f"[AI服务] 警告:提取的数据全部为空,但继续返回(允许部分字段为空)")
# 记录对话(即使数据为空)
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=result,
extracted_data=normalized_data,
error="提取的数据全部为空",
session_id=session_id
)
return normalized_data
# 如果无法提取JSON记录错误但尝试更宽容的处理
print(f"[AI服务] 警告无法从内容中提取完整JSON尝试备用解析方法")
print(f"[AI服务] 清理后的内容前500字符: {content[:500]}")
# 尝试从文本中提取
parsed_data = self._parse_text_response(content, output_fields)
if parsed_data and any(v for v in parsed_data.values() if v): # 至少有一个非空字段
print(f"[AI服务] 使用备用方法解析成功,提取到 {len(parsed_data)} 个字段")
# 记录对话
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=result,
extracted_data=parsed_data,
error=None,
session_id=session_id
)
return parsed_data
# 如果所有方法都失败,返回空字典而不是抛出异常(更宽容)
error_msg = f"无法从API返回内容中提取JSON数据。原始内容长度: {len(raw_content)}, 清理后内容长度: {len(content)}"
print(f"[AI服务] 警告:{error_msg}")
print(f"[AI服务] 完整内容: {content}")
# 返回一个包含所有输出字段的空字典,而不是抛出异常
empty_result = {field['field_code']: '' for field in output_fields}
print(f"[AI服务] 返回空结果(包含 {len(empty_result)} 个字段,全部为空)")
# 记录失败的对话
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=result,
extracted_data=empty_result,
error=error_msg,
session_id=session_id
)
return empty_result
else:
raise Exception("API返回格式异常")
error_msg = "API返回格式异常未找到choices字段或choices为空"
# 记录错误
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=result,
extracted_data=None,
error=error_msg,
session_id=session_id
)
raise Exception(error_msg)
except requests.exceptions.Timeout:
raise Exception("AI服务调用超时")
except Exception as e:
raise Exception(f"AI服务调用失败: {str(e)}")
# 如果发生异常,记录错误日志
error_msg = str(e)
if self.ai_logger:
self.ai_logger.log_conversation(
prompt=prompt,
api_request=api_request_info,
api_response=None,
extracted_data=None,
error=error_msg,
session_id=session_id
)
# 重新抛出异常,让上层处理
raise
def _extract_with_huawei(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
"""
@ -249,7 +441,7 @@ class AIService:
"top_p": 0.9, # 降低top_p更聚焦
"top_k": 40, # 增加top_k允许更多选择
"seed": 1,
"max_tokens": self.api_max_tokens,
"max_tokens": self.huawei_api_max_tokens,
"n": 1,
"enable_thinking": False # 关闭思考模式以提高JSON生成稳定性
}
@ -276,11 +468,11 @@ class AIService:
enable_thinking = payload.get('enable_thinking', False)
if enable_thinking:
# 思考模式使用配置的超时时间默认180秒
timeout = self.api_timeout
timeout = self.huawei_api_timeout
print(f"[AI服务] 思考模式已开启,使用超时时间: {timeout}")
else:
# 非思考模式:使用较短的超时时间
timeout = min(self.api_timeout, 120) # 最多120秒
timeout = min(self.huawei_api_timeout, 120) # 最多120秒
print(f"[AI服务] 思考模式未开启,使用超时时间: {timeout}")
extracted_data = None

View File

@ -15,17 +15,50 @@ class TemplateAIHelper:
"""模板AI辅助类用于智能分析文档内容"""
def __init__(self):
# 华为大模型配置(必需)
# ========== AI服务提供商选择 ==========
# 通过环境变量 AI_PROVIDER 选择使用的AI服务
# 可选值: 'huawei' 或 'siliconflow',默认为 'siliconflow'
ai_provider = os.getenv('AI_PROVIDER', 'siliconflow').lower()
# ========== 华为大模型配置 ==========
huawei_key = os.getenv('HUAWEI_API_KEY', 'sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186')
huawei_endpoint = os.getenv('HUAWEI_API_ENDPOINT', 'http://10.100.31.26:3001/v1/chat/completions')
huawei_model = os.getenv('HUAWEI_MODEL', 'DeepSeek-R1-Distill-Llama-70B')
if not huawei_key or not huawei_endpoint:
raise Exception("未配置华为大模型服务,请设置 HUAWEI_API_KEY 和 HUAWEI_API_ENDPOINT")
# ========== 硅基流动配置 ==========
siliconflow_key = os.getenv('SILICONFLOW_API_KEY', '')
siliconflow_url = os.getenv('SILICONFLOW_URL', 'https://api.siliconflow.cn/v1/chat/completions')
siliconflow_model = os.getenv('SILICONFLOW_MODEL', 'deepseek-ai/DeepSeek-V3.2-Exp')
# 使用华为大模型
self.api_key = huawei_key
self.model = os.getenv('HUAWEI_MODEL', 'DeepSeek-R1-Distill-Llama-70B')
self.api_url = huawei_endpoint
# 根据配置选择服务提供商
if ai_provider == 'huawei':
if not huawei_key or not huawei_endpoint:
raise Exception("未配置华为大模型服务,请设置 HUAWEI_API_KEY 和 HUAWEI_API_ENDPOINT或设置 AI_PROVIDER=siliconflow 使用硅基流动")
self.api_key = huawei_key
self.model = huawei_model
self.api_url = huawei_endpoint
print(f"[模板AI助手] 使用华为大模型: {huawei_model}")
elif ai_provider == 'siliconflow':
if not siliconflow_key:
raise Exception("未配置硅基流动服务,请设置 SILICONFLOW_API_KEY或设置 AI_PROVIDER=huawei 使用华为大模型")
self.api_key = siliconflow_key
self.model = siliconflow_model
self.api_url = siliconflow_url
print(f"[模板AI助手] 使用硅基流动: {siliconflow_model}")
else:
# 自动检测:优先使用硅基流动,如果未配置则使用华为大模型
if siliconflow_key and siliconflow_url:
self.api_key = siliconflow_key
self.model = siliconflow_model
self.api_url = siliconflow_url
print(f"[模板AI助手] 自动选择硅基流动: {siliconflow_model}")
elif huawei_key and huawei_endpoint:
self.api_key = huawei_key
self.model = huawei_model
self.api_url = huawei_endpoint
print(f"[模板AI助手] 自动选择华为大模型: {huawei_model}")
else:
raise Exception("未配置AI服务请设置 AI_PROVIDER 环境变量('huawei''siliconflow'并配置相应的API密钥")
def test_api_connection(self) -> bool:
"""
@ -35,9 +68,9 @@ class TemplateAIHelper:
是否连接成功
"""
try:
print(f" [测试] 正在测试华为大模型API连接...")
print(f" [测试] 正在测试API连接...")
# 华为大模型payload
# 测试payload
test_payload = {
"model": self.model,
"messages": [
@ -46,11 +79,14 @@ class TemplateAIHelper:
"content": "测试"
}
],
"stream": False,
"temperature": 0.5,
"max_tokens": 10
}
# 如果是华为大模型,添加额外的参数
if 'huawei' in self.api_url.lower() or '10.100.31.26' in self.api_url:
test_payload["stream"] = False
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
@ -146,7 +182,7 @@ class TemplateAIHelper:
只返回JSON不要其他说明文字"""
# 调用AI API(华为大模型)
# 调用AI API
payload = {
"model": self.model,
"messages": [
@ -159,18 +195,21 @@ class TemplateAIHelper:
"content": prompt
}
],
"stream": False,
"presence_penalty": 1.03,
"frequency_penalty": 1.0,
"repetition_penalty": 1.0,
"temperature": 0.5,
"top_p": 0.95,
"top_k": 1,
"seed": 1,
"max_tokens": 8192,
"n": 1
"max_tokens": 8192
}
# 如果是华为大模型,添加额外的参数
if 'huawei' in self.api_url.lower() or '10.100.31.26' in self.api_url:
payload["stream"] = False
payload["presence_penalty"] = 1.03
payload["frequency_penalty"] = 1.0
payload["repetition_penalty"] = 1.0
payload["top_p"] = 0.95
payload["top_k"] = 1
payload["seed"] = 1
payload["n"] = 1
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"