豆包SDK(Doubao SDK)
简介
豆包SDK是一个PHP封装类,用于简化与豆包AI大模型API的交互。该SDK支持文本对话和多模态(文本+图像)输入,适用于各种AI对话场景。
特性
- 支持纯文本对话
- 支持多模态输入(文本+图像)
- 支持历史对话上下文
- 灵活的参数配置
- 简单易用的接口
安装
将CallDoubao.php
文件放置在您项目的extend/ai/model/
目录下。
基本用法
<?php
use ai\model\CallDoubao;
// 方式一:快速调用
try {
$result = CallDoubao::run('你好,请介绍一下你自己', 'your_api_key');
echo $result['content'];
} catch (\Exception $e) {
echo $e->getMessage();
}
// 方式二:实例化后调用
try {
$doubao = new CallDoubao('your_api_key');
$result = $doubao->chat('你好,请介绍一下你自己');
echo $result['content'];
} catch (\Exception $e) {
echo $e->getMessage();
}
多模态输入示例
<?php
use ai\model\CallDoubao;
try {
$prompt = "这张图片是什么内容?[image]https://example.com/image.jpg[/image]";
$result = CallDoubao::run($prompt, 'your_api_key');
echo $result['content'];
} catch (\Exception $e) {
echo $e->getMessage();
}
带历史记录的对话示例
<?php
use ai\model\CallDoubao;
try {
$history = [
[
'prompt' => '你好,请介绍一下你自己',
'response' => '我是豆包AI助手,很高兴为你服务!'
]
];
$prompt = '你刚才说了什么?';
$result = CallDoubao::run($prompt, 'your_api_key', 'doubao-1.5-vision-pro-32k-250115', 'ai_chat', $history);
echo $result['content'];
} catch (\Exception $e) {
echo $e->getMessage();
}
API参考
构造函数
__construct($apiKey = '', $model = 'doubao-1.5-vision-pro-32k-250115')
$apiKey
: 豆包API密钥$model
: 模型名称,默认为doubao-1.5-vision-pro-32k-250115
参数设置方法
setApiKey($apiKey) // 设置API密钥
setModel($model) // 设置模型名称
setTemperature($temperature) // 设置温度参数(0-1)
setTopP($topP) // 设置top_p参数
setMaxTokens($maxTokens) // 设置最大生成token数
setUserId($userId) // 设置用户ID
setApiVersion($apiVersion) // 设置API版本
发送对话请求
chat($prompt, $moduleType = 'ai_chat', $history = [], $stream = false)
$prompt
: 用户问题/输入$moduleType
: 模块类型,用于确定系统提示词$history
: 历史对话记录数组$stream
: 是否使用流式响应
静态快速调用方法
run($prompt, $apiKey, $model = 'doubao-1.5-vision-pro-32k-250115', $moduleType = 'ai_chat', $history = [])
$prompt
: 用户问题/输入$apiKey
: API密钥$model
: 模型名称$moduleType
: 模块类型$history
: 历史对话记录数组
返回数据格式
[
'content' => '模型回复内容',
'tokens' => 123, // 消耗的token数量
'finish_reason' => 'stop', // 结束原因
'model' => '使用的模型名称'
]
注意事项
- 使用前请确保已获取有效的豆包API密钥
- 多模态输入使用
[image]图片URL[/image]
格式嵌入到问题中 - 历史对话记录格式为二维数组,每条记录包含
prompt
和response
字段 - 默认模型为
doubao-1.5-vision-pro-32k-250115
,可根据需要更换
错误处理
SDK使用异常机制处理错误,使用时请使用try-catch捕获可能的异常。
入口代码
<?php
namespace ai;
use app\module\ai\model\AichatConfigModel;
use ai\model\CallDeepseek;
use ai\model\CallDoubao;
use think\Exception;
/**
* @NodeAnotation(title="Ai-SDK入口")
* @Return:data
* @Author:李世民
* @DateTime:2025-04-13
*/
class Index
{
/**
* AI调用入口函数
*
* @param string $prompt 用户问题
* @param string $moduleType 模块类型
* @param array $history 历史对话记录
* @return array 响应结果
* @throws Exception
*/
public static function chat($prompt, $moduleType = 'ai_chat', $history = [])
{
try {
// 获取系统配置的模型与key
$config = AichatConfigModel::getCurrentConfig();
if (!$config) {
throw new Exception('未找到AI配置');
}
// 根据当前选择的模型调用对应SDK
switch ($config['current_model']) {
case 'deepseek':
// 调用DeepSeek SDK
return CallDeepseek::run(
$prompt,
$config['deepseek_key'],
$config['deepseek_model'] ?? 'deepseek-chat',
$moduleType,
$history
);
case 'doubao':
// 调用豆包SDK
return CallDoubao::run(
$prompt,
$config['doubao_key'],
$config['doubao_model'] ?? 'doubao-1-5-vision-pro-32k-250115',
$moduleType,
$history
);
default:
throw new Exception('未知的模型类型:' . $config['current_model']);
}
} catch (Exception $e) {
throw new Exception('AI调用失败:' . $e->getMessage());
}
}
/**
* 根据模块类型获取系统角色提示词
*
* @param string $moduleType 模块类型
* @return string 系统角色提示词
*/
public static function getSystemPrompt($moduleType = 'ai_chat')
{
switch ($moduleType) {
case 'ai_essay':
return '你是一个专业的中文作文写作助手,擅长创作各种类型的中文作文,包括议论文、记叙文等。你的作文结构清晰,论点明确,语言优美,善于运用修辞手法和名言警句,符合中国学生的写作习惯。';
case 'ai_english_essay':
return '你是一个专业的英语作文写作助手,擅长创作各种类型的英语作文。你的英语表达地道流畅,语法准确,用词丰富多样,符合英语写作规范。你能根据不同的要求严格控制单词数量或句子数量,并确保内容符合主题要求。';
case 'ai_photo_answer':
return '你是一个学习问题解答专家,擅长识别并回答学生提出的各类学科题目问题,包括数学、物理、化学、生物等。你能从图片中准确识别题目内容,并提供详细的解题思路、步骤和最终答案。你的回答条理清晰,逻辑严密,帮助学生理解知识点和解题方法。如果题目涉及公式,你会使用LaTeX格式正确表示。';
case 'ai_photo_translation':
return '你是一个专业的翻译专家,能够从图片中识别文字并进行准确翻译。当识别到的文字是非中文(如英文、法文、日文等)时,你会将其翻译成中文;当识别到的文字是中文时,你会将其翻译成英文。你的翻译既忠实原文,又符合目标语言的表达习惯,能够传达原文的确切含义和风格。对于难以辨认的内容,你会明确标注。你能够自动识别原文语言,并选择合适的翻译方向。';
case 'code_assistant':
return '你是一个专业的编程助手,擅长解决各种编程问题和提供编程建议。你能够提供清晰、高效且可实现的代码示例,同时提供详细的解释。你熟悉各种编程语言、框架和最佳实践。';
case 'homework_helper':
return '你是一个专业的作业辅导专家,擅长解析和解答各种学科的作业题目,包括数学、物理、化学、生物、历史、地理、语文和英语等。你能够分析题目要点,提供清晰的解题思路、详细的步骤以及准确的答案。对于计算题,你会展示完整的计算过程;对于概念题,你会给出全面而准确的解释;对于应用题,你会通过实例说明。你的解答条理清晰,逻辑严密,重点突出,能有效帮助学生理解知识点、掌握解题方法,提高学习能力。如有必要,你还会提供额外的知识拓展和学习建议,帮助学生建立更完整的知识体系。';
case 'ai_chat':
default:
return '你是一个有帮助的助手,可以回答用户提出的各种问题,并提供有用的信息和建议。';
}
}
}
SDK示例代码
<?php
/**
* @NodeAnotation(title="豆包SDK")
* @Return:data
* @Author:李世民
* @DateTime:2025-04-13
*/
namespace ai\model;
use ai\Index;
use think\facade\Log;
class CallDoubao
{
/**
* API接口URL
* @var string
*/
protected $apiUrl = 'https://ark.cn-beijing.volces.com/api/v3/chat/completions';
/**
* API密钥
* @var string
*/
protected $apiKey;
/**
* 模型名称
* @var string
*/
protected $model;
/**
* 温度参数,控制随机性,0-1之间,越大越随机
* @var float
*/
protected $temperature = 0.7;
/**
* 控制输出文本的多样性
* @var float
*/
protected $topP = 0.95;
/**
* 最大生成的token数
* @var int
*/
protected $maxTokens = 12288;
/**
* 用户标识符
* @var string
*/
protected $userId = 'user_001';
/**
* API版本
* @var string
*/
protected $apiVersion = 'v3';
/**
* 构造函数
*
* @param string $apiKey API密钥
* @param string $model 模型名称
*/
public function __construct($apiKey = '', $model = 'doubao-1.5-vision-pro-32k-250115')
{
$this -> apiKey = $apiKey;
$this -> model = $model;
}
/**
* 设置API密钥
*
* @param string $apiKey API密钥
* @return $this
*/
public function setApiKey($apiKey)
{
$this -> apiKey = $apiKey;
return $this;
}
/**
* 设置模型
*
* @param string $model 模型名称
* @return $this
*/
public function setModel($model)
{
$this -> model = $model;
return $this;
}
/**
* 设置温度参数
*
* @param float $temperature 温度值(0-1)
* @return $this
*/
public function setTemperature($temperature)
{
$this -> temperature = $temperature;
return $this;
}
/**
* 设置top_p参数
*
* @param float $topP top_p值
* @return $this
*/
public function setTopP($topP)
{
$this -> topP = $topP;
return $this;
}
/**
* 设置最大token数
*
* @param int $maxTokens 最大token数
* @return $this
*/
public function setMaxTokens($maxTokens)
{
$this -> maxTokens = $maxTokens;
return $this;
}
/**
* 设置用户ID
*
* @param string $userId 用户ID
* @return $this
*/
public function setUserId($userId)
{
$this -> userId = $userId;
return $this;
}
/**
* 设置API版本
*
* @param string $apiVersion API版本
* @return $this
*/
public function setApiVersion($apiVersion)
{
$this -> apiVersion = $apiVersion;
return $this;
}
/**
* 发送AI请求
*
* @param string $prompt 用户问题
* @param string $moduleType 模块类型,用于确定系统提示词
* @param array $history 历史对话记录
* @param bool $stream 是否使用流式响应
* @return array 响应结果
* @throws \Exception
*/
public function chat($prompt, $moduleType = 'ai_chat', $history = [], $stream = false)
{
try {
if (empty($this -> apiKey)) {
throw new \Exception('API密钥不能为空');
}
if (empty($this -> model)) {
throw new \Exception('模型名称不能为空');
}
// 构建消息数组,使用入口类中的提示词方法
$messages = [
['role' => 'system', 'content' => Index ::getSystemPrompt($moduleType)]
];
// 添加历史对话
if (!empty($history) && is_array($history)) {
foreach ($history as $item) {
if (isset($item['prompt']) && isset($item['response'])) {
// 处理带有图片的历史问题
if (preg_match('/\[image\](.*?)\[\/image\]/i', $item['prompt'], $matches)) {
$imageUrl = trim($matches[1]);
$textContent = trim(str_replace($matches[0], '', $item['prompt']));
$content = [];
// 如果有文本内容,添加文本部分
if ($textContent !== '') {
$content[] = [
'type' => 'text',
'text' => $textContent
];
}
// 添加图片部分
$content[] = [
'type' => 'image_url',
'image_url' => [
'url' => $imageUrl,
'detail' => 'auto'
]
];
$messages[] = ['role' => 'user', 'content' => $content];
} else {
$messages[] = ['role' => 'user', 'content' => $item['prompt']];
}
$messages[] = ['role' => 'assistant', 'content' => $item['response']];
}
}
}
// 处理当前问题,如果包含图片标签
if (preg_match('/\[image\](.*?)\[\/image\]/i', $prompt, $matches)) {
$imageUrl = trim($matches[1]);
$textContent = trim(str_replace($matches[0], '', $prompt));
$content = [];
// 如果有文本内容,添加文本部分
if ($textContent !== '') {
$content[] = [
'type' => 'text',
'text' => $textContent
];
}
// 添加图片部分
$content[] = [
'type' => 'image_url',
'image_url' => [
'url' => $imageUrl,
'detail' => 'auto' // 可选参数,使用默认模式
]
];
$messages[] = ['role' => 'user', 'content' => $content];
} else {
$messages[] = ['role' => 'user', 'content' => $prompt];
}
// 构建请求数据
$data = [
'model' => $this -> model,
'messages' => $messages,
'temperature' => $this -> temperature,
'top_p' => $this -> topP,
'max_tokens' => $this -> maxTokens,
'stream' => $stream,
'user' => $this -> userId
];
// 发送请求
$response = $this -> httpRequest($this -> apiUrl, $data, [
'Authorization: Bearer ' . $this -> apiKey,
'X-API-Version: ' . $this -> apiVersion
]);
if (!isset($response['choices'][0]['message']['content'])) {
throw new \Exception('豆包接口返回数据格式错误:' . json_encode($response));
}
return [
'content' => $response['choices'][0]['message']['content'],
'tokens' => $response['usage']['total_tokens'] ?? 0,
'finish_reason' => $response['choices'][0]['finish_reason'] ?? null,
'model' => $response['model'] ?? $this -> model
];
} catch (\Exception $e) {
throw new \Exception('豆包调用失败:' . $e -> getMessage());
}
}
/**
* HTTP请求封装
*
* @param string $url 请求URL
* @param array $data 请求数据
* @param array $headers 请求头
* @return array 响应结果
* @throws \Exception
*/
protected function httpRequest($url, $data, $headers = [])
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 20,
CURLOPT_CONNECTTIMEOUT => 10, // 连接超时改为10秒
CURLOPT_TIMEOUT => 60, // 请求超时改为60秒
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array_merge([
'Accept: application/json',
'Content-Type: application/json'
], $headers)
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$error = curl_error($curl);
curl_close($curl);
if ($error) {
throw new \Exception('HTTP请求失败:' . $error);
}
if ($httpCode !== 200) {
throw new \Exception('API请求失败,HTTP状态码:' . $httpCode . ',响应:' . $response);
}
$result = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('接口返回数据解析失败:' . $response);
}
return $result;
}
/**
* 快速调用方法
*
* @param string $prompt 用户问题
* @param string $apiKey API密钥
* @param string $model 模型名称
* @param string $moduleType 模块类型
* @param array $history 历史对话记录
* @return array 响应结果
* @throws \Exception
*/
public static function run($prompt, $apiKey, $model = 'doubao-1.5-vision-pro-32k-250115', $moduleType = 'ai_chat', $history = [])
{
$instance = new self($apiKey, $model);
return $instance -> chat($prompt, $moduleType, $history);
}
}