模型 / 資料集
nobodywho-ooo/nobodywho avatar
nobodywho-ooo/nobodywho

NobodyWho:把 GGUF 模型塞進 Kotlin、Swift、Godot 的本地推論引擎

NobodyWho is an inference engine that lets you run LLMs locally and efficiently on any device.

1,107 個 Star79 個 ForkRustEUPL-1.2

秒懂

它是什麼?
NobodyWho 以 llama.cpp 為底層,替七種語言與框架各做一層綁定,讓行動端與遊戲引擎直接跑 GGUF 量化模型。它的價值在於綁定的廣度,風險也在於這份廣度。
適合誰用?
如果你的產品是行動 App 或 Godot 遊戲,需要離線對話、語音輸入輸出,而且不打算自己寫 JNI 或 C ABI 綁定,NobodyWho 省下的正是這一段工作量,值得用 starter example 專案先跑一次真實模型。若你只需要伺服器端推論,或需要微調、自訂取樣與底層 llama.cpp 參數控制,直接使用 llama.cpp 或 Ollama 這類工具會更直接,因為 NobodyWho 的 API 刻意收斂成 Chat 與 ask 兩個概念。
可以商用嗎?
可以,但有條件。EUPL-1.2 是弱 copyleft 授權:可以用在商業與閉源軟體中,但如果你散布了對它本身檔案的修改,這些修改必須以同一授權公開。
還在維護嗎?
有在維護。儲存庫在最近一天內有新的提交。
用什麼語言寫的?
主要是 Rust(依據 GitHub 的語言統計)。

以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。

開源專案深度解析

它解決的是綁定問題,不是模型問題

在手機上跑 LLM 的技術障礙早就不是模型本身。llama.cpp 已經能把 GGUF 量化模型跑在 CPU 與 GPU 上,真正的摩擦在於你的產品是用 Kotlin、Swift、Dart 還是 GDScript 寫的,而 llama.cpp 是 C++。多數團隊走到這一步會發現,自己花在 JNI、Swift Package、FFI 橋接與建置腳本上的時間,比花在提示詞與產品邏輯上的還多。

NobodyWho 針對的就是這一段。README 把支援平台列成 Kotlin、Swift、Python、Flutter、React Native、Expo 與 Godot,每個平台各自有套件來源:Kotlin 走 Maven Central 的 ai.nobodywho:nobodywho-android 與 ai.nobodywho:nobodywho,Swift 走 SPM 的 nobodywho-swift.git,React Native 與 Expo 走 npm 的 react-native-nobodywho,Flutter 走 pub.dev 的 nobodywho,Python 走 PyPI,Godot 則可以從 AssetLib 直接搜尋安裝。

所以它的目標讀者很明確:已經決定要離線推論,但不想自己維護跨平台綁定的產品團隊。反過來說,如果你的服務跑在伺服器上、由後端統一呼叫模型,這層綁定對你毫無價值。

Chat 物件與 ask 的資料流

README 裡每個平台的範例長得幾乎一樣,這件事本身就是設計聲明。Kotlin 是 Chat.fromPath(modelPath = ...) 之後 chat.ask(...).completed(),Swift 是 try await Chat.fromPath(modelPath:) 再 try await chat.ask(...).completed(),React Native 是 await Chat.fromPath({ modelPath }) 再 await chat.ask(...).completed(),Flutter 多一行 nobodywho.NobodyWho.init(),Python 則直接 Chat(...) 建構。

資料流因此可以這樣理解:模型路徑交給 Chat 建構,Chat 持有對話狀態,ask 送入一輪使用者訊息,completed() 取得這一輪的完整回覆。要注意 completed() 的存在暗示了非同步與串流兩種取用方式,README 只示範了等待完成的那一種。

模型來源用字串前綴區分。Kotlin、Swift 與 React Native 用 hf://NobodyWho/Qwen_Qwen3-0.6B-GGUF/Qwen_Qwen3-0.6B-Q4_K_M.gguf,Flutter 與 Python 用 huggingface: 前綴。README 也說可以從 Hugging Face 或任何 URL 載入模型,但沒有示範 URL 的寫法,這部分要查各平台文件。

另一個關鍵字是 GGUF。README 明講相容於任何 GGUF 格式的模型,並列出 Gemma、Qwen、Mistral 作為例子。這代表你的模型選擇被格式綁住,safetensors 或 ONNX 的模型不在範圍內,除非你先自行轉換。

