更新提醒(2026-10):本文寫於 2023 年,使用 gpt-3.5-turbo 模型、orhanerday/open-ai 套件,以及串流範例中的 prompt 參數(舊式 completions 格式)。OpenAI 的模型名稱、API 端點與參數可能已更新,套件版本也可能不同,請以 OpenAI 官方文件目前的說明為準。
利用套件來串接 ChatGPT API
composer require orhanerday/open-ai
到 OpenAI 官方網站註冊,並建立 API token
先設定 .env
OPENAI_API_KEY={OPENAI_API_KEY}
use Orhanerday\OpenAi\OpenAi;
// 建議使用config
$openAi = new OpenAi(env('OPENAI_API_KEY'));
// 跟基本串接API一樣
$chat = $open_ai->chat([
'model' => 'gpt-3.5-turbo',
'messages' => [
[
"role" => "user",
"content" => "今天天氣如何"
],
],
'max_tokens' => 1000,
]);
// message
dd(Arr::get(json_decode($chat,1)),'choices.0.message.content');
會發現回應時間會隨著傳送過去的文字複雜度與長度增加。
後來查了網路上的資料,終於找到一個方法:
串流
使用串流套件的範例如下:
PHP
use Orhanerday\OpenAi\OpenAi;
$openAi = new OpenAi(env('OPEN_AI_API_KEY'));
$opts = [
'prompt' => "Hello",
'temperature' => 0.9,
"max_tokens" => 150,
"frequency_penalty" => 0,
"presence_penalty" => 0.6,
"stream" => true,
];
// set header
header('Content-type: text/event-stream');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Origin: *');
$openAi->chat($opts, function ($curl_info, $data) {
echo $data . "
";
echo PHP_EOL;
ob_flush();
flush();
return strlen($data);
});
HTML
<!DOCTYPE html>
<html>
<head>
<title>SSE Example</title>
</head>
<body>
<div id="divID">Hello</div>
<script>
var eventSource = new EventSource("{endPoint}");
var div = document.getElementById('divID');
eventSource.onmessage = function (e) {
if (e.data == "[DONE]") {
eventSource.close();
console.log('done');
return false;
} else {
const content = JSON.parse(e.data).choices[0].delta.content;
if (content != undefined) {
div.innerHTML += JSON.parse(e.data).choices[0].delta.content;
}
}
};
eventSource.onerror = function (e) {
console.log(e);
};
</script>
</body>
</html>
Demo
![流程圖:瀏覽器用 EventSource 連到 PHP 端,PHP 以 stream 呼叫 OpenAI,回應逐段以 data: 傳回,onmessage 把每段追加到 div,收到 [DONE] 就 close。](https://r2.usongrat.tw/blog/articles/69-chatgpt-stream.png)
每一段 data: 到達就追加到畫面,文字邊產生邊顯示,直到 [DONE] 收尾。
No comments yet.