首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Gradio 是什么?能不能换成 FastAPI 做 WebUI?

Gradio 是什么?能不能换成 FastAPI 做 WebUI?

作者头像
玄同765
发布2026-01-14 14:15:06
发布2026-01-14 14:15:06
400
举报

需求分析

你要做的是Python3 LLM 入门级高星 GitHub 项目,之前纠结 Gradio 和 FastAPI 做 WebUI 的区别,核心关注点是开发效率、用户体验、部署难度、代码量这几个维度。


第一部分:Gradio 是什么?

Gradio 是一个专门为机器学习模型(尤其是 LLM)快速开发可视化 Web 界面的 Python 库,它的核心优势是无需前端基础、快速搭建、开箱即用的交互组件

1. 核心特点
  • 无需前端基础:只需要 Python 代码,不需要写 HTML、CSS、JS;
  • 快速开发:写个简单的 LLM 聊天界面 + 文档上传只需要30~50 行代码
  • 开箱即用的 LLM 交互组件:支持markdown 渲染、代码高亮、文档预览、文件上传、滑块、下拉框这些 LLM 常用的组件;
  • 部署简单:支持直接部署到Hugging Face Spaces、Gradio Hub,或者用Docker Compose 一键启动
  • 社区活跃:有大量的 Gradio 插件和示例代码,用户遇到问题容易解决;
  • 支持多种部署方式:支持本地部署、云部署、嵌入到 Jupyter Notebook
2. 代码示例(简单的 LLM 聊天界面)
代码语言:javascript
复制
import gradio as gr
from langchain.llms import Ollama

def chat_with_llm(message, history):
    """
    与本地部署的Llama 3 8B-Chat聊天
    :param message: 用户输入的消息
    :param history: 聊天历史记录(格式:[(user_msg1, bot_msg1), (user_msg2, bot_msg2)])
    :return: LLM的回复
    """
    llm = Ollama(model="llama3:8b")
    full_prompt = ""
    for user_msg, bot_msg in history:
        full_prompt += f"User: {user_msg}\nAssistant: {bot_msg}\n"
    full_prompt += f"User: {message}\nAssistant: "
    response = llm.predict(full_prompt)
    return response

# 创建Gradio聊天界面
demo = gr.ChatInterface(
    fn=chat_with_llm,
    title="本地部署的Llama 3 8B-Chat聊天机器人",
    description="支持本地部署,数据不传到云端,保护隐私",
    theme="soft"
)

if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7860, share=False)

第二部分:能不能换成 FastAPI 做 WebUI?

答案是肯定的,但要讲清楚换的代价和适用场景

1. 适用场景

如果你的项目对界面有极高定制化要求(比如需要品牌风格、复杂的交互逻辑),或者项目需要和已有 FastAPI 后端深度集成(比如需要统一的 API 接口、身份验证、权限控制),那么可以考虑用 FastAPI 做 WebUI。

2. 代价

用 FastAPI 做 WebUI 需要自己写前端代码(HTML+CSS+JS),开发效率比 Gradio 低很多,代码量也会增加几倍甚至十几倍。

3. 代码示例(FastAPI+HTML+CSS+JS 的简单聊天界面)
3.1 后端代码(main.py)
代码语言:javascript
复制
from fastapi import FastAPI, Depends, HTTPException, status, Form
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from langchain.llms import Ollama
from typing import List, Optional
from pydantic import BaseModel

app = FastAPI(title="FastAPI LLM聊天机器人")

# 挂载静态资源
app.mount("/static", StaticFiles(directory="static"), name="static")

# 初始化Jinja2模板引擎
templates = Jinja2Templates(directory="templates")

# 定义聊天请求的数据验证模型
class ChatRequest(BaseModel):
    message: str
    history: Optional[List[List[str]]] = []

# 定义聊天响应的数据验证模型
class ChatResponse(BaseModel):
    response: str

# 聊天接口
@app.post("/api/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
    """
    与本地部署的Llama 3 8B-Chat聊天
    :param request: 聊天请求数据
    :return: 聊天响应数据
    """
    try:
        llm = Ollama(model="llama3:8b")
        full_prompt = ""
        for user_msg, bot_msg in request.history:
            full_prompt += f"User: {user_msg}\nAssistant: {bot_msg}\n"
        full_prompt += f"User: {request.message}\nAssistant: "
        response = llm.predict(full_prompt)
        return {"response": response}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"聊天失败:{e}")

# 聊天界面
@app.get("/", response_class=HTMLResponse)
async def chat_page():
    return templates.TemplateResponse("chat.html", {"request": None})
3.2 前端代码(templates/chat.html)
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FastAPI LLM聊天机器人</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>FastAPI LLM聊天机器人</h1>
            <p>支持本地部署,数据不传到云端,保护隐私</p>
        </div>
        <div class="chat-container">
            <div class="chat-history" id="chat-history">
                <!-- 聊天历史记录会动态添加到这里 -->
            </div>
            <div class="chat-input-container">
                <input type="text" id="chat-input" placeholder="请输入您的消息..." autofocus>
                <button id="send-btn">发送</button>
            </div>
        </div>
    </div>

    <script src="/static/js/script.js"></script>
