本手册旨在帮助开发者为 TradingAgents-CN 项目添加新的大模型支持。通过遵循本指南,您可以快速集成新的大模型提供商,并提交高质量的 Pull Request。
- 添加新的大模型提供商(如智谱、腾讯、百度等)
- 为现有提供商添加新模型
- 修复或优化现有 LLM 适配器
- 添加新的 API 兼容方式
TradingAgents 的 LLM 集成基于以下架构:
tradingagents/
├── llm_adapters/ # LLM 适配器实现
│ ├── __init__.py # 导出所有适配器
│ ├── openai_compatible_base.py # OpenAI 兼容基类 (核心)
│ ├── dashscope_adapter.py # 阿里百炼适配器
│ ├── dashscope_openai_adapter.py # 阿里百炼 OpenAI 兼容适配器
│ ├── deepseek_adapter.py # DeepSeek 原生适配器
│ ├── deepseek_direct_adapter.py # DeepSeek 直接适配器
│ └── google_openai_adapter.py # Google AI 适配器
└── web/
├── components/sidebar.py # 前端模型选择界面
└── utils/analysis_runner.py # 运行时配置与流程编排
- 适配器基类: —— 为所有 OpenAI 兼容的 LLM 提供统一实现,是新增提供商最重要的扩展点
- 工厂方法: —— 运行时根据提供商与模型创建对应的适配器实例(建议优先使用)
- 提供商注册: 在 中的
OPENAI_COMPATIBLE_PROVIDERS字典 —— 统一管理 base_url、API Key 环境变量名、受支持模型等(单一信息源) - 前端集成: —— 模型选择界面负责把用户选择的 llm_provider 和 llm_model 传递到后端
- 运行时入口: 中统一使用工厂方法创建 LLM; 仅作为参数传递与流程编排,通常无需为新增提供商做修改
-
Fork 并克隆仓库
git clone https://github.com/your-username/TradingAgentsCN.git cd TradingAgentsCN -
安装依赖
pip install -e . # 或使用 uv uv pip install -e .
-
创建开发分支
git checkout develop git checkout -b feature/add-{provider_name}-llm
根据目标大模型的 API 类型,选择适合的集成方式:
适用于:支持 OpenAI API 格式的模型(如智谱、MiniMax、月之暗面等)
优势:
- 开发工作量最小
- 复用现有的工具调用逻辑
- 统一的错误处理和日志记录
备注:百度千帆(Qianfan)已通过 OpenAI 兼容方式集成,provider 名称为
qianfan,只需配置QIANFAN_API_KEY。相关细节见专项文档 QIANFAN_INTEGRATION_GUIDE.md;pricing.json 已包含 ERNIE 系列占位价格,支持在 Web 配置页调整。
适用于:非 OpenAI 兼容格式的模型
需要更多工作:
- 需要自定义消息格式转换
- 需要实现工具调用逻辑
- 需要处理特定的错误格式
在 tradingagents/llm_adapters/ 下创建新文件:
# tradingagents/llm_adapters/your_provider_adapter.py
from .openai_compatible_base import OpenAICompatibleBase
import os
from tradingagents.utils.tool_logging import log_llm_call
import logging
logger = logging.getLogger(__name__)
class ChatYourProvider(OpenAICompatibleBase):
"""你的提供商 OpenAI 兼容适配器"""
def __init__(
self,
model: str = "your-default-model",
temperature: float = 0.7,
max_tokens: int = 4096,
**kwargs
) -> None:
super().__init__(
provider_name="your_provider",
model=model,
temperature=temperature,
max_tokens=max_tokens,
api_key_env_var="YOUR_PROVIDER_API_KEY",
base_url="https://api.yourprovider.com/v1",
**kwargs
)编辑 tradingagents/llm_adapters/openai_compatible_base.py:
# 在 OPENAI_COMPATIBLE_PROVIDERS 字典中添加配置
OPENAI_COMPATIBLE_PROVIDERS = {
# ... 现有配置 ...
"your_provider": {
"adapter_class": ChatYourProvider,
"base_url": "https://api.yourprovider.com/v1",
"api_key_env": "YOUR_PROVIDER_API_KEY",
"models": {
"your-model-1": {"context_length": 8192, "supports_function_calling": True},
"your-model-2": {"context_length": 32768, "supports_function_calling": True},
}
},
}编辑 tradingagents/llm_adapters/__init__.py:
from .your_provider_adapter import ChatYourProvider
__all__ = ["ChatDashScope", "ChatDashScopeOpenAI", "ChatGoogleOpenAI", "ChatYourProvider"]编辑 web/components/sidebar.py,在模型选择部分添加:
# 在 llm_provider 选择中添加选项
options=["dashscope", "deepseek", "google", "openai", "openrouter", "custom_openai", "your_provider"],
# 在格式化映射中添加
format_mapping={
# ... 现有映射 ...
"your_provider": "🚀 您的提供商",
}
# 添加模型选择逻辑
elif llm_provider == "your_provider":
your_provider_options = ["your-model-1", "your-model-2"]
current_index = 0
if st.session_state.llm_model in your_provider_options:
current_index = your_provider_options.index(st.session_state.llm_model)
llm_model = st.selectbox(
"选择模型",
options=your_provider_options,
index=current_index,
format_func=lambda x: {
"your-model-1": "Model 1 - 快速",
"your-model-2": "Model 2 - 强大",
}.get(x, x),
help="选择用于分析的模型",
key="your_provider_model_select"
)在绝大多数情况下,新增一个 OpenAI 兼容提供商时,无需修改 。原因:
- 侧边栏 收集
llm_provider与llm_model - 这些参数会被传入 ,由 基于
OPENAI_COMPATIBLE_PROVIDERS自动实例化正确的适配器 - 因此,真正的“运行时配置”主要体现在 的注册表和工厂方法,而非 analysis_runner 本身
推荐做法:
- 在 中完善
OPENAI_COMPATIBLE_PROVIDERS(base_url、api_key 环境变量、模型清单等) - 在 中新增该
llm_provider的下拉选项与模型列表 - 保持 无需改动
何时需要少量修改 analysis_runner:
- 该提供商要求在分析阶段动态切换不同模型(例如“快速/深度”分开)
- 需要在任务执行流水线中注入特定的 header、代理或文件型鉴权
- 需要为该提供商设置额外的日志或成本估算逻辑
即便如此,也请:
- 不在 analysis_runner 硬编码模型清单或 API 细节,统一放在
OPENAI_COMPATIBLE_PROVIDERS - 仍然使用 创建实例,避免重复初始化逻辑
编辑 web/utils/analysis_runner.py,在模型配置部分添加:
elif llm_provider == "your_provider":
config["backend_url"] = "https://api.yourprovider.com/v1"
logger.info(f"🚀 [您的提供商] 使用模型: {llm_model}")
logger.info(f"🚀 [您的提供商] API端点: https://api.yourprovider.com/v1")在项目根目录的 .env.example 文件中添加:
# 您的提供商 API 配置
YOUR_PROVIDER_API_KEY=your_api_key_here创建测试文件 test_your_provider.py:
import os
from tradingagents.llm_adapters.your_provider_adapter import ChatYourProvider
def test_basic_connection():
"""测试基础连接"""
# 设置测试环境变量
os.environ["YOUR_PROVIDER_API_KEY"] = "your_test_key"
try:
llm = ChatYourProvider(model="your-model-1")
response = llm.invoke("Hello, world!")
print(f"✅ 连接成功: {response.content}")
return True
except Exception as e:
print(f"❌ 连接失败: {e}")
return False
if __name__ == "__main__":
test_basic_connection()from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""获取城市天气信息"""
return f"{city}今天晴天,温度25°C"
def test_function_calling():
"""测试工具调用"""
llm = ChatYourProvider(model="your-model-1")
llm_with_tools = llm.bind_tools([get_weather])
response = llm_with_tools.invoke("北京天气如何?")
print(f"工具调用测试: {response}")启动 Web 应用进行集成测试:
cd web
streamlit run app.py验证:
- 在侧边栏能正确选择新提供商
- 模型选择下拉菜单工作正常
- API 密钥检查显示正确状态
- 能成功进行股票分析
提交 PR 前,请确保以下项目都已完成:
- 创建了适配器类并继承正确的基类
- 在
OPENAI_COMPATIBLE_PROVIDERS中正确注册 - 更新了
__init__.py导入 - 前端集成完整(模型选择、配置界面)
- 运行时配置正确
- 添加了环境变量示例到
.env.example - API 密钥验证逻辑正确
- 错误处理完善
- 基础连接测试通过
- 工具调用测试通过(如果支持)
- Web 界面集成测试通过
- 至少完成一次完整的股票分析
- 更新了相关 README 文档
- 添加了模型特性说明
- 提供了使用示例
百度千帆模型是一个典型的国产大模型接入案例,在实际接入过程中遇到了一些特殊问题,以下是完整的解决方案。
# 在 tradingagents/llm_adapters/openai_compatible_base.py 内部注册
OPENAI_COMPATIBLE_PROVIDERS["qianfan"] = {
"base_url": "https://qianfan.baidubce.com/v2",
"api_key_env": "QIANFAN_API_KEY",
"models": {
"ernie-3.5-8k": {"context_length": 8192, "supports_function_calling": True},
"ernie-4.0-turbo-8k": {"context_length": 8192, "supports_function_calling": True},
"ERNIE-Speed-8K": {"context_length": 8192, "supports_function_calling": True},
"ERNIE-Lite-8K": {"context_length": 8192, "supports_function_calling": False},
}
}提示:无需单独的 qianfan_adapter.py 文件,统一由 openai_compatible_base 进行适配。
# 在 openai_compatible_base.py 中添加
OPENAI_COMPATIBLE_PROVIDERS = {
# ... 现有配置 ...
"qianfan": {
"base_url": "https://qianfan.baidubce.com/v2",
"api_key_env": "QIANFAN_API_KEY",
"models": {
"ernie-3.5-8k": {"context_length": 8192, "supports_function_calling": True},
"ernie-4.0-turbo-8k": {"context_length": 8192, "supports_function_calling": True},
"ERNIE-Lite-8K": {"context_length": 8192, "supports_function_calling": False},
"ERNIE-Speed-8K": {"context_length": 8192, "supports_function_calling": True},
}
},
}在 .env 文件中添加千帆API配置:
# 千帆API配置
QIANFAN_ACCESS_KEY=your_access_key_here
QIANFAN_SECRET_KEY=your_secret_key_here在 config/pricing.json 文件中添加千帆模型的价格信息:
{
"provider": "qianfan",
"model_name": "ernie-3.5-8k",
"input_price_per_1k": 0.0025,
"output_price_per_1k": 0.005,
"currency": "CNY"
},
{
"provider": "qianfan",
"model_name": "ernie-4.0-turbo-8k",
"input_price_per_1k": 0.03,
"output_price_per_1k": 0.09,
"currency": "CNY"
},
{
"provider": "qianfan",
"model_name": "ERNIE-Speed-8K",
"input_price_per_1k": 0.0004,
"output_price_per_1k": 0.0008,
"currency": "CNY"
},
{
"provider": "qianfan",
"model_name": "ERNIE-Lite-8K",
"input_price_per_1k": 0.0008,
"output_price_per_1k": 0.002,
"currency": "CNY"
}价格说明:
- 价格单位为每1000个token的费用
- 货币单位为人民币(CNY)
- 价格基于百度千帆官方定价,可能会有调整
# 在 sidebar.py 中添加千帆选项
elif llm_provider == "qianfan":
qianfan_options = [
"ernie-3.5-8k",
"ernie-4.0-turbo-8k",
"ERNIE-Speed-8K",
"ERNIE-Lite-8K"
]
current_index = 0
if st.session_state.llm_model in qianfan_options:
current_index = qianfan_options.index(st.session_state.llm_model)
llm_model = st.selectbox(
"选择文心一言模型",
options=qianfan_options,
index=current_index,
format_func=lambda x: {
"ernie-3.5-8k": "ERNIE 3.5 8K - ⚡ 快速高效",
"ernie-4.0-turbo-8k": "ERNIE 4.0 Turbo 8K - 🚀 强大推理",
"ERNIE-Speed-8K": "ERNIE Speed 8K - 🏃 极速响应",
"ERNIE-Lite-8K": "ERNIE Lite 8K - 💡 轻量经济"
}[x],
help="选择用于分析的文心一言(千帆)模型",
key="qianfan_model_select"
)
if st.session_state.llm_model != llm_model:
logger.debug(f"🔄 [Persistence] Qianfan模型变更: {st.session_state.llm_model} → {llm_model}")
st.session_state.llm_model = llm_model
logger.debug(f"💾 [Persistence] Qianfan模型已保存: {llm_model}")问题: 环境变量设置正确但仍提示 API 密钥错误
解决方案:
- 检查 API 密钥格式是否符合提供商要求
- 确认环境变量名称拼写正确
- 检查
.env文件是否在正确位置 - 千帆特殊情况: 需要同时设置
QIANFAN_API_KEY
问题: 模型不能正确调用工具
解决方案:
- 确认模型本身支持 Function Calling
- 检查 API 格式是否完全兼容 OpenAI 标准
- 查看是否需要特殊的工具调用格式
- 千帆特殊情况: 需要转换工具定义格式,参考上述案例
问题: 侧边栏看不到新添加的提供商
解决方案:
- 清除浏览器缓存
- 检查
sidebar.py中的选项列表 - 确认 Streamlit 重新加载了代码
- 调试技巧: 在浏览器开发者工具中查看控制台错误
问题: API 请求经常超时
解决方案:
- 调整
timeout参数 - 检查网络连接和 API 端点状态
- 考虑添加重试机制
- 国产模型特殊情况: 某些国产模型服务器在海外访问较慢,建议增加超时时间
问题: 中文输入或输出出现乱码
解决方案:
# 确保请求和响应都使用 UTF-8 编码
import json
def safe_json_dumps(data):
return json.dumps(data, ensure_ascii=False, indent=2)
def safe_json_loads(text):
return json.loads(text.encode('utf-8').decode('utf-8'))问题: 某些模型调用成本过高
解决方案:
- 在配置中设置合理的
max_tokens限制 - 使用成本较低的模型进行初步分析
- 实现智能模型路由,根据任务复杂度选择模型
# 智能模型选择示例
def select_model_by_task(task_complexity: str) -> str:
if task_complexity == "simple":
return "ERNIE-Lite-8K" # 成本低
elif task_complexity == "medium":
return "ERNIE-3.5-8K" # 平衡
else:
return "ERNIE-4.0-8K" # 性能强feat(llm): add {ProviderName} LLM integration
- Add {ProviderName} OpenAI-compatible adapter
- Update frontend model selection UI
- Add configuration and environment variables
- Include basic tests and documentation
Closes #{issue_number}
## 🚀 新增大模型支持:{ProviderName}
### 📋 变更概述
- 添加了 {ProviderName} 的 OpenAI 兼容适配器
- 更新了前端模型选择界面
- 完善了配置和环境变量
- 包含了基础测试
### 🧪 测试情况
- [x] 基础连接测试通过
- [x] 工具调用测试通过(如适用)
- [x] Web 界面集成测试通过
- [x] 完整的股票分析测试通过
### 📚 支持的模型
- `model-1`: 快速模型,适合简单任务
- `model-2`: 强大模型,适合复杂分析
### 🔧 配置要求
需要设置环境变量:`YOUR_PROVIDER_API_KEY`
### 📸 截图
(添加前端界面截图)
### ✅ 检查清单
- [x] 代码遵循项目规范
- [x] 添加了必要的测试
- [x] 更新了相关文档
- [x] 通过了所有现有测试- 提供清晰的错误消息
- 区分不同类型的错误(API 密钥、网络、模型等)
- 添加重试机制处理临时故障
- 使用统一的日志格式
- 记录关键操作和错误
- 避免记录敏感信息(API 密钥等)
- 合理设置超时时间
- 考虑并发限制
- 优化大模型调用的 token 使用
- 提供清晰的模型选择说明
- 添加合适的帮助文本
- 确保错误消息用户友好
如果在开发过程中遇到问题:
- 查看现有实现: 参考
deepseek_adapter.py或dashscope_adapter.py - 阅读基类文档: 查看
openai_compatible_base.py的注释 - 提交 Issue: 在 GitHub 上创建问题描述
- 加入讨论: 参与项目的 Discussion 板块
- 分支命名:
feature/add-{provider}-llm - 提交频率: 小步骤频繁提交
- 提交信息: 使用清晰的描述性信息
- 代码审查: 提交前自我审查代码质量
感谢您为 TradingAgentsCN 项目贡献新的大模型支持! 🎉
通过遵循本指南,您的贡献将更容易被审查和合并,同时也为其他开发者提供了良好的参考示例。