[web教学] 怎样设置openai的返回Stream数据并转发到h5页面按markdown格式流式输出

[复制链接]
查看808 | 回复0 | 2023-8-23 12:05:16 | 显示全部楼层 |阅读模式 来自 中国北京
怎样设置openai返回数据,保持流式输出,可以分段加载
可以利用OpenAI API的stream参数来实现流式输出,并且可以利用max_tokens参数控制每次返回数据的长度。 以下是一个示例代码,演示怎样利用OpenAI API来实现流式输出并分段加载:
  1. python
  2. import openai
  3. # 连接 OpenAI API openai.api_key = "YOUR_API_KEY"
  4. # 设置 OpenAI API 参数
  5. model_engine = "davinci"
  6. # 模型引擎
  7. prompt = "你好,我需要帮助进行自然语言处理任务。" # 请求语句
  8. temperature = 0.5 # 温度参数
  9. max_tokens = 100 # 每次最大输出长度 # 获取 OpenAI 返回数据
  10. completions = openai.Completion.create( engine=model_engine, prompt=prompt, temperature=temperature, max_tokens=max_tokens, n=1, stream=True ) # 分段获取数据
  11. for i, text in enumerate(iter(completions.choices), start=1):
  12. print(f"============== 第 {i} 段输出 ==============")
  13. print(text.text)
复制代码
在这个示例中,我们将stream参数设置为True,如许OpenAI API将会及时地将数据传输回调用方,并且将返回一个生成器对象(iter(completions.choices)),使得我们可以逐段获取数据并打印出来。 同时,我们利用max_tokens参数来控制每次返回的数据长度,如许也可以有效的制止返回数据过长导致内存不敷的标题。 注意,这里的YOUR_API_KEY需要更换为您在OpenAI申请的API密钥。【哀求时间:14秒】
openai 返回stream流,是UDP还是TCP,吸收stream数据代码DEMO
OpenAI GPT-3 API 返回的是 HTTPS 流,利用的是 TCP 协议。
假如您需要处理从 OpenAI GPT-3 API 返回的数据流,您可以利用 Python 中的 requests 库来处理它。
以下是一个可以吸收并处来由 OpenAI GPT-3 API 返回的数据流的示例代码:
  1. python
  2. import requests
  3. def process_stream(stream):
  4. for line in stream.iter_lines():
  5.         if line: # 处理返回的数据
  6.                 print(line.decode('utf-8')) # 发起 API 请求并处理返回的数据流
  7.                 response = requests.post(url, headers=headers, data=data, stream=True)
  8.                 process_stream(response.iter_lines())
复制代码
在上面的代码中,我们利用 requests.post 方法发起了一个带有 stream=True 参数的 POST 哀求,并将相应生存到 response 变量中。接着,我们调用 process_stream 函数来处理从 API 返回的数据流。在 process_stream 函数中,我们利用 iter_lines 迭代器来逐行处理数据流,并将每行转换为 UTF-8 编码字符串。在这个简单的示例中,我们只是将数据打印到控制台上,但您可以根据实际需求来编写相应的逻辑来处理数据。
吸收stream数据的PHP代码示例如下:
  1. php
  2. <?php $ch = curl_init();
  3. curl_setopt($ch, CURLOPT_URL, 'STREAM_URL');
  4. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  5. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data)
  6. { // 处理获得的数据
  7. echo $data;
  8. return strlen($data); });
  9. curl_exec($ch);
  10.   curl_close($ch); ?>
复制代码
此中,STREAM_URL 代表 OpenAI 的 stream URL 地点。这段代码会将数据渐渐地写到屏幕上。
相应的,吸收stream数据的Java代码示例如下:
  1. java
  2. import java.net.*;
  3. import java.io.*;
  4. public class StreamReceiver {
  5.         public static void main(String[] args) throws Exception
  6.                 { URL streamURL = new URL("STREAM_URL");
  7.                 try (
  8.                         BufferedReader reader = new BufferedReader( new InputStreamReader(streamURL.openStream())))
  9.                                 { String line;
  10.                                         while ((line = reader.readLine()) != null)
  11.                                         { // 处理获得的数据 System.out.println(line);
  12.                                         }
  13.                                 }
  14.                  }
  15. }
复制代码
同样的,STREAM_URL 代表 OpenAI 的 stream URL 地点。这段代码会将数据渐渐地输出到下令行界面上
PHP代码示例:
  1. <?php // 请求OpenAI接口获取stream数据,并转发到H5页面端
  2. $openAIUrl = 'https://api.openai.com/v1/engines/davinci-codex/completions'; $headers = array( 'Content-Type: application/json', 'Authorization: Bearer <YOUR_API_KEY>' );
  3. $data = array( 'prompt' => 'Hello, world!', 'max_tokens' => 5, 'temperature' => 0.7 );
  4. $ch = curl_init();
  5. curl_setopt($ch, CURLOPT_URL, $openAIUrl);
  6. curl_setopt($ch, CURLOPT_POST, true);
  7. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  8. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  9. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  10. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  11. $output = fopen('php://output', 'w');
  12. curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use ($output) { fwrite($output, $chunk);
  13. return strlen($chunk); });
  14. curl_exec($ch);
  15. fclose($output); // 将stream数据转发给H5页面端
  16. header('Content-Type: text/event-stream');
  17. header('Cache-Control: no-cache');
  18. header('Connection: keep-alive');
  19. header('Access-Control-Allow-Origin: *');
  20. fpassthru($output);
