jjzjj

如何配置openai的返回Stream数据并转发到h5页面按markdown格式流式输出

学习3人组 2023-11-26 原文

如何配置openai返回数据,保持流式输出,可以分段加载

可以使用OpenAI API的stream参数来实现流式输出,并且可以使用max_tokens参数控制每次返回数据的长度。 以下是一个示例代码,演示如何使用OpenAI API来实现流式输出并分段加载:

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)

在这个示例中,我们将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 返回的数据流的示例代码:

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()) 

在上面的代码中,我们使用 requests.post 方法发起了一个带有 stream=True 参数的 POST 请求,并将响应保存到 response 变量中。接着,我们调用 process_stream 函数来处理从 API 返回的数据流。在 process_stream 函数中,我们使用 iter_lines 迭代器来逐行处理数据流,并将每行转换为 UTF-8 编码字符串。在这个简单的示例中,我们只是将数据打印到控制台上,但您可以根据实际需求来编写相应的逻辑来处理数据。

接收stream数据的PHP代码示例如下:

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); ?> 

其中,STREAM_URL 代表 OpenAI 的 stream URL 地址。这段代码会将数据逐步地写到屏幕上。
相应的,接收stream数据的Java代码示例如下:

 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); 
					}
				} 
		 } 
 } 

同样的,STREAM_URL 代表 OpenAI 的 stream URL 地址。这段代码会将数据逐步地输出到命令行界面上

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); 

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(); } }); } } 

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() 

注意:以上代码仅供参考,具体实现需要根据自己的业务需求进行适当修改。

如何让前端Html能显示mardown格式

要在前端HTML中显示Markdown格式,您可以使用一个叫做Markdown解析器的库或工具。下面是一个简单的例子:
1.首先,通过CDN或将其下载到本地文件夹中,引入一个Markdown解析器库,比如marked.js。

 html <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> 
  1. 在页面上添加一个textarea标签用于输入Markdown格式的文本,添加一个div标签用于显示解析后的HTML内容。
javascripthtml <textarea id="mdInput"></textarea> <div id="htmlOutput"></div> 
  1. 在JavaScript中获取textarea的值,将其传递给Markdown解析器,并将输出的HTML代码插入到div中。
javascript 
var markdown = document.getElementById('mdInput').value; 
var html = marked(markdown); 
document.getElementById('htmlOutput').innerHTML = html; 

这样就可以在浏览器中显示Markdown格式的文本了。

类似于ChatGPT网站使用Node.js中的流(Stream)处理技术将输出转换成markdown格式。
流是一种在处理大量数据时很有用的技术,它允许以逐块的方式处理数据而不必等待加载整个数据集。 在ChatGPT网站中,可能使用了类似于以下代码的方法来将输出流转换为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); 

在这个代码示例中,markdown库用于将输入的纯文本转换为Markdown格式。一个Writable可写流用于接收输出,并将其转换为Markdown格式并将其发送到标准输出流(process.stdout.write())。最后将原始输出流(originalOutputStream)连接到新的可写流(outputStream),并通过该管道输出到标准输出流。 这只是一个简单的示例,实际上,ChatGPT网站可能使用更复杂的技术来流式处理并转换输出到Markdown格式

有关如何配置openai的返回Stream数据并转发到h5页面按markdown格式流式输出的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