對話記憶靠 context shifting,不是靠無限上下文

README 在 Under the Hood 段落寫了一句值得細看的話:conversation-aware preemptive context shifting,用來在沒有訊息長度限制的前提下保留完整對話記憶。

這句話的機制含義是:上下文視窗仍然是有限的,引擎在接近上限時會主動搬移或捨棄部分內容,而不是讓對話直接爆掉。文件沒有說明被移出的內容如何處理、是否會摘要、以及問答品質在長對話中如何衰減。這是採用前應該實測的部分,因為它直接決定你的產品在連續使用半小時後還能不能用。

同段落還提到 GPU 加速透過 Vulkan 或 Metal,涵蓋各作業系統。這裡沒有給出任何效能數字,README 也沒有提供基準測試。任何關於「多快」的期待,都必須由你自己在目標裝置上量測,尤其是中低階 Android 機種與整合式顯卡。

底層是 llama.cpp,這是明確標示的依賴。好處是量化格式與模型生態直接繼承;代價是 llama.cpp 的版本升級節奏會影響 NobodyWho 的行為,而這層綁定是否同步更新,取決於各語言套件的發佈頻率。

工具呼叫與語音:README 給了承諾,沒給範例

功能清單裡有兩項值得單獨看。第一是工具呼叫,README 說會從你的函式簽章自動產生結構化文法,不需要自己寫 schema,並形容為 type-safe。這個做法在概念上合理:既然模型輸出受限於文法,型別正確性就由編譯期或執行期的簽章決定,而不是靠提示詞祈禱。

但 README 沒有給出任何工具呼叫的程式碼範例,也沒有說明支援哪些型別、巢狀結構怎麼處理、呼叫失敗時的重試策略。文件指向 docs.nobodywho.ooo,實際可行性必須以那裡為準。

第二是語音。文字轉語音標示支援 Kokoro、Pocket TTS 與 Supertonic 三個後端,輸出為本地 WAV;語音轉文字用 Whisper。多模態輸入則說可以餵圖片與音訊給 LLM。這幾項同樣沒有範例程式碼,只有功能條目。

把 STT、LLM、TTS 三段放在同一個引擎裡是有意義的取捨:你少接三套依賴,代價是每一段都受制於 NobodyWho 的綁定進度,而語音模型通常比文字模型更吃記憶體。README 沒有說明這三段能否各自替換。

安裝路徑與版本落差

實際動手時,安裝指令是明確的。Python 用 pip install nobodywho;Flutter 用 flutter pub add nobodywho;React Native 用 npm install react-native-nobodywho;Expo 用 npx expo install react-native-nobodywho。Kotlin 在 build.gradle.kts 加入 implementation("ai.nobodywho:nobodywho-android:2.0.0") 或 implementation("ai.nobodywho:nobodywho:2.0.0"),前者是 Android,後者是桌面 JVM 的 Linux、macOS、Windows。Swift 透過 SPM 加入 https://github.com/nobodywho-ooo/nobodywho-swift.git。Godot 在 4.5 以上從 AssetLib 搜尋 NobodyWho,或從 GitHub releases 下載 zip 後在 AssetLib 分頁選 Import,README 特別提醒要在匯入對話框勾選 ignore asset root。

版本號不一致是這裡最容易踩到的坑。README 的 Kotlin 範例寫 2.0.0,最近發佈的卻是 nobodywho-swift-v3.0.0、nobodywho-react-native-v3.0.0 與 nobodywho-python-v2.0.0。Swift 與 React Native 已經到 3,Python 停在 2,Kotlin 與 Flutter 的當期版本在 README 裡看不到。這代表各語言綁定並非同步發佈,跨平台專案要預期 API 表面存在差異。

Godot 的安裝流程還有一個非慣例的細節:手動安裝 zip 時必須勾選 ignore asset root,否則資源路徑會出錯。這種需要特定勾選才能正常運作的匯入流程,說明 Godot 綁定與 AssetLib 的整合仍有粗糙處。

什麼情況下不該用它

第一個明確的排除條件是伺服器端推論。如果你的模型跑在後端、客戶端只是送 HTTP 請求,NobodyWho 提供的跨平台綁定完全用不到,你面對的是 llama.cpp、vLLM 這類推論服務的選擇題。

