LLM提供商集成

📎 引用文件

本文引用的文件 - agent/src/providers/__init__.py - agent/src/providers/capabilities.py - agent/src/providers/chat.py - agent/src/providers/llm.py - agent/src/providers/openai_codex.py - agent/src/providers/llm_providers.json - agent/tests/test_llm.py - agent/tests/test_llm_provider_defaults.py

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论
  10. 附录:新增提供商接入指南

简介

本文件面向 Vibe-Trading 的 LLM 提供商集成层,系统性说明如何以统一接口对接 OpenAI、Anthropic、DeepSeek、Moonshot/Kimi、Gemini、Groq、DashScope/Qwen、Zhipu/GLM、NVIDIA、iFlytek Spark、MiniMax、Mimo、Z.ai、ModelScope、Ollama 等 20+ 提供商。文档重点覆盖: - 多提供商能力检测与差异化处理(reasoning 内容捕获/回写、工具调用签名、响应规范化) - 提供商发现机制、环境变量解析与默认 URL 策略 - 认证流程、请求头定制与错误处理 - 如何扩展新提供商(能力定义、适配器实现、测试用例) - 性能优化建议与常见问题排查

项目结构

LLM 提供商集成位于 agent/src/providers 目录下,采用“能力声明 + 工厂构建 + 统一聊天接口”的分层设计: - capabilities.py:声明各提供商的能力元数据(API Key/Base URL 环境变量名、reasoning 行为、默认请求头等),并提供凭据解析与默认 URL 解析。 - llm.py:提供 build_llm 工厂,根据配置选择原生或兼容路径(Anthropic、DeepSeek、OpenAI 兼容),并注入 reasoning、thought signature、请求头等。 - chat.py:对外暴露 ChatLLM,封装同步/流式调用、工具调用解析、DSML 文本工具调用解析、响应标准化与错误包装。 - openai_codex.py:独立实现 OpenAI Codex OAuth 路径,包含令牌刷新、SSE 事件流、工具调用映射。 - llm_providers.json:提供商目录清单,维护每个提供商的默认模型、默认 Base URL、是否必需 API Key 等。

graph TB subgraph "提供商能力与配置" CAP["capabilities.py<br/>ProviderCapabilities / get_llm_credentials"] JSON["llm_providers.json<br/>默认模型/默认URL"] end subgraph "LLM工厂" LLMF["llm.py<br/>build_llm / ChatOpenAIWithReasoning"] ANTH["llm.py<br/>_build_anthropic"] DS["llm.py<br/>_build_native_deepseek"] end subgraph "统一聊天接口" CHAT["chat.py<br/>ChatLLM<br/>stream_chat / chat"] CODEX["openai_codex.py<br/>OpenAICodexLLM"] end CAP --> LLMF JSON --> CAP LLMF --> CHAT ANTH --> LLMF DS --> LLMF CODEX --> CHAT

图表来源 - agent/src/providers/capabilities.py:14-44 - agent/src/providers/llm.py:1020-1135 - agent/src/providers/chat.py:272-398 - agent/src/providers/openai_codex.py:605-711

章节来源 - agent/src/providers/__init__.py:1-6 - agent/src/providers/capabilities.py:14-44 - agent/src/providers/llm.py:1020-1135 - agent/src/providers/chat.py:272-398 - agent/src/providers/openai_codex.py:605-711 - agent/src/providers/llm_providers.json:1-216

核心组件

章节来源 - agent/src/providers/capabilities.py:14-44 - agent/src/providers/capabilities.py:220-353 - agent/src/providers/llm.py:1020-1135 - agent/src/providers/chat.py:272-514 - agent/src/providers/openai_codex.py:605-711

架构总览

下图展示了从上层调用到具体提供商的完整链路,包括能力检测、凭据解析、适配器选择、请求头注入与响应标准化。

