API 文档中心
📋 概述
AI Key管理中台提供了一套完整的RESTful API接口,用于管理多个AI服务商的API Key、网站配置以及请求转发。当前支持的服务商:
| 服务商 | 类型 | 认证方式 | 接口地址 |
|---|---|---|---|
| DeepSeek | 大语言模型 API | Bearer Token (API Key) | api.deepseek.com |
| 百度文心智能体 | 智能体对话 API | App ID + Secret Key | agentapi.baidu.com |
- 统一管理多个AI服务商的 API Key
- 为多个网站配置不同的Key访问权限
- 自动记录每个网站的调用次数和统计信息
- 无需在各个网站中直接暴露API Key
- 实现Key的负载均衡和自动切换
- 支持每日限额,超额自动跳过
- 按服务商自动路由请求
Key 自动分配策略
当网站未绑定 Key 或绑定的 Key 不可用/已超额时,中台会自动分配 Key:
| 优先级 | 场景 | 分配方式 |
|---|---|---|
| 1 | 网站绑定了 Key 且 Key 活跃且未超额 | 使用绑定的 Key(assign_mode: bound) |
| 2 | 绑定的 Key 已停用 | 自动分配(assign_mode: bound_inactive) |
| 3 | 绑定的 Key 已达每日限额 | 自动分配(assign_mode: bound_exhausted) |
| 4 | 未绑定 Key | 自动分配(assign_mode: auto) |
自动分配算法:优先选择今日使用次数最少的活跃 Key;使用量相同时随机选择,避免全部请求打到同一个 Key。
每日限额:为 Key 设置每日限额后,超额的 Key 会被自动跳过,请求转发到其他可用 Key。所有限额每日零点自动重置。
服务商路由:请求中指定 provider 参数后,中台会按服务商类型分配对应的 Key。DeepSeek 请求只会分配 DeepSeek Key,百度文心智能体请求只会分配百度 Key。不指定 provider 时,自动选择使用量最少的 Key。
Base URL:
http://localhost:5000
适用场景
- 多个网站共用AI API资源(DeepSeek / 百度文心智能体)
- 需要精确统计各网站的API调用情况
- 需要统一管理API Key的安全性和配额
- 需要为不同业务线分配独立的Key
- 需要在DeepSeek和百度文心智能体之间灵活切换
🔐 认证方式
本中台采用网站ID认证机制,无需传统的API Key或Token认证。每个注册的网站都有唯一的ID,用于标识调用方。
获取website_id
- 登录管理后台,进入"网站管理"页面
- 点击"添加网站"按钮,填写网站信息
- 保存后会生成唯一的
website_id - 在代码中使用该ID调用API
请妥善保管您的
website_id,不要在公开的代码仓库中直接暴露。建议将其存储在环境变量或配置文件中。
认证参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
website_id |
string | 是 | 网站唯一标识符,长度20位 |
website_token |
string | 否 | 网站令牌(可选,用于替代ID) |
🚀 请求转发API
这是核心API,用于将客户端的AI对话请求转发到对应服务商(DeepSeek / 百度文心智能体),并自动选择合适的API Key。
POST
/api/request.php
请求头
Content-Type: application/json
通用请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
website_id |
string | 是* | 网站ID(与website_token二选一) |
provider |
string | 否 | 服务商类型:deepseek(默认)或 baidu。不指定时自动选择使用量最少的Key |
messages |
array | 是 | 对话消息数组(DeepSeek格式),百度会自动提取最后一条用户消息 |
重要:
provider 决定了请求被路由到哪个服务商。如果网站绑定了 Key,中台会根据绑定 Key 的 provider 自动路由。如果未绑定 Key 且不指定 provider,将自动选择使用量最少的 Key。
🔹 DeepSeek 调用
调用 DeepSeek 大语言模型 API,兼容 OpenAI 格式。
DeepSeek 专属参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 否 | 模型名称,默认 deepseek-chat。可选 deepseek-reasoner 等 |
temperature | number | 否 | 温度参数,默认1.0,范围0-2 |
max_tokens | number | 否 | 最大token数,默认2000 |
DeepSeek 请求示例
curl -X POST http://localhost:5000/api/request.php \
-H 'Content-Type: application/json' \
-d '{
"website_id": "你的website_id",
"provider": "deepseek",
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "你是一个专业的AI助手"},
{"role": "user", "content": "你好,请介绍一下你自己"}
],
"temperature": 0.7,
"max_tokens": 2000
}'
DeepSeek 响应示例
成功响应 200
{
"id": "chatcmpl-1234567890",
"object": "chat.completion",
"model": "deepseek-chat",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "你好!我是DeepSeek,一个大型语言模型..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 45,
"total_tokens": 57
}
}
🔸 百度文心智能体调用
调用百度文心智能体对话 API,中台会自动将请求格式转换为百度智能体 API 格式。你只需要传入 provider: "baidu" 和 messages 数组,中台会自动处理:
- 自动从 messages 提取最后一条用户消息作为智能体输入
- 自动将消息格式转换为百度智能体要求的
message.content.type=text格式 - 自动填充 App ID、Secret Key、OpenID、Source 参数
- 自动路由到
agentapi.baidu.com/assistant/getAnswer
百度文心智能体专属参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
provider | string | 是 | 必须为 baidu |
messages | array | 是 | 对话消息数组,取最后一条 role=user 的消息作为智能体输入 |
百度智能体 API 原始格式参考:中台会自动将你的请求转换为以下格式发送到百度:
POST https://agentapi.baidu.com/assistant/getAnswer?appId={appId}&secretKey={secretKey}
Content-Type: application/json
{
"message": {
"content": {
"type": "text",
"value": { "showText": "用户消息内容" }
}
},
"source": "openapi",
"from": "openapi",
"openId": "openapi"
}
你无需关心这些细节,只需传入 messages 数组即可。
百度文心智能体请求示例
curl -X POST http://localhost:5000/api/request.php \
-H 'Content-Type: application/json' \
-d '{
"website_id": "你的website_id",
"provider": "baidu",
"messages": [
{"role": "user", "content": "你好"}
]
}'
// JavaScript 调用百度文心智能体
async function callBaiduAgent(websiteId, userMessage) {
const response = await fetch('http://localhost:5000/api/request.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
website_id: websiteId,
provider: 'baidu',
messages: [{ role: 'user', content: userMessage }]
})
});
const data = await response.json();
return data;
}
// 使用示例
callBaiduAgent('你的website_id', '你好')
.then(result => console.log('智能体回复:', result));
import requests
def call_baidu_agent(website_id, user_message):
url = 'http://localhost:5000/api/request.php'
payload = {
'website_id': website_id,
'provider': 'baidu',
'messages': [{'role': 'user', 'content': user_message}]
}
response = requests.post(url, json=payload)
return response.json()
# 使用示例
result = call_baidu_agent('你的website_id', '你好')
print('智能体回复:', result)
<?php
// PHP 调用百度文心智能体
$url = 'http://localhost:5000/api/request.php';
$data = [
'website_id' => '你的website_id',
'provider' => 'baidu',
'messages' => [
['role' => 'user', 'content' => '你好']
],
];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print_r($result);
?>
百度文心智能体响应示例
成功响应 200
{
"traceId": "xxx",
"errorCode": 0,
"errorMsg": "success",
"result": {
"content": [{ "contentType": "text", "content": "你好!我是文心智能体..." }],
"conversationId": "xxx",
"messageId": "xxx"
}
}
失败响应
{
"success": false,
"message": "百度智能体调用失败: ..."
}
百度文心智能体 vs DeepSeek 调用差异
| 对比项 | DeepSeek | 百度文心智能体 |
|---|---|---|
| provider 值 | deepseek(可省略) | baidu(必填) |
| 消息格式 | OpenAI messages 数组 | 同左,自动转换 |
| 多轮对话 | 支持,传入完整 messages | 仅取最后一条用户消息 |
| 模型选择 | 通过 model 参数指定 | 由智能体 App ID 决定 |
| 温度/Token | 支持 temperature / max_tokens | 由智能体配置决定 |
| Key 绑定 | DeepSeek API Key | App ID + Secret Key |
🔑 API Key管理API
用于管理多服务商 API Key 的增删改查操作。当前支持 DeepSeek 和 百度文心智能体 两种类型的 Key。
获取所有Key
GET
/api/keys.php
curl http://localhost:5000/api/keys.php
响应字段说明
| 字段 | 说明 |
|---|---|
provider | 服务商类型:deepseek 或 baidu |
today_usage | 今日使用次数 |
daily_limit | 每日限额(0=不限) |
is_exhausted | 是否已超额 |
🔹 添加 DeepSeek Key
POST
/api/keys.php
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
key_name | string | 是 | Key的显示名称 |
provider | string | 否 | 默认 deepseek |
api_key | string | 是 | DeepSeek API Key(以 sk- 开头) |
daily_limit | number | 否 | 每日限额,0=不限(默认0) |
remark | string | 否 | 备注信息 |
curl -X POST http://localhost:5000/api/keys.php \
-H 'Content-Type: application/json' \
-d '{
"key_name": "生产环境Key",
"provider": "deepseek",
"api_key": "sk-xxxxxxxxxxxx",
"daily_limit": 100,
"remark": "用于生产环境的DeepSeek API Key"
}'
🔸 添加百度文心智能体 Key
POST
/api/keys.php
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
key_name | string | 是 | Key的显示名称 |
provider | string | 是 | 必须为 baidu |
app_id | string | 是 | 智能体ID(App ID),在百度智能体平台获取 |
secret_key | string | 是 | 智能体密钥(Secret Key),在百度智能体平台获取 |
open_id | string | 否 | 用户标识,默认 openapi |
source | string | 否 | 来源标识,默认 openapi |
daily_limit | number | 否 | 每日限额,0=不限(默认0) |
remark | string | 否 | 备注信息 |
如何获取 App ID 和 Secret Key:
- 登录 百度智能体平台
- 创建或选择一个智能体
- 进入智能体详情 → 「发布」→「API调用」
- 获取 App ID 和 Secret Key
curl -X POST http://localhost:5000/api/keys.php \
-H 'Content-Type: application/json' \
-d '{
"key_name": "客服智能体",
"provider": "baidu",
"app_id": "your-app-id",
"secret_key": "your-secret-key",
"open_id": "user_001",
"source": "my_website",
"daily_limit": 50,
"remark": "百度文心客服智能体"
}'
更新Key
PUT
/api/keys.php/{id}
curl -X PUT http://localhost:5000/api/keys.php/69f0a2562ff92 \
-H 'Content-Type: application/json' \
-d '{
"key_name": "更新后的名称",
"status": "inactive",
"daily_limit": 200
}'
删除Key
DELETE
/api/keys.php/{id}
curl -X DELETE http://localhost:5000/api/keys.php/69f0a2562ff92
重要提示: 删除Key后,所有绑定该Key的网站将无法正常使用该Key,建议在删除前先解除绑定或添加新的Key。
🌐 网站管理API
用于管理网站配置和Key绑定关系。
获取所有网站
GET
/api/websites.php
添加网站
POST
/api/websites.php
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
website_name |
string | 是 | 网站名称 |
website_url |
string | 是 | 网站URL |
api_key_id |
string | 否 | 绑定的API Key ID |
remark |
string | 否 | 备注信息 |
curl -X POST http://localhost:5000/api/websites.php \
-H 'Content-Type: application/json' \
-d '{
"website_name": "我的博客",
"website_url": "https://myblog.com",
"api_key_id": "69f0a2562ff92",
"remark": "个人博客网站"
}'
更新网站
PUT
/api/websites.php/{id}
删除网站
DELETE
/api/websites.php/{id}
📊 统计API
用于获取各网站的调用统计信息。
获取所有网站统计
GET
/api/statistics.php
查询参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
range |
string | 否 | 时间范围:today/yesterday/this_week/this_month |
curl http://localhost:5000/api/statistics.php?range=today
获取单个网站统计
GET
/api/statistics.php
查询参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
website_id |
string | 是 | 网站ID |
range |
string | 否 | 时间范围 |
curl "http://localhost:5000/api/statistics.php?website_id=69f0a25a8b73d&range=today"
响应示例
{
"success": true,
"data": {
"total": 156,
"success": 152,
"fail": 4,
"logs": [
{
"id": "log_123",
"website_id": "69f0a25a8b73d",
"website_name": "我的博客",
"model": "deepseek-chat",
"timestamp": 1711234567,
"date": "2024-03-23 10:30:00",
"status": "success",
"http_code": 200
}
]
}
}
💻 完整代码示例
1. Node.js 完整示例
const API_BASE = 'http://localhost:5000';
class DeepSeekClient {
constructor(websiteId) {
this.websiteId = websiteId;
}
async chat(messages, options = {}) {
const response = await fetch(`${API_BASE}/api/request.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
website_id: this.websiteId,
model: options.model || 'deepseek-chat',
messages: messages,
temperature: options.temperature || 0.7,
max_tokens: options.max_tokens || 2000
})
});
if (!response.ok) {
throw new Error(`API请求失败: ${response.status}`);
}
const data = await response.json();
return data.choices[0].message.content;
}
async streamChat(messages, onChunk, options = {}) {
// 流式响应示例
const response = await fetch(`${API_BASE}/api/request.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
website_id: this.websiteId,
model: options.model || 'deepseek-chat',
messages: messages,
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
onChunk(chunk);
}
}
}
// 使用示例
const client = new DeepSeekClient('69f0a25a8b73d');
async function main() {
try {
const response = await client.chat([
{
role: 'system',
content: '你是一个专业的AI助手'
},
{
role: 'user',
content: '请帮我写一首关于春天的诗'
}
]);
console.log('AI回复:', response);
} catch (error) {
console.error('错误:', error);
}
}
main();
2. Python 完整示例
import requests
import json
from typing import List, Dict, Optional
class DeepSeekClient:
def __init__(self, base_url: str, website_id: str):
self.base_url = base_url
self.website_id = website_id
def chat(
self,
messages: List[Dict],
model: str = "deepseek-chat",
temperature: float = 0.7,
max_tokens: int = 2000
) -> str:
"""发送聊天请求"""
url = f"{self.base_url}/api/request.php"
headers = {'Content-Type': 'application/json'}
payload = {
'website_id': self.website_id,
'model': model,
'messages': messages,
'temperature': temperature,
'max_tokens': max_tokens
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 200:
raise Exception(f"API请求失败: {response.status_code}")
data = response.json()
return data['choices'][0]['message']['content']
def stream_chat(self, messages: List[Dict], model: str = "deepseek-chat"):
"""流式聊天(示例)"""
url = f"{self.base_url}/api/request.php"
headers = {'Content-Type': 'application/json'}
payload = {
'website_id': self.website_id,
'model': model,
'messages': messages,
'stream': True
}
response = requests.post(url, headers=headers, json=payload, stream=True)
for line in response.iter_lines():
if line:
yield line.decode('utf-8')
# 使用示例
def main():
client = DeepSeekClient(
base_url='http://localhost:5000',
website_id='69f0a25a8b73d'
)
try:
messages = [
{
'role': 'system',
'content': '你是一个专业的AI助手'
},
{
'role': 'user',
'content': '请帮我写一首关于春天的诗'
}
]
response = client.chat(messages)
print(f"AI回复: {response}")
# 流式响应示例
# for chunk in client.stream_chat(messages):
# print(chunk, end='')
except Exception as e:
print(f"错误: {e}")
if __name__ == "__main__":
main()
3. React Hook 示例
import { useState, useCallback } from 'react';
const API_BASE = 'http://localhost:5000';
export function useDeepSeek(websiteId) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const chat = useCallback(async (messages, options = {}) => {
setLoading(true);
setError(null);
try {
const response = await fetch(`${API_BASE}/api/request.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
website_id: websiteId,
model: options.model || 'deepseek-chat',
messages: messages,
temperature: options.temperature || 0.7,
max_tokens: options.max_tokens || 2000
})
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || '请求失败');
}
return data.choices[0].message.content;
} catch (err) {
setError(err.message);
throw err;
} finally {
setLoading(false);
}
}, [websiteId]);
return { chat, loading, error };
}
// 组件使用示例
function ChatComponent() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const { chat, loading, error } = useDeepSeek('69f0a25a8b73d');
const handleSend = async () => {
if (!input.trim()) return;
const newMessages = [
...messages,
{ role: 'user', content: input }
];
setMessages(newMessages);
setInput('');
try {
const response = await chat(newMessages);
setMessages([
...newMessages,
{ role: 'assistant', content: response }
]);
} catch (err) {
console.error('发送失败:', err);
}
};
return (
);
}
{messages.map((msg, index) => (
{msg.content}
))}
setInput(e.target.value)}
disabled={loading}
placeholder="输入消息..."
/>
{error && {error}
}
4. PHP 完整示例
<?php
/**
* DeepSeek 中台 PHP 客户端
* 支持普通请求、流式请求、多轮对话、错误重试
*/
class DeepSeekClient
{
private string $baseUrl;
private string $websiteId;
private int $timeout;
private int $maxRetries;
public function __construct(
string $baseUrl = 'http://localhost:5000',
string $websiteId = '',
int $timeout = 30,
int $maxRetries = 2
) {
$this->baseUrl = rtrim($baseUrl, '/');
$this->websiteId = $websiteId;
$this->timeout = $timeout;
$this->maxRetries = $maxRetries;
}
/**
* 发送聊天请求
*
* @param array $messages 对话消息数组
* @param array $options 可选参数 (model, temperature, max_tokens)
* @return array DeepSeek API 原始响应
* @throws Exception
*/
public function chat(array $messages, array $options = []): array
{
$payload = [
'website_id' => $this->websiteId,
'model' => $options['model'] ?? 'deepseek-chat',
'messages' => $messages,
'temperature' => $options['temperature'] ?? 0.7,
'max_tokens' => $options['max_tokens'] ?? 2000,
];
return $this->request('/api/request.php', $payload);
}
/**
* 快速单轮对话
*
* @param string $question 用户提问内容
* @param string $system 系统提示词(可选)
* @param array $options 可选参数
* @return string AI 回复文本
*/
public function ask(string $question, string $system = '', array $options = []): string
{
$messages = [];
if ($system !== '') {
$messages[] = ['role' => 'system', 'content' => $system];
}
$messages[] = ['role' => 'user', 'content' => $question];
$result = $this->chat($messages, $options);
return $result['choices'][0]['message']['content'] ?? '';
}
/**
* 流式聊天(SSE)
* 逐块返回数据,适合打字机效果
*
* @param array $messages 对话消息数组
* @param callable $onChunk 每收到一块数据时的回调函数
* @param array $options 可选参数
* @return void
*/
public function streamChat(array $messages, callable $onChunk, array $options = []): void
{
$payload = [
'website_id' => $this->websiteId,
'model' => $options['model'] ?? 'deepseek-chat',
'messages' => $messages,
'temperature' => $options['temperature'] ?? 0.7,
'max_tokens' => $options['max_tokens'] ?? 2000,
'stream' => true,
];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->baseUrl . '/api/request.php',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_WRITEFUNCTION => function ($ch, $data) use ($onChunk) {
$onChunk($data);
return strlen($data);
},
]);
curl_exec($ch);
curl_close($ch);
}
/**
* 多轮对话上下文管理器
*
* @return Conversation
*/
public function conversation(): Conversation
{
return new Conversation($this);
}
/**
* 获取网站统计数据
*
* @param string $range 时间范围: today/yesterday/this_week/this_month
* @return array
*/
public function getStatistics(string $range = 'today'): array
{
$url = "/api/statistics.php?website_id={$this->websiteId}&range={$range}";
return $this->getRequest($url);
}
/* ─── 内部方法 ────────────────────────────── */
private function request(string $endpoint, array $payload): array
{
$attempt = 0;
$lastError = null;
while ($attempt <= $this->maxRetries) {
try {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->baseUrl . $endpoint,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlErr = curl_error($ch);
curl_close($ch);
if ($curlErr) {
throw new Exception("cURL 错误: {$curlErr}");
}
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception('响应 JSON 解析失败');
}
if ($httpCode >= 400) {
$msg = $data['message'] ?? "HTTP {$httpCode}";
throw new Exception($msg);
}
return $data;
} catch (Exception $e) {
$lastError = $e;
$attempt++;
if ($attempt <= $this->maxRetries) {
usleep(500000); // 等待 0.5 秒后重试
}
}
}
throw $lastError;
}
private function getRequest(string $url): array
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->baseUrl . $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true) ?? [];
}
}
/**
* 多轮对话上下文管理
*/
class Conversation
{
private DeepSeekClient $client;
private array $messages = [];
public function __construct(DeepSeekClient $client)
{
$this->client = $client;
}
/**
* 设置系统提示词
*/
public function system(string $content): self
{
$this->messages[] = ['role' => 'system', 'content' => $content];
return $this;
}
/**
* 用户发言
*/
public function user(string $content): self
{
$this->messages[] = ['role' => 'user', 'content' => $content];
return $this;
}
/**
* 发送并获取AI回复(自动追加到上下文)
*/
public function send(array $options = []): string
{
$result = $this->client->chat($this->messages, $options);
$reply = $result['choices'][0]['message']['content'] ?? '';
// 将 AI 回复追加到上下文中
$this->messages[] = ['role' => 'assistant', 'content' => $reply];
return $reply;
}
/**
* 获取完整对话历史
*/
public function getHistory(): array
{
return $this->messages;
}
/**
* 清空对话历史
*/
public function clear(): self
{
$this->messages = [];
return $this;
}
}
// ═══════════════════════════════════════
// 使用示例
// ═══════════════════════════════════════
$client = new DeepSeekClient(
baseUrl: 'http://localhost:5000',
websiteId: '69f0a25a8b73d',
timeout: 30,
maxRetries: 2
);
// ── 示例 1:快速单轮对话 ──
echo "=== 示例 1:快速单轮对话 ===\n";
$answer = $client->ask('PHP 8.3 有什么新特性?', '你是一个PHP专家');
echo "AI: {$answer}\n\n";
// ── 示例 2:多轮对话 ──
echo "=== 示例 2:多轮对话 ===\n";
$conv = $client->conversation();
$conv->system('你是一个专业的技术顾问,回答简洁明了');
$reply1 = $conv->user('什么是REST API?')->send();
echo "AI: {$reply1}\n";
$reply2 = $conv->user('如何在PHP中实现?')->send();
echo "AI: {$reply2}\n";
$reply3 = $conv->user('能给一个完整的代码示例吗?')->send();
echo "AI: {$reply3}\n\n";
// ── 示例 3:流式响应(打字机效果) ──
echo "=== 示例 3:流式响应 ===\n";
$client->streamChat(
[['role' => 'user', 'content' => '写一首短诗']],
function (string $chunk) {
echo $chunk; // 实时输出每一块数据
ob_flush();
flush();
}
);
echo "\n\n";
// ── 示例 4:自定义参数 ──
echo "=== 示例 4:自定义参数 ===\n";
$result = $client->chat(
[['role' => 'user', 'content' => '解释量子计算']],
[
'model' => 'deepseek-reasoner', // 使用推理模型
'temperature' => 0.3, // 更确定性的输出
'max_tokens' => 4000, // 更长的回复
]
);
echo "模型: " . ($result['model'] ?? '') . "\n";
echo "Token用量: " . json_encode($result['usage'] ?? []) . "\n";
echo "回复: " . ($result['choices'][0]['message']['content'] ?? '') . "\n\n";
// ── 示例 5:查看统计数据 ──
echo "=== 示例 5:查看统计数据 ===\n";
$stats = $client->getStatistics('today');
echo "今日统计: " . json_encode($stats, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
?>
5. PHP Laravel 集成示例
<?php
// ── app/Services/DeepSeekService.php ──
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class DeepSeekService
{
private string $baseUrl;
private string $websiteId;
public function __construct()
{
$this->baseUrl = config('deepseek.base_url', 'http://localhost:5000');
$this->websiteId = config('deepseek.website_id');
}
/**
* 发送聊天请求
*/
public function chat(array $messages, array $options = []): array
{
$payload = [
'website_id' => $this->websiteId,
'model' => $options['model'] ?? 'deepseek-chat',
'messages' => $messages,
'temperature' => $options['temperature'] ?? 0.7,
'max_tokens' => $options['max_tokens'] ?? 2000,
];
try {
$response = Http::timeout(30)
->withHeaders(['Content-Type' => 'application/json'])
->post("{$this->baseUrl}/api/request.php", $payload);
if ($response->failed()) {
Log::error('DeepSeek API 请求失败', [
'status' => $response->status(),
'body' => $response->body(),
]);
throw new \Exception('DeepSeek API 请求失败: ' . $response->status());
}
return $response->json();
} catch (\Exception $e) {
Log::error('DeepSeek 调用异常', ['message' => $e->getMessage()]);
throw $e;
}
}
/**
* 快速提问
*/
public function ask(string $question, string $system = ''): string
{
$messages = [];
if ($system) {
$messages[] = ['role' => 'system', 'content' => $system];
}
$messages[] = ['role' => 'user', 'content' => $question];
$result = $this->chat($messages);
return $result['choices'][0]['message']['content'] ?? '';
}
}
// ── config/deepseek.php ──
return [
'base_url' => env('DEEPSEEK_BASE_URL', 'http://localhost:5000'),
'website_id' => env('DEEPSEEK_WEBSITE_ID', ''),
];
// ── .env ──
// DEEPSEEK_BASE_URL=http://localhost:5000
// DEEPSEEK_WEBSITE_ID=69f0a25a8b73d
// ── app/Http/Controllers/ChatController.php ──
namespace App\Http\Controllers;
use App\Services\DeepSeekService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ChatController extends Controller
{
public function __construct(
private DeepSeekService $deepseek
) {}
public function chat(Request $request): JsonResponse
{
$request->validate([
'message' => 'required|string|max:5000',
]);
$reply = $this->deepseek->ask(
$request->input('message'),
'你是一个友好的AI助手'
);
return response()->json([
'success' => true,
'reply' => $reply,
]);
}
}
// ── routes/api.php ──
// Route::post('/chat', [ChatController::class, 'chat']);
?>
6. PHP ThinkPHP 集成示例
<?php
// ── app/service/DeepSeekService.php ──
namespace app\service;
use think\facade\Log;
class DeepSeekService
{
protected string $baseUrl;
protected string $websiteId;
public function __construct()
{
$this->baseUrl = env('DEEPSEEK_BASE_URL', 'http://localhost:5000');
$this->websiteId = env('DEEPSEEK_WEBSITE_ID', '');
}
/**
* 发送聊天请求
*/
public function chat(array $messages, array $options = []): array
{
$payload = [
'website_id' => $this->websiteId,
'model' => $options['model'] ?? 'deepseek-chat',
'messages' => $messages,
'temperature' => $options['temperature'] ?? 0.7,
'max_tokens' => $options['max_tokens'] ?? 2000,
];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->baseUrl . '/api/request.php',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($httpCode >= 400) {
Log::error('DeepSeek API 调用失败', [
'code' => $httpCode,
'body' => $response,
]);
throw new \Exception('DeepSeek API 调用失败');
}
return $data;
}
/**
* 快速提问
*/
public function ask(string $question, string $system = ''): string
{
$messages = [];
if ($system) {
$messages[] = ['role' => 'system', 'content' => $system];
}
$messages[] = ['role' => 'user', 'content' => $question];
$result = $this->chat($messages);
return $result['choices'][0]['message']['content'] ?? '';
}
}
// ── app/controller/Chat.php ──
namespace app\controller;
use app\service\DeepSeekService;
use think\Request;
use think\facade\Config;
class Chat
{
public function index(Request $request)
{
$data = $request->only(['message']);
if (empty($data['message'])) {
return json(['code' => 400, 'msg' => '消息不能为空']);
}
try {
$service = new DeepSeekService();
$reply = $service->ask($data['message'], '你是一个友好的AI助手');
return json([
'code' => 0,
'msg' => 'success',
'data' => ['reply' => $reply],
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => $e->getMessage()]);
}
}
}
// ── .env ──
// DEEPSEEK_BASE_URL = http://localhost:5000
// DEEPSEEK_WEBSITE_ID = 69f0a25a8b73d
?>
❌ 错误码说明
| HTTP状态码 | 错误类型 | 说明 | 解决方案 |
|---|---|---|---|
| 400 | Bad Request | 请求参数错误或缺失 | 检查请求参数是否完整且格式正确 |
| 404 | Not Found | 资源不存在(Key或网站ID无效) | 检查ID是否正确或资源是否已删除 |
| 500 | Internal Server Error | 服务器内部错误 | 联系管理员或稍后重试 |
| - | No active API key | 没有可用的活跃Key | 在管理后台添加并激活API Key |
| - | Website not found | 网站不存在 | 检查website_id是否正确 |
| - | Missing website_id | 缺少网站ID | 在请求中添加website_id参数 |
| - | 百度智能体调用失败 | 百度智能体API返回错误 | 检查App ID和Secret Key是否正确,确认智能体已发布 |
| - | No baidu key available | 没有可用的百度Key | 在管理后台添加百度文心智能体Key |
| - | Provider mismatch | 网站绑定的Key与请求provider不匹配 | 修改网站绑定的Key或请求中的provider参数 |
最佳实践: 在实际应用中,建议添加重试机制、错误日志记录和用户友好的错误提示。
🧪 在线测试
你可以在这里测试API接口,确保配置正确后再在实际项目中使用。