第二個是模型格式。只支援 GGUF 意味著你的模型必須先量化或轉換。如果你的流程需要微調後的權重、需要特定的量化策略、或需要控制 llama.cpp 的底層取樣參數與 KV cache 設定,NobodyWho 的 Chat 與 ask 抽象會變成阻礙,因為它把這些細節收在介面後面。README 沒有列出任何暴露底層參數的方式。

第三個是平台。清單是 Kotlin、Swift、Python、Flutter、React Native、Expo、Godot。沒有網頁瀏覽器的 WASM 目標,沒有 C# 或 Unity,也沒有 Rust 之外的原生介面說明。若你的產品是 Unity 遊戲或純網頁應用,這份清單直接把你排除在外。

第四個是模型規模的期待。README 的範例一律使用 Qwen3-0.6B 的 Q4_K_M 量化版本,這是個很小的模型。行動裝置的記憶體與散熱決定了你能跑多大的模型,而 README 完全沒有提供任何裝置上的記憶體需求或延遲數據。把它當成「在手機上跑大模型」的方案,很可能會失望。

替代方案:llama.cpp 直用與 Ollama 的取捨

最直接的替代是 llama.cpp 本身。NobodyWho 的 README 明說它 powered by llama.cpp,所以兩者的模型相容性一致。差別在於整合層:llama.cpp 提供 C/C++ API 與命令列工具,你要自己寫 JNI、Swift bridging header 或 Dart FFI,但換來的是完整的參數控制與最新的上游功能。NobodyWho 把這層包好,代價是抽象層與各語言發佈節奏。

如果你不需要嵌入既有 App,而是想要一個能跑本地模型並提供 HTTP 介面的服務,Ollama 走的是另一條路:它以服務形式常駐,客戶端用 HTTP 呼叫,模型管理與切換由 Ollama 自己處理。這種架構適合桌面工具與內部服務,不適合要打包進 App Store 的行動應用,因為它多了一個必須隨附或要求使用者自行安裝的常駐程序。

三者其實對應三種部署形態。llama.cpp 是函式庫,NobodyWho 是綁定層,Ollama 是服務。選錯形態比選錯專案更難補救。

授權與維護成本

授權是 EUPL-1.2,歐盟公共授權條款,屬於 copyleft 家族。這意味著散佈基於 NobodyWho 的衍生作品時,可能需要在相同條款下釋出對應原始碼。EUPL 的條款細節與「衍生作品」的界定因使用方式而異,特別是透過套件管理器動態連結的邊界,這部分不是本文能判斷的,需要法務確認。

維護面上有兩個可觀察的訊號。第一是綁定數量:七個平台各自有獨立的套件與版本號,Swift 與 React Native 在 3.0.0、Python 在 2.0.0,這種落差是維護負擔的直接證據,也意味著跨平台專案會遇到行為不一致。第二是發佈節奏,從近期版本的時間戳來看,2026 年 8 月下旬有連續的發佈動作,顯示專案仍在推進,但這不等於每個綁定都同等活躍。

升級成本則取決於 llama.cpp 的上游變動。當 llama.cpp 調整模型載入或量化格式,NobodyWho 必須跟著更新,而你要等的是自己所用語言的套件版本,不是整個專案。在鎖定版本之前,先確認該語言的套件是否仍在更新。

編輯結論

如果你的產品是行動 App 或 Godot 遊戲,需要離線對話、語音輸入輸出,而且不打算自己寫 JNI 或 C ABI 綁定,NobodyWho 省下的正是這一段工作量,值得用 starter example 專案先跑一次真實模型。若你只需要伺服器端推論,或需要微調、自訂取樣與底層 llama.cpp 參數控制,直接使用 llama.cpp 或 Ollama 這類工具會更直接,因為 NobodyWho 的 API 刻意收斂成 Chat 與 ask 兩個概念。採用前請先確認三件事:你的目標平台是否在支援清單內、你的模型是否為 GGUF 格式、以及 EUPL-1.2 的傳染性條款是否與你的散佈方式相容。

官方來源

  1. License: EUPL-1.2
  2. nobodywho-ooo/nobodywho on GitHub
  3. Project website
  4. README
  5. Releases
社群筆記

社群筆記