第一阶段:前端发起批量请求与建立通道
- 任务打包与提交
前端用户准备好一个包含多个生成提升(prompts)的列表。前端将这些提示打包成一个任务数组,每个任务都有自己的唯一ID(如task_1)、提示内容(prompt)和参数(如生成长度)。前端通过一次普通的HTTP POST请求将这个批量任务提交到后端。
- 后端创建任务会话
后端收到这个批量请求后,进行验证。验证通过后,后端会立即生成一个唯一的本次批量处理会话ID(sessionId),并将sessionId和“任务已接受”的状态返回给前端此时,铍铜的HTTP请求交互结束,真正的流式交互即将开始。
- 前端建立SSE长连接
前端拿到返回的sessionId后,使用H5的EventSourseAPI,以这个sessionId为参数,向后端专门的SSE流端点发起一个长连接请求。这个连接一旦建立,就会一直保持打开状态,直到所有任务完成或发生错误,后端可以随时通过这个连接向前端“推送”数据。
第二阶段:后端并行处理与流式推送
- 后端启动并行处理引擎
后端在返回初始响应后,几乎同时开始处理任务队列。它会根据系统资源(如并发数限制),从队列中取出多个任务,同时调用大模型API。这里的“调用”是关键后端要求大模型以“流式”模式(stream=True)进行生成。这意味着模型步是一次性返回完整文本,而是像挤牙膏一样,一个字一个字(或一个token一个token)地返回。
- 推送整体进度与任务开始事件
在处理过程中,只要有任务状态变化,后端就通过已建立的SSE连接向前端推送事件。首先,它会推送“进度更新”事件,告诉前端当前已完成、处理中、待处理的任务数量和各任务状态。当一个任务开始生成第一个字时,后端会推送一个“任务开始”事件,并携带该任务ID。
- 流式推送单个任务的生成结果
对于每个开启流式生成的任务,后端会实时接收到大模型返回的文本片段。后端不会等这个任务的全部文本生成完,而是立即将这个刚出来的文本片段,通过SSE连接,以一个“任务数据”事件(如 event: task_chunk)推送给前端。推送的数据包中会包含任务ID和刚生成的一小段文本(chunk)。
- 标记单个任务完成
当大模型返回某个任务的结束标志(如 [DONE]或 finish_reason)时,表示该任务已全部生成完毕。后端会向SSE连接推送一个“任务完成”事件,并携带该任务的最终完整内容(或只是完成标志)。同时,更新整体进度。
- 处理任务中的错误
如果某个任务在生成过程中失败(如模型调用超时、内容过滤),后端会推送一个“任务错误”事件,包含错误的任务ID和原因,并确保其他独立的任务能继续正常运行。
第三阶段:前端实时接收与展示
- 监听并处理不同类型的事件
前端通过EventSource的onmessage或addEeventListener方法,监听后端推送的不同事件, 收到progress(进度)事件时,更新页面上的总进度条和任务状态列表。 收到task_chunk(数据块)事件时,根据数据包里的任务ID,找到页面对应的展示区域(如某个div),并将文本片段(chunk)追加进去。这样就实现了每个任务文本的“逐字打印”效果。 收到task_done(任务完成)事件时,标记该任务区域为完成状态,并停止其动画。 2. 会话完成与连接关闭
前端持续监听。当它收到一个特殊的complete(完全完成)事件,代表后端所有任务(无论成功或失败)都均处理完毕,前端会在界面上展示“批量生成完成”的总结信息,然后主动调用 eventSource.close()方法,优雅地关闭SSE长连接。
4. 连接异常处理(贯穿全程)
在整个过程中,前端会监听SSE连接的 onerror事件。如果连接意外中断(如网络波动),前端会尝试进行重连,并在重连请求中携带之前的 sessionId。一个设计良好的后端应能根据 sessionId恢复会话上下文,并继续推送未完成的任务结果,实现断线续传。
核心流程总结
- 前端一次HTTP POST提交所有任务,获得一个“流门票”(sessionId)
- 前端凭门票建立SSE长连接,等待接收“实时广播“。
- 后端同时处理多个任务,并要求大模型以”流式“输出。
- 后端成为”直播中转站“,将各个任务流式生成出的文字碎片,实时、有序地通过SSE连接”直播“给前端。
- 前端”切换频道“,根据事件类型将文字碎片拼接到对应任务的展示区,实现所有任务进度和内容的实时、并行、可视化更新。
- 任务全部完成后,直播结束,前后端关闭连接。