优化默认语言模型获取

This commit is contained in:
Azmat@qq.com
2026-09-03 16:00:14 +08:00
parent 6a628b0ca7
commit f53b6e1035
6 changed files with 49 additions and 28 deletions
+3 -18
View File
@@ -520,25 +520,10 @@ def _parse_extracted_entities_response(text: str) -> tuple[list[dict], list[dict
return entities, seg_refs
# 提取步固定锁定豆包 2.0 Pro(与脚本生成同款),不靠 get_default_model 的「最早创建」排序——
# 避免不同环境 DB 创建序漂移把提取路由到别的(中转站)推理模型。取不到再回落默认文本模型。
EXTRACT_TEXT_MODEL_NAME = "doubao-seed-2-0-pro-260215"
def _resolve_extract_model_config():
"""提取实体用的文本模型:优先豆包 2.0 Pro(active 且 provider active),否则回落默认文本模型。"""
pinned = (
ModelConfig.objects.select_related("provider")
.filter(
name=EXTRACT_TEXT_MODEL_NAME,
capability=ModelConfig.Capability.TEXT,
status=ModelConfig.Status.ACTIVE,
provider__status="active",
)
.order_by("created_at")
.first()
)
return pinned or get_default_model(ModelConfig.Capability.TEXT)
"""提取实体用平台后台钦定的默认文本模型(ModelConfig.is_default)。
未设默认时与 get_default_model 一致:回落最早创建的 active 文本模型。"""
return get_default_model(ModelConfig.Capability.TEXT)
def _collect_extract_text(
@@ -6,7 +6,7 @@ from django.test import TestCase
from apps.accounts.models import Team, TeamMember, User
from apps.ai.models import AITask, ModelConfig, ModelProvider
from apps.ai.services import EXTRACT_TEXT_MODEL_NAME, run_extract_entities_task, submit_extract_entities
from apps.ai.services import run_extract_entities_task, submit_extract_entities
from apps.billing.models import CreditAccount, CreditLedger
from apps.products.models import Product
from apps.projects.models import Project, ScriptSegment, ScriptVersion
@@ -66,7 +66,7 @@ class EntityExtractionRoutingTests(TestCase):
metadata={"routing": {"fallback_priority": priority}},
)
def model(self, provider, name, *, outbound=True, base_cost="0.50"):
def model(self, provider, name, *, outbound=True, base_cost="0.50", is_default=False):
return ModelConfig.objects.create(
provider=provider,
name=name,
@@ -75,6 +75,7 @@ class EntityExtractionRoutingTests(TestCase):
endpoint="chat/completions",
unit_price=Decimal("10"),
status=ModelConfig.Status.ACTIVE,
is_default=is_default,
metadata=_metadata(outbound=outbound, base_cost=base_cost),
)
@@ -114,7 +115,7 @@ class EntityExtractionRoutingTests(TestCase):
return CreditLedger.objects.filter(task=task, ledger_type=ledger_type).count()
def test_first_success_records_streaming_structured_attempt_and_persists_entities(self):
primary = self.model(self.provider("entity-primary", 20), "entity-primary")
primary = self.model(self.provider("entity-primary", 20), "entity-primary", is_default=True)
task = self.submit()
run_extract_entities_task(task_id=str(task.id))
@@ -213,7 +214,7 @@ class EntityExtractionRoutingTests(TestCase):
def test_direct_doubao_primary_retries_but_does_not_switch_when_outbound_disabled(self):
primary = self.model(
self.provider("doubao", 10), EXTRACT_TEXT_MODEL_NAME, outbound=False
self.provider("doubao", 10), "doubao-seed-2-0-pro-260215", outbound=False
)
candidate = self.model(
self.provider("entity-unused-candidate", 20), "entity-unused", outbound=False
@@ -236,3 +237,22 @@ class EntityExtractionRoutingTests(TestCase):
self.assertTrue(all(attempt.public_model_name == primary.display_name for attempt in attempts))
self.assertEqual(self.ledger_count(task, CreditLedger.Type.RESERVE), 1)
self.assertEqual(self.ledger_count(task, CreditLedger.Type.RELEASE), 1)
def test_uses_database_default_text_model_not_older_doubao_pin(self):
older = self.model(self.provider("volcengine-old", 20), "doubao-seed-2-0-pro-260215")
default = self.model(
self.provider("volcengine-default", 10),
"deepseek-v4-pro",
is_default=True,
)
task = self.submit()
run_extract_entities_task(task_id=str(task.id))
task.refresh_from_db()
attempt = task.model_attempts.get()
self.assertEqual(task.status, AITask.Status.SUCCEEDED)
self.assertEqual(attempt.model_config_id, default.id)
self.assertNotEqual(attempt.model_config_id, older.id)
self.assertEqual(task.request_payload["model"], "deepseek-v4-pro")