fc / apps /core /llm /backends /base.py
jun2024's picture
Upload 2241 files
b4f2238 verified
Raw History Blame Contribute Delete
5.13 kB
"""
LLM 后端基础定义
定义 LLM 后端的统一接口和数据类.
Requirements: 1.1, 1.5
"""
from collections.abc import AsyncIterator, Iterator
from dataclasses import dataclass, field
from typing import Any, Protocol, runtime_checkable
@dataclass
class LLMResponse:
"""
LLM 响应数据类
统一所有后端的响应格式,便于调用方处理.
Attributes:
content: 生成的文本内容
model: 使用的模型名称
prompt_tokens: 输入 token 数
completion_tokens: 输出 token 数
total_tokens: 总 token 数
duration_ms: 调用耗时(毫秒)
backend: 使用的后端标识 (siliconflow/ollama/openai_compatible)
Requirements: 1.1, 1.5
"""
content: str
model: str
prompt_tokens: int
completion_tokens: int
total_tokens: int
duration_ms: float
backend: str = ""
@dataclass
class LLMUsage:
prompt_tokens: int = 0
completion_tokens: int = 0
total_tokens: int = 0
@dataclass
class LLMStreamChunk:
content: str = ""
usage: LLMUsage | None = None
model: str = ""
backend: str = ""
@dataclass
class BackendConfig:
"""
后端配置数据类
定义 LLM 后端的配置参数.
Attributes:
name: 后端名称 (siliconflow/ollama/openai_compatible)
enabled: 是否启用
priority: 降级优先级,数字越小优先级越高
default_model: 默认模型名称
base_url: API 基础 URL
api_key: API 密钥
timeout: 请求超时时间(秒)
extra_options: 额外配置选项
"""
name: str
enabled: bool
priority: int
default_model: str
base_url: str | None = None
api_key: str | None = None
timeout: int = 60
embedding_model: str | None = None
extra_options: dict[str, Any] = field(default_factory=dict)
@runtime_checkable
class ILLMBackend(Protocol):
"""
LLM 后端接口协议
定义所有 LLM 后端必须实现的方法.使用 Protocol 实现结构化子类型,
无需显式继承即可满足接口约束.
Requirements: 1.1, 1.5
"""
def chat(
self,
messages: list[dict[str, str]],
model: str | None = None,
temperature: float = 0.7,
max_tokens: int | None = None,
**kwargs: Any,
) -> LLMResponse:
"""
同步聊天接口
Args:
messages: 消息列表,格式为 [{"role": "user", "content": "..."}]
model: 模型名称,None 时使用默认模型
temperature: 温度参数,控制输出随机性
max_tokens: 最大输出 token 数
**kwargs: 后端特定参数
Returns:
LLMResponse: 统一格式的响应对象
Raises:
LLMNetworkError: 网络连接失败
LLMAPIError: API 返回错误
LLMAuthenticationError: 认证失败
LLMTimeoutError: 请求超时
"""
...
async def achat(
self,
messages: list[dict[str, str]],
model: str | None = None,
temperature: float = 0.7,
max_tokens: int | None = None,
**kwargs: Any,
) -> LLMResponse:
"""
异步聊天接口
Args:
messages: 消息列表,格式为 [{"role": "user", "content": "..."}]
model: 模型名称,None 时使用默认模型
temperature: 温度参数,控制输出随机性
max_tokens: 最大输出 token 数
**kwargs: 后端特定参数
Returns:
LLMResponse: 统一格式的响应对象
Raises:
LLMNetworkError: 网络连接失败
LLMAPIError: API 返回错误
LLMAuthenticationError: 认证失败
LLMTimeoutError: 请求超时
"""
...
def stream(
self,
messages: list[dict[str, str]],
model: str | None = None,
temperature: float = 0.7,
max_tokens: int | None = None,
**kwargs: Any,
) -> Iterator[LLMStreamChunk]: ...
async def astream(
self,
messages: list[dict[str, str]],
model: str | None = None,
temperature: float = 0.7,
max_tokens: int | None = None,
**kwargs: Any,
) -> AsyncIterator[LLMStreamChunk]: ...
def get_default_model(self) -> str:
"""
获取默认模型名称
Returns:
str: 后端的默认模型名称
"""
...
def get_default_embedding_model(self) -> str:
"""获取默认向量模型名称。"""
...
def embed_texts(
self,
texts: list[str],
model: str | None = None,
**kwargs: Any,
) -> list[list[float]]:
"""向量化文本列表。"""
...
def is_available(self) -> bool:
"""
检查后端是否可用
检查后端的配置是否完整(如 API Key 是否存在),
以及服务是否可达.
Returns:
bool: True 表示后端可用,False 表示不可用
"""
...