使用Declarai、FastAPI和Streamlit构建LLM聊天应用程序 — 第2部分 🚀

使用Declarai、FastAPI和Streamlit构建LLM聊天应用程序 — 第2部分 🚀

聊天截图 | 作者拍摄 | 版权所有

在我们之前的VoAGI文章(链接🔗)受到热烈欢迎后,我们采纳了你们的反馈意见。这篇第二部分介绍了更高级的功能,特别强调了聊天应用的流媒体功能。

许多读者表达了对聊天中的流媒体功能的渴望。在处理复杂的回复时,流媒体变得至关重要。流媒体允许在生成回复时即时发送,而不是让用户等待整个回复。这确保用户可以在从Web服务器分发后立即访问回复。

由于Declarai最近的增强功能,我们很高兴能够利用流媒体功能,该功能从版本0.1.10开始可用🎉。

流媒体演示 📹

流媒体视频 | 作者记录 | 版权所有

正如演示的,流媒体提供了更高的响应性,并已成为最近人工智能聊天应用的标准。你渴望了解我们是如何实现这一点的吗?让我们深入代码:

Declarai 💻

为了使用流媒体功能,请确保通过传递streaming=True来声明启用聊天机器人。

import declaraigpt_35 = declarai.openai(model="gpt-3.5-turbo")@gpt_35.experimental.chat(streaming=True)class StreamingSQLChat:    """    你是一个SQL助手。你正在帮助用户编写SQL查询。你应该首先知道用户想要使用什么SQL语法,可以是mysql、postgresql、sqllite等。如果用户说的与SQL完全无关,你应该说“我不明白。我在这里帮助你编写SQL查询。”在提供给用户查询后,你应该询问用户是否还需要其他帮助。    """    greeting = "嗨亲爱的SQL用户。希望你今天过得很好。我在这里帮助你编写SQL查询。让我们开始吧!你想使用什么SQL语法?可以是mysql、postgresql、sqllite等。"

与聊天机器人使用流媒体进行交互时:

chat = StreamingSQLChat()res = chat.send("我想使用mysql")for chunk in res:    print(chunk.response)>>> 很好>>> 很好!>>> 很好!MySQL>>> 很好!MySQL是>>> 很好!MySQL是一个>>> 很好!MySQL是一个受欢迎的>>> 很好!MySQL是一个受欢迎的选择>>> 很好!MySQL是一个受欢迎的选择用于>>> 很好!MySQL是一个受欢迎的选择用于SQL>>> 很好!MySQL是一个受欢迎的选择用于SQL语法>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助你>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助你与>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助你与你的>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助你与你的MySQL>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助你与你的MySQL查询>>> 很好!MySQL是一个受欢迎的选择用于SQL语法。怎么能帮助你与你的MySQL查询?

发生了什么事情?通过启用流式传输,OpenAI返回一个生成器,它逐个生成项目,并且只在需要时才生成。因此,只要OpenAI有一个新的块可用,它就会立即处理。

FastAPI 🛠️

为了实现流式传输的能力,我们引入了一个独立的REST端点。该端点会发送一个StreamingResponse,它本质上是一个生成器,其中每个块都是包含块详细信息的JSON。必须指定media_type="text/event-stream",表示响应类型是流。

@router.post("/chat/submit/{chat_id}/streaming")def submit_chat_streaming(chat_id: str, request: str):    chat = StreamingSQLChat(chat_history=FileMessageHistory(file_path=chat_id))    response = chat.send(request)    def stream():        for llm_response in response:            # 将LLMResponse转换为JSON字符串            data = json.dumps(jsonable_encoder(llm_response))            yield data + "\n"  # 以换行分隔的JSON字符串    return StreamingResponse(stream(), media_type="text/event-stream")

Streamlit应用

在前端,我们的目标是在收到每个新的响应块时将其显示给用户。这需要访问响应的每个块之间的差异。

实现方法如下:

  1. 使用stream=True发送HTTP POST请求。
  2. 迭代每个块并解码其JSON。
  3. 提取delta值并将其添加到完整的响应中。这基本上是新生成的值。
  4. 使用累积的响应更新UI。
res = requests.post(f"{BACKEND_URL}/api/v1/chat/submit/{session_name}/streaming",                  params={"request": prompt},                  stream=True)with st.chat_message("assistant"):  message_placeholder = st.empty()  full_response = ""  buffer = ""  for chunk in res:      decoded_chunk = chunk.decode('utf-8')      buffer += decoded_chunk      while "\n" in buffer:          line, buffer = buffer.split("\n", 1)          parsed_chunk = json.loads(line.strip())          try:              full_response += parsed_chunk["raw_response"]["choices"][0]["delta"]["content"]              message_placeholder.markdown(full_response + "▌")          except KeyError:              pass  message_placeholder.markdown(full_response)

准备部署您的流式聊天机器人 🤖?请查看此存储库中的完整代码 —

GitHub – matankley/declarai-chat-fastapi-streamlit:使用declarai构建聊天机器人的示例…

使用declarai构建聊天机器人的示例,以便与语言模型进行交互,fastapi作为后端服务器…

github.com

保持与Declarai的发展联系 💌。通过 Linkedin 页面与我们联系,并在 GitHub 上为我们的工具点赞 ⭐️,如果您觉得它们有价值!

您还可以通过阅读我们的文档 📖 深入了解Declarai的功能。

流式传输 — Declarai

一些LLM提供商支持LLM响应的流式传输。当您希望尽快获取结果时,这非常有用…

declarai.com