手写效果流式响应(langchain+fastapi+js)

这是一个前后端完整可用的小项目

后端是 Python 的 FastAPI 框架,调用 langchain 进行 openai 的模型对话。前端是纯html css javascript,没调用任何第三方库,方便集成到 Vue React 等现有前端项目。

聊天界面:

效果就是提问之后, AI 的回答是一个一个字打印出来的效果。

开始讲解

一、html css 就不讲了,具体看项目代码。讲讲核心的 javascript 代码:

复制代码
let server_url = 'http://192.168.56.105:8008'

/***
 * http请求(流式响应处理)
 * @param url
 * @param data
 * @param func
 * @returns {Promise<void>}
 */
async function readChatbotReply(url,data={},func) {
    const response = await fetch(server_url+url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json;charset=UTF-8',
        },
        timeout:15000,
        body: JSON.stringify(data)
    });

  const readableStream = response.body;
  if (readableStream) {
    const reader = readableStream.getReader();
    let first = true
    while (true) {
      const { value, done } = await reader.read();
      if (done) {
        break;
      }

      const chunkValue = new TextDecoder().decode(value);
      // 流式返回的信息,在这里处理您的业务
      func(first,chunkValue)
      first = false
    }
    // Stream fully consumed
    reader.releaseLock();
  }
}

1 使用 fetch 进行 http 请求,javascript 自带。

2 请求后端接口,响应数据在response.body里,后端会一两个字一两个字持续不断的推送过来

3 我们在循环里获取数据:await reader.read();,然后调用传入的第三个参数(回调函数)处理消息打字的展示效果。

二、后端 python 核心代码

复制代码
@app.post("/chat")
async def chat(req_model: request_model.Chat):
    callback = AsyncIteratorCallbackHandler()
    llm = ChatOpenAI(streaming=True, callbacks=[callback], temperature=0)
    messages = [HumanMessage(content=req_model.content)]
    return StreamingResponse(generate_stream_response(callback, llm, messages), media_type="text/event-stream")


async def generate_stream_response(_callback, llm: ChatOpenAI, messages: list[BaseMessage]):
    """流式响应"""
    task = asyncio.create_task(llm.apredict_messages(messages))
    async for token in _callback.aiter():
        yield token

    await task

1 def generate_stream_response 是接收流式数据的方法。

2 def chat 是接口,前端可访问。先利用 langchain 框架调用 openai 接口进行对话,最后使用 StreamingResponse 流式响应类返回,里面传入流式处理的过程,也就是上面的generate_stream_response类。

三、前端不用部署

最开心的是前端不用部署,直接双击 index.html 文件打开即可使用。

后记:

1 全开源

2 github 地址:https://github.com/goophps/fastapi-streaming.git

3 前后端完整的所有代码、启动使用说明,项目里都有写。

4 本项目代码全部来自成熟商业项目,希望大家捧场:chatus.co

相关推荐
橙某人2 小时前
LogicFlow 小地图性能优化:从「实时克隆」到「占位缩略块」!🚀
前端·javascript·vue.js
boooooooom3 小时前
讲清 Proxy + effect + track/trigger 流程
javascript·vue.js·面试
leafyyuki3 小时前
在 Vue 项目中玩转 FullCalendar:从零搭建可交互的事件日历
前端·javascript·vue.js
豆苗学前端3 小时前
彻底讲透浏览器缓存机制,吊打面试官
前端·javascript·面试
swipe3 小时前
箭头函数与 this 面试题深度解析:从原理到实战
前端·javascript·面试
进击的尘埃5 小时前
拖拽搭建场景下的智能布局算法:栅格吸附、参考线与响应式出码
javascript
小猪努力学前端5 小时前
基于PixiJS的试玩广告开发-续篇
前端·javascript·游戏
wuhen_n6 小时前
v-model 的进阶用法:搞定复杂的父子组件数据通信
前端·javascript·vue.js
wuhen_n6 小时前
TypeScript 深度加持:让你的组合式函数拥有“钢筋铁骨”
前端·javascript·vue.js
滕青山6 小时前
基于 ZXing 的 Vue 在线二维码扫描器实现
前端·javascript·vue.js