"""DeepSeek 评测台评审:模型别名解析 + ChatOpenAI 装配。""" from __future__ import annotations from langchain_openai import ChatOpenAI from app.adapters.llm.openai_base_url import normalize_openai_compatible_base_url from app.core.config import settings from app.core.eval_judge_spec import EvalJudgeLlmSpec def resolve_deepseek_eval_judge_model( requested: str, ) -> tuple[str, dict | None, str | None]: """将模型名(含旧别名)规范为 V4 的 model id、extra_body 与 reasoning_effort。 官方:deepseek-chat / deepseek-reasoner 将弃用,分别对应 v4-flash 非思考 / 思考。 """ m = (requested or "").strip() if m == "deepseek-chat": return ( "deepseek-v4-flash", {"thinking": {"type": "disabled"}}, None, ) if m in ( "deepseek-reasoner", "deepseek-r1", ): return ( "deepseek-v4-flash", {"thinking": {"type": "enabled"}}, "high", ) if m == "deepseek-v4-pro": return ("deepseek-v4-pro", None, "high") if m in ("", "deepseek-v4-flash"): if settings.eval_judge_deepseek_thinking_enabled: return ( "deepseek-v4-flash", {"thinking": {"type": "enabled"}}, "high", ) return ( "deepseek-v4-flash", {"thinking": {"type": "disabled"}}, None, ) if "flash" in m.lower() or m.startswith("deepseek-v4"): return (m, None, None) return (m, None, None) def build_deepseek_eval_judge_spec( judge_model: str | None, ) -> EvalJudgeLlmSpec | None: """密钥缺失时返回 None。""" api_key = (settings.deepseek_api_key or settings.llm_api_key or "").strip() if not api_key: return None want = (judge_model or "").strip() base = normalize_openai_compatible_base_url( settings.deepseek_base_url, fallback="https://api.deepseek.com", ) default_m = (settings.eval_judge_deepseek_model or "deepseek-v4-flash").strip() combined = want or default_m model, extra, effort = resolve_deepseek_eval_judge_model(combined) ctx = int(settings.eval_judge_deepseek_context_window_tokens) llm_kw: dict = { "api_key": api_key, "base_url": base, "model": model, "temperature": settings.eval_judge_temperature, } if extra is not None: llm_kw["extra_body"] = extra if effort is not None: llm_kw["reasoning_effort"] = effort return EvalJudgeLlmSpec( llm=ChatOpenAI(**llm_kw), provider="deepseek", resolved_model=model, context_window_tokens=ctx, )