利用 SSE 实现流式 AI 聊天交互(三)
在 AI 赋能的时代,即时交互式对话体验成为众多应用的核心功能之一。本文将介绍如何使用 流式 SSE (Server-Sent Events) 技术,实现高效的 AI 聊天交互,提供更加丝滑的用户体验。
一、SSE 介绍
SSE (Server-Sent Events) 是一种基于 HTTP 的服务器推送技术,适用于需要实时更新但数据流量较小的场景,例如 AI 对话、股票行情、新闻推送等。它的主要特点包括:
单向通信:服务器可以主动向客户端推送消息,而客户端仅能接收。
轻量级:相比 WebSocket,SSE 使用 HTTP 连接,无需额外协议支持。
自动重连:连接断开时,浏览器会自动尝试重新建立连接。
相比 WebSocket,SSE 更适合 AI 聊天等对实时性要求较高但数据方向单一的场景。
二、实现思路
传统的 AI 聊天一般是用户发送请求后,后端计算完成后一次性返回结果。但对于长文本生成,这种方式可能导致较长的响应延迟。
相比之下,流式响应 (Streaming) 可以让 AI 逐步输出生成内容,从而提升用户体验。
我们的实现基于 Odoo 18 + OpenAI API,通过 SSE (Server-Sent Events) 让前端实时接收 AI 生成的内容,达到流畅的交互效果。
三、后端实现
在 Odoo 的 @http.route 中,我们定义了一个流式接口,负责与 AI 进行通信,并通过 SSE 将生成内容逐步推送到前端。
后端代码:请求 AI 生成内容
@http.route('/ai/stream_chat', type='http', auth='public', cors='*')
def ai_stream_chat(self, **kwargs):
user_id = request.session.uid
user_message = kwargs.get('user_message')
file_content = kwargs.get('file_content', '')
api_url = request.env['ir.config_parameter'].sudo().get_param('ai_chat_url')
api_key = request.env['ir.config_parameter'].sudo().get_param('ai_chat_api_key')
ai_model = request.env['ir.config_parameter'].sudo().get_param('ai_chat_model')
# 初始化 OpenAI 客户端
client = OpenAI(base_url=api_url, api_key=api_key)
messages = [
{"role": "system", "content": "我是一个AI助手,我的名字叫小加!"},
{"role": "user", "content": file_content[:5000]},
{"role": "user", "content": user_message}
]
def event_stream():
try:
completion = client.chat.completions.create(
model=ai_model,
messages=messages,
stream=True,
extra_headers={
"HTTP-Referer": "DeepSeek R1",
"X-Title": "Odoo AIChat"
}
)
response_text = ""
for chunk in completion:
delta = chunk.choices[0].delta
if delta and delta.content:
response_text += delta.content
yield f"data: {chunk.model_dump_json()}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
yield f"data: {{\"error\": \"{str(e)}\"}}\n\n"
return Response(event_stream(), content_type='text/event-stream')
实现细节:
参数获取:前端传递
user_message和file_content。AI 请求:使用 OpenAI API 发起流式请求。
SSE 事件流:遍历 AI 生成结果并逐步推送。
异常处理:防止请求失败导致 SSE 断开。
四、前端实现
前端使用 EventSource 监听 SSE 事件流,逐步渲染 AI 回复内容。
前端代码:接收 AI 数据并实时渲染
function startAIStream(userMessage, fileContent, base64File, fileName) {
const chatBox = document.getElementById('chat-box');
const botMessageDiv = document.createElement('div');
botMessageDiv.classList.add('message', 'bot');
botMessageDiv.innerHTML = `
<img src="./image/icon1.gif" alt="Bot">
<span id="bot-response">AI 正在思考...</span>
<span id="bot-time" style="font-size: 10px; color: #888; margin-left: 10px;"></span>`;
chatBox.appendChild(botMessageDiv);
chatBox.scrollTop = chatBox.scrollHeight;
const botResponseSpan = botMessageDiv.querySelector("#bot-response");
const botTimeSpan = botMessageDiv.querySelector("#bot-time");
const params = new URLSearchParams({
user_message: userMessage,
file_content: fileContent
});
const eventSource = new EventSource(`/ai/stream_chat?${params.toString()}`);
let fullBotMessage = "";
botResponseSpan.innerText = "";
eventSource.onmessage = function (event) {
if (event.data === "[DONE]") {
eventSource.close();
botTimeSpan.innerText = new Date().toLocaleTimeString();
createHistoryRecord(userMessage, fullBotMessage, base64File, fileName);
return;
}
try {
const jsonData = JSON.parse(event.data);
const deltaContent = jsonData.choices[0]?.delta?.content;
if (deltaContent) {
fullBotMessage += deltaContent;
requestAnimationFrame(() => {
botResponseSpan.innerHTML = marked.parse(fullBotMessage);
chatBox.scrollTop = chatBox.scrollHeight;
});
}
} catch (e) {
console.error("解析数据出错:", e);
}
};
eventSource.onerror = function (err) {
console.error("SSE 连接错误:", err);
eventSource.close();
botResponseSpan.innerText += "\n[连接已断开]";
};
}
五、效果展示
当用户发送消息后,前端立即显示 AI 正在思考...,随后 AI 逐步返回内容,并以 Markdown 解析进行美化。如下图所示:

