llm-connector 0.1.0

A lightweight Rust library for protocol adaptation across multiple LLM providers. Focuses solely on converting between different LLM provider APIs and providing a unified OpenAI-compatible interface.
Documentation
# llm-connector 简化设计文档

## 项目定位

**llm-connector** 是一个专注于**协议适配**的轻量级 Rust 库。

### 核心职责
- **协议转换**:将不同 LLM 提供商的 API 转换为统一的 OpenAI 兼容格式
-**请求/响应标准化**:提供统一的数据结构
-**流式响应适配**:标准化 SSE 流处理
-**Provider 抽象**:可扩展的提供商接口

### 明确不做的事情
- ❌ 负载均衡(使用 nginx、HAProxy 等)
- ❌ 健康检查(使用外部监控)
- ❌ 熔断器(使用基础设施解决方案)
- ❌ 复杂路由(保持简单)
- ❌ 指标收集(使用 tracing/metrics)
- ❌ 请求队列/限流(使用专门的中间件)

## 架构设计

```
┌─────────────────────────────────────────┐
│                Client                   │
├─────────────────────────────────────────┤
│            Provider Registry            │
├─────────────────────────────────────────┤
│  OpenAI │ Anthropic │ DeepSeek │ ...    │
│ Provider│ Provider  │ Provider │        │
└─────────────────────────────────────────┘
```

### 核心组件

1. **Client** - 主要入口点,处理请求分发
2. **Provider Registry** - 管理已注册的提供商
3. **Provider Trait** - 统一的提供商接口
4. **Types** - 标准化的请求/响应类型

## 代码结构

```
src/
├── lib.rs              # 库入口
├── client.rs           # 主客户端
├── config.rs           # 配置管理
├── error.rs            # 错误类型
├── types/              # 核心类型定义
│   ├── mod.rs
│   ├── request.rs      # 请求类型
│   ├── response.rs     # 响应类型
│   └── streaming.rs    # 流式类型
├── providers/          # 提供商实现
│   ├── mod.rs
│   ├── base.rs         # Provider trait
│   ├── openai.rs       # OpenAI 提供商
│   ├── anthropic.rs    # Anthropic 提供商
│   ├── deepseek.rs     # DeepSeek 提供商
│   └── ...
└── utils/              # 工具函数
    ├── mod.rs
    ├── http.rs         # HTTP 工具
    └── streaming.rs    # 流式工具
```

## 核心接口设计

### Provider Trait

```rust
#[async_trait]
pub trait Provider: Send + Sync {
    /// 提供商名称
    fn name(&self) -> &str;
    
    /// 支持的模型列表
    fn supported_models(&self) -> Vec<String>;
    
    /// 同步聊天完成
    async fn chat(&self, request: &ChatRequest) -> Result<ChatResponse, LlmConnectorError>;
    
    /// 流式聊天完成
    async fn chat_stream(&self, request: &ChatRequest) -> Result<ChatStream, LlmConnectorError>;
    
    /// 检查模型是否支持
    fn supports_model(&self, model: &str) -> bool {
        self.supported_models().contains(&model.to_string())
    }
}
```

### Client 接口

```rust
pub struct Client {
    providers: HashMap<String, Box<dyn Provider>>,
    config: Config,
}

impl Client {
    /// 从环境变量创建客户端
    pub fn from_env() -> Self;
    
    /// 从配置创建客户端
    pub fn with_config(config: Config) -> Self;
    
    /// 聊天完成
    pub async fn chat(&self, request: ChatRequest) -> Result<ChatResponse, LlmConnectorError>;
    
    /// 流式聊天完成
    pub async fn chat_stream(&self, request: ChatRequest) -> Result<ChatStream, LlmConnectorError>;
    
    /// 列出支持的模型
    pub fn list_models(&self) -> Vec<String>;
}
```

## 模型命名约定

支持两种格式:

1. **显式格式**`provider/model`
   - `openai/gpt-4`
   - `anthropic/claude-3-5-sonnet-20241022`
   - `deepseek/deepseek-chat`

2. **自动检测**:直接使用模型名
   - `gpt-4``openai/gpt-4`
   - `claude-3-haiku``anthropic/claude-3-haiku`
   - `deepseek-chat``deepseek/deepseek-chat`

## 配置管理

### 环境变量

```bash
# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1

# DeepSeek
DEEPSEEK_API_KEY=sk-...
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1

# Anthropic
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_BASE_URL=https://api.anthropic.com
```

### 代码配置

```rust
let config = Config {
    openai: Some(ProviderConfig {
        api_key: "sk-...".to_string(),
        base_url: Some("https://api.openai.com/v1".to_string()),
    }),
    deepseek: Some(ProviderConfig {
        api_key: "sk-...".to_string(),
        base_url: Some("https://api.deepseek.com/v1".to_string()),
    }),
    ..Default::default()
};
```

## 错误处理

```rust
#[derive(thiserror::Error, Debug)]
pub enum LlmConnectorError {
    #[error("Authentication failed: {0}")]
    AuthenticationError(String),
    
    #[error("Rate limit exceeded: {0}")]
    RateLimitError(String),
    
    #[error("Network error: {0}")]
    NetworkError(String),
    
    #[error("Invalid request: {0}")]
    InvalidRequest(String),
    
    #[error("Unsupported model: {0}")]
    UnsupportedModel(String),
    
    #[error("Provider error: {0}")]
    ProviderError(String),
    
    #[error("Streaming error: {0}")]
    StreamingError(String),
}
```

## 流式处理

统一的流式接口,自动处理不同提供商的 SSE 格式差异:

```rust
let mut stream = client.chat_stream(request).await?;
while let Some(chunk) = stream.next().await {
    let chunk = chunk?;
    if let Some(content) = chunk.choices[0].delta.content.as_ref() {
        print!("{}", content);
    }
}
```

## 扩展新提供商

1. 实现 `Provider` trait
2. 注册到客户端
3. 添加配置支持

```rust
struct MyProvider {
    config: ProviderConfig,
    client: reqwest::Client,
}

#[async_trait]
impl Provider for MyProvider {
    fn name(&self) -> &str { "myprovider" }
    
    fn supported_models(&self) -> Vec<String> {
        vec!["my-model-1".to_string(), "my-model-2".to_string()]
    }
    
    async fn chat(&self, request: &ChatRequest) -> Result<ChatResponse, LlmConnectorError> {
        // 实现协议转换逻辑
        todo!()
    }
    
    async fn chat_stream(&self, request: &ChatRequest) -> Result<ChatStream, LlmConnectorError> {
        // 实现流式协议转换逻辑
        todo!()
    }
}
```

## 设计原则

1. **单一职责**:只做协议适配
2. **最小依赖**:保持依赖树简洁
3. **可组合性**:作为更大系统的构建块
4. **无魔法**:显式配置,清晰错误
5. **提供商平等**:不偏向任何特定提供商

这个设计确保了 llm-connector 专注于其核心价值:协议适配,而将其他复杂功能留给专门的工具和服务。