是否可以像chatgpt一样中断或停止openai聊天完成流而不浪费令牌?

问题描述 投票:0回答:1

我已经实现了 openai 聊天 api 来获取回复。我已经应用了chatStream,以便它可以像chatGPT一样显示。它在我的代码中运行良好。但是聊天 gpt 中有一个选项,当响应流式传输时,有一个选项可以停止输出响应。如何在 php Laravel 中实现此功能。

这是JS代码

$.ajax({
                method: 'POST',
                url: initArticleGenerateUrl,
                data: form,
            beforeSend: function() {
                $(".ArticleForm .loader").removeClass('hidden');
                $('#ArticleGenerateButton').attr('disabled', 'disabled');
                $('.BlogEditButton').addClass('hidden');
                $('.ArticleSuggestion').addClass('hidden');
                $('.ArticleSection').removeClass('hidden');
                
            },
            complete: function() {
                
                
            },
            success: function(data) {
                if (data.status == 200) {
                    $('.ArticleData').html(`
                        <h1 class="text-color-14 text-24 font-semibold font-RedHat dark:text-white">${$('#ArticleTitle').val()}</h1>
                    `);
                    $('.used-words-percentage').empty().append(data.usedPercentage);
                    $('.article-data').empty().html(data['article']);
                    $('.btn-create-content').prop('disabled', false);
    
                    longArticleFormData.article.data.generatedArticleBlogId = data.longArticleBlogId;
                    setLocalLongArticleData();
    
                    let url = articleGenerateUrl + "?long_article_id=" + data.longArticleBlogId;
    
                    const source = new EventSource(url, {withCredentials: true});
    
                    source.addEventListener("open", (e) => {
                        $('.ArticleSuggestion').addClass('hidden')
                        $('.ArticleData').removeClass('hidden');
                    });
    
                    source.addEventListener('update', function(event) {
    
                        if (event.data === "<END_STREAMING_SSE>") {
                            $('#ArticleGenerateButton').removeAttr('disabled');
                            $(".ArticleForm .loader").addClass('hidden');
                            $(".BlogEditButton").attr("href", SITE_URL + "/user/long-article/edit/" + data.unique_identifier);
                            $('.BlogEditButton').removeClass('hidden');
                            toastMixin.fire({
                                title: 'Article generated successfully.',
                                icon: 'success'
                            });
                            source.close();
                        }
    
                        let txt = event.data;
                        txt = txt.replace(/(?:\r\n|\r|\n)/g, '<br>');
                        let oldValue = '';
                        oldValue += $('.ArticleData').html();
                        let value = oldValue + txt;
                        value = value.replace(/\*\*(.*?)\*\*/g,
                                        '<br><br><h1 class="text-color-14 text-24 font-semibold font-RedHat dark:text-white">$1</h1>');
                        $('.ArticleData').html(value);
                    });
    
                   
    
                }  else {
                    errorMessage('Something went wrong', 'OutlineGenerateButton');
                }
            },
            error: function(data) {
                var jsonData = JSON.parse(data.responseText);
                var message = jsonData.response.records.response ? jsonData.response.records.response : jsonData.response.status.message
                errorMessage(message, 'OutlineGenerateButton');
            }
        });

这是 Laravel 代码

$options['prompt'] = filteringBadWords("This is the title: " . session('title') . ". These are the keywords: " . session('keywords') . ". This is the Heading list: " . session('outlines') . ". Expand each heading section to generate article in " . session('language') . " language. Do not add other headings or write more than the specific headings in Heading list. Give the heading output in bold font.");

        $generator = $this->generator;

        return response()->stream(function () use ($generator, $longArticle, $options, $subscription, $userId) {   
            
            $text = ""; 
            $totalTokens = 0;
            $streamData =  $generator->prepareChatOptions($options)->generateChatContent(['method' => 'createChatCompletionStream']);

            $textValue = '';
            foreach ($streamData as $response) {
                
                $text = $generator->getChatStreamContent($response);
                
                $textValue .= $text;
                $totalTokens++;
                if (connection_aborted()) {
                    break;
                }

                echo "event: update\n";
                echo 'data: ' . $text;
                echo "\n\n";
                ob_flush();
                flush();
            }

            

            echo "event: update\n";
            echo 'data: <END_STREAMING_SSE>';
            echo "\n\n";
            ob_flush();
            flush();

     
        }, 200, [
            'Cache-Control' => 'no-cache',
            'Content-Type' => 'text/event-stream',
        ]);

我想知道...在内容生成过程中(当响应流 foreach 时)我可以通过单击停止按钮来停止生成流吗?

php laravel openai-api server-sent-events responsestream
1个回答
0
投票

试试这个,

客户端 JavaScript:

function stopStreaming() {
    $.ajax({
        method: 'POST',
        url: '/stop-streaming',
        data: { stop: true },
        success: function(data) {
            console.log('Streaming stopped');
        },
        error: function(error) {
            console.log('Error stopping streaming');
        }
    });
}

$('#stopButton').on('click', function() {
    stopStreaming();
});

Laravel 路线:

Route::post('/stop-streaming', function (Request $request) {
    session(['stop_streaming' => true]);
    return response()->json(['message' => 'Streaming will stop']);
});

修改 Laravel 中的流逻辑:

return response()->stream(function () use ($generator, $longArticle, $options) {
    $streamData = $generator->prepareChatOptions($options)->generateChatContent(['method' => 'createChatCompletionStream']);

foreach ($streamData as $response) {
    // Check if the stop flag is set in the session
    if (session('stop_streaming')) {
        session(['stop_streaming' => false]);
        break;
    }
}

echo "event: update\n";
echo 'data: <END_STREAMING_SSE>';
echo "\n\n";
ob_flush();
flush();
}, 200, [
    'Cache-Control' => 'no-cache',
    'Content-Type' => 'text/event-stream',
]);
© www.soinside.com 2019 - 2024. All rights reserved.