Verwenden Sie die SSE-Technologie, um die OPENAI-Schnittstelle aufzurufen und eine Streaming-Ausgabe zu realisieren, die in der PHP-Sprache implementiert ist

Als Anbieter von KI-Sprachmodelldiensten stellt OpenAI eine Reihe von API-Schnittstellen bereit, auf die auf die meisten über HTTP-Anfragen zugegriffen werden muss. Bei großen Mengen an Datenanforderungen verlangsamen herkömmliche synchrone Anforderungen die Netzwerkantwort und können die Anforderungen der Echtzeit-Datenverarbeitung und -analyse nicht erfüllen. Um die Aufrufeffizienz dieser Schnittstellen zu optimieren, können wir daher die SSE-Technologie (Server Sent Events) verwenden, um eine Streaming-Ausgabe zu realisieren, sicherzustellen, dass Daten den Client in Echtzeit erreichen können, und die Datenverarbeitungseffizienz verbessern.

In der PHP-Sprache können wir Werkzeugbibliotheken wie die GuzzleHttp-Bibliothek und die ReactPHP-Bibliothek verwenden, um den Aufruf und die Streaming-Ausgabe der API-Schnittstelle von OpenAI über die SSE-Technologie zu realisieren. Das Folgende ist die spezifische Code-Implementierung:

use GuzzleHttp\Client;
use GuzzleHttp\Event\CompleteEvent;
use GuzzleHttp\Event\MessageCompleteEvent;
use GuzzleHttp\Message\Response;
use GuzzleHttp\Stream\Stream;
use React\EventLoop\Factory as EventLoopFactory;
use React\EventLoop\LoopInterface;

$openaiAccessToken = 'YOUR_OPENAI_ACCESS_TOKEN'; // 请替换为真实的 Access Token,可以去chat.xingtupai.com获取

function openaiApiRequestWithSse($query): void
{
    global $openaiAccessToken;

    $loop = EventLoopFactory::create();
    $client = new Client();
    $request = $client->createRequest('POST', 'https://api.openai.com/v1/engines/davinci-codex/completions');
    $request->setHeader('Content-Type', 'application/json');
    $request->setHeader('Authorization', "Bearer {$openaiAccessToken}");
    $request->setBody(Stream::factory(json_encode($query)));

    $client->send($request)->then(function (Response $response) use ($loop) {
        echo 'data: ';

        $stream = $response->getBody()->detach();
        stream_set_blocking($stream, false);

        $loop->addReadStream($stream, function ($stream, LoopInterface $loop) {
            $data = '';

            while ($buffer = fgets($stream, 2048)) {
                $event = new MessageCompleteEvent(
                    new CompleteEvent(),
                    $response = new Response(200),
                    Stream::factory($buffer)
                );

                $data .= $buffer;

                if (strpos($buffer, "\n\n") !== false) {
                    $loop->removeReadStream($stream);

                    $event->response = new Response(200, [], Stream::factory($data));

                    echo $data . PHP_EOL;
                    break;
                }
            }
        });
    });

    $loop->run();
}

Lassen Sie uns den obigen Code im Detail erklären. Zuerst haben wir einen Guzzle-HTTP-Client initialisiert und dann eine OpenAI-API-Anfrage erstellt. Als Nächstes legen wir den Anforderungsheader „Authorization“ in der Anforderung fest und übergeben das von OpenAI bereitgestellte Zugriffstoken, um sicherzustellen, dass wir über API-Zugriffsrechte verfügen. Anschließend serialisieren wir die Abfragebedingung JSON im Anforderungstext und legen den Anforderungstext als serialisierte JSON-Zeichenfolge für nachfolgende Anforderungen fest.

Als nächstes haben wir die Anfrage gesendet und den Antwortstream von OpenAI verarbeitet. Beachten Sie, dass wir hier die Ereignisüberwachung für den Antwortstream einrichten, um die Antwortergebnisse zu analysieren und eine Streaming-Ausgabe zu erreichen. Insbesondere rufen wir die addReadStream-Methode von EventLoop auf, um die Parameter des Antwortstroms und der Antwortstromüberwachungsfunktion von OpenAI an die Ereignisschleife zu übergeben. In der Ereignisschleife erhalten wir die Daten im Antwortstrom und lesen sie Zeile für Zeile durch die Schleife und die Funktion fgets. Dann verwenden wir eine While-Schleife, um zu beurteilen, ob die gelesenen Daten zwei Zeilenumbrüche enthalten. Wenn die Daten zwei Zeilenumbrüche enthalten, bedeutet dies, dass der aktuelle Datenabschnitt gelesen wurde und ein vollständiges Datenergebnis gebildet wird. Daher haben wir die Methode „removeReadStream“ von EventLoop aufgerufen, um den aktuellen Listener des Antwortstreams aus der Ereignisschleife zu entfernen. Abschließend geben wir das aktuelle Antwortdatenergebnis aus.

Durch die obige Code-Implementierung können wir problemlos SSE-Aufrufe an die API-Schnittstelle von OpenAI durchführen, eine Streaming-Ausgabe realisieren und die Effizienz der Datenverarbeitung effektiv verbessern.
 

おすすめ

転載: blog.csdn.net/weixin_58881595/article/details/130246714