422 lines
9.9 KiB
Markdown
422 lines
9.9 KiB
Markdown
# AI 供应商配置指南
|
||
|
||
## 概述
|
||
|
||
本系统支持多种 AI 供应商的动态配置,所有供应商都使用 **OpenAI 兼容的 API 格式**,但根据不同供应商的特点进行了优化。
|
||
|
||
## 支持的供应商类型
|
||
|
||
### 1. 阿里云 (alibaba)
|
||
|
||
**适用场景:** 通义千问系列模型(Qwen)
|
||
|
||
**配置示例:**
|
||
```json
|
||
{
|
||
"name": "阿里云通义千问",
|
||
"type": "alibaba",
|
||
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||
"apiKey": "sk-xxxxxxxxxxxxxxxx"
|
||
}
|
||
```
|
||
|
||
**可用模型:**
|
||
- `qwen-turbo` - 快速响应,适合日常对话
|
||
- `qwen-plus` - 更强性能,适合复杂任务
|
||
- `qwen-max` - 最强性能
|
||
- `qwen-vl-plus` - 支持图像输入的多模态模型
|
||
- `qwen3-vl-plus` - 最新多模态模型
|
||
|
||
**特点:**
|
||
- 完全兼容 OpenAI Chat Completions API
|
||
- 支持流式响应 (stream: true)
|
||
- 支持 Function Calling
|
||
- 支持多模态输入(图片、视频)
|
||
|
||
**请求示例:**
|
||
```bash
|
||
POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
|
||
Authorization: Bearer sk-xxxxxxxxxxxxxxxx
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"model": "qwen-plus",
|
||
"messages": [
|
||
{"role": "system", "content": "你是一个有帮助的助手"},
|
||
{"role": "user", "content": "你好"}
|
||
],
|
||
"stream": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. OpenAI 官方 (openai)
|
||
|
||
**适用场景:** OpenAI 官方模型(GPT-4、GPT-3.5 等)
|
||
|
||
**配置示例:**
|
||
```json
|
||
{
|
||
"name": "OpenAI 官方",
|
||
"type": "openai",
|
||
"baseUrl": "https://api.openai.com/v1",
|
||
"apiKey": "sk-proj-xxxxxxxxxxxxxxxx"
|
||
}
|
||
```
|
||
|
||
**可用模型:**
|
||
- `gpt-4-turbo` - GPT-4 Turbo
|
||
- `gpt-4` - GPT-4
|
||
- `gpt-3.5-turbo` - GPT-3.5 Turbo
|
||
- `o1` - 推理模型
|
||
- `o1-mini` - 轻量推理模型
|
||
|
||
**特点:**
|
||
- 标准 OpenAI API
|
||
- 支持所有官方功能
|
||
- 支持 Function Calling、Vision、Audio
|
||
|
||
**请求示例:**
|
||
```bash
|
||
POST https://api.openai.com/v1/chat/completions
|
||
Authorization: Bearer sk-proj-xxxxxxxxxxxxxxxx
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"model": "gpt-4-turbo",
|
||
"messages": [
|
||
{"role": "system", "content": "You are a helpful assistant"},
|
||
{"role": "user", "content": "Hello"}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. OpenAI 兼容 (custom)
|
||
|
||
**适用场景:** 任何提供 OpenAI 兼容 API 的第三方服务
|
||
|
||
**配置示例:**
|
||
```json
|
||
{
|
||
"name": "GPT-5 Nano",
|
||
"type": "custom",
|
||
"baseUrl": "https://api.huandutech.com/v1",
|
||
"apiKey": "sk-xxxxxxxxxxxxxxxx"
|
||
}
|
||
```
|
||
|
||
**典型的兼容服务:**
|
||
- Claude via OpenRouter
|
||
- GPT-5 Nano 等第三方优化模型
|
||
- 本地部署的 OpenAI 兼容服务(如 vLLM、Text Generation WebUI)
|
||
- Azure OpenAI Service
|
||
- Cloudflare Workers AI
|
||
|
||
**请求格式:**
|
||
```bash
|
||
POST <baseUrl>/chat/completions
|
||
Authorization: Bearer <apiKey>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"model": "<model_name>",
|
||
"messages": [
|
||
{"role": "user", "content": "Hello"}
|
||
],
|
||
"stream": true // 可选
|
||
}
|
||
```
|
||
|
||
**兼容性要求:**
|
||
1. **必需端点:** `/chat/completions` 或 `/v1/chat/completions`
|
||
2. **必需请求头:** `Authorization: Bearer <apiKey>`
|
||
3. **请求格式:** 符合 OpenAI Chat Completions API 规范
|
||
4. **响应格式:** 返回标准 OpenAI 格式的 JSON 响应
|
||
|
||
**完整请求示例:**
|
||
```json
|
||
{
|
||
"model": "gpt-5-nano",
|
||
"messages": [
|
||
{
|
||
"role": "system",
|
||
"content": "你是一个有帮助的助手。"
|
||
},
|
||
{
|
||
"role": "user",
|
||
"content": "你能做什么?"
|
||
}
|
||
],
|
||
"temperature": 0.7,
|
||
"max_tokens": 2000,
|
||
"stream": true,
|
||
"top_p": 1,
|
||
"frequency_penalty": 0,
|
||
"presence_penalty": 0
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 系统设置配置步骤
|
||
|
||
### 1. 添加 AI 供应商
|
||
|
||
1. 登录管理员账户
|
||
2. 进入 **系统设置** → **AI 提供商**
|
||
3. 点击 **添加提供商**
|
||
4. 填写信息:
|
||
- **名称:** 供应商显示名称(如"阿里云通义千问")
|
||
- **类型:** 选择 alibaba / openai / custom
|
||
- **Base URL:** API 基础地址
|
||
- **API Key:** 您的 API 密钥
|
||
5. 点击 **保存**
|
||
|
||
### 2. 添加 AI 模型
|
||
|
||
1. 在 **系统设置** → **AI 模型** 中
|
||
2. 点击 **添加模型**
|
||
3. 填写信息:
|
||
- **供应商:** 选择刚创建的供应商
|
||
- **模型 ID:** 模型的实际标识符(如 `qwen-plus`、`gpt-4`)
|
||
- **显示名称:** 前端显示的名称(如"通义千问 Plus")
|
||
- **描述:** 模型的简要说明
|
||
- **支持视觉:** 是否支持图像输入
|
||
- **默认模型:** 是否设为系统默认
|
||
- **排序顺序:** 前端显示的顺序
|
||
4. 点击 **保存**
|
||
|
||
### 3. 测试配置
|
||
|
||
1. 返回聊天界面
|
||
2. 在模型选择器中应该能看到新配置的模型
|
||
3. 选择模型并发送测试消息
|
||
4. 查看服务器日志确认请求正常
|
||
|
||
---
|
||
|
||
## API 请求格式详解
|
||
|
||
所有供应商都遵循 OpenAI Chat Completions API 规范:
|
||
|
||
### 基本请求结构
|
||
|
||
```typescript
|
||
interface ChatCompletionRequest {
|
||
model: string; // 模型 ID
|
||
messages: Message[]; // 消息列表
|
||
temperature?: number; // 0-2,控制随机性
|
||
max_tokens?: number; // 最大生成 token 数
|
||
stream?: boolean; // 是否流式响应
|
||
top_p?: number; // 核采样参数
|
||
frequency_penalty?: number; // 频率惩罚
|
||
presence_penalty?: number; // 存在惩罚
|
||
stop?: string | string[]; // 停止序列
|
||
}
|
||
|
||
interface Message {
|
||
role: "system" | "user" | "assistant" | "tool";
|
||
content: string | ContentPart[];
|
||
name?: string;
|
||
tool_calls?: ToolCall[];
|
||
}
|
||
```
|
||
|
||
### 多模态输入(支持的模型)
|
||
|
||
```json
|
||
{
|
||
"model": "qwen-vl-plus",
|
||
"messages": [
|
||
{
|
||
"role": "user",
|
||
"content": [
|
||
{
|
||
"type": "text",
|
||
"text": "这张图片里有什么?"
|
||
},
|
||
{
|
||
"type": "image_url",
|
||
"image_url": {
|
||
"url": "https://example.com/image.jpg"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### Function Calling
|
||
|
||
```json
|
||
{
|
||
"model": "qwen-plus",
|
||
"messages": [
|
||
{
|
||
"role": "user",
|
||
"content": "波士顿今天的天气怎么样?"
|
||
}
|
||
],
|
||
"tools": [
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "get_current_weather",
|
||
"description": "获取指定位置的当前天气",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"location": {
|
||
"type": "string",
|
||
"description": "城市和州,例如 San Francisco, CA"
|
||
}
|
||
},
|
||
"required": ["location"]
|
||
}
|
||
}
|
||
}
|
||
],
|
||
"tool_choice": "auto"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### Q: 配置后前端没有显示新模型?
|
||
|
||
**A:** 请检查:
|
||
1. 模型是否启用(`isEnabled = true`)
|
||
2. 供应商是否启用(`isEnabled = true`)
|
||
3. 清除浏览器缓存和 Cookie
|
||
4. 硬刷新页面(Ctrl+Shift+R / Cmd+Shift+R)
|
||
|
||
### Q: 模型请求失败,返回 503 错误?
|
||
|
||
**A:** 可能原因:
|
||
1. API Key 无效或过期
|
||
2. Base URL 配置错误
|
||
3. 供应商服务不可用
|
||
4. 网络连接问题
|
||
|
||
**调试步骤:**
|
||
1. 检查服务器日志:`pm2 logs ai-chatbot`
|
||
2. 使用 curl 测试 API:
|
||
```bash
|
||
curl -X POST <baseUrl>/chat/completions \
|
||
-H "Authorization: Bearer <apiKey>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"model":"<model>","messages":[{"role":"user","content":"test"}]}'
|
||
```
|
||
|
||
### Q: 阿里云模型和 OpenAI 模型有什么区别?
|
||
|
||
**A:**
|
||
- **API 格式:** 完全相同(OpenAI 兼容)
|
||
- **模型 ID:** 不同(qwen-plus vs gpt-4)
|
||
- **Base URL:** 不同(dashscope.aliyuncs.com vs api.openai.com)
|
||
- **功能支持:** 基本相同,部分高级功能可能有差异
|
||
|
||
### Q: 如何配置本地部署的模型?
|
||
|
||
**A:** 选择 **custom** 类型,配置:
|
||
```json
|
||
{
|
||
"type": "custom",
|
||
"baseUrl": "http://localhost:8000/v1",
|
||
"apiKey": "your-local-key"
|
||
}
|
||
```
|
||
|
||
确保本地服务提供 OpenAI 兼容的 API 接口。
|
||
|
||
---
|
||
|
||
## 技术实现说明
|
||
|
||
### 代码位置
|
||
|
||
- **动态 Provider:** `lib/ai/dynamic-provider.ts`
|
||
- **数据库 Schema:** `lib/db/schema.ts`
|
||
- **API 路由:** `app/api/admin/ai-providers/route.ts`、`app/api/admin/ai-models/route.ts`
|
||
- **前端组件:** `components/model-selector.tsx`、`components/multimodal-input.tsx`
|
||
|
||
### Provider 创建逻辑
|
||
|
||
```typescript
|
||
function getOrCreateProvider(provider: AiProvider) {
|
||
switch (provider.type) {
|
||
case "alibaba":
|
||
return createOpenAI({
|
||
apiKey: provider.apiKey,
|
||
baseURL: provider.baseUrl, // https://dashscope.aliyuncs.com/compatible-mode/v1
|
||
});
|
||
|
||
case "openai":
|
||
return createOpenAI({
|
||
apiKey: provider.apiKey,
|
||
baseURL: provider.baseUrl || "https://api.openai.com/v1",
|
||
});
|
||
|
||
case "custom":
|
||
default:
|
||
return createOpenAI({
|
||
apiKey: provider.apiKey,
|
||
baseURL: provider.baseUrl, // 任何 OpenAI 兼容的 URL
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
### 缓存机制
|
||
|
||
系统使用 `Map` 缓存已创建的 provider 实例,避免重复创建:
|
||
|
||
```typescript
|
||
const providerCache = new Map<string, ReturnType<typeof createOpenAI>>();
|
||
```
|
||
|
||
缓存键格式:`${providerId}-${baseUrl}`
|
||
|
||
---
|
||
|
||
## 最佳实践
|
||
|
||
1. **分类管理:** 为不同用途的模型创建不同的供应商配置(如"快速对话"、"深度思考")
|
||
2. **设置默认:** 为最常用的模型设置 `isDefault = true`
|
||
3. **排序优化:** 使用 `sortOrder` 控制前端显示顺序
|
||
4. **描述清晰:** 为每个模型添加清晰的描述,帮助用户选择
|
||
5. **定期更新:** 供应商可能推出新模型,及时更新配置
|
||
6. **监控使用:** 查看日志了解各模型的使用情况和错误率
|
||
|
||
---
|
||
|
||
## 安全建议
|
||
|
||
1. **API Key 保护:**
|
||
- 不要在前端代码中暴露 API Key
|
||
- API Key 存储在数据库中(建议加密)
|
||
- 定期轮换 API Key
|
||
|
||
2. **访问控制:**
|
||
- 只有管理员可以配置供应商和模型
|
||
- 使用 `requireAdmin()` 中间件保护 API 端点
|
||
|
||
3. **费用控制:**
|
||
- 设置合理的 `max_tokens` 限制
|
||
- 监控 API 使用量
|
||
- 考虑实现用户级别的配额限制
|
||
|
||
---
|
||
|
||
## 更新日志
|
||
|
||
- **2025-12-05:** 实现多供应商独立配置,支持阿里云、OpenAI、OpenAI兼容
|
||
- **未来计划:** 支持更多供应商类型(Claude、Gemini等)
|
||
|