PHP项目大模型接口如何PHP调用对接

wen PHP项目 32

本文目录导读:

PHP项目大模型接口如何PHP调用对接

  1. 基础调用方式
  2. 流式输出(Streaming)
  3. 封装成统一的Service类
  4. 错误处理和重试机制
  5. 配置管理
  6. 性能优化建议

我来详细讲解PHP项目对接大模型接口的方法,以常见的API为例:

基础调用方式

使用 cURL(最常用)

<?php
function callLLM($prompt) {
    $api_key = 'your-api-key';
    $api_url = 'https://api.openai.com/v1/chat/completions';
    $data = [
        'model' => 'gpt-3.5-turbo',
        'messages' => [
            [
                'role' => 'user',
                'content' => $prompt
            ]
        ],
        'temperature' => 0.7,
        'max_tokens' => 1000
    ];
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $api_url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key
        ],
        CURLOPT_TIMEOUT => 30
    ]);
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if (curl_errno($ch)) {
        return ['error' => curl_error($ch)];
    }
    curl_close($ch);
    if ($http_code !== 200) {
        return ['error' => "HTTP Error: $http_code"];
    }
    return json_decode($response, true);
}
// 使用示例
$result = callLLM("请用中文写一首关于AI的诗");
if (!isset($result['error'])) {
    echo $result['choices'][0]['message']['content'];
}
?>

使用 GuzzleHttp(推荐用于复杂项目)

composer require guzzlehttp/guzzle
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class LLMService {
    private $client;
    private $api_key;
    public function __construct($api_key) {
        $this->api_key = $api_key;
        $this->client = new Client([
            'base_uri' => 'https://api.openai.com/',
            'timeout' => 30,
            'headers' => [
                'Authorization' => 'Bearer ' . $api_key,
                'Content-Type' => 'application/json'
            ]
        ]);
    }
    public function chat($messages, $model = 'gpt-3.5-turbo') {
        try {
            $response = $this->client->post('v1/chat/completions', [
                'json' => [
                    'model' => $model,
                    'messages' => $messages,
                    'temperature' => 0.7,
                    'max_tokens' => 1000
                ]
            ]);
            return json_decode($response->getBody(), true);
        } catch (RequestException $e) {
            return [
                'error' => $e->getMessage(),
                'status' => $e->getCode()
            ];
        }
    }
}
// 使用示例
$llm = new LLMService('your-api-key');
$result = $llm->chat([
    ['role' => 'user', 'content' => '你好,请介绍一下自己']
]);
print_r($result);
?>

流式输出(Streaming)

<?php
function streamLLM($prompt, $callback) {
    $api_key = 'your-api-key';
    $data = [
        'model' => 'gpt-3.5-turbo',
        'messages' => [
            ['role' => 'user', 'content' => $prompt]
        ],
        'stream' => true
    ];
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => 'https://api.openai.com/v1/chat/completions',
        CURLOPT_RETURNTRANSFER => false,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key
        ],
        CURLOPT_WRITEFUNCTION => function($ch, $data) use ($callback) {
            // 解析SSE数据
            $lines = explode("\n", $data);
            foreach ($lines as $line) {
                if (strpos($line, 'data: ') === 0) {
                    $json = substr($line, 6);
                    if ($json !== '[DONE]') {
                        $content = json_decode($json, true);
                        if (isset($content['choices'][0]['delta']['content'])) {
                            $callback($content['choices'][0]['delta']['content']);
                        }
                    }
                }
            }
            return strlen($data);
        }
    ]);
    curl_exec($ch);
    curl_close($ch);
}
// 使用示例 - 网页实时显示
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
streamLLM("写一个简短的故事", function($chunk) {
    echo "data: " . json_encode(['content' => $chunk]) . "\n\n";
    ob_flush();
    flush();
});
?>

封装成统一的Service类