sequenceDiagram participant App as "应用/AgentLoop" participant Chat as "ChatLLM" participant Factory as "build_llm(llm.py)" participant Caps as "capabilities.py" participant Adapter as "ChatOpenAIWithReasoning / Anthropic / DeepSeek / Codex" participant Prov as "提供商API" App->>Chat : chat()/stream_chat() Chat->>Factory : 绑定工具并调用 Factory->>Caps : get_provider_capabilities(provider,model) Caps-->>Factory : ProviderCapabilities Factory->>Factory : _sync_provider_env() / 解析凭据 alt 提供商为 anthropic Factory->>Adapter : _build_anthropic(...) else 提供商为 deepseek(原生模式) Factory->>Adapter : _build_native_deepseek(...) else 其他(OpenAI兼容) Factory->>Adapter : ChatOpenAIWithReasoning(...) end Adapter->>Prov : 发送请求(含reasoning/thought_signature/headers) Prov-->>Adapter : 响应(可能含reasoning_content/tool_calls) Adapter-->>Chat : AIMessage/AIMessageChunk Chat->>Chat : _parse_response() 标准化 Chat-->>App : LLMResponse(content, tool_calls, usage_metadata, finish_reason)

图表来源 - agent/src/providers/chat.py:299-398 - agent/src/providers/llm.py:1020-1135 - agent/src/providers/capabilities.py:220-353

详细组件分析

能力检测与差异化处理(ProviderCapabilities)

classDiagram class ProviderCapabilities { +string name +string api_key_env +string base_url_env +bool capture_reasoning +bool send_reasoning_content +bool gemini_thought_signatures +bool normalize_assistant_content +bool openrouter_reasoning_body +Mapping~str,str~ default_headers +string native_adapter_package }

图表来源 - agent/src/providers/capabilities.py:14-44

章节来源 - agent/src/providers/capabilities.py:67-200 - agent/src/providers/capabilities.py:220-353

提供商发现、环境变量与默认 URL 解析

flowchart TD Start(["开始"]) --> GetCaps["get_provider_capabilities(provider,model)"] GetCaps --> CheckExplicit{"显式provider非空且非openai?"} CheckExplicit --> |是| UseExplicit["返回对应能力"] CheckExplicit --> |否| Infer["基于model前缀推断"] Infer --> HasInfer{"推断成功?"} HasInfer --> |是| UseInferred["返回推断能力"] HasInfer --> |否| Fallback["回退到openai能力"] UseExplicit --> Creds["get_llm_credentials()"] UseInferred --> Creds Fallback --> Creds Creds --> ResolveURL{"base_url已设置?"} ResolveURL --> |是| ReturnCreds["返回{provider,api_key,base_url,model}"] ResolveURL --> |否| Catalog["回退到llm_providers.json默认URL"] Catalog --> ReturnCreds

图表来源 - agent/src/providers/capabilities.py:203-247 - agent/src/providers/capabilities.py:258-353 - agent/src/providers/llm_providers.json:1-216

章节来源 - agent/src/providers/capabilities.py:203-353 - agent/tests/test_llm_provider_defaults.py:147-179

认证流程、请求头定制与错误处理

sequenceDiagram participant Client as "调用方" participant Chat as "ChatLLM" participant Stream as "Provider Stream" participant Err as "错误分类" Client->>Chat : stream_chat(messages, tools) Chat->>Stream : 发起流式请求 Stream-->>Chat : 正常chunk或异常 alt 无chunk但非失败 Chat->>Chat : 降级为非流式invoke else 流失败 Chat->>Err : 包装为ProviderStreamError Err-->>Client : 抛出异常(status_code,retryable) end

图表来源 - agent/src/providers/chat.py:117-187 - agent/src/providers/chat.py:315-398 - agent/src/providers/openai_codex.py:57-83

章节来源 - agent/src/providers/llm.py:109-164 - agent/src/providers/chat.py:117-187 - agent/src/providers/openai_codex.py:57-83

响应规范化与工具调用处理

flowchart TD In(["AIMessage/Chunk"]) --> Normalize["_text_content() 合并文本块"] Normalize --> NativeTC{"存在原生tool_calls?"} NativeTC --> |是| MergeExtra["合并extra_content(含thought_signature)"] NativeTC --> |否| DSML["解析DSML文本工具调用"] MergeExtra --> Finish["finish_reason归一化"] DSML --> Finish Finish --> Usage["usage_metadata标准化"] Usage --> Out(["LLMResponse"])

