Standardize LLM clients and expose configurable base URLs.
This commit is contained in:
@@ -12,7 +12,7 @@ import re
|
||||
|
||||
# 添加项目根目录到Python路径以导入config
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from config import GUIJI_QWEN3_API_KEY
|
||||
from config import GUIJI_QWEN3_API_KEY, GUIJI_QWEN3_BASE_URL
|
||||
|
||||
# 添加utils目录到Python路径
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -30,21 +30,24 @@ class ForumHost:
|
||||
使用Qwen3-235B模型作为智能主持人
|
||||
"""
|
||||
|
||||
def __init__(self, api_key: str = None):
|
||||
def __init__(self, api_key: str = None, base_url: Optional[str] = None):
|
||||
"""
|
||||
初始化论坛主持人
|
||||
|
||||
Args:
|
||||
api_key: 硅基流动API密钥,如果不提供则从配置文件读取
|
||||
base_url: 接口基础地址,默认使用配置文件提供的SiliconFlow地址
|
||||
"""
|
||||
self.api_key = api_key or GUIJI_QWEN3_API_KEY
|
||||
|
||||
if not self.api_key:
|
||||
raise ValueError("未找到硅基流动API密钥,请在config.py中设置GUIJI_QWEN3_API_KEY")
|
||||
|
||||
self.base_url = base_url or GUIJI_QWEN3_BASE_URL
|
||||
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://api.siliconflow.cn/v1"
|
||||
base_url=self.base_url
|
||||
)
|
||||
self.model = "Qwen/Qwen3-235B-A22B-Instruct-2507" # Use larger model variant
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ class DeepSearchAgent:
|
||||
if self.config.default_llm_provider == "deepseek":
|
||||
return DeepSeekLLM(
|
||||
api_key=self.config.deepseek_api_key,
|
||||
model_name=self.config.deepseek_model
|
||||
model_name=self.config.deepseek_model,
|
||||
base_url=self.config.deepseek_base_url
|
||||
)
|
||||
elif self.config.default_llm_provider == "openai":
|
||||
return OpenAILLM(
|
||||
@@ -82,7 +83,8 @@ class DeepSearchAgent:
|
||||
elif self.config.default_llm_provider == "kimi":
|
||||
return KimiLLM(
|
||||
api_key=self.config.kimi_api_key,
|
||||
model_name=self.config.kimi_model
|
||||
model_name=self.config.kimi_model,
|
||||
base_url=self.config.kimi_base_url
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"不支持的LLM提供商: {self.config.default_llm_provider}")
|
||||
|
||||
@@ -9,6 +9,8 @@ from openai import OpenAI
|
||||
from .base import BaseLLM
|
||||
import sys
|
||||
|
||||
DEFAULT_DEEPSEEK_BASE_URL = "https://api.deepseek.com"
|
||||
|
||||
# 添加utils目录到Python路径
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
root_dir = os.path.dirname(os.path.dirname(current_dir))
|
||||
@@ -30,13 +32,14 @@ except ImportError:
|
||||
class DeepSeekLLM(BaseLLM):
|
||||
"""DeepSeek LLM实现类"""
|
||||
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None):
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, base_url: Optional[str] = None):
|
||||
"""
|
||||
初始化DeepSeek客户端
|
||||
|
||||
Args:
|
||||
api_key: DeepSeek API密钥,如果不提供则从环境变量读取
|
||||
model_name: 模型名称,默认使用deepseek-chat
|
||||
base_url: DeepSeek API基础地址
|
||||
"""
|
||||
if api_key is None:
|
||||
api_key = os.getenv("DEEPSEEK_API_KEY")
|
||||
@@ -45,10 +48,12 @@ class DeepSeekLLM(BaseLLM):
|
||||
|
||||
super().__init__(api_key, model_name)
|
||||
|
||||
self.base_url = base_url or os.getenv("DEEPSEEK_BASE_URL") or DEFAULT_DEEPSEEK_BASE_URL
|
||||
|
||||
# 初始化OpenAI客户端,使用DeepSeek的endpoint
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://api.deepseek.com"
|
||||
base_url=self.base_url
|
||||
)
|
||||
|
||||
self.default_model = model_name or self.get_default_model()
|
||||
@@ -110,5 +115,5 @@ class DeepSeekLLM(BaseLLM):
|
||||
return {
|
||||
"provider": "DeepSeek",
|
||||
"model": self.default_model,
|
||||
"api_base": "https://api.deepseek.com"
|
||||
"api_base": self.base_url
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ from openai import OpenAI
|
||||
# 假设 .base 模块和 BaseLLM 类已存在
|
||||
from .base import BaseLLM
|
||||
|
||||
DEFAULT_KIMI_BASE_URL = "https://api.moonshot.cn/v1"
|
||||
|
||||
# 添加utils目录到Python路径并导入重试模块
|
||||
try:
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -30,13 +32,14 @@ except ImportError:
|
||||
class KimiLLM(BaseLLM):
|
||||
"""Kimi LLM实现类"""
|
||||
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None):
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, base_url: Optional[str] = None):
|
||||
"""
|
||||
初始化Kimi客户端
|
||||
|
||||
Args:
|
||||
api_key: Kimi API密钥,如果不提供则从环境变量读取
|
||||
model_name: 模型名称,默认使用kimi-k2-0711-preview
|
||||
base_url: Kimi API基础地址
|
||||
"""
|
||||
if api_key is None:
|
||||
api_key = os.getenv("KIMI_API_KEY")
|
||||
@@ -44,11 +47,13 @@ class KimiLLM(BaseLLM):
|
||||
raise ValueError("Kimi API Key未找到!请设置KIMI_API_KEY环境变量或在初始化时提供")
|
||||
|
||||
super().__init__(api_key, model_name)
|
||||
|
||||
|
||||
self.base_url = base_url or os.getenv("KIMI_BASE_URL") or DEFAULT_KIMI_BASE_URL
|
||||
|
||||
# 初始化OpenAI客户端,使用Kimi的endpoint
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://api.moonshot.cn/v1"
|
||||
base_url=self.base_url
|
||||
)
|
||||
|
||||
self.default_model = model_name or self.get_default_model()
|
||||
@@ -136,7 +141,7 @@ class KimiLLM(BaseLLM):
|
||||
return {
|
||||
"provider": "Kimi",
|
||||
"model": self.default_model,
|
||||
"api_base": "https://api.moonshot.cn/v1",
|
||||
"api_base": self.base_url,
|
||||
"max_context_length": "长文本支持(200K+ tokens)"
|
||||
}
|
||||
|
||||
@@ -159,4 +164,4 @@ class KimiLLM(BaseLLM):
|
||||
kwargs.setdefault("max_tokens", 16384)
|
||||
|
||||
# 直接调用核心的invoke方法,将所有参数(包括预设的默认值)传递给它。
|
||||
return self.invoke(system_prompt, user_prompt, **kwargs)
|
||||
return self.invoke(system_prompt, user_prompt, **kwargs)
|
||||
|
||||
@@ -12,7 +12,7 @@ from dataclasses import dataclass
|
||||
|
||||
# 添加项目根目录到Python路径以导入config
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
||||
from config import GUIJI_QWEN3_API_KEY
|
||||
from config import GUIJI_QWEN3_API_KEY, GUIJI_QWEN3_BASE_URL
|
||||
|
||||
# 添加utils目录到Python路径
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -38,21 +38,24 @@ class KeywordOptimizer:
|
||||
使用硅基流动的Qwen3模型将Agent生成的搜索词优化为更贴近真实舆情的关键词
|
||||
"""
|
||||
|
||||
def __init__(self, api_key: str = None):
|
||||
def __init__(self, api_key: str = None, base_url: str = None):
|
||||
"""
|
||||
初始化关键词优化器
|
||||
|
||||
Args:
|
||||
api_key: 硅基流动API密钥,如果不提供则从配置文件读取
|
||||
base_url: 接口基础地址,默认使用配置文件提供的SiliconFlow地址
|
||||
"""
|
||||
self.api_key = api_key or GUIJI_QWEN3_API_KEY
|
||||
|
||||
if not self.api_key:
|
||||
raise ValueError("未找到硅基流动API密钥,请在config.py中设置GUIJI_QWEN3_API_KEY")
|
||||
|
||||
self.base_url = base_url or GUIJI_QWEN3_BASE_URL
|
||||
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://api.siliconflow.cn/v1"
|
||||
base_url=self.base_url
|
||||
)
|
||||
self.model = "Qwen/Qwen3-30B-A3B-Instruct-2507"
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ class Config:
|
||||
deepseek_api_key: Optional[str] = None
|
||||
openai_api_key: Optional[str] = None
|
||||
kimi_api_key: Optional[str] = None
|
||||
deepseek_base_url: str = "https://api.deepseek.com"
|
||||
openai_base_url: Optional[str] = None
|
||||
kimi_base_url: str = "https://api.moonshot.cn/v1"
|
||||
|
||||
# 数据库配置
|
||||
db_host: Optional[str] = None
|
||||
@@ -85,6 +88,10 @@ class Config:
|
||||
return cls(
|
||||
deepseek_api_key=getattr(config_module, "DEEPSEEK_API_KEY", None),
|
||||
openai_api_key=getattr(config_module, "OPENAI_API_KEY", None),
|
||||
kimi_api_key=getattr(config_module, "KIMI_API_KEY", None),
|
||||
deepseek_base_url=getattr(config_module, "DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
openai_base_url=getattr(config_module, "OPENAI_BASE_URL", None),
|
||||
kimi_base_url=getattr(config_module, "KIMI_BASE_URL", "https://api.moonshot.cn/v1"),
|
||||
|
||||
db_host=getattr(config_module, "DB_HOST", None),
|
||||
db_user=getattr(config_module, "DB_USER", None),
|
||||
@@ -131,6 +138,9 @@ class Config:
|
||||
deepseek_api_key=config_dict.get("DEEPSEEK_API_KEY"),
|
||||
openai_api_key=config_dict.get("OPENAI_API_KEY"),
|
||||
kimi_api_key=config_dict.get("KIMI_API_KEY"),
|
||||
deepseek_base_url=config_dict.get("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
openai_base_url=config_dict.get("OPENAI_BASE_URL"),
|
||||
kimi_base_url=config_dict.get("KIMI_BASE_URL", "https://api.moonshot.cn/v1"),
|
||||
|
||||
db_host=config_dict.get("DB_HOST"),
|
||||
db_user=config_dict.get("DB_USER"),
|
||||
|
||||
@@ -60,7 +60,8 @@ class DeepSearchAgent:
|
||||
if self.config.default_llm_provider == "deepseek":
|
||||
return DeepSeekLLM(
|
||||
api_key=self.config.deepseek_api_key,
|
||||
model_name=self.config.deepseek_model
|
||||
model_name=self.config.deepseek_model,
|
||||
base_url=self.config.deepseek_base_url
|
||||
)
|
||||
elif self.config.default_llm_provider == "openai":
|
||||
return OpenAILLM(
|
||||
@@ -70,7 +71,8 @@ class DeepSearchAgent:
|
||||
elif self.config.default_llm_provider == "gemini":
|
||||
return GeminiLLM(
|
||||
api_key=self.config.gemini_api_key,
|
||||
model_name=self.config.gemini_model
|
||||
model_name=self.config.gemini_model,
|
||||
base_url=self.config.gemini_base_url
|
||||
)
|
||||
else:
|
||||
raise ValueError(f"不支持的LLM提供商: {self.config.default_llm_provider}")
|
||||
|
||||
@@ -9,6 +9,8 @@ from typing import Optional, Dict, Any
|
||||
from openai import OpenAI
|
||||
from .base import BaseLLM
|
||||
|
||||
DEFAULT_DEEPSEEK_BASE_URL = "https://api.deepseek.com"
|
||||
|
||||
# 添加utils目录到Python路径并导入重试模块
|
||||
try:
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -29,13 +31,14 @@ except ImportError:
|
||||
class DeepSeekLLM(BaseLLM):
|
||||
"""DeepSeek LLM实现类"""
|
||||
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None):
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, base_url: Optional[str] = None):
|
||||
"""
|
||||
初始化DeepSeek客户端
|
||||
|
||||
Args:
|
||||
api_key: DeepSeek API密钥,如果不提供则从环境变量读取
|
||||
model_name: 模型名称,默认使用deepseek-chat
|
||||
base_url: DeepSeek API基础地址
|
||||
"""
|
||||
if api_key is None:
|
||||
api_key = os.getenv("DEEPSEEK_API_KEY")
|
||||
@@ -44,10 +47,12 @@ class DeepSeekLLM(BaseLLM):
|
||||
|
||||
super().__init__(api_key, model_name)
|
||||
|
||||
self.base_url = base_url or os.getenv("DEEPSEEK_BASE_URL") or DEFAULT_DEEPSEEK_BASE_URL
|
||||
|
||||
# 初始化OpenAI客户端,使用DeepSeek的endpoint
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://api.deepseek.com"
|
||||
base_url=self.base_url
|
||||
)
|
||||
|
||||
self.default_model = model_name or self.get_default_model()
|
||||
@@ -109,5 +114,5 @@ class DeepSeekLLM(BaseLLM):
|
||||
return {
|
||||
"provider": "DeepSeek",
|
||||
"model": self.default_model,
|
||||
"api_base": "https://api.deepseek.com"
|
||||
"api_base": self.base_url
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ from typing import Optional, Dict, Any
|
||||
from openai import OpenAI
|
||||
from .base import BaseLLM
|
||||
|
||||
DEFAULT_GEMINI_BASE_URL = "https://www.chataiapi.com/v1"
|
||||
|
||||
# 添加utils目录到Python路径并导入重试模块
|
||||
try:
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -29,13 +31,14 @@ except ImportError:
|
||||
class GeminiLLM(BaseLLM):
|
||||
"""Gemini LLM实现类"""
|
||||
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None):
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, base_url: Optional[str] = None):
|
||||
"""
|
||||
初始化Gemini客户端
|
||||
|
||||
Args:
|
||||
api_key: Gemini API密钥,如果不提供则从环境变量读取
|
||||
model_name: 模型名称,默认使用gemini-2.5-pro
|
||||
base_url: Gemini API基础地址
|
||||
"""
|
||||
if api_key is None:
|
||||
api_key = os.getenv("GEMINI_API_KEY")
|
||||
@@ -44,10 +47,12 @@ class GeminiLLM(BaseLLM):
|
||||
|
||||
super().__init__(api_key, model_name)
|
||||
|
||||
self.base_url = base_url or os.getenv("GEMINI_BASE_URL") or DEFAULT_GEMINI_BASE_URL
|
||||
|
||||
# 初始化OpenAI客户端,使用Gemini的中转endpoint
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://www.chataiapi.com/v1"
|
||||
base_url=self.base_url
|
||||
)
|
||||
|
||||
self.default_model = model_name or self.get_default_model()
|
||||
@@ -109,5 +114,5 @@ class GeminiLLM(BaseLLM):
|
||||
return {
|
||||
"provider": "Gemini",
|
||||
"model": self.default_model,
|
||||
"api_base": "https://www.chataiapi.com/v1"
|
||||
"api_base": self.base_url
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ class Config:
|
||||
openai_api_key: Optional[str] = None
|
||||
gemini_api_key: Optional[str] = None
|
||||
bocha_api_key: Optional[str] = None
|
||||
deepseek_base_url: str = "https://api.deepseek.com"
|
||||
openai_base_url: Optional[str] = None
|
||||
gemini_base_url: str = "https://www.chataiapi.com/v1"
|
||||
|
||||
# 模型配置
|
||||
default_llm_provider: str = "deepseek" # deepseek、openai 或 gemini
|
||||
@@ -72,6 +75,9 @@ class Config:
|
||||
deepseek_api_key=getattr(config_module, "DEEPSEEK_API_KEY", None),
|
||||
openai_api_key=getattr(config_module, "OPENAI_API_KEY", None),
|
||||
gemini_api_key=getattr(config_module, "GEMINI_API_KEY", None),
|
||||
deepseek_base_url=getattr(config_module, "DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
openai_base_url=getattr(config_module, "OPENAI_BASE_URL", None),
|
||||
gemini_base_url=getattr(config_module, "GEMINI_BASE_URL", "https://www.chataiapi.com/v1"),
|
||||
bocha_api_key=getattr(config_module, "BOCHA_API_KEY", None),
|
||||
default_llm_provider=getattr(config_module, "DEFAULT_LLM_PROVIDER", "deepseek"),
|
||||
deepseek_model=getattr(config_module, "DEEPSEEK_MODEL", "deepseek-chat"),
|
||||
@@ -100,6 +106,9 @@ class Config:
|
||||
deepseek_api_key=config_dict.get("DEEPSEEK_API_KEY"),
|
||||
openai_api_key=config_dict.get("OPENAI_API_KEY"),
|
||||
gemini_api_key=config_dict.get("GEMINI_API_KEY"),
|
||||
deepseek_base_url=config_dict.get("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
openai_base_url=config_dict.get("OPENAI_BASE_URL"),
|
||||
gemini_base_url=config_dict.get("GEMINI_BASE_URL", "https://www.chataiapi.com/v1"),
|
||||
bocha_api_key=config_dict.get("BOCHA_API_KEY"),
|
||||
default_llm_provider=config_dict.get("DEFAULT_LLM_PROVIDER", "deepseek"),
|
||||
deepseek_model=config_dict.get("DEEPSEEK_MODEL", "deepseek-chat"),
|
||||
|
||||
@@ -60,7 +60,8 @@ class DeepSearchAgent:
|
||||
if self.config.default_llm_provider == "deepseek":
|
||||
return DeepSeekLLM(
|
||||
api_key=self.config.deepseek_api_key,
|
||||
model_name=self.config.deepseek_model
|
||||
model_name=self.config.deepseek_model,
|
||||
base_url=self.config.deepseek_base_url
|
||||
)
|
||||
elif self.config.default_llm_provider == "openai":
|
||||
return OpenAILLM(
|
||||
|
||||
@@ -9,6 +9,8 @@ from typing import Optional, Dict, Any
|
||||
from openai import OpenAI
|
||||
from .base import BaseLLM
|
||||
|
||||
DEFAULT_DEEPSEEK_BASE_URL = "https://api.deepseek.com"
|
||||
|
||||
# 添加utils目录到Python路径并导入重试模块
|
||||
try:
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -29,13 +31,14 @@ except ImportError:
|
||||
class DeepSeekLLM(BaseLLM):
|
||||
"""DeepSeek LLM实现类"""
|
||||
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None):
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, base_url: Optional[str] = None):
|
||||
"""
|
||||
初始化DeepSeek客户端
|
||||
|
||||
Args:
|
||||
api_key: DeepSeek API密钥,如果不提供则从环境变量读取
|
||||
model_name: 模型名称,默认使用deepseek-chat
|
||||
base_url: DeepSeek API基础地址
|
||||
"""
|
||||
if api_key is None:
|
||||
api_key = os.getenv("DEEPSEEK_API_KEY")
|
||||
@@ -44,10 +47,12 @@ class DeepSeekLLM(BaseLLM):
|
||||
|
||||
super().__init__(api_key, model_name)
|
||||
|
||||
self.base_url = base_url or os.getenv("DEEPSEEK_BASE_URL") or DEFAULT_DEEPSEEK_BASE_URL
|
||||
|
||||
# 初始化OpenAI客户端,使用DeepSeek的endpoint
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://api.deepseek.com"
|
||||
base_url=self.base_url
|
||||
)
|
||||
|
||||
self.default_model = model_name or self.get_default_model()
|
||||
@@ -109,5 +114,5 @@ class DeepSeekLLM(BaseLLM):
|
||||
return {
|
||||
"provider": "DeepSeek",
|
||||
"model": self.default_model,
|
||||
"api_base": "https://api.deepseek.com"
|
||||
"api_base": self.base_url
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ class Config:
|
||||
deepseek_api_key: Optional[str] = None
|
||||
openai_api_key: Optional[str] = None
|
||||
tavily_api_key: Optional[str] = None
|
||||
deepseek_base_url: str = "https://api.deepseek.com"
|
||||
openai_base_url: Optional[str] = None
|
||||
|
||||
# 模型配置
|
||||
default_llm_provider: str = "deepseek" # deepseek 或 openai
|
||||
@@ -66,6 +68,8 @@ class Config:
|
||||
deepseek_api_key=getattr(config_module, "DEEPSEEK_API_KEY", None),
|
||||
openai_api_key=getattr(config_module, "OPENAI_API_KEY", None),
|
||||
tavily_api_key=getattr(config_module, "TAVILY_API_KEY", None),
|
||||
deepseek_base_url=getattr(config_module, "DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
openai_base_url=getattr(config_module, "OPENAI_BASE_URL", None),
|
||||
default_llm_provider=getattr(config_module, "DEFAULT_LLM_PROVIDER", "deepseek"),
|
||||
deepseek_model=getattr(config_module, "DEEPSEEK_MODEL", "deepseek-chat"),
|
||||
openai_model=getattr(config_module, "OPENAI_MODEL", "gpt-4o-mini"),
|
||||
@@ -93,6 +97,8 @@ class Config:
|
||||
deepseek_api_key=config_dict.get("DEEPSEEK_API_KEY"),
|
||||
openai_api_key=config_dict.get("OPENAI_API_KEY"),
|
||||
tavily_api_key=config_dict.get("TAVILY_API_KEY"),
|
||||
deepseek_base_url=config_dict.get("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
openai_base_url=config_dict.get("OPENAI_BASE_URL"),
|
||||
default_llm_provider=config_dict.get("DEFAULT_LLM_PROVIDER", "deepseek"),
|
||||
deepseek_model=config_dict.get("DEEPSEEK_MODEL", "deepseek-chat"),
|
||||
openai_model=config_dict.get("OPENAI_MODEL", "gpt-4o-mini"),
|
||||
|
||||
+14
-3
@@ -1,12 +1,21 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="static/image/logo_compressed.png" alt="Weibo Public Opinion Analysis System Logo" width="800">
|
||||
<img src="static/image/logo_compressed.png" alt="Weibo Public Opinion Analysis System Logo" width="700">
|
||||
|
||||
<a href="https://trendshift.io/repositories/12461" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12461" alt="666ghj%2FWeibo_PublicOpinion_AnalysisSystem | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||
|
||||
<a href="https://leaflow.net/" target="_blank"><img src="static/image/Leaflow_logo.png" alt="666ghj%2FWeibo_PublicOpinion_AnalysisSystem | Leaflow" style="width: 150px;" width="150"/></a>
|
||||
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem/stargazers)
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem/watchers)
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem/network)
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem/issues)
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem/pulls)
|
||||
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem/blob/main/LICENSE)
|
||||
[](https://github.com/666ghj/Weibo_PublicOpinion_AnalysisSystem)
|
||||
[](https://hub.docker.com/)
|
||||
|
||||
|
||||
[English](./README-EN.md) | [中文文档](./README.md)
|
||||
|
||||
@@ -221,7 +230,7 @@ playwright install chromium
|
||||
|
||||
#### 4.1 Configure API Keys
|
||||
|
||||
Edit the `config.py` file and fill in your API keys (you can also choose your own models and search proxies):
|
||||
Edit the `config.py` file and fill in your API keys (you can also choose your own models and search proxies; please see the config file for details):
|
||||
|
||||
```python
|
||||
# MySQL Database Configuration
|
||||
@@ -283,7 +292,9 @@ conda activate your_conda_name
|
||||
python app.py
|
||||
```
|
||||
|
||||
> Note: Data crawling requires separate operation, see section 5.3 for guidance
|
||||
> Note 1: After a run is terminated, the Streamlit app might not shut down correctly and may still be occupying the port. If this occurs, find the process that is holding the port and kill it.
|
||||
|
||||
> Note 2: Data scraping needs to be performed as a separate operation. Please refer to the instructions in section 5.3.
|
||||
|
||||
Visit http://localhost:5000 to use the complete system
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ playwright install chromium
|
||||
|
||||
#### 4.1 配置API密钥
|
||||
|
||||
编辑 `config.py` 文件,填入您的API密钥(您也可以选择自己的模型、搜索代理):
|
||||
编辑 `config.py` 文件,填入您的API密钥(您也可以选择自己的模型、搜索代理,详情见config文件内):
|
||||
|
||||
```python
|
||||
# MySQL数据库配置
|
||||
@@ -292,7 +292,9 @@ conda activate your_conda_name
|
||||
python app.py
|
||||
```
|
||||
|
||||
> 注:数据爬取需要单独操作,见5.3指引
|
||||
> 注1:一次运行终止后,streamlit app可能结束异常仍然占用端口,此时搜索占用端口的进程kill掉即可
|
||||
|
||||
> 注2:数据爬取需要单独操作,见5.3指引
|
||||
|
||||
访问 http://localhost:5000 即可使用完整系统
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ class ReportAgent:
|
||||
return GeminiLLM(
|
||||
api_key=self.config.gemini_api_key,
|
||||
model_name=self.config.gemini_model,
|
||||
base_url=self.config.gemini_base_url,
|
||||
config=self.config # 传入配置对象以支持动态超时设置
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -9,6 +9,8 @@ from typing import Optional, Dict, Any
|
||||
from openai import OpenAI
|
||||
from .base import BaseLLM
|
||||
|
||||
DEFAULT_GEMINI_BASE_URL = "https://www.chataiapi.com/v1"
|
||||
|
||||
# 导入根目录的config
|
||||
try:
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -50,13 +52,14 @@ except ImportError:
|
||||
class GeminiLLM(BaseLLM):
|
||||
"""Report Engine Gemini LLM实现类"""
|
||||
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, config=None):
|
||||
def __init__(self, api_key: Optional[str] = None, model_name: Optional[str] = None, base_url: Optional[str] = None, config=None):
|
||||
"""
|
||||
初始化Gemini客户端
|
||||
|
||||
Args:
|
||||
api_key: Gemini API密钥,如果不提供则从config或环境变量读取
|
||||
model_name: 模型名称,默认使用gemini-2.5-pro
|
||||
base_url: Gemini API基础地址
|
||||
config: 配置对象,用于获取超时设置
|
||||
"""
|
||||
if api_key is None:
|
||||
@@ -77,15 +80,22 @@ class GeminiLLM(BaseLLM):
|
||||
|
||||
# 从配置获取超时时间,默认15分钟(适应7分钟平均生成时间)
|
||||
timeout = config.api_timeout if config and hasattr(config, 'api_timeout') else 900.0
|
||||
|
||||
|
||||
self.base_url = (
|
||||
base_url
|
||||
or (getattr(self.config, 'gemini_base_url', None) if self.config else None)
|
||||
or os.getenv('GEMINI_BASE_URL')
|
||||
or DEFAULT_GEMINI_BASE_URL
|
||||
)
|
||||
|
||||
# 创建针对此实例的重试配置
|
||||
self.retry_config = create_report_retry_config(config)
|
||||
|
||||
|
||||
# 初始化OpenAI客户端,使用Gemini的中转endpoint
|
||||
# 专门为报告生成设置长超时(15分钟),适应7分钟平均生成时间
|
||||
self.client = OpenAI(
|
||||
api_key=self.api_key,
|
||||
base_url="https://www.chataiapi.com/v1",
|
||||
base_url=self.base_url,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
@@ -188,6 +198,6 @@ class GeminiLLM(BaseLLM):
|
||||
return {
|
||||
"provider": "Gemini",
|
||||
"model": self.default_model,
|
||||
"api_base": "https://www.chataiapi.com/v1",
|
||||
"api_base": self.base_url,
|
||||
"purpose": "Report Generation"
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ class Config:
|
||||
"""Report Engine配置类"""
|
||||
# API密钥
|
||||
gemini_api_key: Optional[str] = None
|
||||
gemini_base_url: str = "https://www.chataiapi.com/v1"
|
||||
|
||||
# 模型配置
|
||||
default_llm_provider: str = "gemini"
|
||||
@@ -56,6 +57,7 @@ class Config:
|
||||
|
||||
return cls(
|
||||
gemini_api_key=getattr(config_module, "GEMINI_API_KEY", None),
|
||||
gemini_base_url=getattr(config_module, "GEMINI_BASE_URL", "https://www.chataiapi.com/v1"),
|
||||
default_llm_provider=getattr(config_module, "DEFAULT_LLM_PROVIDER", "gemini"),
|
||||
gemini_model=getattr(config_module, "GEMINI_MODEL", "gemini-2.5-pro"),
|
||||
max_content_length=getattr(config_module, "MAX_CONTENT_LENGTH", 200000),
|
||||
@@ -82,6 +84,7 @@ class Config:
|
||||
|
||||
return cls(
|
||||
gemini_api_key=config_dict.get("GEMINI_API_KEY"),
|
||||
gemini_base_url=config_dict.get("GEMINI_BASE_URL", "https://www.chataiapi.com/v1"),
|
||||
default_llm_provider=config_dict.get("DEFAULT_LLM_PROVIDER", "gemini"),
|
||||
gemini_model=config_dict.get("GEMINI_MODEL", "gemini-2.5-pro"),
|
||||
max_content_length=int(config_dict.get("MAX_CONTENT_LENGTH", "200000")),
|
||||
|
||||
@@ -27,7 +27,18 @@ except locale.Error:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from InsightEngine import DeepSearchAgent, Config
|
||||
from config import DEEPSEEK_API_KEY, KIMI_API_KEY, DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT, DB_CHARSET
|
||||
from config import (
|
||||
DEEPSEEK_API_KEY,
|
||||
DEEPSEEK_BASE_URL,
|
||||
KIMI_API_KEY,
|
||||
KIMI_BASE_URL,
|
||||
DB_HOST,
|
||||
DB_USER,
|
||||
DB_PASSWORD,
|
||||
DB_NAME,
|
||||
DB_PORT,
|
||||
DB_CHARSET,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -111,6 +122,8 @@ def main():
|
||||
deepseek_api_key=None,
|
||||
openai_api_key=None,
|
||||
kimi_api_key=KIMI_API_KEY, # 强制使用配置文件中的Kimi Key
|
||||
deepseek_base_url=DEEPSEEK_BASE_URL,
|
||||
kimi_base_url=KIMI_BASE_URL,
|
||||
db_host=db_host,
|
||||
db_user=db_user,
|
||||
db_password=db_password,
|
||||
@@ -225,4 +238,4 @@ def display_results(agent: DeepSearchAgent, final_report: str):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -27,7 +27,13 @@ except locale.Error:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from MediaEngine import DeepSearchAgent, Config
|
||||
from config import DEEPSEEK_API_KEY, BOCHA_Web_Search_API_KEY, GEMINI_API_KEY
|
||||
from config import (
|
||||
DEEPSEEK_API_KEY,
|
||||
DEEPSEEK_BASE_URL,
|
||||
BOCHA_Web_Search_API_KEY,
|
||||
GEMINI_API_KEY,
|
||||
GEMINI_BASE_URL,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -112,6 +118,8 @@ def main():
|
||||
openai_api_key=None,
|
||||
gemini_api_key=gemini_key,
|
||||
bocha_api_key=bocha_key,
|
||||
deepseek_base_url=DEEPSEEK_BASE_URL,
|
||||
gemini_base_url=GEMINI_BASE_URL,
|
||||
default_llm_provider=llm_provider,
|
||||
deepseek_model="deepseek-chat", # 保留默认值以兼容
|
||||
openai_model="gpt-4o-mini", # 保留默认值以兼容
|
||||
@@ -220,4 +228,4 @@ def display_results(agent: DeepSearchAgent, final_report: str):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -27,7 +27,7 @@ except locale.Error:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from QueryEngine import DeepSearchAgent, Config
|
||||
from config import DEEPSEEK_API_KEY, TAVILY_API_KEY
|
||||
from config import DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL, TAVILY_API_KEY
|
||||
|
||||
|
||||
def main():
|
||||
@@ -110,6 +110,7 @@ def main():
|
||||
deepseek_api_key=deepseek_key,
|
||||
openai_api_key=None,
|
||||
tavily_api_key=tavily_key,
|
||||
deepseek_base_url=DEEPSEEK_BASE_URL,
|
||||
default_llm_provider=llm_provider,
|
||||
deepseek_model=model_name,
|
||||
openai_model="gpt-4o-mini", # 保留默认值以兼容
|
||||
@@ -217,4 +218,4 @@ def display_results(agent: DeepSearchAgent, final_report: str):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -4,35 +4,52 @@ Intelligence Public Opinion Analysis Platform Configuration File
|
||||
Stores database connection information and API keys
|
||||
"""
|
||||
|
||||
# ============================== 数据库配置 ==============================
|
||||
# MySQL Database Configuration
|
||||
DB_HOST = "your_database_host" # e.g., "localhost" or "127.0.0.1"
|
||||
DB_PORT = 3306
|
||||
DB_PORT = 3306 # e.g., 3306
|
||||
DB_USER = "your_database_user"
|
||||
DB_PASSWORD = "your_database_password"
|
||||
DB_NAME = "your_database_name"
|
||||
DB_CHARSET = "utf8mb4"
|
||||
# 我们也提供云数据库资源便捷配置,日均10w+数据,目前推广阶段可免费申请,联系我们:670939375@qq.com
|
||||
# 我们也提供云数据库资源便捷配置,日均10w+数据,学术研究可免费申请,联系我们:670939375@qq.com
|
||||
|
||||
# DeepSeek API Key
|
||||
|
||||
# ============================== LLM配置 ==============================
|
||||
# 重要提醒:推荐第一次先按照默认模型安排配置,成功跑通后再更改自己的模型!
|
||||
|
||||
# DeepSeek API Key (openai调用格式)
|
||||
# 用于Query Agent
|
||||
# 申请地址https://www.deepseek.com/
|
||||
DEEPSEEK_API_KEY = "your_deepseek_api_key"
|
||||
DEEPSEEK_API_KEY = "sk-xxxxxxxxxxxxxxxxx"
|
||||
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
|
||||
|
||||
# Kimi API Key (openai调用格式)
|
||||
# 用于Insight Agent
|
||||
# 申请地址https://platform.moonshot.cn/
|
||||
KIMI_API_KEY = "sk-xxxxxxxxxxxxxxxxx"
|
||||
KIMI_BASE_URL = "https://api.moonshot.cn/v1"
|
||||
|
||||
# Gemini API Key (openai调用格式)
|
||||
# 用于Media Agent与Report Agent
|
||||
# 这里我用了一个中转api来接入Gemini,申请地址https://api.chataiapi.com/,你也可以使用其他
|
||||
GEMINI_API_KEY = "sk-xxxxxxxxxxxxxxxxx"
|
||||
GEMINI_BASE_URL = "https://www.chataiapi.com/v1"
|
||||
|
||||
# Siliconflow API Key (openai调用格式)
|
||||
# 用于Forum Host与keyword Optimizer
|
||||
# 申请地址https://siliconflow.cn/
|
||||
GUIJI_QWEN3_API_KEY = "sk-xxxxxxxxxxxxxxxxx"
|
||||
GUIJI_QWEN3_BASE_URL = "https://api.siliconflow.cn/v1"
|
||||
|
||||
# 调试阶段出于成本考虑,没有使用ChatGPT与Claude,您也可以接入自己的模型,只要符合openai调用格式即可
|
||||
|
||||
|
||||
# ============================== Web工具配置 ==============================
|
||||
# Tavily Search API Key
|
||||
# 申请地址https://www.tavily.com/
|
||||
TAVILY_API_KEY = "your_tavily_api_key"
|
||||
|
||||
# Kimi API Key
|
||||
# 申请地址https://www.kimi.com/
|
||||
KIMI_API_KEY = "your_kimi_api_key"
|
||||
|
||||
# Gemini API Key (via OpenAI format proxy)
|
||||
# 这里我用了一个中转api来接入Gemini,申请地址https://api.chataiapi.com/,你也可以使用其他
|
||||
GEMINI_API_KEY = "your_gemini_api_key"
|
||||
TAVILY_API_KEY = "tvly-xxxxxxxxxxxxxxxxx"
|
||||
|
||||
# Bocha Search API Key
|
||||
# 申请地址https://open.bochaai.com/
|
||||
BOCHA_Web_Search_API_KEY = "your_bocha_web_search_api_key"
|
||||
|
||||
# Guiji Flow API Key
|
||||
# 申请地址https://siliconflow.cn/
|
||||
GUIJI_QWEN3_API_KEY = "your_guiji_qwen3_api_key"
|
||||
BOCHA_Web_Search_API_KEY = "sk-xxxxxxxxxxxxxxxxx"
|
||||
|
||||
Reference in New Issue
Block a user