53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
"""
|
||||
|
|
LLM Client 路由器:在 DeepSeek / OpenAI 之间切换。
|
|||
|
|
|
|||
|
|
约定:
|
|||
|
|
- 调用方只依赖 duck-typing:需要 ``chat`` / ``chat_with_json`` 等方法。
|
|||
|
|
- 通过环境变量 ``LLM_SERVICE_CODE``(openai|deepseek)决定默认路由;
|
|||
|
|
若未设置则按 Key 存在性自动选择(优先 deepseek)。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
from typing import Any, Optional
|
|||
|
|
|
|||
|
|
from llm.deepseek_client import DeepSeekClient, DeepSeekConfig
|
|||
|
|
from llm.openai_client import create_openai_client
|
|||
|
|
|
|||
|
|
|
|||
|
|
def resolve_llm_service_code(service_code: Optional[str] = None) -> str:
|
|||
|
|
sc = (service_code or os.getenv("LLM_SERVICE_CODE") or "").strip().lower()
|
|||
|
|
if sc in ("openai", "deepseek"):
|
|||
|
|
return sc
|
|||
|
|
|
|||
|
|
# 自动选择:优先 DeepSeek(与历史默认一致)
|
|||
|
|
if (os.getenv("DEEPSEEK_API_KEY") or "").strip():
|
|||
|
|
return "deepseek"
|
|||
|
|
if (os.getenv("OPENAI_API_KEY") or "").strip():
|
|||
|
|
return "openai"
|
|||
|
|
return "deepseek"
|
|||
|
|
|
|||
|
|
|
|||
|
|
def create_llm_client(service_code: Optional[str] = None, **kwargs: Any) -> Any:
|
|||
|
|
"""
|
|||
|
|
创建 LLM Client。
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
DeepSeekClient 或 OpenAIClient(同形态接口)。
|
|||
|
|
"""
|
|||
|
|
sc = resolve_llm_service_code(service_code)
|
|||
|
|
if sc == "openai":
|
|||
|
|
# OpenAI 侧:默认从 OPENAI_* 读取
|
|||
|
|
return create_openai_client(**kwargs)
|
|||
|
|
|
|||
|
|
# DeepSeek 侧:从 DEEPSEEK_* 读取
|
|||
|
|
api_key = (kwargs.pop("api_key", None) or os.getenv("DEEPSEEK_API_KEY") or "").strip()
|
|||
|
|
if not api_key:
|
|||
|
|
raise ValueError("未配置 DEEPSEEK_API_KEY(LLM_SERVICE_CODE=deepseek)")
|
|||
|
|
base_url = (kwargs.pop("base_url", None) or os.getenv("DEEPSEEK_BASE_URL") or "https://api.deepseek.com").strip()
|
|||
|
|
model = (kwargs.pop("model_name", None) or os.getenv("MODEL_PRIMARY") or "deepseek-chat").strip()
|
|||
|
|
cfg = DeepSeekConfig(api_key=api_key, base_url=base_url, model_name=model, **kwargs)
|
|||
|
|
return DeepSeekClient(cfg)
|
|||
|
|
|