图表来源 - agent/src/providers/chat.py:34-49 - agent/src/providers/chat.py:226-269 - agent/src/providers/chat.py:425-514

章节来源 - agent/src/providers/chat.py:226-269 - agent/src/providers/chat.py:425-514

适配器实现要点

章节来源 - agent/src/providers/llm.py:91-423 - agent/src/providers/llm.py:630-733 - agent/src/providers/llm.py:569-614 - agent/src/providers/openai_codex.py:210-245 - agent/src/providers/openai_codex.py:605-711

依赖关系分析

graph LR CHAT["chat.py"] --> LLMF["llm.py"] LLMF --> CAP["capabilities.py"] LLMF --> JSON["llm_providers.json"] LLMF --> |可选| LA["langchain-openai"] LLMF --> |可选| LLANT["langchain-anthropic"] LLMF --> |可选| LLD["langchain-deepseek"] CODEX["openai_codex.py"] --> HTTPX["httpx"] CODEX --> OAUTH["oauth-cli-kit"]

图表来源 - agent/src/providers/chat.py:15-18 - agent/src/providers/llm.py:18-43 - agent/src/providers/openai_codex.py:24-40

章节来源 - agent/src/providers/llm.py:18-43 - agent/src/providers/openai_codex.py:24-40

性能考虑

[本节为通用指导,无需特定文件引用]

故障排除指南

章节来源 - agent/src/providers/chat.py:117-187 - agent/src/providers/llm.py:905-1017 - agent/src/providers/openai_codex.py:57-83

结论

Vibe-Trading 的 LLM 提供商集成通过能力声明、工厂构建与统一聊天接口,实现了 20+ 提供商的统一接入与差异化处理。其核心优势在于: - 能力驱动的 reasoning 与工具调用签名处理 - 灵活的环境变量与默认 URL 解析 - 健壮的认证与错误处理 - 可扩展的适配器体系,便于新增提供商

[本节为总结性内容,无需特定文件引用]

附录:新增提供商接入指南

要新增一个 LLM 提供商,请按以下步骤操作:

  1. 定义能力与凭据 - 在 capabilities.py 中添加 ProviderCapabilities 实例,指定 name、api_key_env、base_url_env,并根据需要启用 capture_reasoning/send_reasoning_content/gemini_thought_signatures/normalize_assistant_content/openrouter_reasoning_body/default_headers。 - 在 _PROVIDERS 字典中注册该提供商。

  2. 添加默认模型与默认 URL - 在 llm_providers.json 中添加条目,包含 name、label、api_key_env、base_url_env、default_model、default_base_url、api_key_required 等。

  3. 适配器实现(如需) - 若提供商有原生 SDK(如 Anthropic/DeepSeek),在 llm.py 中实现 build* 函数,并在 build_llm 中路由。 - 若为 OpenAI 兼容,可直接使用 ChatOpenAIWithReasoning,并通过 capabilities 控制行为。 - 若为特殊协议(如 Codex),参考 openai_codex.py 实现独立适配器。

  4. 环境变量与默认 URL 回退 - 确保 get_llm_credentials 能正确解析新提供商的 *_BASE_URL,并在缺失时回退到 llm_providers.json 的 default_base_url。

  5. 测试用例 - 编写单元测试验证:

    • 能力别名与模型推断(如 glm→zhipu、kimi→moonshot)
    • 环境变量映射(_API_KEY/BASE_URL → OPENAI*)
    • 默认模型与默认 URL 一致性
    • 流式与非流式行为、错误分类与重试策略

示例参考路径 - 能力定义与注册:agent/src/providers/capabilities.py:67-200 - 默认模型与 URL 目录:agent/src/providers/llm_providers.json:1-216 - 适配器路由与构建:agent/src/providers/llm.py:1020-1135 - 测试用例参考:agent/tests/test_llm.py:19-120、agent/tests/test_llm_provider_defaults.py:41-179

章节来源 - agent/src/providers/capabilities.py:67-200 - agent/src/providers/llm_providers.json:1-216 - agent/src/providers/llm.py:1020-1135 - agent/tests/test_llm.py:19-120 - agent/tests/test_llm_provider_defaults.py:41-179