スマートウォッチやスマートスピーカー、あるいは小型ロボットに「照明を少し暗くして」と話しかけたとき、その言葉を set_lights(room="living room", brightness=30) という関数呼び出しに変換したい。組み込み機器やモバイルアプリの開発では、こうした要求が年々増えています。しかしクラウドの LLM API に投げる実装にすると、レイテンシ、通信断時の動作、リクエスト単価、そしてユーザーの発話を外部に送信することの是非という 4 つの問題が同時に立ち上がります。
かといってローカルで LLM を動かそうとすると、今度はサイズの壁にぶつかります。一般的な小型モデルでも数百 MB から GB 単位のファイルと、それを動かすランタイムが必要です。RAM が数十 MB しかないウェアラブルやマイコンには、そもそも載りません。「オンデバイスで完結させたいが、載せられるものがない」という板挟みは、この領域では珍しくない状況です。
Cactus Compute が公開している Needle 2(GitHub リポジトリ名は cactus-compute/needle)は、この板挟みに対して「用途を絞り切る」という解き方を選んだオープンソースモデルです。45M パラメータのモデルを単一の 14MB バイナリに収め、1 セッションあたり約 28MB の RAM で動作します。ただし汎用チャットはできません。できるのはツール呼び出し、デバイス操作、構造化抽出の 3 つだけです。
なお、Function Calling という仕組みそのものの一般的な解説は本記事の範囲外です。概念から押さえたい場合はFunction Callingとはを先にご覧ください。本記事は特定 OSS の技術解説として、実装者が採用可否を判断するための情報に絞ります。
本記事では、公開されているドキュメントをもとに、Needle 2 の設計、Python API と振る舞いの制約、LoRA によるファインチューニング、ベンチマークで見える得意・不得意、類似 OSS との違い、そして採用判断のチェックポイントを整理します。動作検証・インストールは行っておらず、README・公式ドキュメント・公式サイト・論文・モデルカードの記載に基づく整理であることを、あらかじめお断りしておきます。
Needle 2とは|14MBのバイナリで完結するツール呼び出しモデル
リポジトリの基本情報
Needle 2 は cactus-compute/needle で公開されている Python パッケージ(cactus-needle)と、そこから利用する 45M パラメータのモデルの総称です。リポジトリの説明文は「14MB foundation model for tiny devices; phones, wearables, smart home, and robots.」となっており、対象は明確にスマートフォン・ウェアラブル・スマートホーム機器・ロボットに置かれています。
2026 年 8 月時点のリポジトリ情報は以下のとおりです。
項目 | 値(2026年8月時点) |
|---|---|
リポジトリ |
|
主要言語 | Python |
ライセンス | Apache-2.0 |
スター数 | 9,316 |
フォーク数 | 601 |
最終 push | 2026-08-24 |
公開状態 | public(アーカイブされておらず、他リポジトリのフォークでもありません) |
アーカイブ済みリポジトリやフォーク版を掴んでしまうリスクはなく、ライセンスも Apache-2.0 が明示されています。この点は採用検討の入口としては素直な条件です。
モデルが担う用途は、公式の Needle ページの記載どおり「tool calling(ツール呼び出し)/ device use(デバイス操作)/ structured extraction(構造化抽出)」の 3 つです。公式ページでは、45M パラメータのモデルを「single 14MB binary that runs in 28MB of RAM」として提供していると説明されています。想定するハードウェアも具体的で、200 ドル未満のスマートフォン、Raspberry Pi、スマートウォッチ、ESP32-S3 のようなマイコン、そして AI 専用アクセラレータを持たない IoT 機器が挙げられています。
Cactus Compute のプロダクト構成における位置づけ
Cactus Compute は「オンデバイス AI +クラウドフォールバック」をコンセプトに掲げており、公式サイトでは 3 つのプロダクトを提示しています。オンデバイス機能とクラウド連携を担う Cactus Hybrid、小型デバイス向けのモデルである Cactus Needle、そしてエッジ推論用ランタイムの Cactus Engine です。本記事で扱う Needle 2 は、この真ん中の層にあたります。
ここで混同しやすいのが、同じ組織が公開している cactus-compute/cactus との関係です。こちらは C++ で書かれた量子化・カーネル・ランタイム・推論エンジンのリポジトリで、2026 年 8 月時点でスター数 5,935、ライセンスは NOASSERTION(GitHub 上でスタンダードなライセンスとして識別されていない状態)です。Needle 2 のリポジトリが Python パッケージとモデルの層であるのに対し、cactus はその下で動く推論基盤の層にあたります。競合ではなく層が違うため、「どちらを使うか」ではなく「どのレイヤに手を入れたいか」で見るのが実態に近い整理です。ライセンス条件が両者で異なる点は、社内の OSS 利用ポリシーに照らす際に確認しておく価値があります。
Needle 2の仕組み|14MBに収めた設計と文法制約デコード
なぜ 14MB・28MB RAM で成立するのか。README は 5 つの設計上の特徴を挙げています。要点を先に整理すると、次のようになります。
特徴 | README の記載内容 |
|---|---|
Self-contained | 重みが 14MB のエンジンに焼き込み済み。モデルファイルを別途管理する必要がなく、推論時にネットワークを一切使いません |
Simple contract | text in / JSON out。スキーマからコンパイルした byte-level grammar が全トークンを制約します |
Confidence-gated | 学習済みヘッドによる較正済み信頼度スコアを毎回返します。閾値以上なら実行、未満ならエスカレーションです |
Tool retrieval | 大量のツールを宣言しても、内蔵の retrieval ヘッドが 1 ターンあたり上位 5 件だけをレンダリングします |
Bounded memory | 256 トークンのスライディングウィンドウを使い、ツールを KV sink としてピン留めします。会話が長引いても合計メモリは約 28MB のままです |
以下、採用判断に効く順に噛み砕いていきます。
Simple Attention Network という設計選択
README によれば、Needle 2 のアーキテクチャは「Simple Attention Network」と呼ばれる密な小型モデルのレシピに基づいています。構成要素は、FFN の代わりに置かれた Hadamard MLP、GQA(grouped-query attention)、engram key-value memory、そして multi-lane hyper-connections です。
この設計の根拠として README が挙げているのが、同チームが公開している論文 A Controlled Study of Attention-Only Transformers(arXiv:2607.18363、2026 年 7 月 20 日投稿)です。論文は、パラメータ数・計算量・深さを揃えた統制条件下で「Transformer の FFN 層は本当に必要か」を検証しています。結論として、深さを揃えたまま FFN を取り除くと性能は 0.47 nats 悪化しますが、削って浮いた予算を attention 層の深さに回すと、その差は 0.006 nats まで縮まると報告されています。さらに attention のみのモデルは、文脈に根拠を持つタスクでは優位に立つ一方、重みの中に知識を溜め込む必要があるタスクでは苦戦するという分析も示されています。
この非対称性は、Needle 2 の割り切りをよく説明します。ツール呼び出しと構造化抽出は「入力に書かれている内容を、宣言済みのスキーマへ写像する」タスクであり、まさに文脈依存型です。逆に「世界の知識を答える」用途は苦手な側に落ちます。つまり Needle 2 は、attention-only 系が得意な領域だけを切り出してモデル化したもの、と読めます。なお論文の表題は「Simple Attention Network」ではないため、引用時は上記の正式名称を使ってください。
CQ2-bit 量子化とエンジンへの焼き込み
README は、Needle 2 が「Cactus Quants で CQ2-bit に圧縮されている」と記載しています。この圧縮方式について、公式の Needle ページでは、事後的に圧縮をかけるのではなく開発の全工程を通じて 2bit 量子化を効かせている、という趣旨の説明がなされています。技術メディアの MarkTechPost の解説記事(2026 年 8 月 13 日)は、これを「CQ2-bit is trained in from pretraining, not applied post-hoc, so the deployed model is the trained model」と要約しています。事後量子化にありがちな「配布された量子化モデルは学習したモデルとは別物」というズレが起きにくい、という主張です。
そのうえで、圧縮済みの重みは推論エンジンに焼き込まれた状態で配布されます。Hugging Face のモデルカードによれば、対応アーキテクチャは ARM64 / x86-64 / ARMv7 / RISC-V / WebAssembly で、Apple 系 OS・Windows・Linux・Android・ブラウザまでカバーします。モデルファイルの配置・読み込みという運用が丸ごと消えるため、組み込み側のデプロイ設計はかなり単純になります。ただしこの「焼き込み」は後述するとおり、バージョン管理の面では別のコストを生みます。
文法制約デコードが保証するもの
Needle 2 の出力は常に JSON です。しかもその JSON は、宣言したスキーマからコンパイルされた byte-level grammar によって、生成される全トークンが制約されます。
この設計の実利は明確です。一般的なクラウド LLM の Function Calling では、「JSON として壊れている」「enum にない値が入っている」「数値であるべき箇所が文字列になっている」といった出力を、アプリケーション側でバリデーションして再試行する処理が必要になります。文法制約デコードでは、制約を満たさない出力が原理的に生成されないため、この再試行ループそのものが不要になります。
制約はスキーマの粒度で細かく指定できます。ドキュメントによれば、needle.Field は description・enum・const・ge/le/gt/lt・multiple_of・min_length/max_length・pattern・format・min_items/max_items・unique_items をサポートし、これらがすべてデコード時の grammar にコンパイルされます。「0 から 100 の整数」と宣言すれば、101 は出力されません。
256トークン窓・ツール retrieval・信頼度ゲート
残る 3 つの特徴は、いずれも「メモリ上限を守るための割り切り」として理解すると筋が通ります。
256 トークンのスライディングウィンドウは、会話が伸びてもメモリが増えないことを保証します。ツールの定義は KV sink としてピン留めされるため、窓から押し出されません。裏を返せば、長い文脈を参照する用途には向きません。
ツール retrieval は、宣言ツールが 5 件以下ならそのままレンダリングし、6 件以上になると作動します。初期化時に各スキーマを contrastive ヘッドで埋め込み、毎ターン上位 5 件だけをコンテキストに入れます。ここで注意すべきは、選ばれなかったツールが「呼ばれにくくなる」のではなく そのターンでは到達不能になる 点です。数十のツールを宣言する設計では、retrieval が意図どおりに効くかを事前に見積もる必要があります。埋め込みは tool_index_path でディスクに永続化でき、スキーマとモデルのフィンガープリントが一致すれば即座にロードされます。
信頼度ゲートは、2 つのシグナルの最小値として算出されます。1 つはプロンプト全体と生成された呼び出しをスコアする較正済み事後ヘッド、もう 1 つは呼び出しトークンのデコード確率です。両者が揃って高いときだけ高スコアになるため、失敗モードが「誤ったツールを勝手に実行する」ではなく「自信がないのでエスカレーションする」側に倒れます。デバイス操作を任せる用途では、この倒れ方の設計は重要な判断材料になります。
Needle 2のPython APIと「振る舞いの契約」
最小構成のコード
インストールは pip install cactus-needle です。推論エンジンは Hugging Face から一度だけ取得されてキャッシュされ、以降はビルド作業なしで動きます。README の Quickstart は次のとおりです。
import needle
@needle.tool
def get_weather(city: str):
"Get the current weather for a city."
return {"city": city, "temp_c": 27, "sky": "clear"}
agent = needle.Needle(tools=[get_weather])
print(agent.run("what's it like in Lagos right now?")["results"])
# [{'city': 'Lagos', 'temp_c': 27, 'sky': 'clear'}]
出典: cactus-compute/needle README
@needle.tool デコレータが Python 関数をツールスキーマに変換し、Needle(tools=[...]) がそのツールセットに紐づいたエージェントを生成します。run() はエージェントループ全体を回し、モデルが選んだ呼び出しを Needle 側が Python 関数として実行し、結果を戻します。1 ターンだけ回して実行は自前でやりたい場合は complete() を使います。関数の docstring に Google スタイルの Args: ブロックを書けば、それが引数説明になります。
構造化抽出も同じ枠組みで、Pydantic モデルをスキーマとして渡せます。
from pydantic import BaseModel
class Invoice(BaseModel):
vendor: str
total: float
due_date: str
invoice = needle.extract("Invoice from Acme Corp, $1,200.00, due 2026-09-01", Invoice)
print(invoice.vendor, invoice.total) # -> Acme Corp 1200.0
出典: cactus-compute/needle README
毎ターン返るレスポンスの中身
run() / complete() が返す JSON には、呼び出し内容だけでなく実行時のメトリクスも含まれます。公式ドキュメントに掲載されている例は次の形です。
{
"type": "call",
"success": true,
"error": null,
"error_code": null,
"function_calls": [ { "name": "set_lights", "arguments": { "room": "living room", "on": true, "brightness": 30 } } ],
"reasoning": "'living room' -> room; 'dim' -> on true, brightness 30",
"confidence": 0.94,
"prefill_tps": 4300.0,
"decode_tps": 850.0,
"peak_ram_mb": 28.5
}
出典: doc/apis.md
注目すべきは reasoning と peak_ram_mb です。reasoning は各引数がどの入力から導出されたかを示す短い記述で、grammar 制約を受けずに生成されます。JSON 本体の構造健全性を保ったまま、導出過程だけを人間が読める形で受け取れる設計です。ログに残しておけば、誤った引数が入ったときの原因追跡が容易になります。peak_ram_mb が毎回返るのも、リソース制約の厳しい端末では扱いやすい仕様です。
知らないと事故る 4 つの契約
公式ドキュメントの Behaviour 節には、採用判断に直結する制約が書かれています。特に次の 4 つは、既存のクラウド LLM 前提の実装から移行するときに前提が変わる箇所です。
- フリーテキストのフォールバックが存在しない。 宣言されたツールで対応できないリクエストは、空の呼び出し
[]として拒否されます。「わかりませんでした」という自然文を返してくれることはありません。チャット的な応答が必要なら、その部分は別の仕組みで用意する必要があります。 - 引数には入力に根拠のある値しか入らない。 根拠のない任意フィールドは、推測で埋められずに省略されます。デフォルト値を前提にするなら、アプリケーション側で補完する設計が要ります。
- 1 セッション=1 ツールセット。 ツールを差し替えたい場合は新しい
Needle(...)を作る必要があります。reset()は会話履歴だけをクリアし、ツールはロードしたままです。 - 重みはプロセス内にロードされたまま残る。 ファインチューニング済みの
.cactをバインドした後にベースモデルのエージェントを作ったり呼んだりすると例外になります。ベースモデルのエージェントを先に作るか、プロセスを分ける運用が必要です。
もう 1 つ、system パラメータの扱いも独特です。ここは指示を書く場所ではなく、環境の事実を渡す枠として設計されています。認識されるキーは date・locale・device・battery・network・location・user・assistant で、system="date: 2026-07-21 Tue 14:30; locale: en-US; device: phone; battery: 62%" のように渡します。date: の事実があるときにだけ「tomorrow at 7」が絶対時刻に解決される、といった具合です。system にプロンプト的な指示を書いてもモデルの挙動は steer されません。学習時に system がある場合とない場合の両方を経験しているため、省略しても問題ないとされています。
オフライン・エアギャップ環境での配置
推論自体はネットワークを使いませんが、エンジンの初回取得だけは Hugging Face へのアクセスが発生します。ネットワークに接続できない端末へ持ち込む方法は、公式ドキュメントに 3 通り記載されています。
needle fetchで事前に取得する(--platform-tagを指定すれば他プラットフォーム向けのバイナリも取得できます)- 同じキャッシュパス(
~/.cache/cactus-needle/<engine version>/)へコピーする、またはneedle/パッケージ内に配置する(後者はキャッシュより優先されます) NEEDLE_LIB_PATH=/path/to/libneedle.soで直接指定する
Python パッケージ側は pip download してから pip install --no-index --find-links <dir> で導入します。ネットワークを絶対に叩かせたくない端末では、HF_HUB_OFFLINE=1 を設定して fail fast させる運用が推奨されています。閉域網での配布フローが最初から想定されている点は、産業機器や医療機器を扱うプロジェクトでは実務的な利点になります。
Needle 2をLoRAで自社ツールに合わせる
LoRA から .cact までの流れ
ベースモデルのままで精度が足りない場合は、自社のツールセットに合わせたファインチューニングができます。doc/finetuning.md によれば、方式は凍結したベースモデルに LoRA アダプタ(rank 16、全層の attention 5 射影)を学習させ、エクスポート時に重みへマージするというものです。エンジン・トークナイザ・信頼度ヘッドには手を入れません。出力は .cact という単一アーカイブで、Needle(weights=...) に渡して使います。
コマンドは 3 本です。学習データを生成する needle generate-data、学習する needle finetune、.cact を書き出す needle build。既定値は batch 16 / lr 1e-4(warmup + cosine decay)/ grad clip norm 1 / rank 16 / alpha 32 / max-len 1024 / val-split 0.1 となっています。学習は素の JAX で動くため、JAX が対応するアクセラレータであれば利用できます。CUDA 環境は pip install "cactus-needle[gpu]"、Apple GPU は pip install "cactus-needle[metal]" です。後者は jax-metal が jax 0.4.38 以降で動作しないため、旧スタックにピン留めされている点が明記されています。
学習データの作り方でつまずくポイント
データ形式は JSONL で、1 行に query / tools / answers / reasoning(任意だが推奨)を持たせます。ドキュメントが挙げているデータ設計のルールのうち、見落とすと結果に直結するのは次の 2 点です。
off-topic の例を必ず混ぜること。 "answers": [] となる例を入れずに学習すると、何にでもツールを呼ぶモデルになってしまいます。内蔵のデータジェネレータは、およそ 8 件に 1 件の割合でこの種の例を生成します。
引数にはクエリに存在する値だけを入れること。 根拠のない任意フィールドをプレースホルダで埋めた学習データを作ると、推論時にも根拠のない値を捏造するようになります。ベースモデルの契約(根拠のある値のみ)を壊さないための制約です。
また、各例は --max-len(既定 1024)に収める必要があります。超過分は警告なく切り捨てられるため、長いスキーマを扱う場合は事前にトークン長を確認しておくのが安全です。
学習の進み方については、ロスの読み方に癖があります。損失の計算対象が reasoning 行と JSON 呼び出しだけで、定型部分はベースモデルが既に予測できるため、ロスは 1.0 付近から始まります。絶対値ではなく傾向で判断する必要があります。エポック数の目安も具体的で、200 例を batch 16 で回すと 1 エポックあたり 13 ステップにしかならず、既定の 3 エポック(39 ステップ)では rank 16 のアダプタはほとんど動きません。数百例規模なら 10〜30 エポックが目安とされています。
データ量の見積もりも公式ドキュメントに示されています。ツール選択の精度改善は数百例規模で効果が出る一方、引数のグラウンディング(入力から正しい値を取り出す精度)は数千例規模が必要とされています。正しいツールは選べるのに引数値が誤るという症状が出たら、データが少ないか単調すぎるサインです。グラウンディング重視なら --lora-rank 32 を検討する、という指針も添えられています。ツールカタログが大きい場合は、学習量を増やすより 2 パス推論(全カタログでツールを選び、そのツールだけを宣言して呼ばせる)を検討するよう勧められています。
工数見積もりの観点では、「ツールの呼び分けを覚えさせたいだけなら数百例」「引数抽出の精度まで求めるなら数千例」という切り分けが、そのまま作業量の分岐点になります。
ファインチューニングしても変わらないもの
採用判断で見落としやすいのが、LoRA を当てても変わらない要素です。ドキュメントは 2 つを明示しています。
信頼度ヘッドは更新されません。 較正が有効なのはベースモデルのみで、チューニング済みの重みを使うエージェントは confidence が None になり、生成時に警告が一度出ます。信頼度ゲートを運用の前提に組み込んでいる場合、ファインチューニングとの併用は設計を見直す必要があります。
トークナイザも変わりません。 そして公式ドキュメントには、非英語テキストが約 1.7 倍のトークンに分割される(スペイン語で計測)という記載があります。これは品質と 256 トークン窓の両方を圧迫します。さらに信頼度スコアの較正についても、非英語ではベースモデルであってもスコアを鵜呑みにしないよう注意が促されており、正しいスペイン語の呼び出しが confidence 0.0 と計測された例が挙げられています。日本語を主戦場とするプロダクトでは、この 2 点が最も重い制約になります。
トラブルシューティングの項目も公開されており、CPU での初期ステップの loss が NaN になる問題は修正済み(pip install --upgrade cactus-needle で解消)、チューニング後に何でも「Sorry, I can't help with that」と返す症状は旧エンジンの低信頼度ゲートが原因で engine 2.0.1 で撤廃済み、failed to load weights は .cact がエンジンバージョンに紐づくため現行版での再ビルドが必要、といった内容が整理されています。
ベンチマークで見るNeedle 2の得意・不得意
Needle 2 の性能について、README 自身は控えめな書き方をしています。FunctionGemma 270M・LFM2.5 230M・Apple FM といった他の小型モデルと比べて「trades wins」——つまりベンチマークごとに勝ち負けを分け合うという表現です。そのうえで、サイズは 5〜70 倍小さく、相手が f16 であるのに対しこちらは 2bit である、と付け加えています。「すべてで上回る」とは主張していません。
具体的な数値については、README 本体には比較表が掲載されておらず、図(assets/frontier.png)のみが置かれています。数値表として公開されているのは、前掲の MarkTechPost の解説記事(2026 年 8 月 13 日時点の公開値)です。二次情報である点を踏まえたうえで引用すると、次のようになります。
ベンチマーク | Needle 2 (CQ2) | LFM2.5 230M | FunctionGemma 270M | Apple FM |
|---|---|---|---|---|
Mobile Actions(961件) | 63.7% | 69.1% | 64.0% | 57.6% |
DroidCall(200件) | 17.0% | 11.0% | 17.5% | — |
Seal-Tools 社内(700件) | 32.6% | 26.9% | 16.3% | — |
Seal-Tools 社外(654件) | 28.7% | 17.0% | 15.6% | — |
BFCL v4 単一ターン(3,641件) | 42.6% | 60.8% | 46.1% | 61.7% |
読み取れる傾向ははっきりしています。Seal-Tools 系(スキーマが密なツール呼び出し)では他を明確に上回り、BFCL v4 の単一ターンでは LFM2.5 230M・Apple FM に対して 18 ポイント前後の差をつけられて劣後しています。Mobile Actions は僅差で、DroidCall はほぼ横並びです。同記事は、Mobile Actions における関数名の正答率が 98.3% に達している一方で BFCL v4 全体では後れを取る、とも記しています。
この結果は、README の「trades wins」という自己評価と素直に整合します。Needle 2 は万能に強いモデルではなく、サイズ対効果とワークロード適合で選ぶモデルです。自社で扱うツール定義がスキーマ密で、引数の型・範囲がきっちり決まっているなら適合しやすい。逆に汎用的な関数呼び出しの総合力を求めるなら、より大きなモデルが優位に立つ場面が出てきます。ベンチマークのスコアそのものより、「自分のツール定義がどちらの性質に近いか」を照らすほうが判断としては実用的です。
速度面は、サイズ相応に軽快な数値が公表されています。公式ページおよび Hugging Face のモデルカードによれば、デコード速度は Raspberry Pi 5 で 500 tokens/sec、Meta Quest 3S や Apple Vision Pro といった VR デバイスで 400〜1,500 tokens/sec、200 ドル未満のスマートフォンで 300〜700 tokens/sec とされています。対応アーキテクチャは ARM64 / x86-64 / ARMv7 / RISC-V / WebAssembly で、ESP32-S3 のようなマイコンまで射程に入っています。オンデバイス系の OSS がどこまで小さいハードウェアを狙えるかという観点では、31言語対応オンデバイス TTS「supertonic」のような同系統のプロジェクトと合わせて眺めると、この領域の相場感が掴みやすくなります。
類似OSSとの違い|Needle 2をどこで選ぶか
「文法制約で JSON を出す」「エッジで LLM を動かす」という要素だけを見ると、既存の選択肢と重なって見えます。しかし、それぞれが担当するレイヤは異なります。2026 年 8 月時点の情報で並べると次のとおりです。
比較対象 | 規模・言語・ライセンス | Needle 2 との差分 |
|---|---|---|
15,695★ / Python / Apache-2.0 | 文法制約デコードという発想は同じですが、モデルは自前で用意する必要があります。Needle 2 はモデル・エンジン・grammar を 14MB に同梱します | |
8,326★ / Rust / BSD-3-Clause | 汎用のローカル推論 SDK で、モデル差し替えが前提かつサイズは GB 級です。Needle 2 は用途をツール呼び出しに絞り、マイコン級まで下限を下げています | |
6,298★ / C++ / Apache-2.0 | フレームワーク側の選択肢で、FunctionGemma などのモデルを載せて使います。Needle 2 はモデルとエンジンが不可分です | |
5,935★ / C++ / NOASSERTION | 同組織の下位レイヤで、競合ではなく補完関係にあります。ライセンスが Apache-2.0 ではない点は選定時の確認事項です |
outlines と比べたときの差は「モデルを持っているかどうか」に集約されます。すでに動かしたいモデルが決まっていて、その出力を JSON スキーマに従わせたいだけなら outlines のほうが素直です。逆に「モデル選定からやりたくない」「そもそも載るモデルがない」という状況なら、モデルごと同梱された Needle 2 が候補になります。
nexa-sdk との差は「汎用性か特化か」です。フロンティアモデルを端末で動かしたい、チャットも RAG も扱いたいという要求なら汎用 SDK が要ります。一方でツール呼び出しだけができればよく、RAM が数十 MB しかないという制約があるなら、汎用 SDK は端的に載りません。
LiteRT-LM はさらに一段下の層で、モデルを載せる器です。FunctionGemma 270M のようなモデルと組み合わせて使うことになります。「モデルとランタイムを別々に選びたい」「後からモデルを差し替えたい」という要件があるなら、こちらの構成のほうが柔軟です。Needle 2 で差し替えられるのは .cact の重みだけで、エンジンごと別のモデルに置き換えるという使い方は想定されていません。
これらを踏まえると、選定の判断軸は次の 4 つに整理できます。
- モデルを自分で選びたいか、同梱でよいか。 選びたいなら
outlinesやLiteRT-LM、同梱でよいなら Needle 2。 - 必要なのはチャットか、ツール呼び出しだけか。 チャット応答が要るなら Needle 2 は候補から外れます。
- ターゲットデバイスの RAM 上限。 数十 MB のオーダーなら選択肢はかなり絞られ、Needle 2 が数少ない候補になります。
- ライセンス要件。 Needle 2 本体は Apache-2.0 ですが、下位レイヤの
cactusは NOASSERTION です。どこまで依存するかで確認範囲が変わります。
なお、エッジ側で AI を動かすという選択そのものの是非(クラウドとの使い分けや導入判断の基準)を整理したい場合は、エッジAIとはも参考になります。
Needle 2の採用判断チェックポイント
最後に、採用可否を自分で判断するための材料を中立に並べます。
ライセンスとメンテナンス状況
ライセンスは Apache-2.0 で、商用利用に支障はありません(2026 年 8 月時点)。開発の勢いを示す指標としては、スター数 9,316、フォーク数 601、最終 push が 2026-08-24 で、直近 1 週間にも fix・docs・chore のコミットが複数入っています。ツールスキーマの型推論修正や CLI のクラッシュ修正といった実務的な変更が続いており、放置されているリポジトリではありません。
一方で、留意すべき事実もあります。GitHub Releases は 0 件で、バージョンは PyPI の cactus-needle 側(調査時点で 2.0.8)で管理されています。リリースノートで差分を追う運用には向きません。加えて調査時点の open issues は 27 件、リポジトリの作成は 2026 年 2 月と新しく、API の安定性については十分な実績期間があるとは言えない段階です。ドキュメントに記載されているトラブルシューティング項目(旧エンジンの信頼度ゲート撤廃など)からも、仕様が短期間で動いてきたことがうかがえます。
向くケース
- 通信断が前提の環境で動かす必要がある(推論時にネットワークを使いません)
- 音声やテキストのデータを端末外に出せない要件がある
- 固定のツールセットに対する意図解釈、または定型フォーマットからの構造化抽出が主目的
- ターゲット端末の使用可能 RAM が数十 MB 程度しかない
- ツール定義のスキーマが密で、引数の型・範囲・enum がきっちり決まっている
- 閉域網・エアギャップ環境への配布フローが必要
向かないケース
- 自由文での応答が必要(フリーテキストのフォールバックがありません)
- 長い文脈を参照する必要がある(256 トークンのスライディングウィンドウ)
- 日本語など非英語が主戦場である(非英語テキストは約 1.7 倍のトークンに分割され、256 トークン窓を圧迫します。信頼度スコアの較正も英語前提で、正しい非英語の呼び出しが
confidence0.0 と計測された記録があります) - BFCL v4 のような汎用ベンチマークでの総合性能を重視する
- モデルを後から別のものに差し替える前提の構成にしたい
日本語プロダクトを開発している読者にとっては、3 番目が最も重い項目です。トークン効率の悪化はファインチューニングでも解消されず、信頼度スコアもそのままでは信頼できません。日本語で運用するなら、confidence を使わない設計にする、入力を短く保つ、あるいは日本語データでの精度を先に小規模に見積もる、といった前提整理が必要になります。
運用上のコスト
.cact はエンジンのバージョンに紐づきます。パッケージを更新すると failed to load weights で読めなくなるため、ファインチューニング済みの重みは再ビルドが必要です。学習パイプラインを CI に組み込むか、エンジンのバージョンを固定するか、どちらかの運用設計を最初に決めておくと後が楽になります。
これらの材料を、自社の要件(通信条件・RAM 上限・扱う言語・ツール数・ライセンスポリシー)に照らして順に潰していけば、採用可否の判断はつくはずです。特に「日本語での運用可否」と「フリーテキスト応答の要否」の 2 点は、他の項目がすべてクリアでも単独で採用を左右するため、最初に確認することをおすすめします。
関連情報
オンデバイス AI や組み込み向けのシステム開発について、技術選定の段階からご相談を承っています。要件が固まりきっていない構想段階でも、お問い合わせフォームからお気軽にご連絡ください。



