mirror of
https://github.com/Zippland/Snap-Solver.git
synced 2026-02-16 08:16:20 +08:00
优化模型实例创建逻辑,简化API密钥选择,更新阿里巴巴模型的最大Token设置,支持新的Qwen-VL模型,调整思考过程的处理逻辑,增强用户界面设置的动态效果。
This commit is contained in:
@@ -4,15 +4,54 @@ from openai import OpenAI
|
||||
from .base import BaseModel
|
||||
|
||||
class AlibabaModel(BaseModel):
|
||||
def __init__(self, api_key: str, temperature: float = 0.7, system_prompt: str = None, language: str = None, model_name: str = None):
|
||||
self.model_name = model_name or "QVQ-Max-2025-03-25" # 默认使用QVQ-Max模型
|
||||
# 在super().__init__之前设置model_name,这样get_default_system_prompt能使用它
|
||||
super().__init__(api_key, temperature, system_prompt, language)
|
||||
|
||||
def get_default_system_prompt(self) -> str:
|
||||
return """你是一位专业的问题分析与解答助手。当看到一个问题图片时,请:
|
||||
1. 仔细阅读并理解问题
|
||||
2. 分析问题的关键组成部分
|
||||
3. 提供清晰的、逐步的解决方案
|
||||
4. 如果相关,解释涉及的概念或理论
|
||||
5. 如果有多种解决方法,先解释最高效的方法"""
|
||||
"""根据模型名称返回不同的默认系统提示词"""
|
||||
# 检查是否是通义千问VL模型
|
||||
if self.model_name and "qwen-vl" in self.model_name:
|
||||
return """你是通义千问VL视觉语言助手,擅长图像理解、文字识别、内容分析和创作。请根据用户提供的图像:
|
||||
1. 仔细阅读并理解问题
|
||||
2. 分析问题的关键组成部分
|
||||
3. 提供清晰的、逐步的解决方案
|
||||
4. 如果相关,解释涉及的概念或理论
|
||||
5. 如果有多种解决方法,先解释最高效的方法"""
|
||||
else:
|
||||
# QVQ模型使用原先的提示词
|
||||
return """你是一位专业的问题分析与解答助手。当看到一个问题图片时,请:
|
||||
1. 仔细阅读并理解问题
|
||||
2. 分析问题的关键组成部分
|
||||
3. 提供清晰的、逐步的解决方案
|
||||
4. 如果相关,解释涉及的概念或理论
|
||||
5. 如果有多种解决方法,先解释最高效的方法"""
|
||||
|
||||
def get_model_identifier(self) -> str:
|
||||
"""根据模型名称返回对应的模型标识符"""
|
||||
# 直接映射模型ID到DashScope API使用的标识符
|
||||
model_mapping = {
|
||||
"QVQ-Max-2025-03-25": "qvq-max",
|
||||
"qwen-vl-max-latest": "qwen-vl-max", # 修正为正确的API标识符
|
||||
}
|
||||
|
||||
# 从模型映射表中获取模型标识符,如果不存在则使用默认值
|
||||
model_id = model_mapping.get(self.model_name)
|
||||
if model_id:
|
||||
return model_id
|
||||
|
||||
# 如果没有精确匹配,检查是否包含特定前缀
|
||||
if self.model_name and "qwen-vl" in self.model_name:
|
||||
if "max" in self.model_name:
|
||||
return "qwen-vl-max"
|
||||
elif "plus" in self.model_name:
|
||||
return "qwen-vl-plus"
|
||||
elif "lite" in self.model_name:
|
||||
return "qwen-vl-lite"
|
||||
return "qwen-vl-max" # 默认使用最强版本
|
||||
|
||||
# 最后的默认值
|
||||
return "qvq-max"
|
||||
|
||||
def analyze_text(self, text: str, proxies: dict = None) -> Generator[dict, None, None]:
|
||||
@@ -59,7 +98,7 @@ class AlibabaModel(BaseModel):
|
||||
messages=messages,
|
||||
temperature=self.temperature,
|
||||
stream=True,
|
||||
max_tokens=self.max_tokens if hasattr(self, 'max_tokens') and self.max_tokens else 4000
|
||||
max_tokens=self._get_max_tokens()
|
||||
)
|
||||
|
||||
# 记录思考过程和回答
|
||||
@@ -67,14 +106,17 @@ class AlibabaModel(BaseModel):
|
||||
answer_content = ""
|
||||
is_answering = False
|
||||
|
||||
# 检查是否为通义千问VL模型(不支持reasoning_content)
|
||||
is_qwen_vl = "qwen-vl" in self.get_model_identifier()
|
||||
|
||||
for chunk in response:
|
||||
if not chunk.choices:
|
||||
continue
|
||||
|
||||
delta = chunk.choices[0].delta
|
||||
|
||||
# 处理思考过程
|
||||
if hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
|
||||
# 处理思考过程(仅适用于QVQ模型)
|
||||
if not is_qwen_vl and hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
|
||||
reasoning_content += delta.reasoning_content
|
||||
# 思考过程作为一个独立的内容发送
|
||||
yield {
|
||||
@@ -84,7 +126,7 @@ class AlibabaModel(BaseModel):
|
||||
}
|
||||
elif delta.content != "":
|
||||
# 判断是否开始回答(从思考过程切换到回答)
|
||||
if not is_answering:
|
||||
if not is_answering and not is_qwen_vl:
|
||||
is_answering = True
|
||||
# 发送完整的思考过程
|
||||
if reasoning_content:
|
||||
@@ -126,7 +168,7 @@ class AlibabaModel(BaseModel):
|
||||
}
|
||||
|
||||
def analyze_image(self, image_data: str, proxies: dict = None) -> Generator[dict, None, None]:
|
||||
"""Stream QVQ-Max's response for image analysis"""
|
||||
"""Stream model's response for image analysis"""
|
||||
try:
|
||||
# Initial status
|
||||
yield {"status": "started", "content": ""}
|
||||
@@ -186,7 +228,7 @@ class AlibabaModel(BaseModel):
|
||||
messages=messages,
|
||||
temperature=self.temperature,
|
||||
stream=True,
|
||||
max_tokens=self.max_tokens if hasattr(self, 'max_tokens') and self.max_tokens else 4000
|
||||
max_tokens=self._get_max_tokens()
|
||||
)
|
||||
|
||||
# 记录思考过程和回答
|
||||
@@ -194,14 +236,17 @@ class AlibabaModel(BaseModel):
|
||||
answer_content = ""
|
||||
is_answering = False
|
||||
|
||||
# 检查是否为通义千问VL模型(不支持reasoning_content)
|
||||
is_qwen_vl = "qwen-vl" in self.get_model_identifier()
|
||||
|
||||
for chunk in response:
|
||||
if not chunk.choices:
|
||||
continue
|
||||
|
||||
delta = chunk.choices[0].delta
|
||||
|
||||
# 处理思考过程
|
||||
if hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
|
||||
# 处理思考过程(仅适用于QVQ模型)
|
||||
if not is_qwen_vl and hasattr(delta, 'reasoning_content') and delta.reasoning_content is not None:
|
||||
reasoning_content += delta.reasoning_content
|
||||
# 思考过程作为一个独立的内容发送
|
||||
yield {
|
||||
@@ -211,7 +256,7 @@ class AlibabaModel(BaseModel):
|
||||
}
|
||||
elif delta.content != "":
|
||||
# 判断是否开始回答(从思考过程切换到回答)
|
||||
if not is_answering:
|
||||
if not is_answering and not is_qwen_vl:
|
||||
is_answering = True
|
||||
# 发送完整的思考过程
|
||||
if reasoning_content:
|
||||
@@ -250,4 +295,12 @@ class AlibabaModel(BaseModel):
|
||||
yield {
|
||||
"status": "error",
|
||||
"error": str(e)
|
||||
}
|
||||
}
|
||||
|
||||
def _get_max_tokens(self) -> int:
|
||||
"""根据模型类型返回合适的max_tokens值"""
|
||||
# 检查是否为通义千问VL模型
|
||||
if "qwen-vl" in self.get_model_identifier():
|
||||
return 2000 # 通义千问VL模型最大支持2048,留一些余量
|
||||
# QVQ模型或其他模型
|
||||
return self.max_tokens if hasattr(self, 'max_tokens') and self.max_tokens else 4000
|
||||
@@ -126,8 +126,8 @@ class ModelFactory:
|
||||
temperature=temperature,
|
||||
system_prompt=system_prompt
|
||||
)
|
||||
# 对于DeepSeek模型,传递model_name参数
|
||||
elif "deepseek" in model_name.lower():
|
||||
else:
|
||||
# 对于所有其他模型,传递model_name参数
|
||||
return model_class(
|
||||
api_key=api_key,
|
||||
temperature=temperature,
|
||||
@@ -135,14 +135,6 @@ class ModelFactory:
|
||||
language=language,
|
||||
model_name=model_name
|
||||
)
|
||||
else:
|
||||
# 对于其他模型,传递所有参数
|
||||
return model_class(
|
||||
api_key=api_key,
|
||||
temperature=temperature,
|
||||
system_prompt=system_prompt,
|
||||
language=language
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_available_models(cls) -> list[Dict[str, Any]]:
|
||||
|
||||
Reference in New Issue
Block a user