P2-1: 定義 INvidiaProvider Protocol (@runtime_checkable) P2-2: 補充邊界測試 15 → 25 案例 P2-3: model_registry 新增 NVIDIA + tool_calling_fallback_order 首席架構師評分: 82 → 86 → 90/100 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
120 lines
4.1 KiB
Python
120 lines
4.1 KiB
Python
"""
|
|
NVIDIA Nemotron API Models - ADR-036
|
|
====================================
|
|
2026-03-29 ogt: Nemotron Tool Calling 整合 (83.3% 精準度)
|
|
|
|
OpenAI 相容格式 - 用於 Tool Calling 任務
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ToolFunction(BaseModel):
|
|
"""Tool Function 定義"""
|
|
|
|
name: str = Field(..., description="Tool 函數名稱")
|
|
arguments: str = Field(..., description="Tool 參數 (JSON 字串)")
|
|
|
|
|
|
class ToolCall(BaseModel):
|
|
"""Tool Call 結構"""
|
|
|
|
id: str = Field(..., description="Tool Call ID")
|
|
type: str = Field(default="function", description="Tool 類型")
|
|
function: ToolFunction = Field(..., description="Tool 函數")
|
|
|
|
|
|
class NvidiaMessage(BaseModel):
|
|
"""NVIDIA API Message 結構"""
|
|
|
|
role: str = Field(..., description="訊息角色 (assistant/user/system)")
|
|
content: str | None = Field(default=None, description="訊息內容")
|
|
tool_calls: list[ToolCall] | None = Field(
|
|
default=None, description="Tool Calls (僅 assistant)"
|
|
)
|
|
|
|
|
|
class NvidiaChoice(BaseModel):
|
|
"""NVIDIA API Choice 結構"""
|
|
|
|
index: int = Field(default=0, description="選項索引")
|
|
message: NvidiaMessage = Field(..., description="回應訊息")
|
|
finish_reason: str | None = Field(
|
|
default=None, description="結束原因 (stop/tool_calls)"
|
|
)
|
|
|
|
|
|
class NvidiaUsage(BaseModel):
|
|
"""NVIDIA API Token 使用統計"""
|
|
|
|
prompt_tokens: int = Field(default=0, description="輸入 Token 數")
|
|
completion_tokens: int = Field(default=0, description="輸出 Token 數")
|
|
total_tokens: int = Field(default=0, description="總 Token 數")
|
|
|
|
|
|
class NvidiaResponse(BaseModel):
|
|
"""NVIDIA Nemotron API 完整回應"""
|
|
|
|
id: str = Field(..., description="回應 ID")
|
|
object: str = Field(default="chat.completion", description="物件類型")
|
|
created: int = Field(..., description="建立時間戳")
|
|
model: str = Field(..., description="模型名稱")
|
|
choices: list[NvidiaChoice] = Field(..., description="回應選項")
|
|
usage: NvidiaUsage | None = Field(default=None, description="Token 使用統計")
|
|
|
|
|
|
# === Tool Calling 請求結構 ===
|
|
|
|
|
|
class ToolDefinition(BaseModel):
|
|
"""Tool 定義 (發送給 API)"""
|
|
|
|
type: str = Field(default="function", description="Tool 類型")
|
|
function: dict[str, Any] = Field(..., description="函數定義 (JSON Schema)")
|
|
|
|
|
|
class NvidiaToolCallRequest(BaseModel):
|
|
"""NVIDIA Tool Calling 請求"""
|
|
|
|
model: str = Field(
|
|
default="nvidia/nemotron-mini-4b-instruct",
|
|
description="模型名稱 (2026-03-29 ogt: 修正為可用的 mini 模型)",
|
|
)
|
|
messages: list[dict[str, Any]] = Field(..., description="對話訊息")
|
|
tools: list[ToolDefinition] = Field(..., description="可用 Tools")
|
|
tool_choice: str | dict[str, Any] = Field(
|
|
default="auto", description="Tool 選擇策略"
|
|
)
|
|
temperature: float = Field(default=0.0, description="溫度 (0.0 最確定性)")
|
|
max_tokens: int = Field(default=1024, description="最大輸出 Token")
|
|
|
|
|
|
# === 驗證結果結構 ===
|
|
|
|
|
|
class ToolCallValidationResult(BaseModel):
|
|
"""Tool Call 驗證結果"""
|
|
|
|
valid: bool = Field(..., description="是否有效")
|
|
tool_name: str | None = Field(default=None, description="Tool 名稱")
|
|
arguments: dict[str, Any] | None = Field(default=None, description="解析後參數")
|
|
error: str | None = Field(default=None, description="錯誤訊息")
|
|
raw_response: str | None = Field(default=None, description="原始回應 (debug)")
|
|
|
|
|
|
class NvidiaProviderResult(BaseModel):
|
|
"""NvidiaProvider 回傳結果"""
|
|
|
|
success: bool = Field(..., description="是否成功")
|
|
tool_calls: list[ToolCallValidationResult] = Field(
|
|
default_factory=list, description="驗證後的 Tool Calls"
|
|
)
|
|
usage: NvidiaUsage | None = Field(default=None, description="Token 使用統計")
|
|
latency_ms: float = Field(default=0.0, description="延遲 (毫秒)")
|
|
error: str | None = Field(default=None, description="錯誤訊息")
|
|
fallback_triggered: bool = Field(
|
|
default=False, description="是否觸發 Fallback"
|
|
)
|