AI技术栈 —— 流式输出

AI技术栈 —— 流式输出

一、Python实现代码

Server-Sent Events(SSE)技术是实现流式输出功能的核心

import json
import time
from typing import List

from fastapi import FastAPI
from pydantic import BaseModel, Field
from sse_starlette import EventSourceResponse, ServerSentEvent
from fastapi.middleware.cors import CORSMiddleware


class DialogStateResponse:
    def __init__(self, message_type, content):
        self.message_type = message_type
        self.content = content

    def to_json(self, text_test=""):
        tp = time.time()
        time_str = time.strftime("%H:%M:%S", time.localtime(tp))
        return {"text": text_test, "create_time": time_str, "message_type": self.message_type, "content": self.content}


app = FastAPI()
# 添加以下配置

app.add_middleware(
    CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], expose_headers=["*"]  # 生产环境应指定具体域名  # 新增:暴露所有响应头
)

import asyncio

class AgentDtoModel(BaseModel):
	query: str

async def content_generator():
    for i in range(10):
        str_i = str(i) + "_"
        sse = ServerSentEvent(
            event="Chat",
            data=f"{json.dumps({'choices': [{'delta': {'content': DialogStateResponse(message_type='content', content=str_i).to_json()}}]}, ensure_ascii=False)}\n\n",
        )
        yield sse
        await asyncio.sleep(1)  # 使用异步sleep


@app.post("/stream_output")
async def stream_output(agent_dto_model: AgentDtoModel):
    return EventSourceResponse(content=content_generator())


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=11100)

<!DOCTYPE html>
<html>
  <head>
    <title>POST流式测试</title>
  </head>
  <body>
    <button onclick="startPostStream()">开始POST流式请求</button>
    <div id="output" style="white-space: pre-wrap"></div>

    <script>
      async function startPostStream() {
        const output = document.getElementById("output");
        output.innerHTML = "";

        const response = await fetch(
          "http://192.168.10.101:11100/stream_output",
          {
            method: "POST",
            mode: "cors", // 显式声明CORS模式
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              query: "None",
            }),
          }
        );

        const reader = response.body
          .pipeThrough(new TextDecoderStream())
          .getReader();

        while (true) {
          const { value, done } = await reader.read();
          if (done) break;

          // 修复事件解析逻辑
          value.split("\n\n").forEach((eventData) => {
            if (!eventData.trim()) return;

            let jsonStr = "";
            eventData.split("\n").forEach((line) => {
              if (line.startsWith("data: ")) {
                jsonStr += line.slice(6); // 提取data字段内容
              }
            });

            try {
              const data = JSON.parse(jsonStr);
              console.log(data);
              output.innerHTML += `${data.choices[0].delta.content.content}`;
            } catch (e) {
              console.error("解析错误:", jsonStr, e);
            }
          });
        }
      }
    </script>
  </body>
</html>

参考文章或视频链接
[1] 《实用技巧:大模型的流式输出在 OpenAI 和 LangChain 中的使用》—— 阿里云
[2] 《ChatGPT流式输出实现原理》—— 优快云
[3] 《ChatGPT流式输出原理揭秘》—— 掘金
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值