豆包SDK

豆包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'         => '使用的模型名称'
]

注意事项

  1. 使用前请确保已获取有效的豆包API密钥
  2. 多模态输入使用[image]图片URL[/image]格式嵌入到问题中
  3. 历史对话记录格式为二维数组,每条记录包含promptresponse字段
  4. 默认模型为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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值