共用的伺服器
CodefyUI 是透過 HTTP 運作的桌面工具。單人安裝使用環境層級憑證是預期行為;當其他人也能連線時,同一組憑證會由所有人共用。本頁說明這項差異。
若尚未閱讀發佈,請先查看其中第 6 節,了解綁定區域網路會暴露哪些功能。本頁接著說明憑證的影響。
一台伺服器只有一個身分
沒有使用者帳號。工作階段權杖(session token)只能證明請求端能讀取機器上的檔案,不能識別發出請求的人。因此,伺服器持有的所有憑證都屬於整個實例,不屬於目前開啟瀏覽器分頁的個人。
在共用機器上,設定憑證的人會支付所有人的用量,而且系統不記錄各人的支出。
有五種憑證是這樣運作的。
ChatGPT 登入
POST /api/llm/codex/login 完成 OAuth 流程後,會把存取權杖與更新權杖寫入使用者資料目錄下的 llm/codex_auth.json:由 cdui start 或 cdui dev 啟動的伺服器使用 <install dir>/.codefyui_dev/llm/(預設安裝目錄為 ~/CodefyUI);事先匯出 CODEFYUI_USER_DATA_DIR 時使用 <dir>/llm/;平台目錄(Windows 的 %LOCALAPPDATA%\codefyui\llm\、Linux 的 ~/.local/share/codefyui/llm/、macOS 的 ~/Library/Application Support/codefyui/llm/)只供手動啟動的 uvicorn 使用。詳見把 graph 當成函式呼叫。支援 Unix 權限的平台會將檔案設為 chmod 0600;Windows 則由資料夾的個人帳號 ACL 保護。
代理層只檢查「有人登入了」,不檢查「登入的是不是你」:
- 只要有一個人登入,這台伺服器上每一張
LLMChat使用 Codex 供應商的圖,帳都算在那個人的 ChatGPT 帳號上;呼叫/api/llm/chat的openai-codex供應商的外掛也一樣,例如 Graph Copilot。ChatGPT API 供應商則改用 OpenAI API 金鑰(見下一節)。 POST /api/llm/codex/logout除了工作階段權杖以外不需要任何參數。任何連得上編輯器的人都可以把你登出。
來自環境變數的 LLM API 金鑰
當 LLMChat 節點的金鑰參數是空的,節點會依序退回去讀行程的環境變數:
- OpenAI:先
CODEFYUI_OPENAI_API_KEY,再OPENAI_API_KEY - Anthropic:先
CODEFYUI_ANTHROPIC_API_KEY,再ANTHROPIC_API_KEY
伺服器以 --project 啟動時,cdui 會在啟動階段從專案的 .env 載入這些變數(見專案目錄)。因此,該檔案中的金鑰可由實例上的每個 graph 使用。這項 fallback 刻意不顯示提示:金鑰參數留空的 graph 不會指出它使用了實例的金鑰。請假設任何人能執行的 graph 都能消耗組織的 LLM 額度。
這項 fallback 有一個刻意的限制:Ollama 供應商永遠不會收到金鑰,因此把 ollama_base_url 指向攻擊者伺服器的 graph 無法將金鑰傳出機器。
Kaggle
KaggleDataset 節點使用 KAGGLE_USERNAME 加 KAGGLE_KEY,或者是這個服務帳號的 ~/.kaggle/kaggle.json。下載會算在那個 Kaggle 帳號頭上,包括你以那個帳號同意過的競賽規則。
Hugging Face
HuggingFaceDataset、TextCorpusDataset(source 設為 huggingface 時)與套件中心的模型下載,會使用伺服器環境變數中的 HF_TOKEN 驗證身分;沒有設定時,改用 hf auth login 存放在服務帳號家目錄中的權杖檔(~/.cache/huggingface/token)。受限(gated)的資料集與模型會以該 Hugging Face 帳號下載,包括以該帳號同意過的使用條款。
Git
以 --project 啟動的伺服器中,版本控制分頁會在專案目錄執行伺服器帳號自己的 git。fetch、pull 與 push 會使用該帳號既有的憑證(憑證輔助程式、SSH 金鑰),每個 commit 的作者也都是伺服器上設定的同一個 git 身分,因此任何連得上編輯器的人都會以該帳號推送到專案的遠端。請見版本控制。
那什麼才是每張圖各自的
型別標示為 SECRET 的參數,例如 LLMChat 節點的 openai_api_key,屬於輸入該值的人,處理方式不同。伺服器會從寫出的每份副本中清除這些值,包括已儲存的 graph、匯出檔案、已發佈應用程式版本、預設組合(preset)、產生的 Python 程式碼與執行紀錄。按執行時,你輸入的值會隨該次執行傳到這台伺服器,LLMChat 節點會優先使用它,而不是實例環境變數中的金鑰。伺服器不認得某個節點的型別時(例如已停用的自訂節點、已移除的外掛),無法判斷該節點的哪些參數屬於 SECRET,因此會在執行紀錄中清除該節點的所有參數值。若某個預設組合節點的內嵌定義無法讀取,該節點也比照處理,一般設定也會清除;伺服器下次啟動時,也會清除已結束的執行中該節點的值。
這會產生以下結果:
- SECRET 參數不會儲存在任何位置。重新載入編輯器或重新匯入匯出的 graph 後,欄位會是空白;
LLMChat節點會改用實例環境變數中的金鑰(若有設定),否則會以缺少金鑰的錯誤失敗。排隊中的執行只會把輸入的值保存在伺服器記憶體中,直到該執行結束為止;如果伺服器在它開始執行前停止,該執行會被標為interrupted,值也隨之消失。這是刻意的取捨,不是 bug。 - 新版不會儲存之後輸入的金鑰。 值不會寫入資料庫,而且刪除的資料庫頁面會清零,不會保留內容後再重複使用。因此,執行紀錄被清除後不會留下可讀副本,不需要輪替金鑰或執行清理步驟。
- 如果你曾在舊版執行含有 SECRET 參數的 graph,請將該金鑰視為已外洩並立即輪替。 舊版會把執行時的 graph 原樣寫入
exec_runs.graph_snapshot欄位,而執行紀錄依數量保留最新 200 筆,不是依時間清除,因此低用量實例可能長期保留該值。升級會清除仍存在的執行紀錄中的值,並記錄清除數量;但無法處理升級前已被清除的執行。這些資料列已不存在,而舊版釋放的資料庫頁面仍可能保留內容,直到執行VACUUM。輪替金鑰是處理此空窗期的唯一完整方法。包含此修正的版本請見 CHANGELOG。
送到 worker 的執行
指定遠端 worker 的執行會離開這台機器:指派內容帶著填回你輸入的 SECRET 值的 graph,因為 worker 的執行程序需要它們。含 SECRET 參數的執行,只能經由加密的連線送到 worker:憑證受 worker 的 CA 信任或已釘選的 https:// 控制面網址,或 SSH 通道。以未加密的 HTTP 連到另一台機器時,agent 啟動時會印出警告,Workers 面板也會把該 worker 標成未加密 HTTP;執行仍會送出,而該值以路徑上任何人都讀得到的形式經過網路。Agent 會在記憶體中把值交給該執行的子程序,自己不會寫入任何檔案,但 worker 機器在執行期間持有它:管理那台機器的人等同被託付這個值。請見 Agent 與控制面之間的信任。
Worker 也和其他一切一樣屬於整個實例:任何連得到編輯器的人,都能把 run 送到每個已加入的 worker。Worker 上的 run 使用的是 worker 上 agent 帳號的環境憑證(它的環境變數金鑰,以及存在那台機器上的 ChatGPT、Kaggle、Hugging Face 憑證),不是控制面的。依賴實例金鑰的圖,需要在它會執行的每個 worker 上設定該金鑰,而且同樣適用上面的提醒:設定金鑰的人要替送到那裡的每個 run 付費。
如果你需要分辨是誰用的
目前產品不支援個別使用者歸屬。請為每個人執行獨立實例,並讓每個人提供自己的憑證:
- 每個實例使用自己的安裝目錄(安裝程式的
CODEFYUI_DIR)、環境變數檔與埠號。兩個伺服器不會共用同一個使用者資料目錄或資料庫:第二個伺服器會拒絕啟動,記錄一行訊息並以非零離開碼結束。因此,從同一個安裝啟動第二個實例時,必須另外設定CODEFYUI_USER_DATA_DIR(工作階段權杖、ChatGPT 登入、下載的外掛與其 lockfile、下載快取、套件包的控制檔)與CODEFYUI_DB_PATH(執行紀錄、已發佈應用程式、API key);即使如此,它仍會共用已儲存的 graph、模型、圖片、媒體與上傳的資料檔,以及套件包與外掛安裝時加入套件的 Python 環境。cdui start每個安裝只會執行一個背景伺服器,而cdui stop會停止從該安裝啟動的所有伺服器。 - 如果有人使用存放在家目錄中的憑證,請讓每個實例以各自的作業系統帳號執行:
~/.kaggle/kaggle.json、Hugging Face 權杖檔、git 的憑證輔助程式與 SSH 金鑰。
其他部署方式都會共用同一個身分,而且編輯器不會顯示這項共用狀態。