Enhance LLM integration by adding OpenAI client support and enabling dynamic routing between DeepSeek and OpenAI services. Update environment configuration to include LLM_SERVICE_CODE for service selection, and modify API server to accommodate new request parameters for language and model. Implement streaming response improvements for chat interactions, allowing for segmented SSE output. Update documentation and impact analysis to reflect these changes.

This commit is contained in:
陈辅元
2026-04-16 09:15:01 +08:00
parent 85ad31348e
commit df33657099
17 changed files with 958 additions and 64 deletions
+52
View File
@@ -0,0 +1,52 @@
"""
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)