AgentEvalTool/backend/agenteval/model_protocols/base.py
sinohqb c956da7686
All checks were successful
CI / test (pull_request) Successful in 4m3s
feat(v1.3.1): Phase 2 让成本/放弃率/Go-No-Go 基础设施真正生效
- token 用量接入:ModelGateway 经 adapter.parse_usage 累计评测侧 LLM 调用的
  token 消耗,引擎写入 run.summary.eval_token_usage,报告透出
- 放弃率落地:CaseOutcome 新增 abandoned 标记(对话中途发送/接收失败),
  build_run_summary 统计 abandoned_cases / abandonment_rate
- Go/No-Go 可配置:Scenario 新增 acceptance_criteria 字段(DB 列 + 幂等迁移),
  报告按场景标准出 verdict,缺省回退全局默认;标准变更不触发考纲升版
2026-08-25 18:38:18 +08:00

54 lines
1.8 KiB
Python

"""Protocol adapter contract for external model APIs."""
from typing import Any
from agenteval.models import ModelCapability, ModelProtocol
class ProtocolAdapterError(ValueError):
pass
class ModelProtocolAdapter:
protocol: ModelProtocol
supported_capabilities: frozenset[ModelCapability] = frozenset()
def headers(self, api_key: str | None) -> dict[str, str]:
return {"Content-Type": "application/json"}
def chat_payload(
self,
model_name: str | None,
messages: list[dict[str, str]],
temperature: float,
) -> dict[str, Any]:
self._unsupported(ModelCapability.CHAT)
def parse_chat(self, data: dict[str, Any]) -> str:
self._unsupported(ModelCapability.CHAT)
def embedding_payload(self, model_name: str | None, inputs: str | list[str]) -> dict[str, Any]:
self._unsupported(ModelCapability.EMBEDDING)
def parse_embeddings(self, data: dict[str, Any]) -> list[list[float]]:
self._unsupported(ModelCapability.EMBEDDING)
def moderation_payload(self, model_name: str | None, text: str) -> dict[str, Any]:
self._unsupported(ModelCapability.MODERATION)
def parse_moderation(self, data: dict[str, Any]) -> dict[str, Any]:
self._unsupported(ModelCapability.MODERATION)
def parse_usage(self, data: dict[str, Any]) -> dict[str, int] | None:
"""Extract token usage from a response; None for protocols that omit it."""
return None
def _unsupported(self, capability: ModelCapability) -> None:
raise ProtocolAdapterError(f"{self.protocol.value} 协议不支持 {capability.value} 能力")
@staticmethod
def require_model(model_name: str | None) -> str:
if not model_name:
raise ProtocolAdapterError("模型名称不能为空")
return model_name