Gateway
ローカルモデル
ローカルモデルは実用可能です。ただし、ハードウェア、コンテキストサイズ、プロンプトインジェクション防御の要求水準も上がります。小さいカードや極端に量子化されたカードはコンテキストを切り詰め、安全性を損ないます。このページは、上位ローカルスタックとカスタム OpenAI 互換ローカルサーバー向けの、方針を明確にしたガイドです。最小の手間でオンボーディングしたい場合は、LM Studio または Ollama と openclaw onboard から始めてください。
ハードウェアの最低ライン
高めを目指してください。快適なエージェントループには、フル構成の Mac Studio 2台以上、または同等の GPU リグ(約$30k以上)が目安です。単一の 24 GB GPU は、軽めのプロンプトを高めのレイテンシで扱う場合にのみ有効です。常にホストできる最大 / フルサイズのバリアントを実行してください。小さい、または大幅に量子化されたチェックポイントは、プロンプトインジェクションのリスクを高めます(Security を参照)。
バックエンドを選ぶ
| バックエンド | 使う場面 |
|---|---|
| LM Studio | 初回のローカルセットアップ、GUI ローダー、ネイティブ Responses API |
| Ollama | CLI ワークフロー、モデルライブラリ、手間のかからない systemd サービス |
| MLX / vLLM / SGLang | OpenAI 互換 HTTP エンドポイントによる高スループットのセルフホスト配信 |
| LiteLLM / OAI-proxy / custom OpenAI-compatible proxy | 別のモデル API を前段に置き、OpenClaw には OpenAI として扱わせたい場合 |
バックエンドが対応している場合は Responses API(api: "openai-responses")を使ってください(LM Studio は対応しています)。それ以外は Chat Completions(api: "openai-completions")を使います。
推奨: LM Studio + 大規模ローカルモデル(Responses API)
現時点で最良のローカルスタックです。LM Studio で大規模モデル(例: フルサイズの Qwen、DeepSeek、Llama ビルド)を読み込み、ローカルサーバー(既定値 http://127.0.0.1:1234)を有効にし、Responses API を使って推論を最終テキストから分離します。
{
agents: {
defaults: {
model: { primary: "lmstudio/my-local-model" },
models: {
"anthropic/claude-opus-4-6": { alias: "Opus" },
"lmstudio/my-local-model": { alias: "Local" },
},
},
},
models: {
mode: "merge",
providers: {
lmstudio: {
baseUrl: "http://127.0.0.1:1234/v1",
apiKey: "lmstudio",
api: "openai-responses",
models: [
{
id: "my-local-model",
name: "Local Model",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 196608,
maxTokens: 8192,
},
],
},
},
},
}
セットアップチェックリスト
- LM Studio をインストール: https://lmstudio.ai
- LM Studio で利用可能な最大のモデルビルドをダウンロードし(「small」や大幅に量子化されたバリアントは避ける)、サーバーを起動し、
http://127.0.0.1:1234/v1/modelsにそれが表示されることを確認します。 my-local-modelを LM Studio に表示される実際のモデル ID に置き換えます。- モデルを読み込んだままにします。コールドロードは起動レイテンシを増やします。
- LM Studio のビルドが異なる場合は、
contextWindow/maxTokensを調整します。 - WhatsApp では、最終テキストだけが送信されるように Responses API を使い続けます。
ローカル実行中でもホスト型モデルを設定したままにしてください。フォールバックを利用可能に保つため、models.mode: "merge" を使います。
ハイブリッド設定: ホスト型をプライマリ、ローカルをフォールバック
{
agents: {
defaults: {
model: {
primary: "anthropic/claude-sonnet-4-6",
fallbacks: ["lmstudio/my-local-model", "anthropic/claude-opus-4-6"],
},
models: {
"anthropic/claude-sonnet-4-6": { alias: "Sonnet" },
"lmstudio/my-local-model": { alias: "Local" },
"anthropic/claude-opus-4-6": { alias: "Opus" },
},
},
},
models: {
mode: "merge",
providers: {
lmstudio: {
baseUrl: "http://127.0.0.1:1234/v1",
apiKey: "lmstudio",
api: "openai-responses",
models: [
{
id: "my-local-model",
name: "Local Model",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 196608,
maxTokens: 8192,
},
],
},
},
},
}
ローカル優先、ホスト型セーフティネット付き
プライマリとフォールバックの順序を入れ替えます。同じ providers ブロックと models.mode: "merge" を維持して、ローカル環境が停止しているときに Sonnet または Opus にフォールバックできるようにします。
リージョナルホスティング / データルーティング
- ホスト型 MiniMax/Kimi/GLM バリアントは、リージョン固定エンドポイント(例: 米国ホスト)付きで OpenRouter にも存在します。Anthropic/OpenAI フォールバック用に
models.mode: "merge"を使い続けながら、選択した管轄内にトラフィックを留めるため、そこでリージョナルバリアントを選んでください。 - ローカルのみが最も強いプライバシー経路です。ホスト型リージョナルルーティングは、プロバイダー機能が必要だがデータフローを制御したい場合の中間策です。
その他の OpenAI 互換ローカルプロキシ
MLX(mlx_lm.server)、vLLM、SGLang、LiteLLM、OAI-proxy、またはカスタム
Gateway は、OpenAI 形式の /v1/chat/completions
エンドポイントを公開していれば動作します。バックエンドが /v1/responses 対応を明示的に
文書化していない限り、Chat Completions アダプターを使います。上記の provider ブロックを自分の
エンドポイントとモデル ID に置き換えてください。
{
agents: {
defaults: {
model: { primary: "local/my-local-model" },
},
},
models: {
mode: "merge",
providers: {
local: {
baseUrl: "http://127.0.0.1:8000/v1",
apiKey: "sk-local",
api: "openai-completions",
timeoutSeconds: 300,
models: [
{
id: "my-local-model",
name: "Local Model",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 120000,
maxTokens: 8192,
},
],
},
},
},
}
baseUrl を持つカスタムプロバイダーで api を省略した場合、OpenClaw は既定で
openai-completions を使います。127.0.0.1 のようなループバックエンドポイントは
自動的に信頼されます。LAN、tailnet、プライベート DNS エンドポイントには引き続き
request.allowPrivateNetwork: true が必要です。
models.providers.<id>.models[].id の値はプロバイダー内ローカルです。そこに
プロバイダープレフィックスを含めないでください。たとえば、
mlx_lm.server --model mlx-community/Qwen3-30B-A3B-6bit で起動した MLX サーバーでは、次の
カタログ ID とモデル参照を使います。
models.providers.mlx.models[].id: "mlx-community/Qwen3-30B-A3B-6bit"agents.defaults.model.primary: "mlx/mlx-community/Qwen3-30B-A3B-6bit"
ローカルまたはプロキシされたビジョンモデルでは、画像添付がエージェントターンに注入されるように
input: ["text", "image"] を設定します。対話型のカスタムプロバイダー
オンボーディングは、一般的なビジョンモデル ID を推測し、不明な名前についてのみ確認します。
非対話型オンボーディングも同じ推測を使います。不明なビジョン ID には
--custom-image-input を、モデル名はそれらしく見えるがエンドポイントの裏側では
テキスト専用の場合は --custom-text-input を使ってください。
ホスト型モデルをフォールバックとして利用可能に保つため、models.mode: "merge" を維持します。
遅いローカルまたはリモートモデルサーバーには、agents.defaults.timeoutSeconds を上げる前に
models.providers.<id>.timeoutSeconds を使ってください。プロバイダーのタイムアウトは、
接続、ヘッダー、本文ストリーミング、保護された fetch 全体の中断を含むモデル HTTP リクエストにのみ
適用されます。
ローカル / プロキシされた /v1 バックエンドの動作メモ:
- OpenClaw はこれらをネイティブの OpenAI エンドポイントではなく、プロキシ形式の OpenAI 互換ルートとして扱います
- ネイティブ OpenAI 専用のリクエスト整形はここでは適用されません:
service_tierなし、Responsesstoreなし、OpenAI reasoning 互換ペイロード 整形なし、プロンプトキャッシュヒントなし - 非表示の OpenClaw 帰属ヘッダー(
originator、version、User-Agent)は、 これらのカスタムプロキシ URL には注入されません
より厳密な OpenAI 互換バックエンド向けの互換性メモ:
-
一部のサーバーは、Chat Completions で構造化 content-part 配列ではなく、 文字列の
messages[].contentのみを受け付けます。そのようなエンドポイントにはmodels.providers.<provider>.models[].compat.requiresStringContent: trueを設定します。 -
一部のローカルモデルは、
[tool_name]の後に JSON と[END_TOOL_REQUEST]が続くような、 単独の括弧付きツールリクエストをテキストとして出力します。OpenClaw は、その名前がそのターンに登録された ツールと完全一致する場合にのみ、それらを実際のツール呼び出しに昇格します。それ以外の場合、そのブロックは 未対応のテキストとして扱われ、ユーザーに表示される返信から隠されます。 -
モデルがツール呼び出しのように見える JSON、XML、または ReAct 形式のテキストを出力したが、 プロバイダーが構造化された呼び出しを出力しなかった場合、OpenClaw はそれをテキストのままにし、 実行 ID、プロバイダー / モデル、検出されたパターン、利用可能な場合はツール名を含む警告を記録します。 これは完了したツール実行ではなく、プロバイダー / モデルのツール呼び出し 非互換性として扱ってください。
-
ツールが実行されずにアシスタントテキストとして表示される場合、たとえば生の JSON、 XML、ReAct 構文、またはプロバイダーレスポンス内の空の
tool_calls配列が出る場合は、 まずサーバーがツール呼び出し対応のチャットテンプレート / パーサーを使っていることを確認してください。 ツール使用を強制した場合にのみパーサーが機能する OpenAI 互換 Chat Completions バックエンドでは、 テキスト解析に頼るのではなく、モデルごとのリクエスト上書きを設定します。{ agents: { defaults: { models: { "local/my-local-model": { params: { extra_body: { tool_choice: "required", }, }, }, }, }, }, }これは、すべての通常ターンでツールを呼び出すべきモデル / セッションにのみ使ってください。 OpenClaw の既定のプロキシ値である
tool_choice: "auto"を上書きします。local/my-local-modelは、openclaw models listに表示される正確なプロバイダー / モデル参照に 置き換えてください。openclaw config set agents.defaults.models '{"local/my-local-model":{"params":{"extra_body":{"tool_choice":"required"}}}}' --strict-json --merge -
カスタム OpenAI 互換モデルが、組み込みプロファイルを超える OpenAI reasoning efforts を受け付ける場合は、 モデルの compat ブロックで宣言します。ここに
"xhigh"を追加すると、/think xhigh、 セッションピッカー、Gateway 検証、llm-task検証で、その設定済みプロバイダー / モデル参照向けにそのレベルが公開されます。{ models: { providers: { local: { baseUrl: "http://127.0.0.1:8000/v1", apiKey: "sk-local", api: "openai-responses", models: [ { id: "gpt-5.4", name: "GPT 5.4 via local proxy", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192, compat: { supportedReasoningEfforts: ["low", "medium", "high", "xhigh"], reasoningEffortMap: { xhigh: "xhigh" }, }, }, ], }, }, }, }
より小さい、またはより厳密なバックエンド
モデルが正常に読み込まれるものの、完全なエージェントターンが正しく動作しない場合は、上から順に確認してください。まずトランスポートを確認し、その後で対象範囲を絞ります。
-
ローカルモデル自体が応答することを確認します。 ツールなし、エージェントコンテキストなし:
openclaw infer model run --local --model <provider/model> --prompt "Reply with exactly: pong" --json -
Gateway ルーティングを確認します。 指定したプロンプトだけを送信します — transcript、AGENTS ブートストラップ、context-engine アセンブリ、ツール、同梱 MCP サーバーはスキップしますが、Gateway ルーティング、認証、プロバイダー選択は引き続き実行します:
openclaw infer model run --gateway --model <provider/model> --prompt "Reply with exactly: pong" --json -
lean mode を試します。 両方のプローブは通るのに、実際のエージェントターンが不正な形式のツール呼び出しや過大なプロンプトで失敗する場合は、
agents.defaults.experimental.localModelLean: trueを有効にします。これにより、最も重いデフォルトツール 3 つ(browser、cron、message)が除外されるため、プロンプトの形が小さくなり、壊れにくくなります。詳しい説明、使用すべき場合、有効になっていることを確認する方法については、Experimental Features → Local model lean mode を参照してください。 -
最後の手段としてツールを完全に無効にします。 lean mode でも不十分な場合は、そのモデルエントリに
models.providers.<provider>.models[].compat.supportsTools: falseを設定します。そのモデルでは、エージェントはツール呼び出しなしで動作します。 -
それ以降のボトルネックは upstream 側です。 lean mode と
supportsTools: falseの後も、より大きな OpenClaw 実行でのみバックエンドが失敗する場合、残る問題は通常、upstream のモデルまたはサーバー容量です — コンテキストウィンドウ、GPU メモリ、kv-cache エビクション、またはバックエンドのバグです。その時点では OpenClaw のトランスポート層の問題ではありません。
トラブルシューティング
- Gateway はプロキシに到達できますか?
curl http://127.0.0.1:1234/v1/models。 - LM Studio モデルがアンロードされていますか? 再読み込みしてください。コールドスタートは「ハング」のよくある原因です。
- ローカルサーバーが
terminated、ECONNRESETと表示する、またはターンの途中でストリームを閉じますか? OpenClaw は、低カーディナリティのmodel.call.error.failureKindと OpenClaw プロセスの RSS/heap スナップショットを診断情報に記録します。LM Studio/Ollama の メモリ圧迫については、そのタイムスタンプをサーバーログまたは macOS のクラッシュ / jetsam ログと照合し、モデルサーバーが kill されたかどうかを確認してください。 - OpenClaw は、検出されたモデルウィンドウ、または
agents.defaults.contextTokensによって実効ウィンドウが引き下げられている場合は上限なしのモデルウィンドウから、コンテキストウィンドウのプリフライトしきい値を導出します。20% 未満では 8k の下限で警告します。ハードブロックは 4k の下限を持つ 10% しきい値を使用し、実効コンテキストウィンドウで上限を設定するため、過大なモデルメタデータによって、本来有効なユーザー上限が拒否されることはありません。そのプリフライトに当たる場合は、サーバー/モデルのコンテキスト制限を引き上げるか、より大きなモデルを選択してください。 - コンテキストエラーですか?
contextWindowを下げるか、サーバー側の制限を引き上げてください。 - OpenAI 互換サーバーが
messages[].content ... expected a stringを返しますか? そのモデルエントリにcompat.requiresStringContent: trueを追加してください。 - 直接の小さな
/v1/chat/completions呼び出しは動作するのに、openclaw infer model run --localが Gemma または別のローカルモデルで失敗しますか? まずプロバイダー URL、モデル参照、認証 マーカー、サーバーログを確認してください。ローカルのmodel runにはエージェントツールは含まれません。 ローカルのmodel runは成功するのに、より大きなエージェントターンが失敗する場合は、localModelLeanまたはcompat.supportsTools: falseでエージェントの ツールサーフェスを減らしてください。 - ツール呼び出しが生の JSON/XML/ReAct テキストとして表示される、またはプロバイダーが
空の
tool_calls配列を返しますか? アシスタントの テキストを盲目的にツール実行へ変換するプロキシを追加しないでください。まずサーバーのチャットテンプレート/パーサーを修正してください。 ツール使用を強制した場合にのみモデルが動作する場合は、上記のモデル単位のparams.extra_body.tool_choice: "required"オーバーライドを追加し、すべてのターンでツール呼び出しが想定されるセッションにのみ そのモデルエントリを使用してください。 - 安全性: ローカルモデルはプロバイダー側のフィルターをスキップします。プロンプトインジェクションの影響範囲を限定するため、エージェントを狭く保ち、compaction を有効にしてください。