简介
本设计文档围绕 DouPHP 的 AI 供应商表 dou_ai_provider,系统阐述其表结构设计、字段语义、扩展配置 JSON 规范、端点覆盖机制、优先级调度策略,以及多供应商接入、负载均衡与故障转移的实现方案。面向 AI 供应商集成开发者,提供完整的配置与接入指引,帮助快速对接主流大模型与图像生成服务。
项目结构
AI 供应商能力由“数据层 + 网关层 + 驱动层”构成:
- 数据层:ai_provider 表定义供应商元信息与启用状态;ai_key 表管理密钥;ai_model 表登记模型;ai_log/ai_task 记录调用日志与异步任务。
- 网关层:AiGateway 负责解析一次调用所需的完整配置(模型→供应商→密钥→端点),并路由到具体驱动。
- 驱动层:按供应商实现协议适配(OpenAI 兼容、DashScope/Qwen 等),统一对外暴露对话/图像等接口。
graph TB
A["应用/控制器"] --> B["AiGateway<br/>解析配置与路由"]
B --> C["DriverFactory<br/>选择驱动"]
C --> D["OpenAI 兼容驱动"]
C --> E["Qwen/DashScope 驱动"]
C --> F["其他供应商驱动"]
B --> G["数据库<br/>ai_provider / ai_key / ai_model"]
图示来源
- AiGateway.php:43-125
章节来源
- ai.sql:126-152
- AiGateway.php:43-125
核心组件
- 供应商表 ai_provider:承载供应商名称、代码、API基础地址、状态、排序、扩展配置等。
- 密钥表 ai_key:存储加密后的 API Key、别名、过期时间、最后使用时间、失败次数、扩展配置等。
- 模型表 ai_model:登记模型名称、模型代码、上下文长度、最大输出 tokens,并关联 provider_id。
- 网关 AiGateway:解析模型→供应商→密钥→端点的完整配置,决定流式格式与端点路径。
- 驱动工厂 DriverFactory:根据供应商代码与流式格式选择具体驱动实现。
章节来源
- ai.sql:35-95
- AiProvider.php:25-48
- AiGateway.php:43-125
架构总览
下图展示一次文本对话请求从业务侧到供应商的端到端流程,重点体现供应商启用状态校验、端点覆盖与驱动选择。
sequenceDiagram
participant App as "业务调用方"
participant GW as "AiGateway"
participant DB as "数据库(ai_provider/ai_key/ai_model)"
participant DF as "DriverFactory"
participant DRV as "供应商驱动"
App->>GW : resolveConfig(modelId?)
GW->>DB : 查询模型与供应商(含status)
DB-->>GW : 返回模型/供应商/密钥
GW->>GW : 解析provider.config.endpoints<br/>确定端点路径
GW->>DF : make(provider_code, stream_format)
DF-->>GW : 返回驱动实例
GW->>DRV : 发起请求(带鉴权与端点)
DRV-->>GW : 返回结果/错误
GW-->>App : 标准化响应
图示来源
- AiGateway.php:43-125
详细组件分析
表结构与字段说明(ai_provider)
- id:自增主键。
- name:供应商名称,用于界面显示与管理。
- code:供应商唯一代码,如 openai、anthropic、deepseek、bailian、aliyun、zhipu、moonshot、doubao、xiaomi、google、xai 等。
- base_url:API 基础地址,例如 https://api.openai.com/v1。
- status:启用状态,0 禁用、1 启用。停用后该供应商及其模型将被跳过。
- sort:排序权重,列表默认按 sort ASC、id DESC 排序。
- config:JSON 格式的扩展配置,支持 endpoints 覆盖、协议特性开关等。
- created_at / updated_at:创建与更新时间。
erDiagram
AI_PROVIDER {
int id PK
varchar name
varchar code UK
varchar base_url
tinyint status
smallint sort
text config
datetime created_at
datetime updated_at
}
图示来源
- ai.sql:126-152
章节来源
- ai.sql:126-152
- ai_provider_status.upgrade.sql:8-11
- AiProvider.php:34-48
扩展配置 JSON 规范(provider.config)
- endpoints:可选对象,键为模型类型(如 text),值为端点路径字符串,用于覆盖默认端点。
- 优先级:provider.config.endpoints[text] > 供应商预设 > 默认 /chat/completions。
- supports_json_schema:布尔值,表示是否支持 JSON Schema 输出(结合提示词与表单契约)。
- 其他键可由具体驱动按需扩展(如超时、重试、并发限制等)。
示例(仅示意): { "endpoints": { "text": "/chat/completions" }, "supports_json_schema": true }
章节来源
- AiGateway.php:107-125
- ai.lang.php:119-121
端点覆盖机制
- 当 provider.config.endpoints.text 存在时,使用该路径作为文本对话端点。
- 若未设置,则回退到供应商预设(如 baidu 使用 /chat)。
- 仍不存在时,最终兜底为 /chat/completions。
- 流式格式通过 provider.code 或显式配置决定(如 qwen/dashscope 走 qwen 流式,其余走 openai 流式)。
flowchart TD
Start(["开始"]) --> CheckEP["检查 provider.config.endpoints.text"]
CheckEP --> |存在| UseEP["使用自定义端点"]
CheckEP --> |不存在| CheckPreset["检查供应商预设端点"]
CheckPreset --> |存在| UsePreset["使用预设端点"]
CheckPreset --> |不存在| UseDefault["使用默认 /chat/completions"]
UseEP --> End(["结束"])
UsePreset --> End
UseDefault --> End
图示来源
- AiGateway.php:107-125
章节来源
- AiGateway.php:107-125
优先级与调度策略
- 排序:列表默认按 sort ASC、id DESC 排序,便于管理员在后台调整优先级。
- 启用过滤:AiGateway 在解析配置时会读取 ai_provider.status,仅启用状态的供应商参与调度。
- 密钥轮转:ai_key 表维护 last_used_at、failure_count 等字段,可用于实现基于最近使用或失败次数的轮询策略(由上层服务或驱动实现)。
- 流式格式:根据 provider.code 或协议预设选择 qwen/openai 流式格式,确保不同供应商的 SSE/流式行为一致。
章节来源
- AiProvider.php:70-79
- AiGateway.php:43-64
- ai.sql:35-50
多供应商接入、负载均衡与故障转移
- 多供应商接入:
- 在 ai_provider 中新增供应商记录,填写 base_url 与必要 config。
- 在 ai_model 中登记可用模型,绑定 provider_id。
- 在 ai_key 中为该供应商添加至少一个有效密钥。
- 负载均衡:
- 同一供应商下可配置多个密钥,结合 last_used_at/failure_count 实现轮询或加权策略。
- 不同供应商之间可通过业务侧选择 model_id 或应用级配置进行流量分配。
- 故障转移:
- 当某供应商被停用(status=0)或被判定不可用时,网关将跳过该供应商,自动选择下一个可用供应商或模型。
- 异步任务(图片/视频/音频)具备超时与状态机处理,失败时可按策略重试或降级。
章节来源
- ai.sql:35-95
- AiGateway.php:43-64
依赖关系分析
- AiProvider 模型:
- 提供筛选、排序、唯一性校验、统计方法(会话数、日志数、应用引用数)。
- AiGateway:
- 依赖 ai_provider、ai_model、ai_key 三张表完成配置解析与驱动选择。
- 驱动层:
- 依据 provider.code 与流式格式选择具体驱动,屏蔽底层差异。
classDiagram
class AiProvider {
+string name
+string code
+string base_url
+int status
+int sort
+string config
+scopeFilterByKeyword()
+scopeApplyDefaultOrder()
+codeExistsExcluding()
+countChatSessionsForProvider()
+countUsageLogsForProvider()
+countApplicationsForProvider()
}
class AiGateway {
+resolveConfig(modelId) array|null
-getModel(id)
-getDefaultModel()
-getAvailableKey(providerId)
}
AiGateway --> AiProvider : "读取启用状态/排序/配置"
图示来源
- AiProvider.php:25-138
- AiGateway.php:43-125
章节来源
- AiProvider.php:25-138
- AiGateway.php:43-125
性能考量
- 列表排序:sort 字段配合 id 降序,避免全表扫描时的不稳定排序。
- 配置解析:AiGateway 仅在调用时解析 provider.config,减少启动期开销。
- 密钥轮换:利用 last_used_at 与 failure_count 降低热点密钥压力,提升整体吞吐。
- 流式传输:按供应商选择合适流式格式,减少不必要的数据转换。
故障排查指南
- 供应商不可用:
- 检查 ai_provider.status 是否为 1。
- 检查 ai_key 是否存在且未过期,last_used_at 是否正常更新。
- 端点异常:
- 核对 provider.config.endpoints.text 是否正确覆盖。
- 确认 base_url 与端点拼接后可达。
- 流式问题:
- 确认 driver 选择的流式格式(qwen/openai)与供应商实际支持一致。
- 异步任务:
- 查看 ai_task 的状态与错误信息,必要时调整超时阈值或重试策略。
章节来源
- ai.sql:53-79
- AiGateway.php:43-64
结论
ai_provider 表是 DouPHP AI 能力的核心枢纽,通过 code/base_url/status/config 等字段实现对多供应商的统一管理与灵活扩展。结合 AiGateway 的配置解析与驱动路由,系统实现了端点覆盖、流式格式选择、启用状态控制与可扩展的负载均衡/故障转移策略。开发者只需按规范配置 provider 与 model,即可快速接入新供应商。
附录:供应商接入与配置指南
步骤概览
- 在 ai_provider 中添加供应商记录:
- 填写 name、code、base_url。
- 设置 status=1 启用,sort 调整优先级。
- 在 config 中按需配置 endpoints 与其他扩展项。
- 在 ai_model 中登记模型:
- 填写 name、model_code,并绑定 provider_id。
- 在 ai_key 中添加密钥:
- 填写加密后的 api_key,可设置 alias、expires_at。
- 在应用中指定 model_id:
- 由 AiGateway 解析出对应 provider 与驱动,发起请求。
配置要点
- endpoints 覆盖:
- 若供应商非 OpenAI 兼容,可在 config.endpoints.text 中指定正确路径。
- 流式格式:
- Qwen/DashScope 使用 qwen 流式;其他通常使用 openai 流式。
- 启用状态:
- 停用供应商将使其及下属模型不可用,适合灰度下线或故障隔离。
示例(仅示意)
- 文本对话:
- provider.config.endpoints.text = "/chat/completions"
- 图像生成:
- 通过驱动硬编码端点(如 BailianDriver/VolcanoDriver),无需在 provider 中重复配置。
章节来源
- ai.sql:126-152
- ai.sql:82-95
- ai.sql:35-50
- AiGateway.php:90-125
- ai.php:100-166