六、项目特点
流式传输:AI 逐步生成内容,提升用户体验。
轻量级实现:基于 SSE,避免复杂的 WebSocket 连接管理。
Markdown 支持:使用
marked.js美化 AI 回复。自动重连:确保长时间使用时连接稳定。
如果你也在开发 AI 聊天功能,不妨尝试这种流式优化方案!
利用 SSE 实现流式 AI 聊天交互(三)的更多相关文章
- Android之利用HTTP网络通信实现与PHP的交互(三)
Android与PHP的交互是通过Http网络编程来实现的,利用php访问数据库,并且操作数据库中的数据,利用php作为接口,使Android连接数据库. 一般情况下,我们使用Json格式进行传输,利 ...
- 流式大数据处理的三种框架:Storm,Spark和Samza
许多分布式计算系统都可以实时或接近实时地处理大数据流.本文将对三种Apache框架分别进行简单介绍,然后尝试快速.高度概述其异同. Apache Storm 在Storm中,先要设计一个用于实时计算的 ...
- [转载]流式大数据处理的三种框架:Storm,Spark和Samza
许多分布式计算系统都可以实时或接近实时地处理大数据流.本文将对三种Apache框架分别进行简单介绍,然后尝试快速.高度概述其异同. Apache Storm 在Storm中,先要设计一个用于实时计算的 ...
- Java8 新特性之流式数据处理
一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现.比如我们希望对一个包含整数的 ...
- Apple公司Darwin流式服务器源代码分析
当前,伴随着Internet的飞速发展,计算机网络已经进入到每一个普通人的家庭.在这个过程中,一个值得我们关注的现象是:Internet中存储和传输内容的构成已经发生了本质的改变,从传统的基于文本或少 ...
- Java8 新特性之流式数据处理(转)
转自:https://www.cnblogs.com/shenlanzhizun/p/6027042.html 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作 ...
- java1.8新特性之stream流式算法
在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: List& ...
- Java1.8新特性 - Stream流式算法
一. 流式处理简介 在我接触到java8流式数据处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现.比如我们希望对一个包 ...
- Java8 中的流式数据处理
java8的流式处理极大了简化我们对于集合.数组等结构的操作,让我们可以以函数式的思想去操作,本篇文章将探讨java8的流式数据处理的基本使用. 一. 流式处理简介 在我接触到java8流式处理的时候 ...
- JDK8新特性(二) 流式编程Stream
流式编程是1.8中的新特性,基于常用的四种函数式接口以及Lambda表达式对集合类数据进行类似流水线一般的操作 流式编程分为大概三个步骤:获取流 → 操作流 → 返回操作结果 流的获取方式 这里先了解 ...
随机推荐
- 2024.11.12随笔&联考总结
前言 心情不好,因为考试时 T2T3 全看错题了,导致 T2 没做出来,T3 一份没得.然后下午打球眼镜架子坏了,回机房才发现被高二的盒了. 但还是稍微写一下总结吧. 总结 感觉我今天做题状态还行,思 ...
- 记录:tinyrenderer---1.2 Rasterizing the boundary
光栅化三角形 Scanline rendering(扫描线渲染),一个老式的算法 按y轴坐标进行排序,我这里采取降序,ay > by > cy 同时光栅化三角形的左右两边 绘制水平线段,连 ...
- Ubuntu 卸载安装nginx
nginx很顽强,单独的删除它的文件是不够的,这会导致你再次安装时出现一系列的问题. 1.卸载nginx,及其配置文件 sudo apt-get --purge remove nginx 2.自动全部 ...
- g2o优化库实现曲线拟合
g2o优化库实现曲线拟合 最近学习了一下g2o优化库的基本使用,尝试着自己写了一个曲线拟合的函数,也就是下面这个多项式函数: \[y = ax^3 + bx^2 + cx + d \] 我们以 \(a ...
- 学习Django【1】模型
编辑 models.py 文件,改变模型. 运行 python manage.py makemigrations 为模型的改变生成迁移文件. 运行 python manage.py migrate 来 ...
- FastAPI与SQLAlchemy数据库集成与CRUD操作
title: FastAPI与SQLAlchemy数据库集成与CRUD操作 date: 2025/04/16 09:50:57 updated: 2025/04/16 09:50:57 author: ...
- selenium IDE简单使用
selenium IDE可理解为录制操作浏览器的过程,然后回放实现UI级的自动化 一,首先安装,本案例主要在谷歌浏览器上使用,所以用的是支持谷歌的IDE文件 下载,打开https://www.crx4 ...
- MaxKB 开启模型联网搜索
前言 模型联网搜索是当前大语言模型(LLM)领域的重要技术方向,其核心在于通过结合互联网实时数据与模型推理能力,突破预训练数据的时间限制,提供更精准.动态的回答. 核心应用场景 实时信息补充 例如查询 ...
- live555开发笔记(二):live555创建RTSP服务器源码剖析,创建rtsp服务器的基本流程总结
前言 基于Live555的流媒体服务器方案源码剖析,了解基本的代码搭建步骤. Demo 关于.h264与.265 没深入研究,但是h264的后缀名.264替换为.h264文件, ...
- 适用于LixtBox的,开启UI虚拟化时,某些时候需要定位到还没加载的项,比如自动选中某项,视图自动移过去等等
1 /// <summary> 2 /// 将指定父级的下级索引元素,显示在视野下,使其可见 3 /// </summary> 4 /// <param name=&qu ...