</body>
</html>
3.3 前端 CSS 代码(static/css/style.css)
代码语言:javascript
复制
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Microsoft YaHei", sans-serif;
}

body {
    background-color: #f5f5f5;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

.header {
    text-align: center;
    margin-bottom: 30px;
}

.header h1 {
    color: #333;
    margin-bottom: 10px;
}

.header p {
    color: #666;
    font-size: 14px;
}

.chat-container {
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    overflow: hidden;
}

.chat-history {
    height: 400px;
    overflow-y: auto;
    padding: 20px;
}

.chat-history .message {
    margin-bottom: 15px;
    padding: 10px 15px;
    border-radius: 8px;
    max-width: 70%;
    word-wrap: break-word;
}

.chat-history .user-message {
    background-color: #007bff;
    color: #fff;
    margin-left: auto;
    text-align: right;
}

.chat-history .bot-message {
    background-color: #f8f9fa;
    color: #333;
    margin-right: auto;
    text-align: left;
}

.chat-input-container {
    display: flex;
    padding: 20px;
}

.chat-input-container input {
    flex: 1;
    padding: 10px 15px;
    border: 1px solid #ddd;
    border-radius: 8px 0 0 8px;
    font-size: 14px;
}

.chat-input-container button {
    padding: 10px 20px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 0 8px 8px 0;
    font-size: 14px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.chat-input-container button:hover {
    background-color: #0056b3;
}
3.4 前端 JS 代码(static/js/script.js)
代码语言:javascript
复制
// 聊天历史记录
let chatHistory = [];

// 发送消息的函数
async function sendMessage() {
    const chatInput = document.getElementById("chat-input");
    const message = chatInput.value.trim();
    if (!message) return;

    // 清空输入框
    chatInput.value = "";

    // 添加用户消息到聊天历史记录
    chatHistory.push([message, ""]);
    renderChatHistory();

    // 发送消息到后端
    try {
        const response = await fetch("/api/chat", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify({
                message: message,
                history: chatHistory.slice(0, -1)
            })
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        // 更新聊天历史记录
        chatHistory[chatHistory.length - 1][1] = data.response;
        renderChatHistory();
    } catch (error) {
        console.error("发送消息失败:", error);
        chatHistory[chatHistory.length - 1][1] = "抱歉,聊天失败,请重试。";
        renderChatHistory();
    }
}

// 渲染聊天历史记录的函数
function renderChatHistory() {
    const chatHistoryDiv = document.getElementById("chat-history");
    chatHistoryDiv.innerHTML = "";

    chatHistory.forEach(([userMsg, botMsg]) => {
        // 渲染用户消息
        const userMessageDiv = document.createElement("div");
        userMessageDiv.className = "message user-message";
        userMessageDiv.textContent = userMsg;
        chatHistoryDiv.appendChild(userMessageDiv);

        // 渲染机器人消息
        if (botMsg) {
            const botMessageDiv = document.createElement("div");
            botMessageDiv.className = "message bot-message";
            botMessageDiv.textContent = botMsg;
            chatHistoryDiv.appendChild(botMessageDiv);
        }
    });

    // 滚动到聊天历史记录的底部
    chatHistoryDiv.scrollTop = chatHistoryDiv.scrollHeight;
}

// 绑定事件
document.getElementById("send-btn").addEventListener("click", sendMessage);
document.getElementById("chat-input").addEventListener("keypress", (e) => {
    if (e.key === "Enter") {
        sendMessage();
    }
});

第三部分:给你的建议

如果是入门级高星 GitHub 项目,建议优先用Gradio,因为:

  1. 开发效率高:3 天内就能做出一个美观的 WebUI;
  2. 用户体验好:支持开箱即用的 LLM 交互组件;
  3. 部署简单:Gradio 支持直接部署到 Hugging Face Spaces,或者用 Docker Compose 一键启动;
  4. 社区活跃:有大量的 Gradio 插件和示例代码,用户遇到问题容易解决;
  5. 代码量少:写个简单的 LLM 聊天界面 + 文档上传只需要 30~50 行代码。

如果你的项目对界面有极高定制化要求,或者项目需要和已有 FastAPI 后端深度集成,那么可以考虑用FastAPI + 前端框架(如 React、Vue、Angular) 做 WebUI。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求分析
    • 第一部分:Gradio 是什么?
      • 1. 核心特点
      • 2. 代码示例(简单的 LLM 聊天界面)
    • 第二部分:能不能换成 FastAPI 做 WebUI?
      • 1. 适用场景
      • 2. 代价
      • 3. 代码示例(FastAPI+HTML+CSS+JS 的简单聊天界面)
    • 第三部分:给你的建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档