庫(kù)部署調(diào)優(yōu))
做本地知識(shí)庫(kù)這件事我從最初只想把幾份產(chǎn)品手冊(cè)塞進(jìn)模型里問(wèn)答到后來(lái)給幾個(gè)小團(tuán)隊(duì)做內(nèi)部文檔檢索前后折騰了兩年多。中間換過(guò)三輪方案踩過(guò)的坑能寫(xiě)滿(mǎn)兩頁(yè)紙。最后穩(wěn)定下來(lái)的組合就是Ollama 跑模型、Open WebUI 當(dāng)日常對(duì)話(huà)入口、AnythingLLM 管知識(shí)庫(kù)和檢索。這套組合最大的好處是全部跑在自己機(jī)器或內(nèi)網(wǎng)服務(wù)器上文件不出局域網(wǎng)模型不調(diào)用外部接口費(fèi)用是一次性硬件投入后續(xù)零調(diào)用成本。它適合兩類(lèi)人一類(lèi)是對(duì)資料保密有要求的個(gè)人比如手上有些合同模板、技術(shù)筆記、研究草稿不想往云端傳另一類(lèi)是十幾到幾十人規(guī)模的小團(tuán)隊(duì)需要一套能查內(nèi)部文檔、又不愿意每年付訂閱費(fèi)的問(wèn)答系統(tǒng)。這篇文章我會(huì)把整套東西從選型到落地拆開(kāi)講包括每個(gè)參數(shù)為什么這么設(shè)、哪里最容易翻車(chē)、以及我實(shí)測(cè)下來(lái)比較穩(wěn)的配置組合。1. 整體架構(gòu)怎么搭以及為什么這么搭1.1 三層分離模型、界面、知識(shí)層各管一段很多人一開(kāi)始會(huì)想找一個(gè)“全能軟件”把模型、界面、知識(shí)庫(kù)全包了省事。我試過(guò)結(jié)論是不劃算。全能型工具往往在某一塊特別弱要么模型選擇受限要么文檔解析拉胯要么界面難用。分層之后每層都能單獨(dú)替換出問(wèn)題也容易定位。我現(xiàn)在的結(jié)構(gòu)是這樣層級(jí)承擔(dān)角色具體組件替換成本模型層提供推理能力與向量化能力Ollama 服務(wù)常駐在 11434 端口低換個(gè)模型名就行界面層日常對(duì)話(huà)、多輪上下文、賬號(hào)管理Open WebUI中可換成任意兼容接口的前端知識(shí)層文檔解析、分塊、向量存儲(chǔ)、檢索召回AnythingLLM中數(shù)據(jù)在 storage 目錄里可遷移關(guān)鍵點(diǎn)在于Ollama 提供的是標(biāo)準(zhǔn) HTTP 接口AnythingLLM 和 Open WebUI 都能直接對(duì)接它。這就意味著模型層是公共底座上面兩個(gè)應(yīng)用是平行的消費(fèi)者互不干擾。我平時(shí)用 Open WebUI 做通用問(wèn)答和代碼輔助用 AnythingLLM 專(zhuān)門(mén)查內(nèi)部文檔兩個(gè)入口分開(kāi)避免把閑聊上下文和檢索上下文混在一起污染回答。還有個(gè)細(xì)節(jié)AnythingLLM 自己也能當(dāng)聊天界面用那為什么還要 Open WebUI我的理由是 Open WebUI 的多輪對(duì)話(huà)體驗(yàn)、模型切換、提示詞預(yù)設(shè)更順手適合“問(wèn)模型本身”的場(chǎng)景AnythingLLM 的強(qiáng)項(xiàng)是文檔工作區(qū)和引用溯源適合“問(wèn)我的資料”的場(chǎng)景。硬塞進(jìn)一個(gè)界面里兩邊都不舒服。1.2 不上云的真實(shí)理由數(shù)據(jù)邊界和成本賬先說(shuō)數(shù)據(jù)邊界。企業(yè)文檔里最敏感的不是技術(shù)文檔是合同、報(bào)價(jià)、客戶(hù)名單、內(nèi)部復(fù)盤(pán)。這些東西一旦上傳到外部服務(wù)你就失去了對(duì)它的控制權(quán)哪怕對(duì)方承諾不訓(xùn)練審計(jì)上也過(guò)不去。本地部署的價(jià)值不在于“更安全”這種空話(huà)而在于物理隔離拔掉網(wǎng)線系統(tǒng)照樣能問(wèn)答。再說(shuō)成本。我?guī)鸵粋€(gè)小團(tuán)隊(duì)算過(guò)賬20 人規(guī)模如果按人頭訂閱云端問(wèn)答服務(wù)一年下來(lái)是四位數(shù)到五位數(shù)不等的支出而且隨著文檔量增長(zhǎng)向量存儲(chǔ)還要另外計(jì)費(fèi)。本地方案的成本結(jié)構(gòu)完全不同一次性硬件一臺(tái)帶 24GB 顯存的機(jī)器或者二手的同規(guī)格卡價(jià)格固定電費(fèi)滿(mǎn)載 300W 左右按每天跑 4 小時(shí)算一年電費(fèi)可以忽略軟件全部開(kāi)源零授權(quán)費(fèi)隱性成本你自己的時(shí)間部署加調(diào)優(yōu)大概兩三天對(duì)于長(zhǎng)期使用的場(chǎng)景本地方案在 8 到 14 個(gè)月左右回本之后全是凈收益。但如果只是臨時(shí)查幾份 PDF那真沒(méi)必要折騰直接用現(xiàn)成服務(wù)更省事。選型的第一原則是匹配使用強(qiáng)度和保密要求而不是技術(shù)潔癖。1.3 硬件與模型的匹配測(cè)算別拍腦袋買(mǎi)卡這是最容易花冤枉錢(qián)的地方。模型能不能跑核心看顯存。粗略的估算方式是顯存占用 ≈ 參數(shù)量 × 每參數(shù)字節(jié)數(shù) 上下文緩存量化等級(jí)決定每參數(shù)字節(jié)數(shù)。Q4_K_M 大約 0.55 到 0.6 字節(jié)/參數(shù)Q8 大約 1 字節(jié)/參數(shù)FP16 是 2 字節(jié)/參數(shù)。實(shí)際還要加上 KV 緩存跟上下文長(zhǎng)度和層數(shù)相關(guān)長(zhǎng)上下文時(shí)這部分能占到幾個(gè) GB。我整理了一張常用檔位的實(shí)測(cè)參考表單卡、Q4_K_M 量化、上下文 8K模型規(guī)模權(quán)重大小實(shí)際顯存占用機(jī)器配置建議適用場(chǎng)景7B / 8B約 4.5GB6 到 7GB8GB 顯存或 16GB 內(nèi)存純 CPU簡(jiǎn)單問(wèn)答、摘要速度可接受14B約 9GB11 到 12GB12GB 顯存日常主力性?xún)r(jià)比最高32B約 20GB23 到 25GB24GB 顯存復(fù)雜推理、長(zhǎng)文檔理解70B約 40GB45GB 以上雙卡或大內(nèi)存 CPU 推理效果最好但速度慢一般不推薦純 CPU 也能跑只是速度按 token/秒 算會(huì)掉到個(gè)位數(shù)7B 在普通桌面 CPU 上大概 3 到 6 token/s讀一段回答要等半分鐘。如果只是偶爾查資料能忍如果天天用還是建議上顯卡。還有一個(gè)常被忽略的點(diǎn)嵌入模型也要吃資源。文檔入庫(kù)時(shí)要把每個(gè)分塊轉(zhuǎn)成向量這個(gè)過(guò)程是批量的如果嵌入模型太大首次入庫(kù)會(huì)非常慢。我的建議是嵌入模型和對(duì)話(huà)模型分開(kāi)選嵌入用輕量的專(zhuān)用模型對(duì)話(huà)用大一點(diǎn)的通用模型。2. Ollama 部署與模型選型的實(shí)操細(xì)節(jié)2.1 部署前的環(huán)境檢查清單裝之前先確認(rèn)幾件事能省掉后面一半的麻煩系統(tǒng)是 64 位 Linux、macOS 或 WindowsLinux 建議較新的內(nèi)核版本否則容器網(wǎng)絡(luò)會(huì)有奇怪問(wèn)題磁盤(pán)至少留 50GB模型文件比想象中大一個(gè) 14B 模型加嵌入模型輕松吃掉 15GB如果用容器部署上層應(yīng)用先確認(rèn) Docker 或同類(lèi)容器運(yùn)行時(shí)能正常工作內(nèi)網(wǎng)服務(wù)器要確認(rèn)防火墻策略后面要放行幾個(gè)端口關(guān)閉系統(tǒng)的休眠和自動(dòng)更新重啟半夜重啟服務(wù)是運(yùn)維事故的常見(jiàn)原因還有一個(gè)隱形坑模型目錄的磁盤(pán)掛載。默認(rèn)模型存在用戶(hù)主目錄下如果主目錄分區(qū)很小拉到一半報(bào)磁盤(pán)滿(mǎn)。建議提前把模型目錄指到大容量分區(qū)用環(huán)境變量控制。2.2 安裝與模型拉取安裝走官方腳本最省事注意腳本地址從官方文檔取不要用來(lái)源不明的鏡像# 從官方渠道獲取安裝腳本并執(zhí)行 curl -fsSL 官方安裝腳本地址 | sh # 確認(rèn)服務(wù)已啟動(dòng) systemctl status ollama # 檢查版本 ollama --version服務(wù)起來(lái)后默認(rèn)監(jiān)聽(tīng)本地 11434 端口。這里有個(gè)必須改的配置如果上層應(yīng)用跑在容器里默認(rèn)只聽(tīng) 127.0.0.1 會(huì)導(dǎo)致容器連不上。需要讓它監(jiān)聽(tīng)所有網(wǎng)卡# 修改服務(wù)配置讓 Ollama 監(jiān)聽(tīng)所有網(wǎng)卡 sudo systemctl edit ollama # 在編輯器中加入 [Service] EnvironmentOLLAMA_HOST0.0.0.0:11434 EnvironmentOLLAMA_MODELS/data/ollama/models EnvironmentOLLAMA_KEEP_ALIVE30m # 重載并重啟 sudo systemctl daemon-reload sudo systemctl restart ollama三個(gè)環(huán)境變量分別解決三個(gè)問(wèn)題OLLAMA_HOST讓容器能訪問(wèn)OLLAMA_MODELS把模型存到大盤(pán)OLLAMA_KEEP_ALIVE讓模型在內(nèi)存里多待一會(huì)兒避免每次提問(wèn)都重新加載。最后這個(gè)特別重要默認(rèn)只有 5 分鐘超過(guò)就卸載下一次提問(wèn)要等十幾秒加載。設(shè)成 30 分鐘之后連續(xù)使用體驗(yàn)差別巨大。拉模型# 對(duì)話(huà)模型14B 級(jí)別日常夠用 ollama pull qwen2.5:14b # 小一點(diǎn)的備選硬件緊張時(shí)用 ollama pull llama3.1:8b # 嵌入模型專(zhuān)門(mén)做向量化體積小速度快 ollama pull bge-m3 # 查看已安裝模型 ollama list # 簡(jiǎn)單驗(yàn)證推理是否正常 ollama run qwen2.5:14b 用一句話(huà)說(shuō)明向量檢索的原理2.3 模型檔位怎么選不是越大越好我在這上面走過(guò)最大的彎路就是迷信大模型。一開(kāi)始上 32B覺(jué)得效果肯定好結(jié)果發(fā)現(xiàn)三個(gè)問(wèn)題加載慢、并發(fā)差、長(zhǎng)文檔一塞就爆上下文。后來(lái)退回 14B實(shí)際使用滿(mǎn)意度反而更高。我的判斷標(biāo)準(zhǔn)是這樣的使用強(qiáng)度推薦檔位理由個(gè)人每天幾十次問(wèn)答7B 到 8B響應(yīng)快顯存占用低能同時(shí)跑嵌入模型個(gè)人主力每天上百次14B理解力和速度的平衡點(diǎn)中文表達(dá)也更自然團(tuán)隊(duì)共用3 到 10 人14B 加并發(fā)限制單卡能撐住配合隊(duì)列避免排隊(duì)過(guò)久復(fù)雜文檔分析、代碼審查32B只在需要深度推理時(shí)切換不做常駐還有一個(gè)經(jīng)驗(yàn)同一檔位下選中文語(yǔ)料訓(xùn)練更充分的模型。這個(gè)差別在中文問(wèn)答上非常明顯英文強(qiáng)中文弱的模型經(jīng)常在專(zhuān)業(yè)術(shù)語(yǔ)上翻車(chē)把“向量維度”理解成幾何概念。測(cè)試方法是拿三五個(gè)你業(yè)務(wù)里的真實(shí)問(wèn)題去問(wèn)看回答是否貼合領(lǐng)域比看榜單有用得多。2.4 嵌入模型的單獨(dú)考量嵌入模型不參與對(duì)話(huà)只負(fù)責(zé)把文本轉(zhuǎn)成向量。它的選擇直接影響檢索質(zhì)量重要性被嚴(yán)重低估。選型時(shí)看三點(diǎn)第一是維度。維度高表達(dá)能力更強(qiáng)但存儲(chǔ)和計(jì)算成本也高。常見(jiàn)的有 768 維、1024 維。幾百份文檔的規(guī)模1024 維完全夠用。第二是多語(yǔ)言支持。中文文檔必須選對(duì)中文友好的嵌入模型純英文模型在中文上召回率會(huì)明顯下降因?yàn)樗鼘?duì)中文的語(yǔ)義空間建模不充分。第三是最大輸入長(zhǎng)度。如果分塊設(shè)成 1024 token嵌入模型的最大長(zhǎng)度至少要覆蓋這個(gè)值否則會(huì)被截?cái)鄩K尾的信息直接丟失。配置上Ollama 拉下來(lái)的嵌入模型可以直接在 AnythingLLM 里選。切換嵌入模型要注意換了嵌入模型之前入庫(kù)的向量全部失效必須清空重新向量化。這個(gè)坑我踩過(guò)一次換了模型沒(méi)重新入庫(kù)檢索結(jié)果全是亂的排查了半天才想起來(lái)。3. Open WebUI 的部署與訪問(wèn)控制3.1 容器化部署與端口規(guī)劃Open WebUI 我推薦用容器跑依賴(lài)干凈升級(jí)方便。端口規(guī)劃上要提前想好避免和已有服務(wù)沖突。我習(xí)慣的規(guī)劃是11434Ollama 模型服務(wù)3000Open WebUI 對(duì)話(huà)界面3001AnythingLLM 知識(shí)庫(kù)界面部署命令大致長(zhǎng)這樣鏡像地址以官方文檔為準(zhǔn)docker run -d \ --name open-webui \ --restart always \ -p 3000:8080 \ -e OLLAMA_BASE_URLhttp://host.docker.internal:11434 \ -e WEBUI_SECRET_KEY自定義長(zhǎng)隨機(jī)串 \ -e DEFAULT_MODELSqwen2.5:14b \ -v /data/open-webui:/app/backend/data \ 官方鏡像名:main幾個(gè)參數(shù)值得單獨(dú)解釋OLLAMA_BASE_URL是關(guān)鍵。容器里的localhost指的是容器自己不是宿主機(jī)。Linux 上host.docker.internal不一定默認(rèn)可用穩(wěn)妥的做法是用宿主機(jī)的內(nèi)網(wǎng) IP或者在啟動(dòng)容器時(shí)加--add-hosthost.docker.internal:host-gateway。這個(gè)配置錯(cuò)一次界面能打開(kāi)但模型列表是空的很多人卡在這一步。WEBUI_SECRET_KEY必須設(shè)不設(shè)的話(huà)每次重啟會(huì)話(huà)密鑰都變用戶(hù)全部被登出。生成一個(gè)長(zhǎng)隨機(jī)串固定下來(lái)。--restart always別忘了服務(wù)器重啟后服務(wù)自動(dòng)起來(lái)不然第二天上班發(fā)現(xiàn)系統(tǒng)掛了。數(shù)據(jù)卷掛載到宿主機(jī)目錄升級(jí)容器時(shí)數(shù)據(jù)不丟。這條是血淚教訓(xùn)我有次直接docker rm重建所有對(duì)話(huà)記錄和配置一起沒(méi)了。3.2 賬號(hào)體系與內(nèi)網(wǎng)訪問(wèn)邊界Open WebUI 默認(rèn)第一個(gè)注冊(cè)的賬號(hào)是管理員后面注冊(cè)的是普通用戶(hù)。這個(gè)設(shè)計(jì)很方便但也意味著部署完第一件事就是立刻注冊(cè)管理員賬號(hào)否則誰(shuí)先訪問(wèn)誰(shuí)就是管理員。訪問(wèn)控制我建議做三層第一層是網(wǎng)絡(luò)層。這套系統(tǒng)只在內(nèi)網(wǎng)使用不要在公網(wǎng)暴露端口。如果確實(shí)需要遠(yuǎn)程訪問(wèn)走內(nèi)網(wǎng)穿透或者專(zhuān)線別直接把端口映射到公網(wǎng)。第二層是應(yīng)用層。關(guān)閉開(kāi)放注冊(cè)改成管理員手動(dòng)創(chuàng)建賬號(hào)。設(shè)置路徑在管理面板的賬號(hào)設(shè)置里把“允許新用戶(hù)注冊(cè)”關(guān)掉。團(tuán)隊(duì)規(guī)模小的時(shí)候手動(dòng)建號(hào)最省心。第三層是數(shù)據(jù)層。定期備份數(shù)據(jù)目錄尤其是對(duì)話(huà)記錄和用戶(hù)配置。備份策略我一般用每天增量、每周全量保留四周。還有一個(gè)容易忽略的點(diǎn)用戶(hù)之間的會(huì)話(huà)是隔離的但知識(shí)庫(kù)不一定。如果讓 Open WebUI 和 AnythingLLM 共用同一個(gè)模型服務(wù)模型本身沒(méi)有權(quán)限概念誰(shuí)都能調(diào)用。所以涉及分部門(mén)資料隔離的場(chǎng)景要靠 AnythingLLM 的工作區(qū)權(quán)限來(lái)控制而不是指望模型層。3.3 對(duì)接 Ollama 的常見(jiàn)故障界面能打開(kāi)但模型列表空白這是最高頻的問(wèn)題八成是網(wǎng)絡(luò)不通。排查順序在宿主機(jī)上curl http://localhost:11434/api/tags看有沒(méi)有返回模型列表在容器內(nèi)docker exec -it open-webui curl http://host.docker.internal:11434/api/tags看容器能不能通檢查 Ollama 是否設(shè)了OLLAMA_HOST0.0.0.0檢查宿主機(jī)防火墻有沒(méi)有攔 11434 端口如果第 2 步不通但第 1 步通那就是容器網(wǎng)絡(luò)問(wèn)題換用宿主機(jī)內(nèi)網(wǎng) IP 通常能解決。另一個(gè)問(wèn)題是回答到一半中斷。原因通常是上下文超限或者模型被卸載。前者調(diào)小上下文長(zhǎng)度參數(shù)后者加大OLLAMA_KEEP_ALIVE。還有一種情況是顯存不夠模型加載到一半被系統(tǒng)殺掉日志里能看到 OOM 字樣這時(shí)候只能換小模型。4. AnythingLLM 知識(shí)庫(kù)的搭建與調(diào)優(yōu)4.1 工作區(qū)劃分與文檔投喂策略AnythingLLM 的核心概念是“工作區(qū)”Workspace一個(gè)工作區(qū)就是一個(gè)獨(dú)立的知識(shí)庫(kù)加一套對(duì)話(huà)上下文。劃分工作區(qū)的原則不是按文檔類(lèi)型而是按提問(wèn)場(chǎng)景。比如“產(chǎn)品資料”一個(gè)區(qū)、“技術(shù)文檔”一個(gè)區(qū)、“行政制度”一個(gè)區(qū)。這樣檢索時(shí)范圍更聚焦召回準(zhǔn)確率會(huì)明顯提升。我見(jiàn)過(guò)有人把所有文檔塞進(jìn)一個(gè)工作區(qū)結(jié)果問(wèn)產(chǎn)品參數(shù)的時(shí)候檢索出一堆行政通知回答自然跑偏。分區(qū)的本質(zhì)是給檢索加一個(gè)前置過(guò)濾條件。文檔投喂這塊格式支持挺全PDF、Word、Markdown、純文本、網(wǎng)頁(yè)都能進(jìn)。但有幾點(diǎn)必須注意掃描版 PDF 沒(méi)有文字層直接扔進(jìn)去解析出來(lái)是空的。這類(lèi)文件必須先做文字識(shí)別轉(zhuǎn)成可搜索的 PDF 或者純文本否則入庫(kù)了也檢索不到。判斷方法很簡(jiǎn)單用閱讀器試著選中文字選不中就說(shuō)明是圖片。表格類(lèi)文檔容易被切碎。一份參數(shù)表如果按字符數(shù)硬切行和列會(huì)錯(cuò)位檢索出來(lái)的片段沒(méi)法看。這類(lèi)文檔建議先轉(zhuǎn)成 Markdown 表格再入庫(kù)結(jié)構(gòu)保留完整。超長(zhǎng)文檔要做章節(jié)拆分。幾百頁(yè)的手冊(cè)直接入庫(kù)分塊后每塊都是碎片語(yǔ)義不完整。我的做法是按章節(jié)拆成多個(gè)文件再傳天然形成語(yǔ)義邊界。入庫(kù)方式有兩種一是上傳文件二是給一個(gè)網(wǎng)頁(yè)地址讓它抓取。網(wǎng)頁(yè)抓取適合內(nèi)部 Wiki但注意抓取范圍別把導(dǎo)航欄和頁(yè)腳重復(fù)抓進(jìn)每一頁(yè)會(huì)嚴(yán)重污染檢索結(jié)果。4.2 分塊與檢索參數(shù)這幾個(gè)數(shù)值決定成敗這是整篇文章最值錢(qián)的部分。默認(rèn)參數(shù)能用但效果離“好用”差得遠(yuǎn)。核心參數(shù)就四個(gè)參數(shù)默認(rèn)值附近我常用的值作用與調(diào)整邏輯分塊大小1000 字符左右512 到 800 token太大語(yǔ)義混雜太小語(yǔ)義殘缺分塊重疊20 到 5080 到 120 token防止句子被切斷重疊太少會(huì)丟上下文召回?cái)?shù)量 TopN44 到 6太多會(huì)引入噪音太少會(huì)漏關(guān)鍵信息相似度閾值0.25 左右0.2 到 0.3太高召回不足太低全是無(wú)關(guān)內(nèi)容分塊大小的判斷標(biāo)準(zhǔn)是一個(gè)塊能不能獨(dú)立講清一件事。中文大概 500 到 800 字是一個(gè)自然段落的量級(jí)對(duì)應(yīng) 512 到 800 token。如果你的文檔是條文式的短句比如制度條款可以切小一點(diǎn)400 左右如果是敘述性長(zhǎng)文可以切大到 1000。重疊的作用是保險(xiǎn)。舉個(gè)例子一句話(huà)被切在兩塊中間前半句在第一塊末尾后半句在第二塊開(kāi)頭檢索時(shí)只召回其中一塊模型就只能看到半句話(huà)。加上 100 token 的重疊兩塊都包含完整句子就不會(huì)丟。閾值這個(gè)參數(shù)最需要實(shí)測(cè)。設(shè) 0.25 意味著相似度低于這個(gè)分?jǐn)?shù)的片段直接丟掉。如果你的文檔用詞和提問(wèn)用詞差異大比如文檔寫(xiě)“采購(gòu)審批流程”用戶(hù)問(wèn)“買(mǎi)東西怎么申請(qǐng)”閾值設(shè)高了就什么都召不回來(lái)。這種情況要么降低閾值要么在文檔里補(bǔ)充同義表述。4.3 提示詞模板與引用溯源AnythingLLM 允許自定義系統(tǒng)提示詞這是提升回答質(zhì)量最便宜的手段。默認(rèn)提示詞比較泛我一般改成這樣幾個(gè)要求你是內(nèi)部資料檢索助手。請(qǐng)嚴(yán)格依據(jù)提供的上下文片段回答問(wèn)題。 規(guī)則 1. 只使用上下文中的信息不要引入外部知識(shí)補(bǔ)充。 2. 如果上下文中沒(méi)有相關(guān)信息直接回答“資料中未找到相關(guān)內(nèi)容”不要猜測(cè)。 3. 回答時(shí)標(biāo)注信息來(lái)源的文檔名和章節(jié)。 4. 涉及數(shù)字、日期、金額時(shí)必須原文引用不要改寫(xiě)。 5. 用簡(jiǎn)體中文回答語(yǔ)言簡(jiǎn)潔不使用客套話(huà)。這幾條規(guī)則解決四個(gè)真實(shí)問(wèn)題模型愛(ài)編造、愛(ài)客套、愛(ài)改寫(xiě)數(shù)字、不給出處。尤其是第 4 條涉及金額和日期的時(shí)候模型“順手”把 3 個(gè)工作日改成 5 個(gè)工作日這種錯(cuò)誤最致命。引用溯源功能要打開(kāi)。它會(huì)在回答后面附上引用的文檔片段和來(lái)源方便核對(duì)。剛開(kāi)始用的時(shí)候我建議每次都點(diǎn)開(kāi)引用看一眼確認(rèn)模型是真的讀了文檔還是在編。用兩周之后你就能判斷哪些回答可信、哪些需要復(fù)核。溫度參數(shù)也要調(diào)。知識(shí)庫(kù)問(wèn)答不需要?jiǎng)?chuàng)造性溫度設(shè) 0.1 到 0.3 之間讓回答穩(wěn)定、可復(fù)現(xiàn)。默認(rèn)值偏高的話(huà)同一個(gè)問(wèn)題問(wèn)兩次答案不一樣用起來(lái)很難受。4.4 多用戶(hù)與權(quán)限邊界AnythingLLM 支持多用戶(hù)模式開(kāi)啟后可以給不同用戶(hù)分配不同工作區(qū)的訪問(wèn)權(quán)限。這對(duì)小團(tuán)隊(duì)很實(shí)用行政資料只給行政看技術(shù)文檔全員可見(jiàn)財(cái)務(wù)相關(guān)的單獨(dú)建區(qū)。開(kāi)啟多用戶(hù)需要注意幾點(diǎn)一是必須設(shè)置管理員賬號(hào)二是每個(gè)用戶(hù)的工作區(qū)權(quán)限要單獨(dú)配置三是默認(rèn)情況下新用戶(hù)看不到任何工作區(qū)需要手動(dòng)授權(quán)。權(quán)限配置界面不算直觀第一次配容易漏。還有一個(gè)現(xiàn)實(shí)問(wèn)題模型服務(wù)本身沒(méi)有權(quán)限隔離。用戶(hù)在 AnythingLLM 里看不到某個(gè)工作區(qū)但如果他知道模型服務(wù)地址理論上可以直接調(diào)用。所以真正的隔離要靠網(wǎng)絡(luò)層比如把模型服務(wù)只監(jiān)聽(tīng)內(nèi)網(wǎng)、用防火墻限制來(lái)源 IP。應(yīng)用層的權(quán)限更多是防誤操作不是防惡意訪問(wèn)。5. 檢索效果調(diào)優(yōu)與實(shí)測(cè)記錄5.1 文檔清洗比換模型更有用這句話(huà)我想強(qiáng)調(diào)三遍。很多人檢索效果差第一反應(yīng)是換更大的模型實(shí)際上八成的質(zhì)量問(wèn)題出在文檔本身。我做過(guò)一次對(duì)比。同一批 200 份技術(shù)文檔第一輪直接入庫(kù)問(wèn) 20 個(gè)標(biāo)準(zhǔn)問(wèn)題答對(duì) 11 個(gè)。第二輪做了清洗去掉頁(yè)眉頁(yè)腳、統(tǒng)一術(shù)語(yǔ)表述、把表格轉(zhuǎn)成 Markdown、按章節(jié)拆分文件、補(bǔ)上文檔標(biāo)題和版本號(hào)同樣的模型和參數(shù)答對(duì) 17 個(gè)。模型一個(gè)字沒(méi)改效果提升 55%。清洗清單我總結(jié)成這幾條刪除重復(fù)的頁(yè)眉頁(yè)腳、頁(yè)碼、水印文字統(tǒng)一同義詞比如“客戶(hù)端”和“用戶(hù)端”選一個(gè)另一個(gè)在檢索時(shí)靠同義詞擴(kuò)展補(bǔ)表格保留結(jié)構(gòu)用 Markdown 或明確的分隔符每份文檔開(kāi)頭加三行元信息文檔名、版本、適用范圍按章節(jié)拆分成獨(dú)立文件文件名帶上章節(jié)號(hào)去掉目錄頁(yè)和修訂記錄頁(yè)這些內(nèi)容沒(méi)有檢索價(jià)值還容易誤召回最后那條特別有用。目錄頁(yè)里堆滿(mǎn)了章節(jié)標(biāo)題語(yǔ)義密度高但信息量為零特別容易被誤召回然后模型拿著一堆標(biāo)題硬編答案。5.2 分塊參數(shù)的實(shí)測(cè)對(duì)比我在同一批文檔上做了幾組分塊實(shí)驗(yàn)用 30 個(gè)問(wèn)題的命中率作為指標(biāo)命中指召回的片段中至少有一塊包含正確答案分塊大小重疊TopN閾值命中率觀察10005040.2568%塊太大語(yǔ)義混雜回答常跑題5125040.2574%有改善但句子切斷情況多51210040.2581%重疊加大后明顯改善80012060.2287%綜合最好的一組800120100.2284%召回太多噪音拉低準(zhǔn)確率40010060.2279%切太碎上下文不完整結(jié)論很清楚分塊 800 加重疊 120 加 TopN 6 是這批文檔的最優(yōu)組合。但這個(gè)數(shù)值不能直接抄因?yàn)樗臋n的寫(xiě)作風(fēng)格強(qiáng)相關(guān)。條文式文檔適合切小敘述式文檔適合切大。我的建議是拿 20 到 30 個(gè)真實(shí)問(wèn)題做一次小規(guī)模網(wǎng)格測(cè)試花兩個(gè)小時(shí)后面幾個(gè)月都受益。測(cè)試方法很簡(jiǎn)單列一張表左邊是問(wèn)題右邊是期望答案的關(guān)鍵詞。每換一組參數(shù)就跑一遍統(tǒng)計(jì)命中。別憑感覺(jué)判斷“好像變好了”人的感覺(jué)在檢索質(zhì)量上極不可靠。5.3 檢索不準(zhǔn)的三條排查路徑回答不準(zhǔn)的時(shí)候先分清是召回問(wèn)題還是生成問(wèn)題。判斷方法打開(kāi)引用溯源看召回的片段里到底有沒(méi)有答案。如果引用的片段里根本沒(méi)有正確答案那是召回問(wèn)題。排查方向提問(wèn)的用詞和文檔用詞差異太大試試換成文檔里的表述方式再問(wèn)分塊把關(guān)鍵信息切斷了調(diào)大重疊閾值太高把相關(guān)片段過(guò)濾掉了降到 0.2 試試該文檔壓根沒(méi)入庫(kù)或者入庫(kù)時(shí)解析失敗掃描件常見(jiàn)嵌入模型對(duì)中文支持不好換一個(gè)中文友好的如果引用的片段里有正確答案但模型答錯(cuò)了那是生成問(wèn)題。排查方向上下文塞太多關(guān)鍵信息被淹沒(méi)了降低 TopN提示詞沒(méi)強(qiáng)調(diào)“只用上下文”模型自由發(fā)揮溫度太高回答不穩(wěn)定降到 0.2模型本身理解力不足換大一號(hào)的模型這個(gè)二分法能省掉大量盲目調(diào)試。我見(jiàn)過(guò)有人一直換模型實(shí)際上問(wèn)題是文檔沒(méi)入庫(kù)成功。6. 常見(jiàn)問(wèn)題速查與運(yùn)維加固6.1 部署與運(yùn)行問(wèn)題速查表現(xiàn)象可能原因處理辦法界面能開(kāi)模型列表空容器連不上 Ollama改用宿主機(jī)內(nèi)網(wǎng) IP加 host-gateway 參數(shù)提問(wèn)后長(zhǎng)時(shí)間無(wú)響應(yīng)模型正在加載調(diào)大 keep-alive預(yù)熱一次模型回答到一半中斷上下文超限或顯存不足減小上下文長(zhǎng)度換小模型服務(wù)重啟后數(shù)據(jù)丟失數(shù)據(jù)目錄沒(méi)掛載到宿主機(jī)加 volume 掛載重建前先備份用戶(hù)頻繁被登出會(huì)話(huà)密鑰未固定設(shè)置固定的 secret key入庫(kù)進(jìn)度卡住文檔過(guò)大或解析超時(shí)拆分文件分批入庫(kù)檢索返回空閾值過(guò)高或向量未生成降閾值檢查文檔是否顯示已向量化中文回答夾雜英文模型訓(xùn)練語(yǔ)料偏英文換中文更強(qiáng)的模型提示詞要求中文6.2 運(yùn)維層面的加固建議系統(tǒng)跑起來(lái)只是開(kāi)始長(zhǎng)期穩(wěn)定靠的是運(yùn)維習(xí)慣。我固定在做的幾件事備份三件套模型目錄、Open WebUI 數(shù)據(jù)目錄、AnythingLLM 存儲(chǔ)目錄。前兩個(gè)丟了重裝就行第三個(gè)丟了所有向量和文檔元信息都要重建幾百份文檔重新入庫(kù)要幾個(gè)小時(shí)。備份用定時(shí)任務(wù)每周全量、每天增量異地存一份。日志保留。容器日志默認(rèn)會(huì)無(wú)限增長(zhǎng)加日志輪轉(zhuǎn)配置限制單文件大小和保留份數(shù)。我遇到過(guò)磁盤(pán)被日志寫(xiě)滿(mǎn)導(dǎo)致服務(wù)崩潰的情況排查了半天才發(fā)現(xiàn)是這個(gè)原因。版本鎖定。鏡像不要用 latest 標(biāo)簽用具體版本號(hào)。開(kāi)源項(xiàng)目迭代快某次更新改了配置項(xiàng)格式升級(jí)后服務(wù)起不來(lái)回滾又找不到舊鏡像。鎖定版本升級(jí)前先在測(cè)試環(huán)境驗(yàn)證。資源限制。給容器加內(nèi)存和 CPU 限制防止某個(gè)進(jìn)程吃滿(mǎn)整機(jī)。尤其是嵌入模型批量處理的時(shí)候內(nèi)存占用會(huì)突然飆升。訪問(wèn)日志。內(nèi)網(wǎng)服務(wù)也要記錄訪問(wèn)日志至少記錄誰(shuí)在什么時(shí)候問(wèn)了什么。這既是審計(jì)需要也是排查問(wèn)題的依據(jù)。6.3 安全邊界的三條底線雖然這套系統(tǒng)跑在內(nèi)網(wǎng)但基本的安全習(xí)慣還是要守住。第一條不要在公網(wǎng)暴露任何端口。這套系統(tǒng)設(shè)計(jì)上就沒(méi)考慮公網(wǎng)安全沒(méi)有防暴力破解、沒(méi)有驗(yàn)證碼、沒(méi)有速率限制。真要遠(yuǎn)程訪問(wèn)套一層帶認(rèn)證的反向代理并且限制來(lái)源 IP。第二條模型服務(wù)不做鑒權(quán)。Ollama 的接口默認(rèn)沒(méi)有認(rèn)證機(jī)制任何能訪問(wèn) 11434 端口的人都能調(diào)用模型。所以這個(gè)端口只能在內(nèi)網(wǎng)開(kāi)放不要做端口轉(zhuǎn)發(fā)。如果多人共用一臺(tái)機(jī)器考慮給上層應(yīng)用做賬號(hào)隔離而不是指望模型層。第三條敏感文檔單獨(dú)分區(qū)。合同、報(bào)價(jià)、人事資料這類(lèi)文檔單獨(dú)建工作區(qū)只授權(quán)給特定賬號(hào)。同時(shí)注意刪文檔不等于刪向量刪除文檔后要確認(rèn)向量也被清理否則殘留數(shù)據(jù)還能被檢索到。這個(gè)細(xì)節(jié)很多人會(huì)忽略。7. 我個(gè)人跑下來(lái)的一點(diǎn)體會(huì)這套組合我從最早的單機(jī)試玩到后來(lái)給幾個(gè)小團(tuán)隊(duì)部署前后搭過(guò)七八次。最大的感受是部署只占兩成工作量剩下八成都在文檔治理和參數(shù)調(diào)優(yōu)上。工具本身沒(méi)有魔法。同一套 Ollama 加 AnythingLLM文檔整理得好的團(tuán)隊(duì)問(wèn)答準(zhǔn)確率能到八成以上文檔亂七八糟直接往里扔的準(zhǔn)確率不到五成然后就開(kāi)始懷疑模型不行、工具不行。實(shí)際上問(wèn)題出在源頭。還有個(gè)心態(tài)上的建議別追求一步到位。先把系統(tǒng)跑通能用起來(lái)然后拿真實(shí)問(wèn)題去試發(fā)現(xiàn)哪里不準(zhǔn)就針對(duì)性地調(diào)。我見(jiàn)過(guò)有人花兩周時(shí)間研究各種參數(shù)組合結(jié)果一份文檔都沒(méi)入庫(kù)。先跑起來(lái)再優(yōu)化這個(gè)順序不能反。最后分享一個(gè)我自己常用的小技巧建一個(gè)“測(cè)試問(wèn)題集”文檔把 20 個(gè)真實(shí)問(wèn)題和標(biāo)準(zhǔn)答案寫(xiě)進(jìn)去每次改參數(shù)或者換模型跑一遍看命中率變化。這張表比任何主觀感受都可靠也是我判斷“這次改動(dòng)到底有沒(méi)有用”的唯一依據(jù)。攢了半年之后它已經(jīng)成了我評(píng)估這套系統(tǒng)健康度的基準(zhǔn)線。