概述
默认情况下,Chainlit 应用不会保留其生成的聊天和元素。即网页一刷新,所有的聊天记录,页面上的所有聊天记录都会消失。但是,存储和利用这些数据的能力可能是您的项目或组织的重要组成部分。
之前讲到通过Literal AI可以一分钟快速实现聊天记录数据持久化《Chainlit快速实现AI对话应用1 分钟内实现聊天数据的持久化保存》,但是Literal AI在国内无法正常访问,所以还需自定义聊天数据到本地,才能方便国内使用。
教程
- 安装chainlit依赖
pip install chainlit
- 配置环境变量
在项目根目录下,创建.env
文件,内容如下:
OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
OPENAI_API_KEY="your api_key"
- 由于国内无法访问
open ai
的chatgpt
,所以需要配置OPENAI_BASE_URL
的代理地址,如果使用国内的LLM
大模型接口,可以使用兼容open ai
的接口地址
- 创建代码
在项目根目录下,创建一个app.py
的文件,代码如下:
import uuid
from typing import Dict, List, Optional
import chainlit.data as cl_data
from chainlit.step import StepDict
from literalai.helper import utc_now
from openai import AsyncOpenAI
import chainlit as cl
client = AsyncOpenAI()
now = utc_now()
thread_history = [] # type: List[cl_data.ThreadDict]
deleted_thread_ids = [] # type: List[str]
class CustomDataLayer(cl_data.BaseDataLayer):
async def get_user(self, identifier: str):
return cl.PersistedUser(id="",createdAt=now, identifier=identifier)
async def create_user(self, user: cl.User):
return cl.PersistedUser(id="",createdAt=now, identifier=user.identifier)
async def update_thread(
self,
thread_id: str,
name: Optional[str] = None,
user_id: Optional[str] = None,
metadata: Optional[Dict] = None,
tags: Optional[List[str]] = None,
):
thread = next((t for t in thread_history if t["id"] == thread_id), None)
print('name', name)
print('thread', thread)
print('user_id', user_id)
print('metadata', metadata)
if thread:
if name:
thread["name"] = name
if user_id:
thread["user_id"] = user_id
if metadata:
thread["metadata"] = metadata
if tags:
thread["tags"] = tags
else:
thread_history.append(
{
"id": thread_id,
"name": name,
"metadata": metadata,
"tags": tags,
"createdAt": utc_now(),
"userId": user_id,
"userIdentifier": user_id,
"steps": [],
}
)
@cl_data.queue_until_user_message()
async def create_step(self, step_dict: StepDict):
thread = next(
(t for t in thread_history if t["id"] == step_dict.get("threadId")), None
)
if thread:
thread["steps"].append(step_dict)
@cl_data.queue_until_user_message()
async def update_step(self, step_dict: "StepDict"):
await self.create_step(step_dict)
async def get_thread_author(self, thread_id: str) -> str:
thread = next(
(t for t in thread_history if t["id"] == thread_id), None
)
if not thread:
return ""
user_identifier = thread.get("userIdentifier")
if not user_identifier:
return ""
return user_identifier
async def list_threads(
self, pagination: cl_data.Pagination, filters: cl_data.ThreadFilter
) -> cl_data.PaginatedResponse[cl_data.ThreadDict]:
return cl_data.PaginatedResponse(
data=[t for t in thread_history if t["id"] not in deleted_thread_ids],
pageInfo=cl_data.PageInfo(
hasNextPage=False, startCursor=None, endCursor=None
),
)
async def get_thread(self, thread_id: str):
thread = next((t for t in thread_history if t["id"] == thread_id), None)
if not thread:
return None
thread["steps"] = sorted(thread["steps"], key=lambda x: x["createdAt"])
return thread
async def delete_thread(self, thread_id: str):
deleted_thread_ids.append(thread_id)
cl_data._data_layer = CustomDataLayer()
@cl.on_chat_start
async def main():
content = "你好,我是泰山AI智能客服,有什么可以帮助您吗?"
await cl.Message(content).send()
@cl.on_message
async def handle_message():
# Wait for queue to be flushed
await cl.sleep(1)
msg = cl.Message(content="")
await msg.send()
stream = await client.chat.completions.create(
model="qwen-turbo", messages=cl.chat_context.to_openai(), stream=True
)
async for part in stream:
if token := part.choices[0].delta.content or "":
await msg.stream_token(token)
await msg.update()
@cl.password_auth_callback
def auth_callback(username: str, password: str) -> Optional[cl.User]:
if (username, password) == ("admin", "admin"):
return cl.User(identifier="admin")
else:
return cl.User(identifier=uuid.uuid4().hex)
@cl.on_chat_resume
async def on_chat_resume():
pass
- 执行命令创建
AUTH_SECRET
鉴权
chainlit create-secret
复制最后一行代码到.env
环境配置文件中
CHAINLIT_AUTH_SECRET="$b?/v0NeJlAU~I5As1WSCa,j8wJ3w%agTyIFlUt4408?mfC*,/wovlfA%3O/751U"
OPENAI_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
OPENAI_API_KEY=""
- 执行服务启动命令
chainlit run app.py -w
- 启动后效果展示
- 现在聊天记录都被保存在服务的内存中了,只要不重启服务,聊天记录就不会丢失,下一节我在将如何将聊天记录持久化保存在数据库中
相关文章推荐
《使用 Xinference 部署本地模型》
《Fastgpt接入Whisper本地模型实现语音输入》
《Fastgpt部署和接入使用重排模型bge-reranker》
《Fastgpt部署接入 M3E和chatglm2-m3e文本向量模型》
《Fastgpt 无法启动或启动后无法正常使用的讨论(启动失败、用户未注册等问题这里)》
《vllm推理服务兼容openai服务API》
《vLLM模型推理引擎参数大全》
《解决vllm推理框架内在开启多显卡时报错问题》
《Ollama 在本地快速部署大型语言模型,可进行定制并创建属于您自己的模型》