踐)
在實(shí)際部署開源 LLM 項(xiàng)目時(shí)最常遇到的并不是模型效果問題而是“一個(gè)有界面的系統(tǒng)怎么跑起來、怎么配通、怎么讓人正常訪問”。OSS WebUI Llms.py v4 這個(gè)名字里包含了三層信息它首先是一個(gè)開源Open Source SoftwareOSSWebUI 項(xiàng)目其次它面向 LLM 場景提供 Web 操作界面最后它通過 v4 版本把能力收斂成了四大塊——Projects、Agent Profiles、PDF Studio 和 1-Click Sharing。下面這篇文章會從技術(shù)實(shí)踐角度把這套系統(tǒng)從概念、部署、功能配置到問題排查完整過一遍適合正在評估開源 LLM 工作臺、需要給團(tuán)隊(duì)搭建 WebUI或者準(zhǔn)備接管這類項(xiàng)目運(yùn)維的開發(fā)者閱讀。這里還要先解釋一個(gè)常見的混淆點(diǎn)在中文技術(shù)語境里OSS 往往也指對象存儲Object Storage Service比如阿里云 OSS。開源 WebUI 項(xiàng)目為了統(tǒng)一保存頭像、PDF、離線文件等資源通常也確實(shí)會對接對象存儲。所以標(biāo)題里的 OSS 理解為“開源軟件”更準(zhǔn)確但部署過程中你很有可能會碰到“對象存儲 OSS”的配置項(xiàng)。文章會同時(shí)把這兩層含義講清楚先把 WebUI 本身部署起來再把文件類數(shù)據(jù)接到對象存儲上。1. 先理解 Llms.py v4 這類 WebUI 解決什么問題1.1 為什么 LLM 項(xiàng)目需要獨(dú)立的 WebUI很多人第一次接觸 LLM 應(yīng)用時(shí)習(xí)慣用 API 調(diào)用或者命令行腳本去測試模型。這種方式做原型驗(yàn)證沒問題但一旦系統(tǒng)要交給產(chǎn)品、運(yùn)營、業(yè)務(wù)同事使用就缺少了三樣?xùn)|西可視化的交互界面、可復(fù)用的會話管理、可配置的權(quán)限體系。WebUI 這一類開源項(xiàng)目要解決的就是這個(gè)“最后一公里”問題。它把模型調(diào)用、提示詞管理、文件上傳、知識庫檢索、會話歷史這些能力封裝成一個(gè)網(wǎng)頁應(yīng)用。用戶不需要寫代碼也不需要知道模型服務(wù)部署在哪個(gè)端口只要登錄頁面選擇一個(gè) Agent就能開始工作。從 v4 的功能集合來看Llms.py 已經(jīng)不再是一個(gè)單純的“聊天頁面”。Projects、Agent Profiles、PDF Studio、1-Click Sharing 這四組能力疊加之后它更像是一個(gè)面向 LLM 應(yīng)用的輕量工作臺既有項(xiàng)目管理又有角色配置還有文檔處理入口同時(shí)支持把結(jié)果分享給外部人員。1.2 v4 的四大能力從“聊天框”升級為“工作臺”用表格可以把 v4 的功能變化看得更清楚。功能模塊解決的問題典型使用場景Projects多個(gè)業(yè)務(wù)場景混在一起會話和文件互相污染給不同項(xiàng)目分配獨(dú)立會話、數(shù)據(jù)和建議Agent Profiles每次提問都要重新寫角色和參數(shù)無法沉淀把客服、翻譯、代碼審查等角色固化成可復(fù)用的 ProfilePDF Studio文檔資料無法進(jìn)入對話上下文上傳 PDF、解析文本、生成知識庫后再讓模型回答1-Click Sharing內(nèi)部結(jié)果要發(fā)給外部人員但不想開通賬號生成帶權(quán)限的分享鏈接別人通過鏈接查看對話或文檔換句話說v4 把“模型交互”和“業(yè)務(wù)側(cè)協(xié)作”這兩條線合并了。普通用戶仍然可以把它當(dāng)聊天工具用但團(tuán)隊(duì)負(fù)責(zé)人、知識管理專員、產(chǎn)品運(yùn)營可以把它當(dāng)作一個(gè)帶權(quán)限、帶知識庫、帶分享能力的小平臺。1.3 部署前要先想清楚的三件事第一件事是模型從哪里來。WebUI 本身很少內(nèi)置大模型它通常只是一個(gè)前端加編排層后端要接一個(gè)模型服務(wù)比如本地部署的推理服務(wù)或者云上的模型 API。部署前必須先確認(rèn)模型服務(wù)的地址、API Key、模型名稱否則 WebUI 啟動后并沒有可以對話的對象。第二件事是文件要放哪里。項(xiàng)目里上傳的 PDF、截圖、用戶頭像如果只存在 WebUI 所在服務(wù)器的本地磁盤擴(kuò)容和備份都很麻煩。v4 里的 PDF Studio 會處理文檔Projects 會保存項(xiàng)目文件這些數(shù)據(jù)都應(yīng)該落到對象存儲里。第三件事是訪問方式。WebUI 部署完成后團(tuán)隊(duì)成員是通過內(nèi)網(wǎng)訪問還是需要公網(wǎng)訪問如果分享功能要對外使用就必須考慮域名、反向代理、HTTPS 證書和訪問權(quán)限而不是只開放一個(gè)裸端口。2. 部署環(huán)境準(zhǔn)備容器化是最省事的路徑2.1 硬件和系統(tǒng)環(huán)境建議這里給出的是通用參考值具體資源配置要結(jié)合模型服務(wù)和并發(fā)量調(diào)整。環(huán)境級別CPU內(nèi)存磁盤說明學(xué)習(xí)體驗(yàn)2 核4 GB20 GB跑通 WebUI不接大模型推理團(tuán)隊(duì)試用4 核8 GB50 GB對接外部模型 API處理少量 PDF生產(chǎn)使用8 核及以上16 GB 及以上100 GB 以上需要獨(dú)立數(shù)據(jù)庫、對象存儲、監(jiān)控日志操作系統(tǒng)建議使用 Debian、Ubuntu 或 CentOS 之類的 Linux 服務(wù)器。需要提前安裝 Docker 和 Docker Compose。如果目標(biāo)服務(wù)器無法拉取鏡像要先配置鏡像加速器或者在網(wǎng)絡(luò)代理允許的環(huán)境里提前把鏡像導(dǎo)出再引入過來。2.2 用 docker-compose 搭建最小化服務(wù)下面是一個(gè)用于說明思路的 docker-compose 示例。它包含三類服務(wù)WebUI 主應(yīng)用、數(shù)據(jù)庫、對象存儲。實(shí)際項(xiàng)目可能需要根據(jù)官方文檔調(diào)整鏡像名稱、端口和依賴關(guān)系。version: 3.8 services: webui: image: your-registry/llms-py-webui:v4 container_name: llms-py-webui restart: unless-stopped ports: - 8080:8080 environment: WEBUI_PORT: 8080 DB_URL: postgresql://llms:llms_passworddb:5432/llms STORAGE_TYPE: s3 S3_ENDPOINT: http://minio:9000 S3_ACCESS_KEY: minioadmin S3_SECRET_KEY: minioadmin S3_BUCKET: llms-files S3_REGION: us-east-1 S3_PATH_STYLE: true MODEL_API_BASE: http://your-model-server:8000/v1 MODEL_API_KEY: sk-xxxx depends_on: - db - minio db: image: postgres:15-alpine container_name: llms-db restart: unless-stopped environment: POSTGRES_DB: llms POSTGRES_USER: llms POSTGRES_PASSWORD: llms_password volumes: - db-data:/var/lib/postgresql/data minio: image: minio/minio:latest container_name: llms-minio restart: unless-stopped command: server /data --console-address :9001 environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: - 9000:9000 - 9001:9001 volumes: - minio-data:/data volumes: db-data: minio-data:這個(gè)示例里的STORAGE_TYPE: s3表示使用 S3 兼容協(xié)議的對象存儲。S3 是對象存儲的事實(shí)標(biāo)準(zhǔn)MinIO、阿里云 OSS、騰訊云 COS 都支持 S3 兼容接口所以 WebUI 通常通過 S3 客戶端對接。S3_PATH_STYLE: true這個(gè)配置對自建 MinIO 很重要因?yàn)?MinIO 默認(rèn)通過路徑方式訪問 bucket。2.3 對象存儲為什么不是可選配置如果在部署時(shí)跳過對象存儲配置只把文件寫在本地目錄初期不會有明顯問題。但項(xiàng)目運(yùn)行一段時(shí)間后會碰到三類麻煩第一是文件難備份。上傳的 PDF、項(xiàng)目附件和頭像如果散落在容器內(nèi)或者某個(gè)掛載目錄備份時(shí)要額外處理文件目錄數(shù)據(jù)庫和文件容易出現(xiàn)時(shí)間點(diǎn)不一致。第二是擴(kuò)容麻煩。當(dāng) WebUI 部署在多臺機(jī)器后面用戶第一次請求落到 A 機(jī)器第二次請求落到 B 機(jī)器B 機(jī)器上找不到 A 機(jī)器保存的文件就會出現(xiàn)上傳成功但讀取失敗的問題。第三是分享功能受限。1-Click Sharing 生成的鏈接如果指向 WebUI 服務(wù)本身那么 WebUI 宕機(jī)后分享內(nèi)容也會失效。如果文件已經(jīng)存放在對象存儲分享鏈接可以直接指向?qū)ο蟠鎯Φ呐R時(shí)訪問 URL服務(wù)可用性更高。所以即使是內(nèi)網(wǎng)試用也建議從一開始就配置 S3 兼容存儲。MinIO 可以在一臺低配置機(jī)器上運(yùn)行適合測試生產(chǎn)環(huán)境可以選擇云廠商的對象存儲或自建高可用 MinIO 集群。2.4 啟動前的環(huán)境變量檢查清單容器啟動失敗的原因里環(huán)境變量錯(cuò)誤占了很大比例。建議按照下面的清單逐項(xiàng)確認(rèn)。檢查項(xiàng)常見錯(cuò)誤正確做法數(shù)據(jù)庫連接串密碼包含特殊字符未轉(zhuǎn)義使用DB_URL時(shí)對密碼做 URL 編碼S3 Endpoint忘了加 http/https 前綴必須寫完整協(xié)議如http://minio:9000Bucket 是否存在啟動后報(bào) BucketNotFound提前在 MinIO 控制臺創(chuàng)建 bucket模型服務(wù)地址寫成了內(nèi)網(wǎng) IP 但 WebUI 容器無法訪問容器內(nèi)執(zhí)行curl測試接口連通性API Key填錯(cuò)或過期先手動調(diào)用模型服務(wù)驗(yàn)證 Key 有效注意不要只看容器是否變成 Running 狀態(tài)要打開日志確認(rèn)服務(wù)完成初始化。很多 WebUI 應(yīng)用即使連不上數(shù)據(jù)庫也可能先啟動 HTTP 端口等用戶訪問時(shí)才暴露問題。3. 核心功能配置Projects、Agent Profiles、PDF Studio、1-Click Sharing3.1 Projects用項(xiàng)目空間隔離會話、文件和知識庫Projects 的定位是“業(yè)務(wù)空間”。一個(gè)項(xiàng)目下面可以包含多輪會話、關(guān)聯(lián)的 PDF 文檔、固定的知識庫目錄和項(xiàng)目成員。這樣設(shè)計(jì)的好處是法務(wù)組的資料不會出現(xiàn)在市場組的會話里產(chǎn)品經(jīng)理上傳的 PRD 也只對當(dāng)前項(xiàng)目開放。從實(shí)現(xiàn)角度看Projects 通常對應(yīng)后端的一張項(xiàng)目表結(jié)構(gòu)上類似下面這樣CREATE TABLE projects ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, owner_id UUID NOT NULL, knowledge_base_id UUID, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() );操作上管理員新建項(xiàng)目后再邀請成員加入項(xiàng)目。用戶可以切換當(dāng)前項(xiàng)目空間也可以按項(xiàng)目維度搜索歷史會話。使用 Projects 時(shí)要注意權(quán)限邊界用戶在 A 項(xiàng)目里創(chuàng)建的會話不應(yīng)該自動出現(xiàn)在 B 項(xiàng)目里。如果發(fā)現(xiàn)跨項(xiàng)目會話串場優(yōu)先檢查接口是否按項(xiàng)目 ID 過濾了數(shù)據(jù)。3.2 Agent Profiles把模型參數(shù)和角色行為固化成配置Agent Profiles 解決的是“重復(fù)配置”問題。以前每次和模型對話都要在輸入框里重復(fù)寫“你是一名運(yùn)維工程師請用簡潔中文回答”。有了 Agent Profiles可以把角色描述、模型、溫度、輸出格式、啟用工具都保存成一個(gè)檔案下次直接選用。一個(gè) Agent Profile 在后端可能長這樣{ id: agent-ops-001, name: 運(yùn)維排查助手, description: 面向服務(wù)異常排查的助手, model: deepseek-v3, system_prompt: 你是一名運(yùn)維工程師回答問題時(shí)先給出排查步驟再給結(jié)論。, temperature: 0.2, max_tokens: 2048, tools: [search_logs, view_metrics], knowledge_base_ids: [kb-incident-2025] }每個(gè)字段的含義如下參數(shù)作用注意事項(xiàng)model指定使用哪個(gè)模型模型名稱必須與模型服務(wù)返回的 model 字段一致system_prompt設(shè)定角色行為不要把所有業(yè)務(wù)規(guī)則都塞進(jìn) prompt過長會占 tokentemperature控制隨機(jī)性偏向穩(wěn)定輸出的場景用 0.1 到 0.3創(chuàng)意場景用 0.7 以上max_tokens限制最長回復(fù)長度設(shè)置過短會導(dǎo)致長答案被截?cái)鄑ools啟用的工具列表工具未注冊或未授權(quán)時(shí)會調(diào)用失敗knowledge_base_ids綁定的知識庫知識庫上線后要重建索引否則引用不到新文檔關(guān)鍵點(diǎn)在于Agent Profile 修改之后是否需要新建會話才能生效。多數(shù)實(shí)現(xiàn)里正在進(jìn)行的會話已經(jīng)帶有舊 Prompt 和舊參數(shù)修改 Profile 只會影響后續(xù)新建的會話。遇到“改了沒生效”的問題時(shí)優(yōu)先確認(rèn)是不是繼續(xù)使用舊會話導(dǎo)致。3.3 PDF Studio從“傳文件”升級為“傳知識”PDF Studio 是 v4 里比較重的一個(gè)模塊。它不只是讓用戶上傳 PDF 并保存而是要把 PDF 變成模型可用的知識。核心處理鏈路通常分四步上傳并存儲 PDF 到對象存儲。從 PDF 中提取文本。按固定大小切片可能做清洗和去重。生成向量索引寫入向量數(shù)據(jù)庫。下面是一段用于說明解析和切片思路的 Python 示例from typing import List def extract_text_from_pdf(pdf_path: str) - str: # 使用 pdfplumber、PyMuPDF 或底層 Poppler 工具實(shí)現(xiàn) # 實(shí)際實(shí)現(xiàn)需要按對應(yīng)庫 API 調(diào)整 return extracted_text def chunk_text(text: str, chunk_size: int 800, overlap: int 100) - List[str]: chunks [] start 0 while start len(text): end start chunk_size chunks.append(text[start:end]) start end - overlap return chunks切片參數(shù)會直接影響檢索效果。chunk_size 太大檢索到的片段可能包含大量無關(guān)內(nèi)容浪費(fèi) token太小語義可能不完整。overlap 用于避免兩個(gè)切片的邊界處語義斷裂。實(shí)際參數(shù)要結(jié)合文檔類型和模型上下文長度調(diào)整。PDF Studio 常見的使用場景是合同分析、研發(fā)文檔問答、產(chǎn)品說明書檢索。生產(chǎn)環(huán)境需要注意三點(diǎn)PDF 中包含掃描圖片時(shí)必須先做 OCR否則提取不出文字。中文 PDF 可能需要處理字體嵌入問題提取出的文本會出現(xiàn)亂碼。多語言混合文檔要統(tǒng)一編碼建議在解析后打印前幾行確認(rèn)文本質(zhì)量。3.4 1-Click Sharing一鍵分享背后的權(quán)限模型一鍵分享并不是簡單的“生成一個(gè)鏈接”。要實(shí)現(xiàn)安全的分享至少要考慮四個(gè)維度分享范圍、有效期、訪問密碼、水印或?qū)徲?jì)。常見的分享鏈接參數(shù)如下https://webui.example.com/s/Jk8a2LxQmZ后端收到這個(gè)短碼后會查分享記錄判斷鏈接是否有效、是否過期、訪問者是否有密碼然后決定返回頁面還是要求驗(yàn)證。分享記錄表可以這樣設(shè)計(jì)CREATE TABLE share_links ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), token VARCHAR(64) NOT NULL UNIQUE, resource_type VARCHAR(32) NOT NULL, -- project, conversation, document resource_id UUID NOT NULL, creator_id UUID NOT NULL, password_hash VARCHAR(255), expires_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() );生產(chǎn)環(huán)境建議給分享功能單獨(dú)配置域名不要直接暴露 WebUI 的管理端口。分享鏈接如果要支持公網(wǎng)訪問WebUI 前面必須加反向代理并且正確配置 HTTPS 證書。否則分享頁面的附件可能因?yàn)榛旌蟽?nèi)容被瀏覽器攔截。4. 對象存儲 OSS 接入阿里云 OSS、MinIO 與 S3 兼容協(xié)議4.1 統(tǒng)一用 S3 客戶端對接對象存儲主流 WebUI 項(xiàng)目在對接對象存儲時(shí)往往不是單獨(dú)實(shí)現(xiàn)阿里云 OSS SDK、MinIO SDK、騰訊云 COS SDK而是通過 S3 兼容協(xié)議統(tǒng)一封裝。S3 協(xié)議最早來自 AWS Simple Storage Service后來幾乎所有云廠商和自建系統(tǒng)都做了兼容層。這意味著你在配置界面里只需要填寫幾個(gè)核心參數(shù)STORAGE_TYPEs3 S3_ENDPOINThttps://oss-cn-hangzhou.aliyuncs.com S3_REGIONcn-hangzhou S3_ACCESS_KEYyour_access_key_id S3_SECRET_KEYyour_access_key_secret S3_BUCKETllms-webui-files S3_PATH_STYLEfalse對阿里云 OSS 來說S3_ENDPOINT必須使用對應(yīng)地域的 EndpointS3_REGION也要匹配否則上傳時(shí)會報(bào)簽名不匹配。如果 WebUI 部署在阿里云服務(wù)器內(nèi)網(wǎng)Endpoint 可以使用內(nèi)網(wǎng)地址既快又省流量。4.2 公共讀、私有讀與臨時(shí)簽名 URL 的選擇對象存儲中 bucket 的權(quán)限直接影響文件訪問方式。下面區(qū)分三種情況權(quán)限類型是否需簽名適用場景風(fēng)險(xiǎn)公共讀不需要網(wǎng)站靜態(tài)資源、公開分享的文檔任何人都能訪問泄露風(fēng)險(xiǎn)高私有讀寫需要簽名內(nèi)部項(xiàng)目文件、未公開 PDF每次訪問都要生成臨時(shí) URL較麻煩混合策略部分公共讀部分私有頭像公開讀項(xiàng)目文檔私有讀配置復(fù)雜需要明確 bucket 路徑規(guī)劃推薦做法是 bucket 默認(rèn)私有讀寫WebUI 在需要展示文件時(shí)生成帶時(shí)效的簽名 URL。比如用戶查看 PDF 時(shí)后端調(diào)用 S3 SDK 生成一個(gè)有效期 10 分鐘或一小時(shí)的訪問鏈接瀏覽器直接訪問該鏈接渲染 PDF。這樣既能限制訪問又不需要把文件下載到 WebUI 本地再轉(zhuǎn)發(fā)。4.3 用 curl 驗(yàn)證對象存儲資源是否可訪問很多團(tuán)隊(duì)在排查“頭像加載不出來”“PDF 打不開”時(shí)會把問題直接歸結(jié)為代碼 bug但更常見的原因是文件訪問權(quán)限或路徑拼接錯(cuò)誤。用 curl 可以快速定位。先測公共讀文件curl -I https://your-bucket.oss-cn-hangzhou.aliyuncs.com/projects/2025/04/readme.pdf正常響應(yīng)會返回200 OK和Content-Length。如果返回403 AccessDenied說明文件不是公共讀需要改用簽名 URL 訪問。再測簽名 URLcurl -I https://your-bucket.oss-cn-hangzhou.aliyuncs.com/projects/2025/04/readme.pdf?Expires1720000000SignaturexxxxAccessKeyIdxxxx如果簽名 URL 能訪問而普通 URL 不能訪問說明權(quán)限策略符合預(yù)期。如果簽名 URL 也返回 403優(yōu)先檢查系統(tǒng)時(shí)間是否準(zhǔn)確簽名 URL 的過期時(shí)間與服務(wù)器本地時(shí)間偏差不要超過 5 分鐘。4.4 CORS 配置瀏覽器上傳失敗的隱形原因curl 能訪問對象存儲不代表瀏覽器端能正常上傳。瀏覽器的跨域限制要求對象存儲必須配置 CORS 規(guī)則否則前端會把請求攔截掉。以阿里云 OSS 的 CORS 配置為例通常需要允許的來源、方法、請求頭如下配置項(xiàng)推薦值說明來源https://webui.example.com不要用*除非是公開演示環(huán)境允許 MethodsGET, POST, PUT, DELETE上傳通常用 PUT下載用 GET允許 Headers*允許所有請求頭便于攜帶 Content-Type暴露 HeadersETag分片上傳等場景需要暴露響應(yīng)頭緩存時(shí)間600 秒瀏覽器緩存預(yù)檢結(jié)果瀏覽器上傳失敗時(shí)F12 控制臺通常會看到類似Access to XMLHttpRequest ... has been blocked by CORS policy的報(bào)錯(cuò)。這時(shí)不要去后端翻代碼先去對象存儲控制臺檢查 CORS 規(guī)則是否生效。5. 運(yùn)行驗(yàn)證從啟動日志到功能驗(yàn)收5.1 啟動日志應(yīng)該看到哪些關(guān)鍵信息Docker 部署完成后第一步是查看運(yùn)行狀態(tài)和日志docker ps docker logs -f llms-py-webui一個(gè)正常的啟動流程通常會出現(xiàn)以下階段配置加載完成打印當(dāng)前環(huán)境變量名但不會打印完整密碼。數(shù)據(jù)庫連接成功執(zhí)行遷移腳本。對象存儲連接成功校驗(yàn)或者創(chuàng)建 bucket。模型服務(wù)連接檢測打印可用模型列表。HTTP 服務(wù)監(jiān)聽指定端口。如果日志停留在“連接數(shù)據(jù)庫”階段說明數(shù)據(jù)庫配置有問題。如果日志明確報(bào)S3ConnectionError或NoSuchBucket先去檢查對象存儲參數(shù)。如果日志顯示模型服務(wù)連接失敗而 WebUI 還能啟動說明模型服務(wù)是懶加載模式要等到第一次會話才會報(bào)錯(cuò)。5.2 功能驗(yàn)收清單建議部署完成后按下面的清單逐項(xiàng)驗(yàn)收而不是只登錄頁面看一眼。功能驗(yàn)收方式預(yù)期結(jié)果登錄注冊創(chuàng)建新用戶并登錄能進(jìn)入主頁面會話創(chuàng)建正常Projects新建項(xiàng)目進(jìn)入項(xiàng)目空間項(xiàng)目會話與普通會話隔離Agent Profiles創(chuàng)建一個(gè)運(yùn)維 Agent 并選擇它對話按 system_prompt 風(fēng)格回答PDF Studio上傳一個(gè) 10 頁以內(nèi)的 PDF文本提取成功可基于 PDF 提問對象存儲在項(xiàng)目中上傳一個(gè)附件文件出現(xiàn)在對象存儲 bucket 中不是本地磁盤1-Click Sharing生成分享鏈接用無痕瀏覽器訪問按設(shè)定的權(quán)限顯示內(nèi)容過期后訪問失敗5.3 驗(yàn)證對象存儲是否真的被使用有些項(xiàng)目在配置了對象存儲后仍可能因?yàn)榕渲庙?xiàng)未生效繼續(xù)寫本地目錄。驗(yàn)證方式很簡單往 WebUI 上傳一個(gè)文件然后去對象存儲的 bucket 目錄里找看有沒有出現(xiàn)對應(yīng)的 key。如果 bucket 里始終沒有文件但在服務(wù)器上能找到文件說明STORAGE_TYPE配置沒有實(shí)際生效或者上傳路徑走的是另一套邏輯。另一條驗(yàn)證路徑是看數(shù)據(jù)庫里文件表的存儲路徑前綴SELECT id, name, storage_path, created_at FROM files ORDER BY created_at DESC LIMIT 10;如果storage_path是s3://llms-files/xxx或https://bucket.endpoint/xxx說明已經(jīng)切換到對象存儲。如果還是/uploads/xxx這種本地相對路徑需要回到 WebUI 的運(yùn)維配置或配置文件里檢查。6. 常見問題排查按現(xiàn)象倒推原因6.1 部署類問題問題現(xiàn)象可能原因檢查方式處理建議容器啟動后立即退出環(huán)境變量缺失或數(shù)據(jù)庫無法訪問docker logs查看退出前日志補(bǔ)齊環(huán)境變量確認(rèn)數(shù)據(jù)庫健康鏡像拉取速度慢或超時(shí)網(wǎng)絡(luò)到鏡像倉庫不穩(wěn)定執(zhí)行docker pull測試配置鏡像加速器或換標(biāo)簽重試頁面能開但無法登錄數(shù)據(jù)庫初始用戶未創(chuàng)建檢查數(shù)據(jù)庫表中用戶記錄按官方初始化流程創(chuàng)建管理員登錄后會話丟失Redis/Session 存儲未配置查看會話相關(guān)日志配置持久化會話存儲WebUI 域名背后的靜態(tài)資源 404前端資源路徑配置錯(cuò)誤打開瀏覽器控制臺看請求路徑設(shè)置正確的PUBLIC_BASE_URL或反向代理路徑6.2 對象存儲和文件類問題問題現(xiàn)象可能原因檢查方式處理建議圖片上傳失敗bucket 不存在或 CORS 未配置瀏覽器控制臺查看 CORS 錯(cuò)誤創(chuàng)建 bucket配置 CORSPDF 訪問顯示 403文件私有讀未使用簽名 URLcurl 訪問文件 URL打開簽名 URL 功能上傳報(bào)簽名不匹配本地時(shí)間偏差超過 5 分鐘執(zhí)行date查看服務(wù)器時(shí)間配置 NTP 時(shí)間同步文件上傳成功但刷新后丟失數(shù)據(jù)庫文件記錄與對象存儲不一致檢查數(shù)據(jù)庫文件表確認(rèn)上傳接口是否同時(shí)寫庫和寫存儲中文文件名亂碼URL 編碼處理不當(dāng)查看對象存儲中的 key使用 UUID 或編碼后的文件名存儲6.3 模型和會話類問題問題現(xiàn)象可能原因檢查方式處理建議保存 Agent Profile 后對話無變化繼續(xù)使用了舊會話新建會話再測試修改 Profile 后另開會話模型總是超時(shí)模型服務(wù)吞吐不足查看模型服務(wù)日志加大并發(fā)或更換更快的模型PDF 知識庫回答不到內(nèi)容文檔切片或檢索參數(shù)不合理在知識庫中手動搜索關(guān)鍵詞調(diào)小 chunk_size重建索引分享鏈接打開后提示 502反向代理未轉(zhuǎn)發(fā)或域名配置錯(cuò)誤curl 查看返回頭檢查 Nginx 到 WebUI 的轉(zhuǎn)發(fā)鏈路6.4 分享鏈接無法訪問的排查鏈路分享鏈接是最容易暴露網(wǎng)絡(luò)配置問題的一個(gè)功能。從用戶點(diǎn)擊鏈接到頁面展示中間有多個(gè)環(huán)節(jié)。排查時(shí)建議按這個(gè)順序先確認(rèn)鏈接本身是否能訪問。用 curl 訪問短鏈接看返回是 200、302 還是 502。再確認(rèn)短鏈接轉(zhuǎn)發(fā)的目標(biāo)地址。302 跳轉(zhuǎn)后要檢查最終 URL 是否指向正確域名。確認(rèn)目標(biāo)域名能否解析到服務(wù)器。本地可以改 hosts 測試避免 DNS 緩存干擾。確認(rèn)反向代理配置。Nginx 的 location 是否正確轉(zhuǎn)發(fā)到 WebUI 容器端口。確認(rèn)分享記錄是否有效。數(shù)據(jù)庫中看 share_links 表檢查過期時(shí)間和資源 ID 是否存在。如果頁面能打開但附件加載失敗回到上一步檢查對象存儲的簽名 URL 和 CORS 配置。注意排查網(wǎng)絡(luò)問題時(shí)要先抓“能訪問”和“不能訪問”的具體差異比如內(nèi)網(wǎng)可以訪問而公網(wǎng)不行還是普通瀏覽器可以而無痕模式不行。這些差異能幫助快速縮小問題范圍。7. 最佳實(shí)踐從試用走向穩(wěn)定運(yùn)行7.1 學(xué)習(xí)環(huán)境與生產(chǎn)環(huán)境的分界很多團(tuán)隊(duì)習(xí)慣先在一臺服務(wù)器上把全部服務(wù)跑起來用久了之后發(fā)現(xiàn)數(shù)據(jù)、文件、配置都混在一起難以遷移。建議從一開始就區(qū)分兩套環(huán)境維度學(xué)習(xí)/試用環(huán)境生產(chǎn)環(huán)境數(shù)據(jù)庫隨 WebUI 容器一起部署使用獨(dú)立數(shù)據(jù)庫實(shí)例定期備份對象存儲MinIO 單節(jié)點(diǎn)云廠商 OSS 或高可用 MinIO模型服務(wù)本地測試模型或 API帶監(jiān)控和限流的模型網(wǎng)關(guān)HTTPS可暫緩必須配置否則分享和附件功能受限日志控制臺輸出集中采集按天歸檔升級可直接拉最新鏡像先備份數(shù)據(jù)再灰度升級如果團(tuán)隊(duì)決定長期使用這個(gè) WebUI要盡量讓 WebUI 應(yīng)用本身保持無狀態(tài)。會話數(shù)據(jù)放數(shù)據(jù)庫文件數(shù)據(jù)放對象存儲WebUI 容器可以隨時(shí)銷毀重建這樣升級、擴(kuò)容、遷移都容易。7.2 配置管理建議不要把對象存儲的 AccessKey 明文寫在 docker-compose 文件里尤其是包含了 Secret Key 的情況下。建議通過環(huán)境變量文件或者密鑰管理服務(wù)注入。以 docker-compose 為例可以使用.env文件加載但.env文件不要提交到代碼倉庫。STORAGE_TYPEs3 S3_ACCESS_KEYyour_ak S3_SECRET_KEYyour_sk更嚴(yán)格的場景可以用 Vault、KMS 等密鑰管理服務(wù)在 WebUI 啟動前把密鑰注入到容器環(huán)境變量。生產(chǎn)環(huán)境還建議給對象存儲配置獨(dú)立的 IAM 權(quán)限只允許 WebUI 訪問特定 bucket 的指定前綴避免出現(xiàn) AccessKey 泄露后的橫向越權(quán)。7.3 數(shù)據(jù)備份和容災(zāi)WebUI 的數(shù)據(jù)可以分為三類數(shù)據(jù)庫中的業(yè)務(wù)數(shù)據(jù)、對象存儲中的文件、配置文件。備份策略要覆蓋這三類。數(shù)據(jù)庫可以用定時(shí)任務(wù)執(zhí)行 pg_dump 或類似工具pg_dump llms /backup/llms_$(date %Y%m%d).sql對象存儲建議開啟版本控制或跨區(qū)域復(fù)制。如果使用的是云廠商對象存儲可以直接開啟服務(wù)端版本控制用來防止誤刪和文件覆蓋。自建 MinIO 也要開啟 Versioning并定期把 bucket 同步到異地存儲。7.4 二次開發(fā)擴(kuò)展點(diǎn)如果一個(gè) WebUI 項(xiàng)目滿足不了所有需求通常可以在以下幾個(gè)位置做二次開發(fā)擴(kuò)展位置典型需求實(shí)現(xiàn)方式認(rèn)證層對接企業(yè) SSO/LDAP實(shí)現(xiàn)自定義認(rèn)證過濾器或 OAuth 插件Agent 工具層接入內(nèi)部運(yùn)維系統(tǒng)新增自定義工具注冊到工具列表PDF 解析層增加 OCR 能力接入 Tesseract 或云 OCR 服務(wù)分享服務(wù)增加分享審批流在生成分享鏈接前插入審批邏輯數(shù)據(jù)層切換向量數(shù)據(jù)庫替換向量存儲實(shí)現(xiàn)保持接口一致擴(kuò)展時(shí)最需要注意的是保持主流程穩(wěn)定。新增功能最好做成獨(dú)立服務(wù)或插件不要輕易修改核心會話管理邏輯。因?yàn)檫@類改動容易影響所有用戶。7.5 給團(tuán)隊(duì)的落地建議把 Llms.py v4 這樣的 WebUI 真正引入團(tuán)隊(duì)可以按三個(gè)階段推進(jìn)。第一階段先讓 3 到 5 名核心成員試用重點(diǎn)驗(yàn)證 Projects 和 Agent Profiles 是否符合協(xié)作方式。第二階段把團(tuán)隊(duì)常用文檔導(dǎo)入 PDF Studio建立知識庫觀察模型答案的準(zhǔn)確率。第三階段再開放分享功能制定分享審批規(guī)則進(jìn)入穩(wěn)定運(yùn)行。整個(gè)過程中最值得投入的是 Agent Profiles 和知識庫的調(diào)優(yōu)。一個(gè)好的 Agent Profile 可以大幅減少用戶重復(fù)描述一個(gè)結(jié)構(gòu)清晰的知識庫能讓 PDF 回答效果明顯提升。界面上增加和刪除功能很容易難的是把這些功能固化成團(tuán)隊(duì)可復(fù)用的工作流。這也是 v4 從“工具”走向“工作臺”的核心價(jià)值所在。