使用 php 从 openai GPT-3 API 传输数据

Log*_*nse 3 php streaming openai-api

我在使用 OpenAI API 时遇到了问题,基本上我想做的是流式传输从 openai API 响应流回的每个数据节点,并在从 API 调用流入时一次输出一个数据节点,但我不知道这是如何完成的,我研究了几个小时,但找不到任何关于如何使用 PHP 实现这一点的信息。

如何让我的代码在 API 流式传输数据时实时输出每个数据节点?

以下是我能想到的最好的,它在调用完成后立即输出所有数据,但它不会流入数据。

function openAI(){
  $OPENAI_API_KEY="API_KEY_GOES_HERE";
  $user_id="1";  //  users id optional
   
    $prompt="tell me what you can do for me.";
    $temperature=0.5;  // 1 adds complete randomness  0 no randomness 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,// stream back response
              '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();
Run Code Online (Sandbox Code Playgroud)

Log*_*nse 6

我最终解决了我的问题。希望我的回答对将来的人有所帮助。

我对我的代码做了以下添加。这个简单的逻辑使我询问的内容变得有效。

// This should be at the very top, alternatively can be set in you php.ini file
@ini_set('zlib.output_compression',0);
@ini_set('implicit_flush',1);
// This function discards the contents of the topmost output buffer and turns off this output buffering.
@ob_end_clean(); 
Run Code Online (Sandbox Code Playgroud)

还应添加以下curl_setopt。我个人是在CURLOPT_POSTFIELDS之后添加的

curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) {
  # str_repeat(' ',1024*8) is needed to fill the buffer and will make streaming the data possible
   echo $data.str_repeat(' ',1024*8);
   return strlen($data); 
});
Run Code Online (Sandbox Code Playgroud)

或者,您可以关闭 Web 服务器配置文件中的缓冲,例如(nginx.conf),而不是添加 str_repeat(' ',1024*8)

gzip off;
proxy_buffering off;
Run Code Online (Sandbox Code Playgroud)