Nanbeige4.1-3B实战教程vLLM API封装为REST服务Chainlit对接调用1. 开篇为什么需要这个组合如果你正在寻找一个既强大又轻量的开源大模型并且希望它能像ChatGPT一样通过一个漂亮的网页界面来对话那么你来对地方了。Nanbeige4.1-3B是一个仅有30亿参数的小模型但它在推理、对话和智能体任务上的表现却相当出色。不过模型本身只是一个“大脑”我们需要为它搭建一个“身体”和“嘴巴”——也就是部署服务和交互界面。本教程要做的就是手把手教你完成这两件事搭建服务身体使用vLLM这个高性能推理引擎将Nanbeige4.1-3B模型封装成一个标准的REST API服务。这样任何程序都可以通过HTTP请求来调用它。创建界面嘴巴使用Chainlit这个专为AI应用设计的框架快速构建一个类似ChatGPT的Web聊天界面并让它去调用我们刚刚搭建好的API服务。学完这篇教程你将拥有一个完全由自己掌控的、私有部署的AI对话服务。无论是用于学习、开发还是内部工具都非常实用。我们开始吧2. 环境准备与模型部署确认在开始封装和对接之前我们需要确保模型已经通过vLLM成功部署。通常在云平台或服务器上这一步可能已经由镜像或脚本完成了。2.1 检查vLLM服务状态首先我们需要确认模型服务是否已经在运行。最直接的方法是查看服务的日志文件。打开终端或WebShell执行以下命令cat /root/workspace/llm.log如果部署成功你会在日志中看到类似下面的关键信息Uvicorn running on http://0.0.0.0:8000这表示vLLM的API服务已经启动并在8000端口监听。Loading model weights...和Model loaded successfully.这表示Nanbeige4.1-3B模型权重已成功加载。可能还会有关于GPU内存分配、模型路径等详细信息。看到这些恭喜你模型服务已经在后台跑起来了它现在就像一个“黑盒”服务等待我们通过HTTP请求来交互。2.2 理解vLLM提供的APIvLLM部署后会默认提供OpenAI兼容的API接口。这是我们后续封装的基础。主要用到两个端点聊天补全接口(/v1/chat/completions) 这是我们最常用的接口用于多轮对话。它接收一个包含对话历史的消息列表并返回模型的回复。# 示例请求结构 POST http://localhost:8000/v1/chat/completions { model: nanbeige-4.1-3b, messages: [ {role: user, content: 你好请介绍一下你自己。} ] }模型列表接口(/v1/models) 用于查询当前服务加载了哪些模型。我们的目标就是先确保这个服务是通的然后为它披上一层更易用或更定制化的“外衣”REST服务最后再用Chainlit做一个前端。3. 第一步封装vLLM API为定制化REST服务虽然vLLM的API已经是RESTful的但有时我们可能需要增加额外的逻辑如请求预处理、响应后处理、日志记录。简化参数隐藏一些底层细节。集成认证、限流等中间件。提供一个更符合内部规范的API格式。这里我们使用轻量级的FastAPI来创建一个中间层服务它接收请求然后去调用后端的vLLM服务最后将结果返回。3.1 创建FastAPI应用首先确保你的Python环境已安装必要库。如果没有请安装pip install fastapi uvicorn httpx pydantic然后创建一个名为api_server.py的文件# api_server.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional import httpx import logging # 设置日志 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) # 初始化FastAPI应用 app FastAPI(titleNanbeige4.1-3B API Server, version1.0) # 配置后端vLLM服务的地址 VLLM_SERVER_URL http://localhost:8000 # 根据你的vLLM服务地址修改 # 定义请求数据模型 class ChatMessage(BaseModel): role: str # “user” 或 “assistant” content: str class ChatRequest(BaseModel): messages: List[ChatMessage] model: Optional[str] nanbeige-4.1-3b # 默认模型名可与vLLM配置对应 max_tokens: Optional[int] 1024 temperature: Optional[float] 0.7 stream: Optional[bool] False # 我们先处理非流式响应 # 定义响应数据模型 class ChatResponse(BaseModel): message: ChatMessage model: str usage: dict app.get(/) async def root(): return {message: Nanbeige4.1-3B API Server is running!} app.get(/health) async def health_check(): 健康检查端点也可用于检查vLLM后端是否存活 try: async with httpx.AsyncClient() as client: resp await client.get(f{VLLM_SERVER_URL}/v1/models, timeout5.0) if resp.status_code 200: return {status: healthy, backend: vLLM is reachable} else: return {status: degraded, backend: fvLLM returned {resp.status_code}} except Exception as e: logger.error(fHealth check failed: {e}) raise HTTPException(status_code503, detailBackend vLLM service is unavailable) app.post(/v1/chat/completions, response_modelChatResponse) async def chat_completion(request: ChatRequest): 聊天补全接口。 接收前端请求转发至vLLM后端并返回格式化后的响应。 # 构造转发给vLLM的请求体 vllm_payload { model: request.model, messages: [msg.dict() for msg in request.messages], max_tokens: request.max_tokens, temperature: request.temperature, stream: request.stream } logger.info(fForwarding request to vLLM: {vllm_payload}) try: async with httpx.AsyncClient() as client: # 转发请求到vLLM服务 response await client.post( f{VLLM_SERVER_URL}/v1/chat/completions, jsonvllm_payload, timeout30.0 # 根据模型响应时间调整 ) response.raise_for_status() # 如果状态码不是2xx抛出异常 vllm_data response.json() except httpx.RequestError as e: logger.error(fRequest to vLLM failed: {e}) raise HTTPException(status_code502, detailfBackend service error: {e}) except httpx.HTTPStatusError as e: logger.error(fvLLM returned error status: {e.response.status_code}) raise HTTPException(status_codee.response.status_code, detaile.response.text) # 解析vLLM的响应并格式化为我们定义的响应模型 # 注意vLLM返回的choices是一个列表我们取第一个 choice vllm_data[choices][0] message choice[message] return ChatResponse( messageChatMessage(rolemessage[role], contentmessage[content]), modelvllm_data[model], usagevllm_data.get(usage, {}) ) if __name__ __main__: import uvicorn # 启动服务运行在8001端口避免与vLLM的8000端口冲突 uvicorn.run(app, host0.0.0.0, port8001)3.2 启动并测试封装后的API服务保存文件后在终端运行python api_server.py你应该看到输出提示服务在http://0.0.0.0:8001启动。现在我们可以测试这个新API。打开另一个终端使用curl或任何API测试工具如Postmancurl -X POST http://localhost:8001/v1/chat/completions \ -H Content-Type: application/json \ -d { messages: [ {role: user, content: 你好请用一句话介绍下你自己。} ] }如果一切正常你会收到一个JSON响应其中包含了Nanbeige4.1-3B模型的回复。我们的封装服务成功了4. 第二步使用Chainlit构建Web聊天前端Chainlit是一个超级好用的工具可以让你用很少的代码就做出功能丰富的AI聊天界面。现在我们要让Chainlit前端连接到我们刚刚搭建的api_server。4.1 创建Chainlit应用首先安装Chainlitpip install chainlit然后创建一个名为chainlit_app.py的文件。同时Chainlit需要一个配置文件chainlit.md来定义应用说明。创建chainlit.md(可选但推荐)# Welcome to Nanbeige4.1-3B Chatbot! This is a chatbot powered by the Nanbeige4.1-3B model, served via a custom API. You can start chatting right away!创建chainlit_app.py# chainlit_app.py import chainlit as cl import httpx import json from typing import List, Dict # 配置我们自建的API服务器地址 API_SERVER_URL http://localhost:8001 # 指向我们刚才启动的FastAPI服务 cl.on_chat_start async def start_chat(): 会话开始时的初始化操作。 这里可以设置系统提示词或者向用户发送欢迎信息。 system_prompt 你是一个由Nanbeige4.1-3B模型驱动的智能助手。请用友好、专业且简洁的方式回答用户的问题。 cl.user_session.set(system_prompt, system_prompt) cl.user_session.set(message_history, []) # 初始化消息历史 # 可选发送一条欢迎消息 await cl.Message( contentf你好我是Nanbeige4.1-3B助手。{system_prompt}\n\n请开始你的提问吧 ).send() cl.on_message async def handle_message(message: cl.Message): 处理用户发送的每一条消息。 user_input message.content message_history: List[Dict] cl.user_session.get(message_history, []) system_prompt cl.user_session.get(system_prompt, ) # 1. 构建对话历史格式化为API需要的messages列表 # 如果历史为空先加入系统提示如果模型支持 api_messages [] if system_prompt: # 注意并非所有API都支持system角色这里我们将其作为第一条用户消息的上下文或按API要求处理。 # 为了通用性我们可以选择不单独发送system消息或者将其融入历史。 # 这里我们采用一种简单方式如果历史为空在用户消息前加上系统提示。 pass # 将历史消息加入列表 for hist_msg in message_history[-10:]: # 只保留最近10轮对话防止上下文过长 api_messages.append({role: hist_msg[role], content: hist_msg[content]}) # 加入当前用户消息 api_messages.append({role: user, content: user_input}) # 2. 构造请求体 request_payload { messages: api_messages, model: nanbeige-4.1-3b, max_tokens: 1024, temperature: 0.7, stream: False # 我们先实现非流式流式响应更复杂一些 } # 显示一个“正在思考”的指示器 msg cl.Message(content) await msg.send() # 3. 调用我们的API服务 try: async with httpx.AsyncClient(timeout60.0) as client: response await client.post( f{API_SERVER_URL}/v1/chat/completions, jsonrequest_payload, headers{Content-Type: application/json} ) response.raise_for_status() api_response response.json() except httpx.RequestError as e: await msg.update(contentf抱歉连接API服务器时出错{e}) return except httpx.HTTPStatusError as e: await msg.update(contentfAPI服务器返回错误状态码{e.response.status_code}) return except Exception as e: await msg.update(contentf处理请求时发生未知错误{e}) return # 4. 提取模型回复并显示 assistant_reply api_response[message][content] await msg.update(contentassistant_reply) # 5. 更新会话历史同时保存用户消息和助手回复 message_history.append({role: user, content: user_input}) message_history.append({role: assistant, content: assistant_reply}) cl.user_session.set(message_history, message_history) cl.on_chat_end def end_chat(): 会话结束时的清理操作可选。 print(Chat session ended.)4.2 启动Chainlit应用并测试在终端中运行以下命令启动Chainlit应用chainlit run chainlit_app.py -w-w参数表示自动重载当你修改代码后会自动重启。启动后终端会输出一个URL通常是http://localhost:8000。用浏览器打开这个地址。现在你应该能看到一个干净、现代的聊天界面了。在输入框里问它一个问题比如“Which number is bigger, 9.11 or 9.8?”Chainlit前端会将你的问题发送到我们自建的api_server(端口8001)然后api_server将请求转发给真正的vLLM模型服务(端口8000)最后将答案一路返回并显示在网页上。整个流程就打通了5. 进阶优化与问题排查恭喜你完成了核心流程但一个健壮的应用还需要考虑更多。这里提供一些进阶思路和常见问题解决方法。5.1 功能增强建议支持流式响应 让答案像ChatGPT一样一个字一个字地出来体验更好。这需要在api_server.py的chat_completion接口中将stream参数设为True并处理vLLM返回的流式数据。在chainlit_app.py的handle_message中使用async for循环来逐步接收和更新消息内容。Chainlit对流式响应有原生支持。添加对话记忆管理 目前的代码只保存了简单的历史列表。对于长对话你需要管理上下文窗口Token数。可以在api_server层实现一个智能的“历史截断”逻辑当总Token数接近模型上限时优先保留最重要的对话部分。集成身份认证与限流 如果你的服务要对公网或多人开放在api_server.py中使用FastAPI的中间件添加API Key验证和请求频率限制是非常必要的。完善错误处理与日志 为api_server和chainlit_app添加更细致的错误分类处理如模型加载失败、输入过长、生成错误等并记录到文件方便排查。5.2 常见问题与解决问题Chainlit页面打开后无法连接或报错。检查1确保api_server.py正在运行 (python api_server.py)。检查2确保chainlit_app.py中的API_SERVER_URL地址和端口正确。检查3检查防火墙或安全组设置是否允许了相关端口的访问如8000, 8001。问题API调用返回超时错误。原因模型推理时间过长。httpx客户端或uvicorn服务器的默认超时时间可能太短。解决增加超时设置。如在api_server.py中调用vLLM时增加timeout参数教程中已设为30秒在chainlit_app.py中调用自建API时也增加timeout教程中已设为60秒。问题对话历史混乱或模型回答不符合预期。检查message_history的格式是否正确。确保每条消息的role是”user”或”assistant”。尝试在api_server转发给vLLM的请求中尝试在messages列表的最前面插入一条{“role”: “system”, “content”: “你的系统指令”}看看模型是否支持并遵循。不同模型对system角色的支持度不同。问题如何修改模型参数如temperature解决可以在chainlit_app.py的请求体request_payload中直接修改temperature、max_tokens等参数。更友好的方式是在Chainlit界面添加侧边栏设置组件让用户动态调整。6. 总结回顾一下我们完成的工作确认了基础我们首先验证了Nanbeige4.1-3B模型已通过vLLM成功部署并运行。搭建了桥梁我们使用FastAPI创建了一个中间层REST服务 (api_server)。它扮演了“翻译官”和“调度员”的角色接收标准格式的请求转发给vLLM并将结果整理后返回。这层封装让后续的集成和维护变得更加灵活。打造了门面我们利用Chainlit快速构建了一个直观、易用的Web聊天界面 (chainlit_app)。它负责与用户交互并将用户的对话请求发送给我们自建的API服务。这个“vLLM后端 FastAPI中间层 Chainlit前端”的组合是一个经典且强大的AI应用架构。它解耦了模型推理、业务逻辑和用户界面每一层都可以独立开发和扩展。你可以在此基础上继续探索将前端做得更美观利用Chainlit的元素图片、文件上传、卡片等。尝试集成其他模型只需修改api_server中转发的后端地址即可。将整个项目容器化Docker实现一键部署。希望这篇教程能帮助你顺利启动自己的AI应用。动手试试遇到问题就回头看看对应的章节祝你玩得开心获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
Nanbeige4.1-3B实战教程:vLLM API封装为REST服务+Chainlit对接调用
Nanbeige4.1-3B实战教程vLLM API封装为REST服务Chainlit对接调用1. 开篇为什么需要这个组合如果你正在寻找一个既强大又轻量的开源大模型并且希望它能像ChatGPT一样通过一个漂亮的网页界面来对话那么你来对地方了。Nanbeige4.1-3B是一个仅有30亿参数的小模型但它在推理、对话和智能体任务上的表现却相当出色。不过模型本身只是一个“大脑”我们需要为它搭建一个“身体”和“嘴巴”——也就是部署服务和交互界面。本教程要做的就是手把手教你完成这两件事搭建服务身体使用vLLM这个高性能推理引擎将Nanbeige4.1-3B模型封装成一个标准的REST API服务。这样任何程序都可以通过HTTP请求来调用它。创建界面嘴巴使用Chainlit这个专为AI应用设计的框架快速构建一个类似ChatGPT的Web聊天界面并让它去调用我们刚刚搭建好的API服务。学完这篇教程你将拥有一个完全由自己掌控的、私有部署的AI对话服务。无论是用于学习、开发还是内部工具都非常实用。我们开始吧2. 环境准备与模型部署确认在开始封装和对接之前我们需要确保模型已经通过vLLM成功部署。通常在云平台或服务器上这一步可能已经由镜像或脚本完成了。2.1 检查vLLM服务状态首先我们需要确认模型服务是否已经在运行。最直接的方法是查看服务的日志文件。打开终端或WebShell执行以下命令cat /root/workspace/llm.log如果部署成功你会在日志中看到类似下面的关键信息Uvicorn running on http://0.0.0.0:8000这表示vLLM的API服务已经启动并在8000端口监听。Loading model weights...和Model loaded successfully.这表示Nanbeige4.1-3B模型权重已成功加载。可能还会有关于GPU内存分配、模型路径等详细信息。看到这些恭喜你模型服务已经在后台跑起来了它现在就像一个“黑盒”服务等待我们通过HTTP请求来交互。2.2 理解vLLM提供的APIvLLM部署后会默认提供OpenAI兼容的API接口。这是我们后续封装的基础。主要用到两个端点聊天补全接口(/v1/chat/completions) 这是我们最常用的接口用于多轮对话。它接收一个包含对话历史的消息列表并返回模型的回复。# 示例请求结构 POST http://localhost:8000/v1/chat/completions { model: nanbeige-4.1-3b, messages: [ {role: user, content: 你好请介绍一下你自己。} ] }模型列表接口(/v1/models) 用于查询当前服务加载了哪些模型。我们的目标就是先确保这个服务是通的然后为它披上一层更易用或更定制化的“外衣”REST服务最后再用Chainlit做一个前端。3. 第一步封装vLLM API为定制化REST服务虽然vLLM的API已经是RESTful的但有时我们可能需要增加额外的逻辑如请求预处理、响应后处理、日志记录。简化参数隐藏一些底层细节。集成认证、限流等中间件。提供一个更符合内部规范的API格式。这里我们使用轻量级的FastAPI来创建一个中间层服务它接收请求然后去调用后端的vLLM服务最后将结果返回。3.1 创建FastAPI应用首先确保你的Python环境已安装必要库。如果没有请安装pip install fastapi uvicorn httpx pydantic然后创建一个名为api_server.py的文件# api_server.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional import httpx import logging # 设置日志 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) # 初始化FastAPI应用 app FastAPI(titleNanbeige4.1-3B API Server, version1.0) # 配置后端vLLM服务的地址 VLLM_SERVER_URL http://localhost:8000 # 根据你的vLLM服务地址修改 # 定义请求数据模型 class ChatMessage(BaseModel): role: str # “user” 或 “assistant” content: str class ChatRequest(BaseModel): messages: List[ChatMessage] model: Optional[str] nanbeige-4.1-3b # 默认模型名可与vLLM配置对应 max_tokens: Optional[int] 1024 temperature: Optional[float] 0.7 stream: Optional[bool] False # 我们先处理非流式响应 # 定义响应数据模型 class ChatResponse(BaseModel): message: ChatMessage model: str usage: dict app.get(/) async def root(): return {message: Nanbeige4.1-3B API Server is running!} app.get(/health) async def health_check(): 健康检查端点也可用于检查vLLM后端是否存活 try: async with httpx.AsyncClient() as client: resp await client.get(f{VLLM_SERVER_URL}/v1/models, timeout5.0) if resp.status_code 200: return {status: healthy, backend: vLLM is reachable} else: return {status: degraded, backend: fvLLM returned {resp.status_code}} except Exception as e: logger.error(fHealth check failed: {e}) raise HTTPException(status_code503, detailBackend vLLM service is unavailable) app.post(/v1/chat/completions, response_modelChatResponse) async def chat_completion(request: ChatRequest): 聊天补全接口。 接收前端请求转发至vLLM后端并返回格式化后的响应。 # 构造转发给vLLM的请求体 vllm_payload { model: request.model, messages: [msg.dict() for msg in request.messages], max_tokens: request.max_tokens, temperature: request.temperature, stream: request.stream } logger.info(fForwarding request to vLLM: {vllm_payload}) try: async with httpx.AsyncClient() as client: # 转发请求到vLLM服务 response await client.post( f{VLLM_SERVER_URL}/v1/chat/completions, jsonvllm_payload, timeout30.0 # 根据模型响应时间调整 ) response.raise_for_status() # 如果状态码不是2xx抛出异常 vllm_data response.json() except httpx.RequestError as e: logger.error(fRequest to vLLM failed: {e}) raise HTTPException(status_code502, detailfBackend service error: {e}) except httpx.HTTPStatusError as e: logger.error(fvLLM returned error status: {e.response.status_code}) raise HTTPException(status_codee.response.status_code, detaile.response.text) # 解析vLLM的响应并格式化为我们定义的响应模型 # 注意vLLM返回的choices是一个列表我们取第一个 choice vllm_data[choices][0] message choice[message] return ChatResponse( messageChatMessage(rolemessage[role], contentmessage[content]), modelvllm_data[model], usagevllm_data.get(usage, {}) ) if __name__ __main__: import uvicorn # 启动服务运行在8001端口避免与vLLM的8000端口冲突 uvicorn.run(app, host0.0.0.0, port8001)3.2 启动并测试封装后的API服务保存文件后在终端运行python api_server.py你应该看到输出提示服务在http://0.0.0.0:8001启动。现在我们可以测试这个新API。打开另一个终端使用curl或任何API测试工具如Postmancurl -X POST http://localhost:8001/v1/chat/completions \ -H Content-Type: application/json \ -d { messages: [ {role: user, content: 你好请用一句话介绍下你自己。} ] }如果一切正常你会收到一个JSON响应其中包含了Nanbeige4.1-3B模型的回复。我们的封装服务成功了4. 第二步使用Chainlit构建Web聊天前端Chainlit是一个超级好用的工具可以让你用很少的代码就做出功能丰富的AI聊天界面。现在我们要让Chainlit前端连接到我们刚刚搭建的api_server。4.1 创建Chainlit应用首先安装Chainlitpip install chainlit然后创建一个名为chainlit_app.py的文件。同时Chainlit需要一个配置文件chainlit.md来定义应用说明。创建chainlit.md(可选但推荐)# Welcome to Nanbeige4.1-3B Chatbot! This is a chatbot powered by the Nanbeige4.1-3B model, served via a custom API. You can start chatting right away!创建chainlit_app.py# chainlit_app.py import chainlit as cl import httpx import json from typing import List, Dict # 配置我们自建的API服务器地址 API_SERVER_URL http://localhost:8001 # 指向我们刚才启动的FastAPI服务 cl.on_chat_start async def start_chat(): 会话开始时的初始化操作。 这里可以设置系统提示词或者向用户发送欢迎信息。 system_prompt 你是一个由Nanbeige4.1-3B模型驱动的智能助手。请用友好、专业且简洁的方式回答用户的问题。 cl.user_session.set(system_prompt, system_prompt) cl.user_session.set(message_history, []) # 初始化消息历史 # 可选发送一条欢迎消息 await cl.Message( contentf你好我是Nanbeige4.1-3B助手。{system_prompt}\n\n请开始你的提问吧 ).send() cl.on_message async def handle_message(message: cl.Message): 处理用户发送的每一条消息。 user_input message.content message_history: List[Dict] cl.user_session.get(message_history, []) system_prompt cl.user_session.get(system_prompt, ) # 1. 构建对话历史格式化为API需要的messages列表 # 如果历史为空先加入系统提示如果模型支持 api_messages [] if system_prompt: # 注意并非所有API都支持system角色这里我们将其作为第一条用户消息的上下文或按API要求处理。 # 为了通用性我们可以选择不单独发送system消息或者将其融入历史。 # 这里我们采用一种简单方式如果历史为空在用户消息前加上系统提示。 pass # 将历史消息加入列表 for hist_msg in message_history[-10:]: # 只保留最近10轮对话防止上下文过长 api_messages.append({role: hist_msg[role], content: hist_msg[content]}) # 加入当前用户消息 api_messages.append({role: user, content: user_input}) # 2. 构造请求体 request_payload { messages: api_messages, model: nanbeige-4.1-3b, max_tokens: 1024, temperature: 0.7, stream: False # 我们先实现非流式流式响应更复杂一些 } # 显示一个“正在思考”的指示器 msg cl.Message(content) await msg.send() # 3. 调用我们的API服务 try: async with httpx.AsyncClient(timeout60.0) as client: response await client.post( f{API_SERVER_URL}/v1/chat/completions, jsonrequest_payload, headers{Content-Type: application/json} ) response.raise_for_status() api_response response.json() except httpx.RequestError as e: await msg.update(contentf抱歉连接API服务器时出错{e}) return except httpx.HTTPStatusError as e: await msg.update(contentfAPI服务器返回错误状态码{e.response.status_code}) return except Exception as e: await msg.update(contentf处理请求时发生未知错误{e}) return # 4. 提取模型回复并显示 assistant_reply api_response[message][content] await msg.update(contentassistant_reply) # 5. 更新会话历史同时保存用户消息和助手回复 message_history.append({role: user, content: user_input}) message_history.append({role: assistant, content: assistant_reply}) cl.user_session.set(message_history, message_history) cl.on_chat_end def end_chat(): 会话结束时的清理操作可选。 print(Chat session ended.)4.2 启动Chainlit应用并测试在终端中运行以下命令启动Chainlit应用chainlit run chainlit_app.py -w-w参数表示自动重载当你修改代码后会自动重启。启动后终端会输出一个URL通常是http://localhost:8000。用浏览器打开这个地址。现在你应该能看到一个干净、现代的聊天界面了。在输入框里问它一个问题比如“Which number is bigger, 9.11 or 9.8?”Chainlit前端会将你的问题发送到我们自建的api_server(端口8001)然后api_server将请求转发给真正的vLLM模型服务(端口8000)最后将答案一路返回并显示在网页上。整个流程就打通了5. 进阶优化与问题排查恭喜你完成了核心流程但一个健壮的应用还需要考虑更多。这里提供一些进阶思路和常见问题解决方法。5.1 功能增强建议支持流式响应 让答案像ChatGPT一样一个字一个字地出来体验更好。这需要在api_server.py的chat_completion接口中将stream参数设为True并处理vLLM返回的流式数据。在chainlit_app.py的handle_message中使用async for循环来逐步接收和更新消息内容。Chainlit对流式响应有原生支持。添加对话记忆管理 目前的代码只保存了简单的历史列表。对于长对话你需要管理上下文窗口Token数。可以在api_server层实现一个智能的“历史截断”逻辑当总Token数接近模型上限时优先保留最重要的对话部分。集成身份认证与限流 如果你的服务要对公网或多人开放在api_server.py中使用FastAPI的中间件添加API Key验证和请求频率限制是非常必要的。完善错误处理与日志 为api_server和chainlit_app添加更细致的错误分类处理如模型加载失败、输入过长、生成错误等并记录到文件方便排查。5.2 常见问题与解决问题Chainlit页面打开后无法连接或报错。检查1确保api_server.py正在运行 (python api_server.py)。检查2确保chainlit_app.py中的API_SERVER_URL地址和端口正确。检查3检查防火墙或安全组设置是否允许了相关端口的访问如8000, 8001。问题API调用返回超时错误。原因模型推理时间过长。httpx客户端或uvicorn服务器的默认超时时间可能太短。解决增加超时设置。如在api_server.py中调用vLLM时增加timeout参数教程中已设为30秒在chainlit_app.py中调用自建API时也增加timeout教程中已设为60秒。问题对话历史混乱或模型回答不符合预期。检查message_history的格式是否正确。确保每条消息的role是”user”或”assistant”。尝试在api_server转发给vLLM的请求中尝试在messages列表的最前面插入一条{“role”: “system”, “content”: “你的系统指令”}看看模型是否支持并遵循。不同模型对system角色的支持度不同。问题如何修改模型参数如temperature解决可以在chainlit_app.py的请求体request_payload中直接修改temperature、max_tokens等参数。更友好的方式是在Chainlit界面添加侧边栏设置组件让用户动态调整。6. 总结回顾一下我们完成的工作确认了基础我们首先验证了Nanbeige4.1-3B模型已通过vLLM成功部署并运行。搭建了桥梁我们使用FastAPI创建了一个中间层REST服务 (api_server)。它扮演了“翻译官”和“调度员”的角色接收标准格式的请求转发给vLLM并将结果整理后返回。这层封装让后续的集成和维护变得更加灵活。打造了门面我们利用Chainlit快速构建了一个直观、易用的Web聊天界面 (chainlit_app)。它负责与用户交互并将用户的对话请求发送给我们自建的API服务。这个“vLLM后端 FastAPI中间层 Chainlit前端”的组合是一个经典且强大的AI应用架构。它解耦了模型推理、业务逻辑和用户界面每一层都可以独立开发和扩展。你可以在此基础上继续探索将前端做得更美观利用Chainlit的元素图片、文件上传、卡片等。尝试集成其他模型只需修改api_server中转发的后端地址即可。将整个项目容器化Docker实现一键部署。希望这篇教程能帮助你顺利启动自己的AI应用。动手试试遇到问题就回头看看对应的章节祝你玩得开心获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。