创建新分支,用于静态交通本地服务器部署,调整默认为华为大模型调用
This commit is contained in:
parent
5830de355d
commit
7d50b160c2
12
README.md
12
README.md
@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
- ✅ AI解析接口 (`/api/ai/extract`) - 从输入文本中提取结构化字段
|
- ✅ AI解析接口 (`/api/ai/extract`) - 从输入文本中提取结构化字段
|
||||||
- ✅ 字段配置管理 - 从数据库读取字段配置
|
- ✅ 字段配置管理 - 从数据库读取字段配置
|
||||||
- ✅ 支持硅基流动大模型(DeepSeek)
|
- ✅ 支持华为大模型(DeepSeek-R1-Distill-Llama-70B)
|
||||||
- 🔄 预留华为大模型接口支持
|
|
||||||
- ✅ Web测试界面 - 可视化测试解析功能
|
- ✅ Web测试界面 - 可视化测试解析功能
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
@ -73,9 +72,10 @@ cp .env.example .env
|
|||||||
编辑 `.env` 文件,填入你的API密钥:
|
编辑 `.env` 文件,填入你的API密钥:
|
||||||
|
|
||||||
```env
|
```env
|
||||||
# 硅基流动API配置(必需)
|
# 华为大模型API配置(必需,已内置默认值,如需修改可调整)
|
||||||
SILICONFLOW_API_KEY=your_api_key_here
|
HUAWEI_API_KEY=sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186
|
||||||
SILICONFLOW_MODEL=deepseek-ai/DeepSeek-V3.2-Exp
|
HUAWEI_API_ENDPOINT=http://10.100.31.26:3001/v1/chat/completions
|
||||||
|
HUAWEI_MODEL=DeepSeek-R1-Distill-Llama-70B
|
||||||
|
|
||||||
# 数据库配置(已默认配置,如需修改可调整)
|
# 数据库配置(已默认配置,如需修改可调整)
|
||||||
DB_HOST=152.136.177.240
|
DB_HOST=152.136.177.240
|
||||||
@ -243,7 +243,7 @@ print(response.json())
|
|||||||
## 常见问题
|
## 常见问题
|
||||||
|
|
||||||
**Q: 提示"未配置AI服务"?**
|
**Q: 提示"未配置AI服务"?**
|
||||||
A: 检查 `.env` 文件中的 `SILICONFLOW_API_KEY` 是否已正确配置。
|
A: 系统仅支持华为大模型(已内置默认配置),请确保 `.env` 文件中正确设置了 `HUAWEI_API_KEY` 和 `HUAWEI_API_ENDPOINT`。如果华为大模型不可用,请检查网络连接和API配置。
|
||||||
|
|
||||||
**Q: 解析结果为空?**
|
**Q: 解析结果为空?**
|
||||||
A: 检查输入文本是否包含足够的信息,可以尝试更详细的输入文本。
|
A: 检查输入文本是否包含足够的信息,可以尝试更详细的输入文本。
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
AI服务 - 封装大模型调用
|
AI服务 - 封装大模型调用
|
||||||
支持硅基流动和华为大模型(预留)
|
仅支持华为大模型
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
@ -12,22 +12,17 @@ class AIService:
|
|||||||
"""AI服务类"""
|
"""AI服务类"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.siliconflow_api_key = os.getenv('SILICONFLOW_API_KEY')
|
# 华为大模型配置(必需)
|
||||||
self.siliconflow_model = os.getenv('SILICONFLOW_MODEL', 'deepseek-ai/DeepSeek-V3.2-Exp')
|
self.huawei_api_endpoint = os.getenv('HUAWEI_API_ENDPOINT', 'http://10.100.31.26:3001/v1/chat/completions')
|
||||||
self.siliconflow_url = "https://api.siliconflow.cn/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')
|
||||||
# 华为大模型配置(预留)
|
|
||||||
self.huawei_api_endpoint = os.getenv('HUAWEI_API_ENDPOINT')
|
|
||||||
self.huawei_api_key = os.getenv('HUAWEI_API_KEY')
|
|
||||||
|
|
||||||
# 确定使用的AI服务
|
# 确定使用的AI服务
|
||||||
self.ai_provider = self._determine_ai_provider()
|
self.ai_provider = self._determine_ai_provider()
|
||||||
|
|
||||||
def _determine_ai_provider(self) -> str:
|
def _determine_ai_provider(self) -> str:
|
||||||
"""确定使用的AI服务提供商"""
|
"""确定使用的AI服务提供商(仅支持华为大模型)"""
|
||||||
if self.siliconflow_api_key:
|
if self.huawei_api_endpoint and self.huawei_api_key:
|
||||||
return 'siliconflow'
|
|
||||||
elif self.huawei_api_endpoint and self.huawei_api_key:
|
|
||||||
return 'huawei'
|
return 'huawei'
|
||||||
else:
|
else:
|
||||||
return 'none'
|
return 'none'
|
||||||
@ -44,17 +39,18 @@ class AIService:
|
|||||||
提取的字段字典,格式: {field_code: field_value}
|
提取的字段字典,格式: {field_code: field_value}
|
||||||
"""
|
"""
|
||||||
if self.ai_provider == 'none':
|
if self.ai_provider == 'none':
|
||||||
raise Exception("未配置AI服务,请设置SILICONFLOW_API_KEY或华为大模型配置")
|
raise Exception("未配置华为大模型服务,请设置 HUAWEI_API_KEY 和 HUAWEI_API_ENDPOINT")
|
||||||
|
|
||||||
if self.ai_provider == 'siliconflow':
|
if self.ai_provider == 'huawei':
|
||||||
return self._extract_with_siliconflow(prompt, output_fields)
|
|
||||||
elif self.ai_provider == 'huawei':
|
|
||||||
return self._extract_with_huawei(prompt, output_fields)
|
return self._extract_with_huawei(prompt, output_fields)
|
||||||
else:
|
else:
|
||||||
raise Exception(f"未知的AI服务提供商: {self.ai_provider}")
|
raise Exception(f"未知的AI服务提供商: {self.ai_provider}")
|
||||||
|
|
||||||
def _extract_with_siliconflow(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
|
def _extract_with_siliconflow(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
|
||||||
"""使用硅基流动API提取字段"""
|
"""
|
||||||
|
使用硅基流动API提取字段(已不再使用,仅保留用于参考)
|
||||||
|
系统仅支持华为大模型,不再支持自动回退
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
payload = {
|
payload = {
|
||||||
"model": self.siliconflow_model,
|
"model": self.siliconflow_model,
|
||||||
@ -119,9 +115,77 @@ class AIService:
|
|||||||
raise Exception(f"AI服务调用失败: {str(e)}")
|
raise Exception(f"AI服务调用失败: {str(e)}")
|
||||||
|
|
||||||
def _extract_with_huawei(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
|
def _extract_with_huawei(self, prompt: str, output_fields: List[Dict]) -> Optional[Dict]:
|
||||||
"""使用华为大模型API提取字段(预留实现)"""
|
"""使用华为大模型API提取字段"""
|
||||||
# TODO: 实现华为大模型接口调用
|
try:
|
||||||
raise Exception("华为大模型接口暂未实现,请使用硅基流动API")
|
payload = {
|
||||||
|
"model": self.huawei_model,
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "你是一个专业的数据提取助手,能够从文本中准确提取结构化信息。请严格按照JSON格式返回结果。"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {self.huawei_api_key}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
self.huawei_api_endpoint,
|
||||||
|
json=payload,
|
||||||
|
headers=headers,
|
||||||
|
timeout=60
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise Exception(f"API调用失败: {response.status_code} - {response.text}")
|
||||||
|
|
||||||
|
result = response.json()
|
||||||
|
|
||||||
|
# 提取AI返回的内容
|
||||||
|
if 'choices' in result and len(result['choices']) > 0:
|
||||||
|
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()
|
||||||
|
|
||||||
|
extracted_data = json.loads(content)
|
||||||
|
return extracted_data
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
# 如果不是JSON,尝试从文本中提取
|
||||||
|
return self._parse_text_response(content, output_fields)
|
||||||
|
else:
|
||||||
|
raise Exception("API返回格式异常")
|
||||||
|
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
raise Exception("AI服务调用超时")
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f"AI服务调用失败: {str(e)}")
|
||||||
|
|
||||||
def _parse_text_response(self, text: str, output_fields: List[Dict]) -> Dict:
|
def _parse_text_response(self, text: str, output_fields: List[Dict]) -> Dict:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -15,12 +15,17 @@ class TemplateAIHelper:
|
|||||||
"""模板AI辅助类,用于智能分析文档内容"""
|
"""模板AI辅助类,用于智能分析文档内容"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.api_key = os.getenv('SILICONFLOW_API_KEY')
|
# 华为大模型配置(必需)
|
||||||
self.model = os.getenv('SILICONFLOW_MODEL', 'deepseek-ai/DeepSeek-V3.2-Exp')
|
huawei_key = os.getenv('HUAWEI_API_KEY', 'sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186')
|
||||||
self.api_url = "https://api.siliconflow.cn/v1/chat/completions"
|
huawei_endpoint = os.getenv('HUAWEI_API_ENDPOINT', 'http://10.100.31.26:3001/v1/chat/completions')
|
||||||
|
|
||||||
if not self.api_key:
|
if not huawei_key or not huawei_endpoint:
|
||||||
raise Exception("未配置 SILICONFLOW_API_KEY,请在 .env 文件中设置")
|
raise Exception("未配置华为大模型服务,请设置 HUAWEI_API_KEY 和 HUAWEI_API_ENDPOINT")
|
||||||
|
|
||||||
|
# 使用华为大模型
|
||||||
|
self.api_key = huawei_key
|
||||||
|
self.model = os.getenv('HUAWEI_MODEL', 'DeepSeek-R1-Distill-Llama-70B')
|
||||||
|
self.api_url = huawei_endpoint
|
||||||
|
|
||||||
def test_api_connection(self) -> bool:
|
def test_api_connection(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -30,7 +35,9 @@ class TemplateAIHelper:
|
|||||||
是否连接成功
|
是否连接成功
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
print(" [测试] 正在测试硅基流动API连接...")
|
print(f" [测试] 正在测试华为大模型API连接...")
|
||||||
|
|
||||||
|
# 华为大模型payload
|
||||||
test_payload = {
|
test_payload = {
|
||||||
"model": self.model,
|
"model": self.model,
|
||||||
"messages": [
|
"messages": [
|
||||||
@ -39,6 +46,8 @@ class TemplateAIHelper:
|
|||||||
"content": "测试"
|
"content": "测试"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"stream": False,
|
||||||
|
"temperature": 0.5,
|
||||||
"max_tokens": 10
|
"max_tokens": 10
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +146,7 @@ class TemplateAIHelper:
|
|||||||
|
|
||||||
只返回JSON,不要其他说明文字。"""
|
只返回JSON,不要其他说明文字。"""
|
||||||
|
|
||||||
# 调用AI API
|
# 调用AI API(华为大模型)
|
||||||
payload = {
|
payload = {
|
||||||
"model": self.model,
|
"model": self.model,
|
||||||
"messages": [
|
"messages": [
|
||||||
@ -150,8 +159,16 @@ class TemplateAIHelper:
|
|||||||
"content": prompt
|
"content": prompt
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"temperature": 0.2,
|
"stream": False,
|
||||||
"max_tokens": 4000
|
"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
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
测试硅基流动API连接
|
测试大模型API连接(华为大模型默认,硅基流动备用)
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
@ -8,23 +8,23 @@ import requests
|
|||||||
# 加载环境变量
|
# 加载环境变量
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
def test_siliconflow_api():
|
def test_huawei_api():
|
||||||
"""测试硅基流动API连接"""
|
"""测试华为大模型API连接"""
|
||||||
print("="*80)
|
print("="*80)
|
||||||
print("测试硅基流动API连接")
|
print("测试华为大模型API连接")
|
||||||
print("="*80)
|
print("="*80)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
# 读取配置
|
# 读取配置(华为大模型)
|
||||||
api_key = os.getenv('SILICONFLOW_API_KEY')
|
api_key = os.getenv('HUAWEI_API_KEY', 'sk-PoeiV3qwyTIRqcVc84E8E24cD2904872859a87922e0d9186')
|
||||||
model = os.getenv('SILICONFLOW_MODEL', 'deepseek-ai/DeepSeek-V3.2-Exp')
|
model = os.getenv('HUAWEI_MODEL', 'DeepSeek-R1-Distill-Llama-70B')
|
||||||
api_url = "https://api.siliconflow.cn/v1/chat/completions"
|
api_url = os.getenv('HUAWEI_API_ENDPOINT', 'http://10.100.31.26:3001/v1/chat/completions')
|
||||||
|
|
||||||
# 检查配置
|
# 检查配置
|
||||||
print("1. 检查配置...")
|
print("1. 检查配置...")
|
||||||
if not api_key:
|
if not api_key:
|
||||||
print(" ✗ 错误: 未找到 SILICONFLOW_API_KEY")
|
print(" ✗ 错误: 未找到 HUAWEI_API_KEY")
|
||||||
print(" 请在 .env 文件中设置: SILICONFLOW_API_KEY=你的API密钥")
|
print(" 请在 .env 文件中设置: HUAWEI_API_KEY=你的API密钥")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print(f" ✓ API密钥: {api_key[:10]}...{api_key[-5:]}")
|
print(f" ✓ API密钥: {api_key[:10]}...{api_key[-5:]}")
|
||||||
@ -43,7 +43,16 @@ def test_siliconflow_api():
|
|||||||
"content": "请回复'测试成功'"
|
"content": "请回复'测试成功'"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"max_tokens": 20
|
"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": 20,
|
||||||
|
"n": 1
|
||||||
}
|
}
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
@ -87,7 +96,7 @@ def test_siliconflow_api():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
success = test_siliconflow_api()
|
success = test_huawei_api()
|
||||||
print()
|
print()
|
||||||
print("="*80)
|
print("="*80)
|
||||||
if success:
|
if success:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user