72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
"""模型能力档案: 不同模型的参数差异都收敛到 yaml,加新模型不用改代码。"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field, fields
|
|
from pathlib import Path
|
|
from typing import List
|
|
|
|
import yaml
|
|
|
|
|
|
@dataclass
|
|
class ModelCapabilities:
|
|
model_id: str = ""
|
|
family: str = ""
|
|
variant: str = ""
|
|
|
|
# 上下文
|
|
max_context: int = 128_000
|
|
reliable_context: int = 64_000
|
|
max_output: int = 4096
|
|
|
|
# Tool calling
|
|
parallel_tools: bool = False
|
|
tool_calling_quality: str = "good"
|
|
|
|
# 思考模式
|
|
thinking_mode: bool = False
|
|
reasoning_effort_levels: List[str] = field(default_factory=list)
|
|
default_reasoning_effort: str = ""
|
|
|
|
# 代码 / 沙盒
|
|
code_quality: str = "good"
|
|
enable_run_python: bool = False
|
|
|
|
# 工程参数
|
|
max_iterations: int = 50
|
|
optimal_temperature: float = 0.3
|
|
|
|
# provider 特性
|
|
prompt_caching: bool = False
|
|
extended_thinking: bool = False
|
|
|
|
# API 接入
|
|
api_base: str = ""
|
|
api_key_env: str = ""
|
|
|
|
@classmethod
|
|
def load(cls, name: str, models_dir: Path) -> "ModelCapabilities":
|
|
"""name: '<family>.<variant>',如 'deepseek_v4.flash'。"""
|
|
if "." in name:
|
|
family, variant = name.split(".", 1)
|
|
else:
|
|
family, variant = name, "default"
|
|
|
|
path = Path(models_dir) / f"{family}.yaml"
|
|
if not path.exists():
|
|
raise FileNotFoundError(f"模型档案不存在: {path}")
|
|
|
|
data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
|
|
variants = data.get("variants", {})
|
|
if variant not in variants:
|
|
raise ValueError(
|
|
f"档案 {path} 没有 variant={variant};可选: {list(variants)}"
|
|
)
|
|
|
|
var = variants[variant]
|
|
valid_keys = {f.name for f in fields(cls)}
|
|
kwargs = {k: v for k, v in var.items() if k in valid_keys}
|
|
kwargs["family"] = data.get("family", family)
|
|
kwargs["variant"] = variant
|
|
return cls(**kwargs)
|