wow-rag—task5:流式部署

ops/2025/3/26 2:04:18/

我们希望做一个流式输出的后端,然后让前端去捕获这个流式输出,并且在聊天界面中流式输出。
首先构造流式输出引擎。

# 构造流式输出引擎
query_engine = index.as_query_engine(streaming=True, similarity_top_k=3,llm=llm)

然后生成response_stream,这个response_stream里面有一个生成器,叫做response_gen。我们可以像列表一样去迭代这个生成器,然后取出生成的文本。

response_stream = query_engine.query("请写一篇1000字的文章论述法学专业就业前景") 
for text in response_stream.response_gen:print(text,end="")

在这里插入图片描述
在这里插入图片描述

这样我们就可以在Jupyter的界面看到流式输出了。

我们也可以做一个后端,可以用FastAPI来做。这是一个新的python web框架,性能很强悍。

我们先来安装一下这个框架:
在Jupyter的格子中输入以下内容。

%pip install fastapi
%pip install uvicorn

框架都很小,很快就安装好。

下面我们来改造一下,用fastapi做成http接口。
新建一个Jupyter notebook的格子,填入以下代码:

import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
app = FastAPI()
app.add_middleware(CORSMiddleware,allow_origins=["*"])
@app.get('/stream_chat')
async def stream_chat(param:str = "你好"):async def generate():  # 我们假设query_engine已经构建完成response_stream = query_engine.query(param) for text in response_stream.response_gen:yield textreturn StreamingResponse(generate(), media_type='text/event-stream')  
if __name__ == '__main__':config = uvicorn.Config(app, host='0.0.0.0', port=5000)server = uvicorn.Server(config)await server.serve()

可以看到,这里的关键的关键在于yield语句的使用以及用一个generate函数构建Response。

然后在前端我们就可以愉快地接收了。

当然也可以新建一个python文件,填入以下代码:

import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
app = FastAPI()
app.add_middleware(CORSMiddleware,allow_origins=["*"])
@app.get('/stream_chat')
async def stream_chat(param:str = "你好"):def generate():  # 我们假设query_engine已经构建完成response_stream = query_engine.query(param) for text in response_stream.response_gen:yield textreturn StreamingResponse(generate(), media_type='text/event-stream')  
if __name__ == '__main__':uvicorn.run(app, host='0.0.0.0', port=5000)

可以看到在jupyter的格子中运行的代码与在py文件中运行的代码的区别仅仅在于if __name__ == '__main__':之后的代码。这是因为Jupyter是一个交互式的环境,它会在每个单元格中运行代码,而不是在一个独立的程序中运行。因此,当我们在Jupyter中运行一个程序时,它会在一个新的进程中运行,而不是在当前进程中运行。这就是为什么我们在Jupyter中运行的代码需要在if __name__ == '__main__':之后的代码中用uvicorn.Server启动服务器。而在py文件中运行的代码则不需要。

我们甚至可以直接在浏览器地址栏里输入:
http://127.0.0.1:5000/stream_chat?param=你是谁?
然后浏览器页面就会出现流式输出。

我们也可以把它封装到一个js函数中

async function fetchStream(param) {  const url = `http://127.0.0.1:5000/stream_chat?param=${encodeURIComponent(param)}`;const response = await fetch(url);  const reader = response.body.getReader();  while (true) {  const { value, done } = await reader.read();  if (done) {  // 如果没有更多的数据可读,退出循环 statusvue.isTalking=false;  break; }  // 处理接收到的数据  const text = new TextDecoder("utf-8").decode(value);  console.log(text)}  
} 

然后我们就可以在想要用到地地方调用这个fetchStream函数了。这个函数需要一个参数,是字符串形式的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/ops/168003.html

相关文章

【USTC 计算机网络】第二章:应用层 - TCP UDP 套接字编程

本文详细介绍了 TCP 与 UDP 套接字编程,并在 Windows 下使用 C 实现套接字编程,对代码做了十分精细的讲解,这部分内容非常重要,是计算机网络学到目前为止第一次编程,也是网络编程开发中最基础的一个部分,必…

遇到一个奇怪问题,页面请求不到后端

背景 页面有两个请求,第一个接口获取令牌,第二个接口根据令牌去获取数据, 突然发现获取数据接口校验令牌的时候一直报错 而且报错的时候服务器没有获取令牌请求 而且发现偶尔是正常的,正常的发现服务器ip和异常的不一样,同事定位可能是域名解析问题 解决 最后定位是腾讯cdn解…

Rust 生命周期

Rust 生命周期 概述 Rust 语言以其内存安全性、并发和性能著称,其生命周期(Lifetimes)是其核心特性之一。生命周期机制允许 Rust 在编译时确保内存安全,同时提供极大的灵活性。本文将深入探讨 Rust 生命周期的概念、用法以及在实际编程中的应用。 生命周期概念 在 Rust…

JAVA泛型的作用

‌1. 类型安全(Type Safety)‌ 在泛型出现之前,集合类(如 ArrayList、HashMap)只能存储 Object 类型元素,导致以下问题: ‌问题‌:从集合中取出元素时,需手动强制类型转…

【负载均衡系列】Nginx

1. 工作原理 ​事件驱动模型: 基于异步非阻塞 I/O(如 Linux 的 epoll、BSD 的 kqueue),高效处理高并发连接。单线程可处理数千并发请求,避免传统多线程模型的资源竞争问题。​多进程架构: ​主进程(Master)​:管理配置加载、热升级、工作进程启停。​工作进程(Worker…

2维压缩感知SL0重构实现算法

压缩感知:2维压缩感知SL0重构算法,涉及两个测量矩阵,两个方向进行。 列表 SL0_2D_2/Lena.bmp , 66616 SL0_2D_2/SL0_2D.m , 778 SL0_2D_2/SL0_2D_Test.m , 601

【云上CPU玩转AIGC】——腾讯云高性能应用服务HAI已支持DeepSeek-R1模型预装环境和CPU算力

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大三学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL&#xff0…

【Linux网络】手动部署并测试内网穿透

📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…