复制代码
Java代码示例:
  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.io.OutputStream;
  4. import java.net.HttpURLConnection;
  5. import java.net.URL;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.Executors;
  8. import javax.servlet.AsyncContext;
  9. import javax.servlet.ServletException;
  10. import javax.servlet.annotation.WebServlet;
  11. import javax.servlet.http.HttpServlet;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. @WebServlet(asyncSupported = true, urlPatterns = {"/stream"})
  15. public class StreamServlet extends HttpServlet
  16. {
  17. private static final ExecutorService executor = Executors.newCachedThreadPool();
  18. @Override
  19. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  20. // 创建异步上下文
  21. AsyncContext asyncContext = request.startAsync(); // 提交任务到线程池
  22. executor.submit(() -> { try {
  23. // 请求OpenAI接口获取stream数据
  24. URL url = new URL("https://api.openai.com/v1/engines/davinci-codex/completions");
  25. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  26. conn.setRequestMethod("POST");
  27. conn.setRequestProperty("Content-Type", "application/json");
  28. conn.setRequestProperty("Authorization", "Bearer <YOUR_API_KEY>"); conn.setDoOutput(true);
  29. OutputStream out = conn.getOutputStream();
  30. out.write("{"prompt": "Hello, world!", "max_tokens": 5, "temperature": 0.7}".getBytes());
  31. out.flush();
  32. out.close();
  33. InputStream in = conn.getInputStream();
  34. response.setContentType("text/event-stream");
  35. response.setHeader("Cache-Control", "no-cache");
  36. response.setHeader("Connection", "keep-alive");
  37. response.setHeader("Access-Control-Allow-Origin", "*");
  38. byte[] buffer = new byte[1024];
  39. int count;
  40. while ((count = in.read(buffer)) != -1) {
  41. // 将stream数据转发给H5页面端
  42. OutputStream outputStream = asyncContext.getResponse().getOutputStream();
  43. String data = new String(buffer, 0, count);
  44. outputStream.write(("data: " + data + "\n\n").getBytes());
  45. outputStream.flush(); } in.close(); }
  46. catch (IOException e) { e.printStackTrace(); }
  47. finally { asyncContext.complete(); } }); } }
复制代码
Python代码示例:
  1. import requests from flask
  2. import Flask, Response app = Flask(__name__) @app.route('/stream')
  3. def stream(): # 请求OpenAI接口获取stream数据
  4. url = 'https://api.openai.com/v1/engines/davinci-codex/completions'
  5. headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer <YOUR_API_KEY>' }
  6. data = { 'prompt': 'Hello, world!', 'max_tokens': 5, 'temperature': 0.7 } res = requests.post(url, headers=headers, json=data, stream=True)
  7. # 将stream数据转发给H5页面端
  8. def generate():
  9. for chunk in res.iter_content(chunk_size=1024):
  10. if chunk: yield 'data: ' + chunk.decode() + '\n\n'
  11. return Response(generate(), mimetype='text/event-stream', headers={ 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*' })
  12. if __name__ == '__main__':
  13. app.run()
复制代码
注意:以上代码仅供参考,具体实现需要根据本身的业务需求举行适当修改。
怎样让前端Html能显示mardown格式
要在前端HTML中显示Markdown格式,您可以利用一个叫做Markdown剖析器的库或工具。下面是一个简单的例子:
1.首先,通过CDN或将其下载到当地文件夹中,引入一个Markdown剖析器库,比如marked.js。
  1. html <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
复制代码

  • 在页面上添加一个textarea标签用于输入Markdown格式的文本,添加一个div标签用于显示剖析后的HTML内容。
  1. javascripthtml <textarea id="mdInput"></textarea> <div id="htmlOutput"></div>
复制代码

  • 在JavaScript中获取textarea的值,将其转达给Markdown剖析器,并将输出的HTML代码插入到div中。
  1. javascript
  2. var markdown = document.getElementById('mdInput').value;
  3. var html = marked(markdown);
  4. document.getElementById('htmlOutput').innerHTML = html;
复制代码
如许就可以在欣赏器中显示Markdown格式的文本了。
类似于ChatGPT网站利用Node.js中的流(Stream)处理技能将输出转换成markdown格式。
流是一种在处理大量数据时很有效的技能,它答应以逐块的方式处理数据而不必等候加载整个数据集。 在ChatGPT网站中,大概利用了类似于以下代码的方法来将输出流转换为markdown格式:
  1. javascript
  2. const markdown = require('markdown').markdown;
  3. const stream = require('stream');
  4. const outputStream = new stream.Writable({
  5.         write(chunk, encoding, callback) {
  6.                  const text = chunk.toString();
  7.                  const markdownText = markdown.toHTML(text);
  8.                  process.stdout.write(markdownText);
  9.                  callback(); },
  10.                  });
  11. // Stream output to markdown formatter
  12. originalOutputStream.pipe(outputStream);
复制代码
在这个代码示例中,markdown库用于将输入的纯文本转换为Markdown格式。一个Writable可写流用于吸收输出,并将其转换为Markdown格式并将其发送到标准输出流(process.stdout.write())。最后将原始输出流(originalOutputStream)毗连到新的可写流(outputStream),并通过该管道输出到标准输出流。 这只是一个简单的示例,实际上,ChatGPT网站大概利用更复杂的技能来流式处理并转换输出到Markdown格式

来源:https://blog.csdn.net/Climbman/article/details/129920946
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则