当然可以!如果不需要集成 Open WebUI,你可以完全自主开发 Web 前端。以下是完整的解决方案:
1. 技术选型
前端 :React/Vue.js + Axios(HTTP请求)
后端 :FastAPI(Python)
RAG核心 :LangChain + Chroma + Ollama(或其他本地LLM)
2. 实现步骤 (附代码)步骤1:确保RAG服务已运行 使用之前的 rag_api.py
,启动 FastAPI 服务:
1 uvicorn rag_api:app --host 0.0.0.0 --port 5000
步骤2:创建基础前端 以 React 为例,快速搭建:
1 2 3 npx create-react-app rag-frontend cd rag-frontendnpm install axios @mui/material @mui/icons-material
步骤3:核心前端代码 修改 src/App.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 import React , { useState } from 'react' ;import axios from 'axios' ;import { Box , TextField , Button , CircularProgress , Typography } from '@mui/material' ;function App ( ) { const [query, setQuery] = useState ('' ); const [answer, setAnswer] = useState ('' ); const [loading, setLoading] = useState (false ); const handleSubmit = async (e ) => { e.preventDefault (); setLoading (true ); try { const response = await axios.post ('http://localhost:5000/generate' , { text : query }); setAnswer (response.data .answer ); } catch (error) { setAnswer (`错误: ${error.message} ` ); } setLoading (false ); }; return ( <Box sx ={{ maxWidth: 800 , margin: '2rem auto ', padding: 3 }}> <form onSubmit ={handleSubmit} > <TextField fullWidth variant ="outlined" label ="输入你的问题" value ={query} onChange ={(e) => setQuery(e.target.value)} disabled={loading} /> <Button type ="submit" variant ="contained" sx ={{ mt: 2 }} disabled ={loading} > {loading ? <CircularProgress size ={24} /> : '提交'} </Button > </form > {answer && ( <Box sx ={{ mt: 4 , p: 3 , bgcolor: '#f5f5f5 ', borderRadius: 2 }}> <Typography variant ="h6" gutterBottom > 回答:</Typography > <Typography > {answer}</Typography > </Box > )} </Box > ); } export default App ;
步骤4:启动前端
访问 http://localhost:3000
即可使用。
3. 进阶功能扩展 功能1:对话历史记录 1 2 3 4 5 6 7 8 const [history, setHistory] = useState ([]);const handleSubmit = async (e ) => { setHistory (prev => [...prev, { question : query, answer : response.data .answer }]); };
功能2:文件上传接口 后端新增端点(rag_api.py
):
1 2 3 4 5 6 7 from fastapi import UploadFile, File@app.post("/upload" ) async def upload_file (file: UploadFile = File(... ) ): with open (f"./docs/{file.filename} " , "wb" ) as f: f.write(await file.read()) return {"status" : "文件已更新,请重新执行向量化" }
前端添加上传组件:
1 2 3 4 5 6 <input type="file" onChange={async (e) => { const file = e.target .files [0 ]; const formData = new FormData (); formData.append ('file' , file); await axios.post ('http://localhost:5000/upload' , formData); }} />
功能3:流式输出 后端修改(SSE实现):
1 2 3 4 5 6 7 8 9 10 from sse_starlette.sse import EventSourceResponse@app.get("/stream-generate" ) async def stream_generate (query: str ): async def event_generator (): result = qa_chain.run(query) for word in result.split(): yield {"data" : word} await asyncio.sleep(0.1 ) return EventSourceResponse(event_generator())
前端使用 EventSource:
1 2 3 4 5 6 7 const eventSource = new EventSource ( `http://localhost:5000/stream-generate?query=${encodeURIComponent (query)} ` ); eventSource.onmessage = (e ) => { setAnswer (prev => prev + e.data + ' ' ); };
4. 部署优化 生产环境部署 1 2 3 4 5 npm run build docker run -d -p 80:80 -v $(pwd )/build:/usr/share/nginx/html nginx
性能优化 1 2 3 4 5 from fastapi_cache import FastAPICachefrom fastapi_cache.backends.inmemory import InMemoryBackendFastAPICache.init(InMemoryBackend())
5. 自主开发 vs Open WebUI 对比
特性
自主开发前端
Open WebUI
定制灵活性
⭐⭐⭐⭐⭐
⭐⭐
开发成本
需要前端开发能力
零成本快速集成
功能扩展性
无限制
受限于项目功能
多模型支持
需自行实现
原生支持
适合场景
企业级定制/特殊需求
快速原型/个人使用
6. 自研前端的核心优势
完全控制UI/UX :可自定义交互流程和视觉风格
深度集成业务逻辑 :添加审批流程、权限控制等企业特性
数据隔离 :敏感数据无需经过第三方界面
性能优化 :针对特定场景做前端专项优化
通过上述方案,你可以用约 100 行代码实现一个基础但完整的前端,后续可根据需求逐步扩展功能。自主开发的关键优势在于能精准匹配业务需求,特别适合需要高度定制化的场景。