TwKit
正在载入
TwKit

# 模型跑在自己機器上,憑什麼出事了沒人說得清? 模型跑在自己機器上,解決了隱私和成本問題,卻製造了可見性問題:一旦自架模型,沒人告訴你為什麼一個提示跑了 … · @swordBluesy · TwKit

@swordBluesy

# 模型跑在自己機器上,憑什麼出事了沒人說得清? 模型跑在自己機器上,解決了隱私和成本問題,卻製造了可見性問題:一旦自架模型,沒人告訴你為什麼一個提示跑了 40 秒,也沒人告訴你哪一步檢索餵錯了上下文。解法是 LLM 可觀測性,而最適合本地技術棧的,是自架 Langfuse。這篇教程用 13 步、大約 50 分鐘,從一台空 Ubuntu 機器做到一個被追蹤、被評分、本地託管的 LLM 應用。 ## 一、為什麼需要可觀測性,Langfuse v4 又改了什麼 託管 API 免費送你一個儀表板,本地模型只給你一個終端機和一個希望。一個被追蹤的請求能回答第二週一定會出現的問題:檢索步驟花了多久、提示用了多少 token、模型有沒有撞到輸出上限、上週二的提示修改是讓答案變差了還是只是變得不一樣? McKinsey 2025 年 AI 現況調查發現,62% 的受訪者表示所屬組織至少在實驗 AI Agent。Agent 讓問題成倍放大:一個使用者請求變成五到十次模型呼叫。很多團隊因此同時跑託管模型和本地模型,你需要一個地方記錄每一次呼叫,不管是哪個執行環境提供的。 Langfuse 是開源、可自架的 LLM 應用除錯與迭代平台,最近一季變化很大,四點跟本教程直接相關: - **伺服器 v4 是當前世代**,自架部署已全面可用,Cloud 預定 2026 年 11 月 16 日起只支援 v4,自架使用者自己選遷移日期。 - **SDK 大版本在 2026 年 10 月 14 日一起上線**:Python SDK v5、JS/TS SDK v6,兩者都要求 Cloud 或 v4.59.0 以上版本的自架伺服器。 - **舊 API 刪掉了**:v5、v6 客戶端拿掉了 `api.legacy.*`、`api.ingestion` 這類介面,新增了實驗連結、巢狀元資料篩選、gzip 壓縮的 span 批次。 - **資料模型改為 observation-first**:使用者 ID、會話 ID、元資料、標籤這類關聯屬性,現在存在每個 observation 上,而不只存在 trace 上。 如果你還在跑自架 v3,就不能用新的 SDK 大版本,先留在 Python SDK v4(或 JS/TS SDK v5),直到伺服器升級。本教程假設全新安裝 v4。 ## 二、成品長什麼樣 成品專案叫 TraceLab,五個部分:Docker Compose 跑 Langfuse;本地 OpenAI 相容模型伺服器(Ollama 或 llama.cpp 的 `llama-server`)回答提示;一個小型 Python 套件把每次請求包進 trace,含檢索 span 和生成 span;一個測試套件重放提示檔案,把通過/失敗和延遲分數寫回 Langfuse;一個檢查腳本在你相信任何圖表之前先驗證整條鏈。 每一層記錄的東西、回答的問題: | 層 | 記錄什麼 | 回答什麼問題 | | --- | --- | --- | | Trace | 一次使用者請求、使用者 ID、會話 ID、標籤 | 哪段對話出錯了? | | 檢索 span | 查詢、返回片段、耗時 | 模型看到正確的上下文了嗎? | | 生成 | 提示、完成內容、模型名稱、token 用量 | 花了多少 token 和時間? | | 分數 | trace 上的數字或布林標籤 | 提示版本之間品質是升還是降? | | 會話 | 歸為一次對話的 traces | 多輪對話是怎麼漂移的? | Langfuse 在 2026 年 10 月 13 日重做了會話檢視,可以跨 traces 把使用者和助手訊息顯示為一段連續對話,讓最後一行比一個月前有用得多。 ## 三、先決條件與版本對照 需要一台 Linux 或 macOS 機器,記憶體要夠同時跑 Langfuse 容器和模型。Langfuse 本身是網頁服務、worker、PostgreSQL、ClickHouse、Redis、物件儲存,載入大模型之前先留足餘量。 | 元件 | 用這個版本 | 備註 | | --- | --- | --- | | 作業系統 | Ubuntu 24.04 LTS 或 macOS | Windows 走 WSL 2 | | Docker Engine | 27 以上,含 Compose 插件 | 用 `docker compose version` 檢查 | | Langfuse 伺服器 | v4.59.0 以上 | Python SDK v5 和 JS/TS SDK v6 的硬要求 | | Langfuse Python SDK | v5 系列(當前大版本) | 需要 Python 3.11 以上 | | Python | 3.11 以上 | 3.10 不在 v5 的支援範圍內 | | 本地模型伺服器 | Ollama v0.40.8 以上,或 llama.cpp v0.7.0 | 兩者都提供 OpenAI 相容 API | | Git、OpenSSL | 任何當前版本 | 複製專案和生成密鑰用 | 兩個版本規則值得再看一眼:第一,SDK 和伺服器必須對得上,v4.59.0 之前的 v4 伺服器會拒絕 SDK v5;第二,OpenAI 整合不再支援 1.0 之前的 OpenAI SDK,裝當前的 `openai` 套件。如果現有專案的某個釘選依賴擋住任一升級,就讓那個專案留在 Python SDK v4,給本教程開一個獨立環境。 ## 四、步驟 1 到 3:準備主機、複製 Langfuse、生成密鑰 前面三步故意做得很無聊,因為大多數自架安裝失敗都源於缺工具或密鑰留在預留位置,花十分鐘在這裡,後面省一小時。 **步驟 1:檢查工具。** 跑這五條指令,對照上表,低於最低版本的先升級: ```bash docker --version docker compose version python3 --version openssl version git --version ``` 典型輸出(補丁號會不同):Docker 27.x、Compose v2.x、Python 3.12.x、OpenSSL 3.0.x、git 2.43.x。如果 `python3 --version` 印出 3.10 以下,先裝新版直譯器,Python SDK v5 在 3.10 上裝不上,而且那個報錯很容易被誤讀成網路問題。 **步驟 2:複製 Langfuse 倉庫。** Langfuse 在主倉庫裡發布 Docker Compose 檔案,淺複製就夠,因為你只需要 compose 定義,不需要完整歷史: ```bash mkdir -p ~/tracelab && cd ~/tracelab git clone --depth 1 https://github.com/langfuse/langfuse.git cd langfuse docker compose config --services ``` 最後一條指令列出服務名稱,應該看到網頁服務、worker、PostgreSQL、ClickHouse、Redis、S3 相容物件儲存。Langfuse 2026 年 10 月 22 日發布的自架指南建議,給每個部件指定明確負責人,服務清單就是跟團隊展開這場對話的好起點。寫下名字,因為步驟 3 的覆蓋檔案會按名字引用網頁服務,寫作時網頁和 worker 服務分別叫 `langfuse-web` 和 `langfuse-worker`,如果你的輸出不同就相應調整。 **步驟 3:替換每一個預留密鑰。** 隨附的 compose 檔案用 `CHANGEME` 註解標出每個必須改的值,先全部找出來: ```bash grep -n "CHANGEME" docker-compose.yml ``` 用 OpenSSL 生成新值。Langfuse 要求加密金鑰是 64 個十六進位字元,正好是 `openssl rand -hex 32` 印出的長度: ```bash # ENCRYPTION_KEY 用 64 個十六進位字元 openssl rand -hex 32 # NEXTAUTH_SECRET、SALT、資料庫密碼用隨機字串 openssl rand -base64 32 openssl rand -hex 24 ``` 打開 `docker-compose.yml` 替換每個被標記的值。同一個密碼出現兩次的地方(例如 PostgreSQL 服務和網頁、worker 服務裡的連接字串),兩邊必須用相同的值。如果機器能從其他主機連到,公開連接埠要從 `3000:3000` 改成 `127.0.0.1:3000:3000`,因為介面裡會放你的提示和完成內容。 接著在 compose 檔案旁邊建一個 `.env`,放三個應用密鑰,再加一個 `docker-compose.override.yml`,在啟動時建立組織、專案、API 金鑰、第一個使用者,省掉點滑鼠註冊的流程,也讓整套設定以後可以寫成腳本: ```bash cat > .env <<EOF NEXTAUTH_SECRET=<redacted> SALT=$(openssl rand -base64 32) ENCRYPTION_KEY=$(openssl rand -hex 32) LF_PUBLIC_KEY=pk-lf-tracelab-$(openssl rand -hex 8) LF_SECRET_KEY=sk-lf-tracelab-$(openssl rand -hex 16) LF_ADMIN_PASSWORD=<redacted> EOF chmod 600 .env ``` ```yaml # docker-compose.override.yml services: langfuse-web: environment: NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} SALT: ${SALT} ENCRYPTION_KEY: ${ENCRYPTION_KEY} LANGFUSE_INIT_ORG_ID: tracelab-org LANGFUSE_INIT_ORG_NAME: TraceLab LANGFUSE_INIT_PROJECT_ID: tracelab LANGFUSE_INIT_PROJECT_NAME: tracelab-local LANGFUSE_INIT_PROJECT_PUBLIC_KEY: ${LF_PUBLIC_KEY} LANGFUSE_INIT_PROJECT_SECRET_KEY: ${LF_SECRET_KEY} LANGFUSE_INIT_USER_EMAIL: [email protected] LANGFUSE_INIT_USER_NAME: Admin LANGFUSE_INIT_USER_PASSWORD: ${LF_ADMIN_PASSWORD} langfuse-worker: environment: SALT: ${SALT} ENCRYPTION_KEY: ${ENCRYPTION_KEY} ``` 金鑰對和管理員密碼抄一份放進密碼管理器,步驟 7 的 Python 專案會用到。這個 `.env` 絕對不要提交進 Git。 ## 五、步驟 4 到 5:啟動並驗證健康狀態 **步驟 4:啟動容器。** 第一次啟動會拉取多個映像並跑資料庫遷移,給它幾分鐘: ```bash docker compose up -d docker compose ps docker compose logs -f langfuse-web ``` 看到網頁伺服器就緒的日誌行就可以按 Ctrl+C 離開日誌檢視。健康的 `docker compose ps` 顯示每個服務都在跑、資料庫都是 healthy。網頁容器在 ClickHouse 和 PostgreSQL 跑遷移時重啟一兩次是正常的。如果某個容器持續重啟超過五分鐘,對照疑難排解章節裡對應的症狀處理。 接著確認你實際拉到的伺服器版本,compose 檔案釘住映像標籤,Python SDK v5 需要 v4.59.0 以上: ```bash docker compose images langfuse-web curl -s http://localhost:3000/api/public/health ``` **步驟 5:驗證健康狀態並登入。** 健康端點會返回一個小 JSON,裡面含伺服器版本: ```json {"status":"OK","version":"4.x.y"} ``` 如果版本以 3 開頭,compose 檔案還指著舊世代。先 `docker compose down` 停掉(不要加 `-v`,這樣資料還在),把網頁和 worker 的映像標籤改到 v4 系列再啟動。GitHub 發布紀錄列出 v4.68.0 在 2026 年 10 月 22 日發布,所以接近這個數字的都算當前版本。 打開 `http://localhost:3000`,用 `[email protected]` 和 `.env` 裡的密碼登入,應該落在 `tracelab-local` 專案、空的 traces 表。進設定確認 API 金鑰跟你生成的值一致。如果登入頁提供建立帳號但沒有專案存在,說明初始化變數沒送到網頁容器,用 `docker compose config | grep LANGFUSE_INIT` 查 Compose 實際解析出來的值。 Langfuse 在 2026 年 10 月 7 日加上了 API 金鑰過期功能,預設 30 天、60 天、90 天、一年、自訂日期或不過期。透過初始化變數建立的金鑰跟其他金鑰行為一樣,所以現在就決定要不要輪換:一次性實驗室放著不管沒關係,共用團隊伺服器的話,在介面裡建有過期時間的新金鑰,不要再依賴啟動時那對。 ## 六、步驟 6 到 13:接模型、寫追蹤、跑評分 **步驟 6:跑本地 OpenAI 相容模型伺服器。** Ollama 最新版是 v0.40.9(2026 年 10 月 22 日發布),v0.40 系列為支援的硬體加了自動 MLX 執行;也可以用 llama.cpp 的 `llama-server`。兩個都說 OpenAI 聊天格式,Langfuse 不在乎誰回答,只在乎你的程式碼能不能跟它對話。 **步驟 7:建 Python 專案並接上 Langfuse。** 把 `.env` 裡的公鑰、私鑰貼進專案設定,用 Python SDK v5 的裝飾器把請求包進 trace:一次使用者請求一個 trace,裡面一個檢索 span、一個生成 span。裝飾器寫法讓追蹤程式碼跟業務程式碼分開,之後要關掉追蹤也只要拿掉裝飾器。 **步驟 8 到 10:跑通第一條 trace、掛分數、重放提示檔案。** 先跑一次請求,進介面確認 trace 出現、span 層級正確、token 用量有數字。再給 trace 掛分數:通過/失敗、延遲、品質標籤,分數就是你以後比較提示版本的標尺。最後寫一個測試套件,重放一個提示檔案,把每個提示的通過/失敗和延遲分數寫回 Langfuse,提示一改,整個檔案重跑一遍,品質升降一目了然。 **步驟 11 到 13:檢查腳本、會話檢視、收尾。** 寫一個檢查腳本,在你相信任何圖表之前先驗證整條鏈:伺服器版本對不對、SDK 能不能連上、trace 是不是真的寫進去了。再用 2026 年 10 月 13 日重做的會話檢視,看一次多輪對話是怎麼漂移的。最後把檢查腳本和測試套件一起提交進倉庫,觀測能力才算正式成為專案的一部分,而不是你本機上的一次性實驗。 ## S1哥觀點 自架模型最大的幻覺,是以為「跑起來」就等於「管得住」。跑起來只是第一天,第十天你要回答的問題全是可觀測性問題:哪一步慢了、哪段上下文錯了、哪個提示版本把品質拉下去了。沒有 trace,這些問題的答案全靠猜;有 trace,答案就在表裡。更殘酷的是,SDK 和伺服器版本對不上時,trace 連寫都寫不進去——你以為自己在觀測,其實什麼都沒記下來。問題留給你:你的本地模型今天出問題時,你是打開儀表板,還是打開終端機開始猜?這兩個動作的差距,就是業餘和專業的差距。 原文連結:https://tech-insider.org/llm-observability-langfuse-self-hosted-13-steps-2026/ 原文:@Tech Insider(由 S1哥 編譯)

曝光 323 · 评论 7 · 点赞 2 · 书签 0

查看原帖