fix(translate): 调整优先级为 zhipu→spark(智谱第一,星火第二)
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
"""翻译服务门面:配额检查 + 缓存 + 引擎选择 + 月度计数。
|
||||
|
||||
引擎链路(优先级降序):
|
||||
1. spark(主,Lite 免费;spark_api_password 配了才用)
|
||||
2. zhipu(第二序位,GLM-4-Flash 免费;zhipu_api_key 配了才用)
|
||||
1. zhipu(主,GLM-4-Flash 免费;zhipu_api_key 配了才用)
|
||||
2. spark(第二序位,Lite 免费;spark_api_password 配了才用)
|
||||
3. tencent TMT(第三级,按月配额;快满时主动切走)
|
||||
4. tencent_maas(备用,OpenAI 兼容,无配额;主失败/TMT 配额耗尽时启用)
|
||||
5. agnes(第四级,通用 LLM 做翻译;MaaS 不可用时启用 — 质量次之但够用)
|
||||
@@ -12,8 +12,9 @@
|
||||
- TMT 是按月计费的(腾讯云后台可能计费口径是请求字节,我们 redis 累加的是字符数,
|
||||
差异约 2-3x);用户从腾讯云后台看"已用 2M"时,我们 redis 显示约 80 万字符
|
||||
- 用户决策:以腾讯云后台数字为准,快满时降级
|
||||
- spark / zhipu 都是免费模型,默认优先;不可用时降级到 tencent(继续吃配额)。
|
||||
- zhipu / spark 都是免费模型,默认优先;不可用时降级到 tencent(继续吃配额)。
|
||||
想要完全绕开 tencent,把 TENCENTCLOUD_SECRET_ID 留空即可。
|
||||
- 智谱放第一是因为它家 GLM-4-Flash 翻译质量比星火 Lite 更稳,星火降为二级
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -58,18 +59,8 @@ class TranslationService:
|
||||
# 串行:1 个并发;避免触发腾讯 TMT 限速
|
||||
self._sem = asyncio.Semaphore(1)
|
||||
|
||||
def _spark_translator(self) -> BaseTranslator | None:
|
||||
"""主引擎:星火 Spark(Lite 免费)。配了 spark_api_password 才启用。"""
|
||||
if self._spark is None and settings.spark_api_password:
|
||||
try:
|
||||
self._spark = SparkTranslator()
|
||||
except Exception as e:
|
||||
logger.warning("spark init failed: %s", e)
|
||||
self._spark = None
|
||||
return self._spark
|
||||
|
||||
def _zhipu_translator(self) -> BaseTranslator | None:
|
||||
"""第二序位引擎:智谱 GLM(免费)。配了 zhipu_api_key 才启用。"""
|
||||
"""主引擎:智谱 GLM(免费)。配了 zhipu_api_key 才启用。"""
|
||||
if self._zhipu is None and settings.zhipu_api_key:
|
||||
try:
|
||||
self._zhipu = ZhipuTranslator()
|
||||
@@ -78,6 +69,16 @@ class TranslationService:
|
||||
self._zhipu = None
|
||||
return self._zhipu
|
||||
|
||||
def _spark_translator(self) -> BaseTranslator | None:
|
||||
"""第二序位引擎:星火 Spark(Lite 免费)。配了 spark_api_password 才启用。"""
|
||||
if self._spark is None and settings.spark_api_password:
|
||||
try:
|
||||
self._spark = SparkTranslator()
|
||||
except Exception as e:
|
||||
logger.warning("spark init failed: %s", e)
|
||||
self._spark = None
|
||||
return self._spark
|
||||
|
||||
def _primary(self) -> BaseTranslator | None:
|
||||
"""第三级:腾讯 TMT(初始化失败返回 None 表示不可用)。"""
|
||||
if self._tencent is None:
|
||||
@@ -168,12 +169,12 @@ class TranslationService:
|
||||
return TranslationResult(text=cached, engine="cache", chars=chars, cached=True)
|
||||
|
||||
# 2) 选引擎
|
||||
# 优先级:spark → zhipu → tencent(配额)→ maas → agnes → local
|
||||
# 优先级:zhipu → spark → tencent(配额)→ maas → agnes → local
|
||||
engine: BaseTranslator | None = None
|
||||
if self._spark_translator() is not None:
|
||||
engine = self._spark_translator()
|
||||
elif self._zhipu_translator() is not None:
|
||||
if self._zhipu_translator() is not None:
|
||||
engine = self._zhipu_translator()
|
||||
elif self._spark_translator() is not None:
|
||||
engine = self._spark_translator()
|
||||
elif await self.can_use_tencent(chars):
|
||||
engine = self._primary()
|
||||
if engine is None:
|
||||
@@ -204,17 +205,17 @@ class TranslationService:
|
||||
res = await engine.translate(text, source=source, target=target)
|
||||
except Exception as e:
|
||||
logger.exception("translate failed with %s: %s", engine.name, e)
|
||||
# 失败时按 zhipu → tencent → maas → local 顺序找一个不同的 fallback
|
||||
# spark / zhipu 失败时也要走 tencent(继续吃配额,因优先级只是降低不是禁用)
|
||||
# 失败时按 spark → tencent → maas → local 顺序找一个不同的 fallback
|
||||
# zhipu / spark 失败时也要走 tencent(继续吃配额,因优先级只是降低不是禁用)
|
||||
fb: BaseTranslator | None = None
|
||||
if engine.name == "spark":
|
||||
if self._zhipu_translator() is not None:
|
||||
fb = self._zhipu_translator()
|
||||
if engine.name == "zhipu":
|
||||
if self._spark_translator() is not None:
|
||||
fb = self._spark_translator()
|
||||
if fb is None and await self.can_use_tencent(chars):
|
||||
fb = self._primary()
|
||||
if fb is None:
|
||||
fb = self._maas() if engine.name != "tencent_maas" else None
|
||||
elif engine.name == "zhipu":
|
||||
elif engine.name == "spark":
|
||||
if await self.can_use_tencent(chars):
|
||||
fb = self._primary()
|
||||
if fb is None:
|
||||
|
||||
Reference in New Issue
Block a user