【Nanobot】README04_LEVEL2 提供商系统设计
### 文章目录
- [【Nanobot】README04_LEVEL2 提供商系统设计](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [@[toc]](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🎯 现实类比:万能电源适配器](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🧬 0 到 1 推演:如何从零设计 Provider 系统](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [阶段 1:直接调用 OpenAI API](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [阶段 2:抽象 Provider 基类](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [阶段 3:统一响应格式(LLMResponse)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [阶段 4:自动 Provider 选择(ProviderFactory)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [阶段 5:Provider 注册表(Registry)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [阶段 6:消息格式转换](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🏗️ 核心类/函数列表](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [1. LLMProvider(抽象基类)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [2. AnthropicProvider(Claude API 实现)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [3. ProviderFactory(Provider 工厂)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [4. ProviderRegistry(Provider 注册表)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🔗 调用链追踪](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [完整 LLM 调用链路](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [📊 数据流图](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🎨 设计模式分析](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [1. 策略模式(Strategy Pattern)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [2. 工厂模式(Factory Pattern)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [3. 适配器模式(Adapter Pattern)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [4. 注册表模式(Registry Pattern)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🔍 代码标注分析](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [AnthropicProvider.chat() 完整实现(带标注)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [_convert_messages() 格式转换(带标注)](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [🎯 Provider 速查表](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
- [📚 扩展阅读](#文章目录 【Nanobot】README04_LEVEL2 提供商系统设计 @[toc] 🎯 现实类比:万能电源适配器 🧬 0 到 1 推演:如何从零设计 Provider 系统 阶段 1:直接调用 OpenAI API 阶段 2:抽象 Provider 基类 阶段 3:统一响应格式(LLMResponse) 阶段 4:自动 Provider 选择(ProviderFactory) 阶段 5:Provider 注册表(Registry) 阶段 6:消息格式转换 🏗️ 核心类/函数列表 1. LLMProvider(抽象基类) 2. AnthropicProvider(Claude API 实现) 3. ProviderFactory(Provider 工厂) 4. ProviderRegistry(Provider 注册表) 🔗 调用链追踪 完整 LLM 调用链路 📊 数据流图 🎨 设计模式分析 1. 策略模式(Strategy Pattern) 2. 工厂模式(Factory Pattern) 3. 适配器模式(Adapter Pattern) 4. 注册表模式(Registry Pattern) 🔍 代码标注分析 AnthropicProvider.chat() 完整实现(带标注) _convert_messages() 格式转换(带标注) 🎯 Provider 速查表 📚 扩展阅读)
🎯 现实类比:万能电源适配器
想象国际旅行时的万能电源适配器:
-
LLMProvider = 接口标准:定义了输入/输出的规范
- 输入:消息列表 + 工具定义 + 生成参数
- 输出:LLMResponse(文本内容、工具调用、Token 使用量)
-
具体 Provider = 不同国家的插头转换器
AnthropicProvider= 美国插头转换器(Claude API)AzureOpenAIProvider= 欧盟插头转换器(Azure OpenAI)OpenAICompatProvider= 通用插头转换器(兼容 OpenAI 格式的 API)
-
ProviderFactory = 插头识别器
- 根据模型名称自动识别使用哪个 Provider
- 例如:
claude-opus-4-6→AnthropicProvider
核心设计思想:
- 接口统一 :所有 Provider 实现相同的
chat()方法 - 格式转换:将统一的 OpenAI 格式消息转换为各 Provider 原生格式
- 自动重试:内置智能重试机制,处理速率限制和瞬态错误
🧬 0 到 1 推演:如何从零设计 Provider 系统
阶段 1:直接调用 OpenAI API
python
# 伪代码:最初的最简单设计
import openai
async def chat(messages: list, model: str = "gpt-4"):
response = await openai.ChatCompletion.acreate(
model=model,
messages=messages,
)
return response.choices[0].message.content
问题:
- 只支持 OpenAI
- 无法切换到 Claude、Gemini 等其他 LLM
- 难以处理不同 API 的差异
阶段 2:抽象 Provider 基类
python
class LLMProvider(ABC):
@abstractmethod
async def chat(
self, messages: list, model: str, temperature: float
) -> str:
"""调用 LLM 并返回文本。"""
pass
class AnthropicProvider(LLMProvider):
async def chat(self, messages, model, temperature):
# 将 OpenAI 格式消息转换为 Anthropic 格式
# 调用 Anthropic API
# 返回结果
...
class OpenAIProvider(LLMProvider):
async def chat(self, messages, model, temperature):
# 直接调用 OpenAI API
...
对应代码 :base.py:92 和 anthropic_provider.py:737
python
class LLMProvider(ABC):
"""[核心业务] LLM 提供商基类。"""
@abstractmethod
async def chat(
self,
messages: list[dict[str, Any]],
tools: list[dict[str, Any]] | None = None,
model: str | None = None,
max_tokens: int = 4096,
temperature: float = 0.7,
...
) -> LLMResponse:
"""[核心] 执行聊天请求。"""
...
问题:LLM 返回格式不同,需要标准化。
阶段 3:统一响应格式(LLMResponse)
python
@dataclass
class LLMResponse:
"""[核心业务] 标准化的 LLM 响应。"""
content: str | None # 文本内容
tool_calls: list[ToolCallRequest] # 工具调用列表
finish_reason: str # 结束原因(stop/tool_calls/length/error)
usage: dict[str, int] # Token 使用量
对应代码 :base.py:48-78
python
@dataclass
class LLMResponse:
"""
[核心业务] 来自 LLM 提供者的响应数据类。
统一不同 Provider 的响应格式:
- Anthropic 返回 {"stop_reason": "tool_use"}
- OpenAI 返回 {"finish_reason": "tool_calls"}
→ 统一为 finish_reason="tool_calls"
"""
content: str | None
tool_calls: list[ToolCallRequest]
finish_reason: str = "stop"
usage: dict[str, int] = field(default_factory=dict)
@property
def has_tool_calls(self) -> bool:
"""[工具代码] 检查是否包含工具调用。"""
return len(self.tool_calls) > 0
阶段 4:自动 Provider 选择(ProviderFactory)
python
def make_provider(config: Config) -> LLMProvider:
"""
[核心] 根据模型名称自动选择 Provider。
示例:
- "claude-opus-4-6" → AnthropicProvider
- "gpt-4" → OpenAIProvider
- "bedrock/claude" → BedrockProvider
"""
model = config.model
provider_name = config.get_provider_name(model)
if provider_name == "anthropic":
return AnthropicProvider(api_key=config.api_key)
elif provider_name == "azure_openai":
return AzureOpenAIProvider(...)
elif provider_name == "openai_compat":
return OpenAICompatProvider(...)
else:
raise ValueError(f"Unknown provider: {provider_name}")
对应代码 :factory.py:29-100
阶段 5:Provider 注册表(Registry)
python
@dataclass(frozen=True)
class ProviderSpec:
"""
[核心] Provider 元数据。
示例:
ProviderSpec(
name="anthropic",
keywords=("claude",),
env_key="ANTHROPIC_API_KEY",
backend="anthropic",
default_api_base="https://api.anthropic.com",
)
"""
name: str
keywords: tuple[str, ...]
env_key: str
backend: str
default_api_base: str = ""
PROVIDERS = [
ProviderSpec(
name="anthropic",
keywords=("claude",),
env_key="ANTHROPIC_API_KEY",
backend="anthropic",
),
ProviderSpec(
name="openrouter",
keywords=("openrouter", "mistral", "deepseek"),
env_key="OPENROUTER_API_KEY",
backend="openai_compat",
is_gateway=True,
),
...
]
对应代码 :registry.py:21-82
阶段 6:消息格式转换
问题:不同 Provider 的消息格式不同。
OpenAI 格式:
json
{
"role": "user",
"content": "你好"
}
Anthropic 格式:
json
{
"role": "user",
"content": [{"type": "text", "text": "你好"}]
}
解决方案:在 Provider 内部转换消息格式。
对应代码 :anthropic_provider.py:168-229
python
def _convert_messages(
self, messages: list[dict[str, Any]]
) -> tuple[str, list[dict]]:
"""
[核心] 将 OpenAI 格式消息转换为 Anthropic 格式。
处理:
1. 系统提示词分离
2. 工具结果消息转换
3. 用户消息内容转换(文本/图片)
4. 助手消息(文本/工具调用)
"""
raw = []
system = ""
for msg in messages:
role = msg["role"]
content = msg.get("content")
if role == "system":
system = content
elif role == "user":
raw.append({
"role": "user",
"content": self._convert_user_content(content),
})
elif role == "assistant":
raw.append({
"role": "assistant",
"content": self._assistant_blocks(msg),
})
...
return system, self._merge_consecutive(raw)
🏗️ 核心类/函数列表
1. LLMProvider(抽象基类)
职责:
- 定义 Provider 接口
- 提供通用功能(重试逻辑、错误处理)
- 定义响应数据结构
关键方法 (base.py:92-680):
python
class LLMProvider(ABC):
"""
[核心业务] LLM 提供商基类。
统一不同 LLM API 的差异:
1. 消息格式(OpenAI vs Anthropic vs Gemini)
2. 工具调用格式
3. 流式传输接口
4. 错误处理和重试
"""
# 是否支持增量进度通知
supports_progress_deltas = False
@abstractmethod
async def chat(
self,
messages: list[dict[str, Any]],
tools: list[dict[str, Any]] | None = None,
model: str | None = None,
max_tokens: int = 4096,
temperature: float = 0.7,
reasoning_effort: str | None = None,
tool_choice: str | dict[str, Any] | None = None,
) -> LLMResponse:
"""
[核心] 执行聊天请求(非流式)。
返回标准化的 LLMResponse。
"""
...
async def chat_stream(
self,
messages: list[dict[str, Any]],
tools: list[dict[str, Any]] | None = None,
model: str | None = None,
max_tokens: int = 4096,
temperature: float = 0.7,
on_content_delta: Callable[[str], Awaitable[None]] | None = None,
) -> LLMResponse:
"""
[核心] 执行聊天请求(流式)。
on_content_delta: 接收增量文本的回调函数
"""
...
async def _run_with_retry(
self, func: Callable, retry_mode: str = "standard"
) -> LLMResponse:
"""
[工具代码] 带智能重试的执行器。
特性:
1. 识别瞬态错误(429, 500, 503, timeout)
2. 指数退避重试(1s, 2s, 4s)
3. 持久重试模式(用于配额限制)
4. 心跳机制(长时间等待时定期通知进度)
"""
...
2. AnthropicProvider(Claude API 实现)
职责:
- 实现
chat()和chat_stream()方法 - OpenAI 格式 ↔ Anthropic 格式转换
- 提示词缓存(cache_control)
- 扩展思维模式(thinking blocks)
关键方法 (anthropic_provider.py:29-880):
python
class AnthropicProvider(LLMProvider):
"""
[Adapter - 可替换组件] Anthropic Claude API 实现。
特性:
1. 原生 SDK 集成(anthropic-python)
2. 自动流式降级(max_tokens 超限时透明切换)
3. 提示词缓存(breakpoints)
4. 扩展思维模式支持
"""
def __init__(
self,
api_key: str | None = None,
api_base: str | None = None,
default_model: str = "claude-sonnet-4-20250514",
extra_headers: dict[str, str] | None = None,
):
from anthropic import AsyncAnthropic
# [核心] 初始化 Anthropic 客户端
self._client = AsyncAnthropic(
api_key=api_key,
base_url=api_base,
default_headers=extra_headers,
max_retries=0, # 重试由 LLMProvider 统一处理
)
async def chat(
self,
messages: list[dict[str, Any]],
tools: list[dict[str, Any]] | None = None,
model: str | None = None,
max_tokens: int = 4096,
temperature: float = 0.7,
reasoning_effort: str | None = None,
tool_choice: str | dict[str, Any] | None = None,
) -> LLMResponse:
"""
[核心业务] 执行非流式聊天请求。
流程:
1. 构建请求参数(_build_kwargs)
2. 调用 Anthropic API
3. 解析响应(_parse_response)
4. 错误处理(必要时透明切换到流式)
"""
kwargs = self._build_kwargs(
messages, tools, model, max_tokens, temperature,
reasoning_effort, tool_choice,
)
try:
response = await self._client.messages.create(**kwargs)
return self._parse_response(response)
except Exception as e:
if self._is_streaming_required_error(e):
# [核心] 透明切换到流式(避免 max_tokens 超限)
return await self.chat_stream(
messages=messages,
tools=tools,
model=model,
max_tokens=max_tokens,
...
)
return self._handle_error(e)
def _convert_messages(
self, messages: list[dict]
) -> tuple[str, list[dict]]:
"""
[核心] OpenAI 格式 → Anthropic 格式。
转换规则:
1. 提取系统提示词
2. 工具结果消息 → tool_result 块
3. 用户消息 → content 块(支持图片)
4. 助手消息 → text/tool_use 块
"""
...
def _parse_response(self, response) -> LLMResponse:
"""
[核心] Anthropic 格式 → LLMResponse。
解析:
1. 文本内容(content 块)
2. 工具调用(tool_use 块)
3. Token 使用量(usage)
4. 停止原因(stop_reason → finish_reason)
"""
...
3. ProviderFactory(Provider 工厂)
职责:
- 根据配置创建 Provider 实例
- 自动检测 Provider 类型
- 验证 API 密钥
关键方法 (factory.py:29-100):
python
def make_provider(config: Config) -> LLMProvider:
"""
[核心] 根据配置创建 Provider。
流程:
1. 解析模型名称 → Provider 名称
2. 查找 Provider 注册表
3. 确定后端类型(anthropic/openai_compat/azure_openai/...)
4. 验证配置(API 密钥、base URL)
5. 实例化具体 Provider
"""
model = config.agents.defaults.model
provider_name = config.get_provider_name(model)
p = config.get_provider(model)
spec = find_by_name(provider_name)
backend = spec.backend if spec else "openai_compat"
# [工具代码] 配置验证
if backend == "azure_openai":
if not p or not p.api_key or not p.api_base:
raise ValueError("Azure OpenAI requires api_key and api_base.")
elif backend == "openai_compat" and not model.startswith("bedrock/"):
needs_key = not (p and p.api_key)
exempt = spec and (spec.is_oauth or spec.is_local or spec.is_direct)
if needs_key and not exempt:
raise ValueError(f"No API key configured for '{provider_name}'.")
# [核心] 实例化 Provider
if backend == "anthropic":
from nanobot.providers.anthropic_provider import AnthropicProvider
provider = AnthropicProvider(
api_key=p.api_key if p else None,
api_base=config.get_api_base(model),
default_model=model,
extra_headers=p.extra_headers if p else None,
)
elif backend == "openai_codex":
from nanobot.providers.openai_codex_provider import OpenAICodexProvider
provider = OpenAICodexProvider(default_model=model)
...
return provider
4. ProviderRegistry(Provider 注册表)
职责:
- 维护所有 Provider 的元数据
- 提供查找功能(按名称/模型/关键词)
- 管理环境变量映射
关键数据结构 (registry.py:21-500):
python
@dataclass(frozen=True)
class ProviderSpec:
"""
[核心] Provider 元数据。
字段说明:
- name: 配置文件中的字段名(如 "anthropic")
- keywords: 模型名称关键词(用于自动检测)
- env_key: API 密钥的环境变量名
- backend: 实现类型(anthropic/openai_compat/...)
- default_api_base: 默认 API 端点
- is_gateway: 是否为网关(路由任意模型)
- is_local: 是否为本地部署
- is_oauth: 是否使用 OAuth(无 API 密钥)
"""
name: str
keywords: tuple[str, ...]
env_key: str
backend: str = "openai_compat"
default_api_base: str = ""
is_gateway: bool = False
is_local: bool = False
is_oauth: bool = False
...
# Provider 注册表
PROVIDERS = [
ProviderSpec(
name="anthropic",
keywords=("claude",),
env_key="ANTHROPIC_API_KEY",
backend="anthropic",
default_api_base="https://api.anthropic.com",
supports_prompt_caching=True,
),
ProviderSpec(
name="openrouter",
keywords=("openrouter", "mistral", "deepseek", "qwen"),
env_key="OPENROUTER_API_KEY",
backend="openai_compat",
is_gateway=True,
default_api_base="https://openrouter.ai/api/v1",
),
ProviderSpec(
name="ollama",
keywords=("ollama",),
env_key="OLLAMA_API_KEY",
backend="openai_compat",
is_local=True,
default_api_base="http://localhost:11434/v1",
),
...
]
🔗 调用链追踪
完整 LLM 调用链路
AgentRunner 需要调用 LLM
↓
AgentRunner.run(spec) [runner.py:237]
↓
LLMProvider.chat(messages, tools, model) [anthropic_provider.py:737]
↓
构建请求参数
├→ _convert_messages(messages) [格式转换]
│ ├→ 提取系统提示词
│ ├→ 转换工具结果消息
│ ├→ 转换用户消息(文本/图片)
│ └→ 转换助手消息(文本/工具调用)
└→ _build_kwargs(tools, temperature, ...)
↓
调用 Anthropic API
├→ 非流式:_client.messages.create(**kwargs)
└→ 流式:_client.messages.stream(**kwargs)
↓
解析响应
├→ _parse_response(response)
│ ├→ 提取文本内容
│ ├→ 提取工具调用(tool_use 块)
│ ├→ 提取 Token 使用量
│ └→ 转换 finish_reason
└→ 返回 LLMResponse
↓
AgentRunner 处理 LLMResponse
├→ 如果有 tool_calls → 执行工具
└→ 如果是纯文本 → 结束循环
📊 数据流图
LLMProvider Anthropic API AnthropicProvider AgentRunner LLMProvider Anthropic API AnthropicProvider AgentRunner 1. 消息格式转换 2. 构建请求参数 3. 调用 API 4. 解析响应 5. 处理响应 alt [response.t- ool_calls] [response.c- ontent] chat(messages, tools, model) _convert_messages(messages) OpenAI 格式 → Anthropic 格式 _build_kwargs(tools, temp, ...) client.messages.create(**kwargs) Response _parse_response(response) Anthropic 格式 → LLMResponse LLMResponse 执行工具 返回结果
🎨 设计模式分析
1. 策略模式(Strategy Pattern)
体现 :LLMProvider 定义接口,具体 Provider 实现不同策略。
好处:
- 运行时切换 LLM 后端
- 统一的调用接口
- 易于添加新 Provider
代码位置 :base.py:92
2. 工厂模式(Factory Pattern)
体现 :make_provider() 根据配置创建具体 Provider。
好处:
- 集中管理 Provider 创建逻辑
- 隐藏具体实例化细节
- 支持自动检测
代码位置 :factory.py:29
3. 适配器模式(Adapter Pattern)
体现 :AnthropicProvider 将 Anthropic API 适配到统一接口。
适配内容:
- 消息格式(OpenAI ↔ Anthropic)
- 工具调用格式
- 响应格式
代码位置 :anthropic_provider.py:168-229, 310-340
4. 注册表模式(Registry Pattern)
体现 :PROVIDERS 列表维护所有 Provider 元数据。
好处:
- 单一事实来源
- 自动配置匹配
- 环境变量管理
代码位置 :registry.py:21-500
🔍 代码标注分析
AnthropicProvider.chat() 完整实现(带标注)
python
async def chat(
self,
messages: list[dict[str, Any]],
tools: list[dict[str, Any]] | None = None,
model: str | None = None,
max_tokens: int = 4096,
temperature: float = 0.7,
reasoning_effort: str | None = None,
tool_choice: str | dict[str, Any] | None = None,
) -> LLMResponse:
"""
[核心业务] 执行非流式聊天请求。
关键特性:
1. 透明流式降级(max_tokens 超限时自动切换)
2. 提示词缓存(cache_control)
3. 扩展思维模式支持
"""
# [核心] 构建请求参数
kwargs = self._build_kwargs(
messages, tools, model, max_tokens, temperature,
reasoning_effort, tool_choice,
)
try:
# [核心业务] 调用 Anthropic API
response = await self._client.messages.create(**kwargs)
# [核心] 解析响应
return self._parse_response(response)
except Exception as e:
# [核心] 透明流式降级
# 当 max_tokens 过大时,Anthropic API 要求使用流式
# 此处自动切换,无需调用方感知
if self._is_streaming_required_error(e):
return await self.chat_stream(
messages=messages,
tools=tools,
model=model,
max_tokens=max_tokens,
temperature=temperature,
reasoning_effort=reasoning_effort,
tool_choice=tool_choice,
)
# [工具代码] 错误处理
return self._handle_error(e)
_convert_messages() 格式转换(带标注)
python
def _convert_messages(
self, messages: list[dict[str, Any]]
) -> tuple[str, list[dict]]:
"""
[核心] OpenAI 格式 → Anthropic 格式。
转换对照表:
| OpenAI 格式 | Anthropic 格式 |
|-------------|----------------|
| {"role": "system", "content": "..."} | system = "..." (独立参数) |
| {"role": "user", "content": "文本"} | {"role": "user", "content": [{"type": "text", "text": "文本"}]} |
| {"role": "tool", "content": "...", "tool_call_id": "..."} | {"role": "user", "content": [{"type": "tool_result", "tool_use_id": "...", "content": "..."}]} |
| {"role": "assistant", "tool_calls": [...]} | {"role": "assistant", "content": [{"type": "tool_use", "name": "...", "input": {...}}]} |
"""
raw = []
system = ""
for msg in messages:
role = msg["role"]
content = msg.get("content")
# [核心] 处理系统提示词(Anthropic 要求独立参数)
if role == "system":
system = content
continue
# [核心] 处理工具结果消息
if role == "tool":
block = self._tool_result_block(msg)
# 合并到上一条用户消息(Anthropic 要求)
if raw and raw[-1]["role"] == "user":
prev_c = raw[-1]["content"]
if isinstance(prev_c, list):
prev_c.append(block)
else:
raw[-1]["content"] = [
{"type": "text", "text": prev_c or ""},
block,
]
else:
raw.append({"role": "user", "content": [block]})
continue
# [核心] 处理用户消息(支持文本和图片)
if role == "user":
raw.append({
"role": "user",
"content": self._convert_user_content(content),
})
continue
# [核心] 处理助手消息(文本 + 工具调用)
if role == "assistant":
raw.append({
"role": "assistant",
"content": self._assistant_blocks(msg),
})
continue
# [核心] 合并连续的同角色消息(Anthropic 推荐)
return system, self._merge_consecutive(raw)
🎯 Provider 速查表
| Provider | 后端类型 | 配置键 | 环境变量 | 特殊特性 |
|---|---|---|---|---|
| Anthropic | anthropic |
anthropic |
ANTHROPIC_API_KEY |
提示词缓存、思维模式 |
| OpenAI Codex | openai_codex |
openai_codex |
GITHUB_TOKEN |
OAuth 认证 |
| Azure OpenAI | azure_openai |
azure_openai |
AZURE_API_KEY |
需要 api_base |
| GitHub Copilot | github_copilot |
github_copilot |
GITHUB_TOKEN |
OAuth 认证 |
| OpenRouter | openai_compat |
openrouter |
OPENROUTER_API_KEY |
网关 |
| Ollama | openai_compat |
ollama |
OLLAMA_API_KEY |
本地部署 |
| vLLM | openai_compat |
vllm |
VLLM_API_KEY |
本地部署 |
| Bedrock | bedrock |
bedrock |
AWS_* |
AWS 集成 |
📚 扩展阅读
下一篇 : README05_LEVEL2_渠道系统设计
相关文件:
nanobot/providers/base.py- LLMProvider 基类和 LLMResponse 定义nanobot/providers/factory.py- Provider 工厂nanobot/providers/registry.py- Provider 注册表nanobot/providers/anthropic_provider.py- Anthropic Provider 实现nanobot/providers/openai_compat_provider.py- OpenAI 兼容 Provider 实现
如何添加新 Provider:
- 在
registry.py的PROVIDERS中添加ProviderSpec - 在
config/schema.py的ProvidersConfig中添加配置字段 - 如果是新后端类型,在
factory.py中添加实例化逻辑