这是一个前后端完整可用的小项目
后端是 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 = truewhile (true) {const { value, done } = await reader.read();if (done) {break;}const chunkValue = new TextDecoder().decode(value);// 流式返回的信息,在这里处理您的业务func(first,chunkValue)first = false}// Stream fully consumedreader.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 tokenawait 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