<?php
class AIService {
    private $provider;
    private $config;
    public function __construct($provider = 'openai') {
        $this->provider = $provider;
        $this->config = [
            'openai' => [
                'url' => 'https://api.openai.com/v1/chat/completions',
                'key' => getenv('OPENAI_API_KEY'),
                'model' => 'gpt-3.5-turbo'
            ],
            'claude' => [
                'url' => 'https://api.anthropic.com/v1/messages',
                'key' => getenv('CLAUDE_API_KEY'),
                'model' => 'claude-3-opus-20240229'
            ],
            '文心一言' => [
                'url' => 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions',
                'key' => getenv('BAIDU_API_KEY'),
                'model' => 'ernie-bot-turbo'
            ]
        ];
    }
    public function chat($messages, $options = []) {
        $config = $this->config[$this->provider];
        switch ($this->provider) {
            case 'openai':
                return $this->callOpenAI($messages, $config, $options);
            case 'claude':
                return $this->callClaude($messages, $config, $options);
            case '文心一言':
                return $this->callBaidu($messages, $config, $options);
            default:
                throw new Exception("不支持的AI提供商");
        }
    }
    private function callOpenAI($messages, $config, $options) {
        // OpenAI 调用实现
        $data = array_merge([
            'model' => $config['model'],
            'messages' => $messages
        ], $options);
        return $this->httpPost($config['url'], $data, [
            'Authorization: Bearer ' . $config['key']
        ]);
    }
    private function callClaude($messages, $config, $options) {
        // Claude 调用实现
        $data = array_merge([
            'model' => $config['model'],
            'messages' => $messages,
            'max_tokens' => 1000
        ], $options);
        return $this->httpPost($config['url'], $data, [
            'x-api-key: ' . $config['key'],
            'anthropic-version: 2023-06-01'
        ]);
    }
    private function callBaidu($messages, $config, $options) {
        // 百度文心一言调用实现
        // 需要先获取access_token
        $token = $this->getBaiduToken();
        $data = array_merge([
            'messages' => $messages
        ], $options);
        return $this->httpPost(
            $config['url'] . '?access_token=' . $token,
            $data,
            ['Content-Type: application/json']
        );
    }
    private function httpPost($url, $data, $headers = []) {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => array_merge(
                ['Content-Type: application/json'],
                $headers
            ),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 30
        ]);
        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        if ($error) {
            return ['error' => $error];
        }
        return json_decode($response, true);
    }
    private function getBaiduToken() {
        // 实现百度access_token获取逻辑
        // 通常使用client_credentials方式
    }
}
// 使用示例
$ai = new AIService('openai');
$result = $ai->chat([
    ['role' => 'system', 'content' => '你是一个AI助手'],
    ['role' => 'user', 'content' => '介绍一下PHP的优势']
]);
?>

错误处理和重试机制

<?php
class AIClient {
    private $maxRetries = 3;
    private $retryDelay = 2; // 秒
    public function callWithRetry($prompt) {
        $attempts = 0;
        while ($attempts < $this->maxRetries) {
            try {
                $result = $this->callAPI($prompt);
                if (isset($result['error'])) {
                    throw new Exception($result['error']);
                }
                return $result;
            } catch (Exception $e) {
                $attempts++;
                if ($attempts >= $this->maxRetries) {
                    throw $e;
                }
                // 指数退避
                sleep($this->retryDelay * $attempts);
                // 记录日志
                error_log("API调用失败,第{$attempts}次重试: " . $e->getMessage());
            }
        }
    }
}
?>

配置管理

// .env 文件
OPENAI_API_KEY=sk-xxx
CLAUDE_API_KEY=sk-ant-xxx
BAIDU_API_KEY=xxx
BAIDU_SECRET_KEY=xxx
// 使用 vlucas/phpdotenv
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$apiKey = $_ENV['OPENAI_API_KEY'];

性能优化建议

  1. 连接池: 使用持久连接
  2. 缓存: 对相同请求结果缓存
  3. 异步处理: 使用队列处理大量请求
  4. 限流: 实现令牌桶算法
// 简单的缓存示例
$cacheKey = md5($prompt);
$cached = apcu_fetch($cacheKey);
if ($cached !== false) {
    return $cached;
}
$result = callLLM($prompt);
apcu_store($cacheKey, $result, 3600); // 缓存1小时
return $result;

选择哪种方式取决于你的项目需求,个人推荐使用 GuzzleHttp 配合 Service 类封装,这样更易于维护和扩展。

抱歉,评论功能暂时关闭!