Como configurar o openai para retornar dados, manter a saída de streaming e carregar em segmentos
Você pode usar o parâmetro stream da API OpenAI para obter saída de streaming e pode usar o parâmetro max_tokens para controlar o comprimento de cada dado retornado. Veja a seguir um exemplo de código para demonstrar como usar a API OpenAI para obter a saída de streaming e carregar em partes:
python
import openai
# 连接 OpenAI API openai.api_key = "YOUR_API_KEY"
# 设置 OpenAI API 参数
model_engine = "davinci"
# 模型引擎
prompt = "你好,我需要帮助进行自然语言处理任务。" # 请求语句
temperature = 0.5 # 温度参数
max_tokens = 100 # 每次最大输出长度 # 获取 OpenAI 返回数据
completions = openai.Completion.create( engine=model_engine, prompt=prompt, temperature=temperature, max_tokens=max_tokens, n=1, stream=True ) # 分段获取数据
for i, text in enumerate(iter(completions.choices), start=1):
print(f"============== 第 {
i} 段输出 ==============")
print(text.text)
Neste exemplo, stream
definimos o parâmetro como True
, para que a API OpenAI transmita os dados de volta ao chamador em tempo real e retorne um objeto gerador ( iter(completions.choices)
) que nos permite buscar os dados parte por parte e imprimi-los. Ao mesmo tempo, usamos max_tokens
parâmetros para controlar o comprimento dos dados retornados a cada vez, o que também pode evitar efetivamente o problema de memória insuficiente causada por dados retornados muito longos. Observe que aqui YOUR_API_KEY
precisa ser substituído pela chave de API que você solicitou no OpenAI. [Tempo de solicitação: 14 segundos]
openai retorna o stream, seja UDP ou TCP, e recebe o código de dados do stream DEMO
A API OpenAI GPT-3 retorna um fluxo HTTPS usando o protocolo TCP.
Se você precisar processar o fluxo de dados retornado da API OpenAI GPT-3, poderá usar a biblioteca de solicitações em Python para processá-lo.
Veja a seguir um exemplo de código que pode receber e processar o fluxo de dados retornado pela API OpenAI GPT-3:
python
import requests
def process_stream(stream):
for line in stream.iter_lines():
if line: # 处理返回的数据
print(line.decode('utf-8')) # 发起 API 请求并处理返回的数据流
response = requests.post(url, headers=headers, data=data, stream=True)
process_stream(response.iter_lines())
No código acima, utilizamos requests.post
o método para fazer uma stream=True
requisição POST com o parâmetro e salvar a resposta response
na variável . Em seguida, chamamos process_stream
a função para processar o fluxo de dados retornado da API. Na process_stream
função , usamos iter_lines
o iterador para processar o fluxo de dados linha por linha e converter cada linha em uma string codificada em UTF-8. Neste exemplo simples, apenas imprimimos os dados no console, mas você pode escrever a lógica correspondente para processar os dados de acordo com as necessidades reais.
O exemplo de código PHP para receber dados de fluxo é o seguinte:
php
<?php $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'STREAM_URL');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data)
{
// 处理获得的数据
echo $data;
return strlen($data); });
curl_exec($ch);
curl_close($ch); ?>
Entre eles, STREAM_URL
representa o endereço URL do stream do OpenAI. Este código gravará dados na tela de forma incremental.
Da mesma forma, o exemplo de código Java para receber dados de fluxo é o seguinte:
java
import java.net.*;
import java.io.*;
public class StreamReceiver {
public static void main(String[] args) throws Exception
{
URL streamURL = new URL("STREAM_URL");
try (
BufferedReader reader = new BufferedReader( new InputStreamReader(streamURL.openStream())))
{
String line;
while ((line = reader.readLine()) != null)
{
// 处理获得的数据 System.out.println(line);
}
}
}
}
Da mesma forma, STREAM_URL
representa o endereço URL do stream do OpenAI. Este código enviará os dados passo a passo para a interface de linha de comando
Exemplo de código PHP:
<?php // 请求OpenAI接口获取stream数据,并转发到H5页面端
$openAIUrl = 'https://api.openai.com/v1/engines/davinci-codex/completions'; $headers = array( 'Content-Type: application/json', 'Authorization: Bearer <YOUR_API_KEY>' );
$data = array( 'prompt' => 'Hello, world!', 'max_tokens' => 5, 'temperature' => 0.7 );
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $openAIUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$output = fopen('php://output', 'w');
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use ($output) {
fwrite($output, $chunk);
return strlen($chunk); });
curl_exec($ch);
fclose($output); // 将stream数据转发给H5页面端
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('Access-Control-Allow-Origin: *');
fpassthru($output);
Exemplo de código Java:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(asyncSupported = true, urlPatterns = {
"/stream"})
public class StreamServlet extends HttpServlet
{
private static final ExecutorService executor = Executors.newCachedThreadPool();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建异步上下文
AsyncContext asyncContext = request.startAsync(); // 提交任务到线程池
executor.submit(() -> {
try {
// 请求OpenAI接口获取stream数据
URL url = new URL("https://api.openai.com/v1/engines/davinci-codex/completions");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Bearer <YOUR_API_KEY>"); conn.setDoOutput(true);
OutputStream out = conn.getOutputStream();
out.write("{\"prompt\": \"Hello, world!\", \"max_tokens\": 5, \"temperature\": 0.7}".getBytes());
out.flush();
out.close();
InputStream in = conn.getInputStream();
response.setContentType("text/event-stream");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Connection", "keep-alive");
response.setHeader("Access-Control-Allow-Origin", "*");
byte[] buffer = new byte[1024];
int count;
while ((count = in.read(buffer)) != -1) {
// 将stream数据转发给H5页面端
OutputStream outputStream = asyncContext.getResponse().getOutputStream();
String data = new String(buffer, 0, count);
outputStream.write(("data: " + data + "\n\n").getBytes());
outputStream.flush(); } in.close(); }
catch (IOException e) {
e.printStackTrace(); }
finally {
asyncContext.complete(); } }); } }
Exemplo de código Python:
import requests from flask
import Flask, Response app = Flask(__name__) @app.route('/stream')
def stream(): # 请求OpenAI接口获取stream数据
url = 'https://api.openai.com/v1/engines/davinci-codex/completions'
headers = {
'Content-Type': 'application/json', 'Authorization': 'Bearer <YOUR_API_KEY>' }
data = {
'prompt': 'Hello, world!', 'max_tokens': 5, 'temperature': 0.7 } res = requests.post(url, headers=headers, json=data, stream=True)
# 将stream数据转发给H5页面端
def generate():
for chunk in res.iter_content(chunk_size=1024):
if chunk: yield 'data: ' + chunk.decode() + '\n\n'
return Response(generate(), mimetype='text/event-stream', headers={
'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*' })
if __name__ == '__main__':
app.run()
Observação: o código acima é apenas para referência e a implementação específica precisa ser modificada adequadamente de acordo com suas próprias necessidades de negócios.
Como fazer o formato mardown de exibição Html front-end
Para exibir a formatação Markdown no HTML front-end, você pode usar uma biblioteca ou ferramenta chamada analisador Markdown. Aqui está um exemplo simples:
1. Primeiro, importe uma biblioteca do analisador Markdown, como marcado.js, por meio do CDN ou baixe-o para uma pasta local.
html <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
- Adicione uma tag textarea na página para inserir texto no formato Markdown e adicione uma tag div para exibir o conteúdo HTML analisado.
javascripthtml <textarea id="mdInput"></textarea> <div id="htmlOutput"></div>
- Obtenha o valor da textarea em JavaScript, passe-o para o analisador Markdown e insira o código HTML de saída no div.
javascript
var markdown = document.getElementById('mdInput').value;
var html = marked(markdown);
document.getElementById('htmlOutput').innerHTML = html;
Desta forma, o texto no formato Markdown pode ser exibido no navegador.
Semelhante ao site ChatGPT, a tecnologia de processamento de fluxo (Stream) em Node.js é usada para converter a saída em formato markdown.
Streaming é uma técnica útil ao trabalhar com grandes quantidades de dados, permitindo que os dados sejam processados em blocos sem esperar que todo o conjunto de dados seja carregado. No site do ChatGPT, um método semelhante ao código a seguir pode ser usado para converter o fluxo de saída para o formato markdown:
javascript
const markdown = require('markdown').markdown;
const stream = require('stream');
const outputStream = new stream.Writable({
write(chunk, encoding, callback) {
const text = chunk.toString();
const markdownText = markdown.toHTML(text);
process.stdout.write(markdownText);
callback(); },
});
// Stream output to markdown formatter
originalOutputStream.pipe(outputStream);
Neste exemplo de código, markdown
a biblioteca é usada para converter texto simples de entrada para o formato Markdown. Um Writable
fluxo gravável para receber a saída, convertê-la no formato Markdown e enviá-la para o fluxo de saída padrão ( process.stdout.write()
). Por fim, originalOutputStream
conecte o fluxo de saída original ( ) ao novo fluxo gravável ( outputStream
) e canalize a saída para a saída padrão por meio desse fluxo. Este é apenas um exemplo simples, na realidade, o site ChatGPT pode usar técnicas mais complexas para transmitir e converter a saída para o formato Markdown