feat: 添加LLM服务模块
- 添加LLM服务以支持DeepSeek和其他兼容OpenAI的LLM - 支持通过环境变量配置API密钥、基础URL和模型名称 - 提供LLM实例获取和可用性检查功能
This commit is contained in:
92
api/services/llm_service.py
Normal file
92
api/services/llm_service.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""
|
||||
LLM 服务模块:支持 DeepSeek 和其他兼容 OpenAI 的 LLM
|
||||
"""
|
||||
import os
|
||||
from typing import Optional
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
|
||||
class LLMService:
|
||||
"""LLM 服务,支持 DeepSeek 和其他兼容 OpenAI 的 LLM"""
|
||||
|
||||
def __init__(self):
|
||||
"""初始化 LLM 服务"""
|
||||
# 优先使用 DEEPSEEK_API_KEY,如果没有则使用 LLM_API_KEY
|
||||
api_key = (
|
||||
os.getenv("DEEPSEEK_API_KEY") or
|
||||
os.getenv("LLM_API_KEY", "")
|
||||
)
|
||||
|
||||
# 获取 base_url,优先使用 DEEPSEEK_BASE_URL
|
||||
base_url = (
|
||||
os.getenv("DEEPSEEK_BASE_URL") or
|
||||
os.getenv("LLM_BASE_URL", "")
|
||||
)
|
||||
|
||||
# 获取模型名称,优先使用 DEEPSEEK_MODEL
|
||||
model_name = (
|
||||
os.getenv("DEEPSEEK_MODEL") or
|
||||
os.getenv("LLM_MODEL") or
|
||||
"deepseek-chat" # DeepSeek 默认模型
|
||||
)
|
||||
|
||||
# 如果没有提供 base_url 但有 DEEPSEEK_API_KEY,使用 DeepSeek 默认地址
|
||||
if not base_url and os.getenv("DEEPSEEK_API_KEY"):
|
||||
base_url = "https://api.deepseek.com"
|
||||
|
||||
if not api_key:
|
||||
self.llm = None
|
||||
return
|
||||
|
||||
# 配置 LLM 参数
|
||||
# 获取 temperature,处理字符串默认值
|
||||
temp_str = os.getenv("LLM_TEMPERATURE", "0.7")
|
||||
try:
|
||||
temperature = float(temp_str)
|
||||
except (ValueError, TypeError):
|
||||
temperature = 0.7
|
||||
|
||||
llm_kwargs = {
|
||||
"temperature": temperature,
|
||||
"model": model_name,
|
||||
"api_key": api_key,
|
||||
}
|
||||
|
||||
if base_url:
|
||||
# 移除可能的 /v1/chat/completions 路径,langchain 会自动添加
|
||||
if base_url.endswith("/v1/chat/completions"):
|
||||
base_url = base_url[:-20] # 移除 "/v1/chat/completions"
|
||||
elif base_url.endswith("/v1"):
|
||||
base_url = base_url[:-3] # 移除 "/v1"
|
||||
# 确保 base_url 不以 / 结尾(langchain 会自动添加)
|
||||
if base_url.endswith("/"):
|
||||
base_url = base_url[:-1]
|
||||
llm_kwargs["base_url"] = base_url
|
||||
|
||||
try:
|
||||
self.llm = ChatOpenAI(**llm_kwargs)
|
||||
except Exception as e:
|
||||
print(f"初始化 LLM 失败: {e}")
|
||||
self.llm = None
|
||||
|
||||
def get_llm(self) -> Optional[ChatOpenAI]:
|
||||
"""
|
||||
获取 LLM 实例
|
||||
|
||||
Returns:
|
||||
ChatOpenAI 实例,如果未配置则返回 None
|
||||
"""
|
||||
return self.llm
|
||||
|
||||
def is_available(self) -> bool:
|
||||
"""
|
||||
检查 LLM 服务是否可用
|
||||
|
||||
Returns:
|
||||
True 如果 LLM 已配置且可用,否则 False
|
||||
"""
|
||||
return self.llm is not None
|
||||
|
||||
|
||||
# 创建全局实例
|
||||
llm_service = LLMService()
|
||||
Reference in New Issue
Block a user