# 架构设计

## 🧩 架构总览

```css
[Client] ──HTTP/gRPC──> [Core Service API Layer]
                             │
                             ▼
                    [SPI 接口（定义操作）]
                             │
                ┌────────────┴────────────┐
                ▼                         ▼
     [LocalModelProviderImpl]     [OpenAIProviderImpl]
     (本地部署模型)                (远程平台模型)
```

## 🧱 模块划分

### `core-service`（核心服务模块）

- 定义统一的 AI 接口（API）
- 定义模型服务的 SPI（接口 + 工厂 + 可能的适配器）
- SPI 示例：`ModelProvider`、`ChatModelService`、`EmbeddingService` 等
- 提供自动发现机制（如 Spring SPI 自动注入）

### `local-model-impl`（本地模型实现模块）

- 实现核心服务定义的 SPI
- 例如调用本地 llama.cpp、Transformers 或自己封装的模型服务 API

### `openai-impl`（远程平台实现模块）

- 通过 OpenAI、Azure OpenAI、通义千问等平台接口实现 SPI

## 🧱 核心设计目标

| 功能           | 说明                                                         |
| -------------- | ------------------------------------------------------------ |
| 单模型默认调用 | 默认只调用当前设定好的模型                                   |
| 指定模型调用   | 允许按名字、类型、模型id调用特定实现(需要有接口获取当前能使用的模型) |
| 多模型并行调用 | 调用所有或自定义多个模型实现（如 benchmark）                 |
| 策略调度       | 本地优先、平台优先、负载均衡、自定义权重等                   |
| 插件式接入     | 支持新增模型实现模块无需修改主逻辑                           |

## 🎯 架构核心要素

### 1. `ModelProvider` SPI 接口

```kotlin
interface ModelProvider {
    fun getName(): String // 模型名称
    fun getType(): String // 本地 远程
    fun getModelId(): String // 模型id 唯一
    fun getChatService(): ChatModelService // 对话服务
    fun getEmbeddingService(): EmbeddingService // 嵌入服务
    fun isAvailable(): Boolean // 是否可用
}
```

### 2. `ModelProviderManager` 管理器

负责注册、发现、调度所有实现。

```kotlin
@Service
class ModelProviderManager(
    providers: List<ModelProvider>
) {
    private val providerMap = providers.filter { it.isAvailable() }
        .associateBy { it.getModelId() }
    
    fun getProviderByModelId(modelId: String): ModelProvider? = providerMap[name]

    fun getByIds(modelIds: List<String>): List<ModelProvider> =
        ids.mapNotNull { idMap[it] }
    
    fun getProvidersByType(type: String): List<ModelProvider> =
        providerMap.values.filter { it.getType() == type }

    fun getAll(): Collection<ModelProvider> = providerMap.values
}
```

### 3. `ModelFilterStrategy`（策略接口）

允许通过策略实现来筛选出所需模型提供者

```kotlin
interface ModelFilterStrategy {
    fun filter(providers: Collection<ModelProvider>): Collection<ModelProvider>
}
```

实现策略举例：

```kotlin
@Component("localTop2")
class LocalTop2Strategy : ModelFilterStrategy {
    override fun filter(providers: Collection<ModelProvider>): Collection<ModelProvider> {
        return providers.filter { it.getType() == "local" }.take(2)
    }
}
```

### 4. `ModelDispatcher` 分发器

```kotlin
@Service
class ModelDispatcher(
    private val providerManager: ModelProviderManager,
    private val strategies: Map<String, ModelFilterStrategy>
) {

    fun dispatchById(id: String): ModelProvider {
        return providerManager.getById(id)
            ?: throw IllegalArgumentException("Model not found: $id")
    }

    fun dispatchByIds(ids: List<String>): Collection<ModelProvider> {
        return providerManager.getByIds(ids)
    }

    fun dispatchByStrategy(strategy: String): Collection<ModelProvider> {
        val strategyImpl = strategies[strategy]
            ?: throw IllegalArgumentException("Unknown strategy: $strategy")
        return strategyImpl.filter(providerManager.getAll())
    }

    fun dispatchAll(): Collection<ModelProvider> = providerManager.getAll()
}
```

💡 调用方式

| 使用方式 | 示例                                                        |
| -------- | ----------------------------------------------------------- |
| 单模型   | `dispatcher.dispatchById("openai-gpt4")`                    |
| 多模型   | `dispatcher.dispatchByIds(["openai-gpt4", "local-llama3"])` |
| 策略模型 | `dispatcher.dispatchByStrategy("localTop2")`                |
| 全部模型 | `dispatcher.dispatchAll()`                                  |

