我在使用OpenAI API时遇到了问题。我试图做的是从OpenAI API的响应中流式传输每个数据节点,并在API调用过程中逐个输出每个数据节点,但我不知道如何实现这一点。我研究了几个小时,也找不到任何关于如何用PHP实现的信息。
如何让我的代码在API流式传输数据时实时输出每个数据节点?
以下是我能想到的最佳解决方案,它会在调用完成后一次性输出所有数据,但它并不会流式传输数据。
function openAI(){ $OPENAI_API_KEY="API_KEY_GOES_HERE"; $user_id="1"; // 用户ID,可选 $prompt="告诉我你能为我做些什么。"; $temperature=0.5; // 1 完全随机,0 无随机性,0.0 $max_tokens=30; $data = array('model'=>'text-davinci-002', 'prompt'=>$prompt, 'temperature'=>$temperature, 'max_tokens'=>$max_tokens, 'top_p'=>1.0, 'stream'=>TRUE,// 流式返回响应 'frequency_penalty'=>0.0, 'presence_penalty'=>0.0, 'user' => $user_id); $post_json= json_encode($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/completions'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_json); $headers = array(); $headers[] = 'Content-Type: application/json'; // $headers[] = 'Content-Type: text/event-stream'; $headers[] = "Authorization: Bearer $OPENAI_API_KEY"; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); return $result; curl_close($ch);}echo openAI();
回答:
我最终解决了我的问题。希望我的答案能在未来帮助到其他人。
我对我的代码做了以下补充。这些简单的逻辑使得我所询问的功能得以实现。
// 这应该放在最前面,或者可以设置在你的php.ini文件中@ini_set('zlib.output_compression',0);@ini_set('implicit_flush',1);// 此函数清空最顶层的输出缓冲区并关闭此输出缓冲。@ob_end_clean();
还应该添加以下curl_setopt。我个人将其添加在CURLOPT_POSTFIELDS之后的那一行
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) { # str_repeat(' ',1024*8) 需要填充缓冲区,这将使数据流式传输成为可能 echo $data.str_repeat(' ',1024*8); return strlen($data); });
或者,除了添加str_repeat(‘ ‘,1024*8),你还可以在你的web服务器配置文件中关闭缓冲,例如(nginx.conf)
gzip off;proxy_buffering off;