"""LLM Protocol - 数据类与抽象基类""" from abc import ABC, abstractmethod from dataclasses import dataclass, field from typing import Any @dataclass class TokenUsage: """Token 使用量""" prompt_tokens: int = 0 completion_tokens: int = 0 @property def total_tokens(self) -> int: return self.prompt_tokens + self.completion_tokens @dataclass class ToolCall: """工具调用""" id: str name: str arguments: dict[str, Any] @dataclass class LLMRequest: """LLM 请求""" messages: list[dict[str, str]] model: str tools: list[dict[str, Any]] | None = None tool_choice: str = "auto" temperature: float = 0.7 max_tokens: int = 2000 def __init__( self, messages: list[dict[str, str]], model: str, tools: list[dict[str, Any]] | None = None, tool_choice: str = "auto", temperature: float = 0.7, max_tokens: int = 2000, **kwargs: Any, ): self.messages = messages self.model = model self.tools = tools self.tool_choice = tool_choice self.temperature = temperature self.max_tokens = max_tokens self._extra = kwargs @dataclass class LLMResponse: """LLM 响应""" content: str model: str usage: TokenUsage tool_calls: list[ToolCall] = field(default_factory=list) latency_ms: float = 0.0 @property def has_tool_calls(self) -> bool: return len(self.tool_calls) > 0 class LLMProvider(ABC): """LLM Provider 抽象基类""" @abstractmethod async def chat(self, request: LLMRequest) -> LLMResponse: """发送 chat 请求并返回响应""" ...