## 🧩 扩展方向

| 功能         | 建议                                                   |
| ------------ | ------------------------------------------------------ |
| 模型标签     | 支持用标签分类筛选（如 `"tags": ["fast", "offline"]`） |
| 权重调度     | 给每个模型配置权重，实现加权随机策略                   |
| 异步聚合调用 | 多模型调用支持并发执行后聚合                           |
| 模型分组     | 通过配置将多个模型划入组（如 benchmark-group）         |

`api-core`（定义 SPI）

`api-core-spring`（定义 Dispatcher、Manager、策略等）

`impl-local`, `impl-openai`（示例实现）

`starter-server`（Web 接口）

## 🧱 单项目多模块结构设计

```perl
ai-core-platform/
├── api-core/                  # 💡 定义 SPI 接口（抽象接口层）
├── api-core-service/          # 💡 Dispatcher、Manager、策略实现（核心服务逻辑）
├── model-impl-openai/         # ✅ OpenAI 实现模块（实现 SPI）
├── model-impl-local/          # ✅ 本地模型实现模块
├── model-impl-xxx/            # ✅ 其他模型实现模块
├── sdk-client/                # 📦 封装 HTTP 客户端 SDK（可依赖 core-service）
├── ai-core-server/            # 🚪 Spring Boot 控制器层（暴露 HTTP 接口）
└── build.gradle.kts
```

## 🧱 微服务结构设计

### ✅ 核心目标

| 角色                                         | 职责                                                 |
| -------------------------------------------- | ---------------------------------------------------- |
| 🎯 **核心服务（Core Service）**               | 定义模型 SPI，负责模型选择策略、调度逻辑等           |
| ⚙️ **实现服务（Impl Service）**               | 每个模型一个服务，实现核心服务 SPI 的调用接口        |
| 🧩 **门面服务（Gateway/Federation Service）** | 统一对外暴露接口，调用者只知道它，它向下调度和路由   |
| 📦 **调用端（SDK / 其他服务）**               | 只调用门面服务，看不到内部实现细节                   |
| 🚀 **横向扩展**                               | 核心服务和实现服务都可部署多个副本，服务注册自动发现 |

### 🔁 系统调用流程示意图（简化版）

```html
      [前端/调用方]
             ↓
      [🧩 门面服务 Gateway]
             ↓
  ┌────────────────────────────┐
  │          Dispatcher        │
  │                            │
  │     查找服务注册表         │
  └────────────────────────────┘
       ↓                  ↓
[Core Service A]     [Core Service B]   <- 可扩展集群
       ↓                  ↓
  [Impl Service 1]    [Impl Service 2]  <- 每个模型一个服务（OpenAI、LLaMA等）

```

#### 🧱 项目结构（服务拆分）

```bash
ai-model-platform/
├── model-api-core/              # SPI 接口定义（公共模块，所有服务依赖）
├── model-core-service/          # 核心服务（模型管理、策略、调度）
├── model-impl-openai-service/   # 实现服务（OpenAI GPT等）
├── model-impl-llama-service/    # 实现服务（本地模型）
├── model-gateway-service/       # 门面服务（统一入口，封装核心服务和路由）
├── model-sdk-client/            # HTTP SDK（封装对 gateway 的访问）
```

### 📌 各服务职责详解

#### `model-api-core`（接口层）

- 定义 SPI 接口（如 `ModelProvider`、`ChatModelService`）
- 提供调用参数类、返回类（DTO）

#### `model-core-service`（核心服务）

- 维护模型注册信息（可注册远程实现）
- 定义策略组件（如：本地优先、负载均衡）
- 提供一个「统一调用的客户端」用于远程 HTTP 调用实现服务

#### `model-impl-*`（实现服务）

- 每个服务注册为一个 Provider，提供模型实际调用能力
- 实现 SPI 接口，通过 HTTP 接口暴露服务

#### `model-gateway-service`（门面服务）

- 对外暴露统一 HTTP 接口
- 请求转发至核心服务，核心服务根据策略调度到目标实现服务
- 可添加身份鉴权、限流、缓存等网关能力

#### `model-sdk-client`（客户端）

- 对接 `model-gateway-service` 的 SDK
- 提供统一调用封装（如 chat、embedding、tokenize）

### 🎯 模型调用过程

1. 外部发起调用：POST `/api/chat`
2. 请求被 `model-gateway-service` 接收
3. 门面服务通过核心服务获取候选模型（本地优先 / 多模型）
4. 核心服务选择合适实现服务，发起 HTTP 请求
5. 实现服务完成调用，响应结果回传给前端

