外出先からスマホで自宅PCを操作できる「AI秘書」を、できるだけ高品質に・できるだけ安全に動かしたい。そんな欲張りな目的で OpenClaw とローカル LLM を組み合わせて構築した際の手順をまとめました。
筆者は構築途中でかなりハマったので、同じ構成を試そうとする方が迷わないように、つまずきポイントも含めて記録しています。
なぜこの構成にしたのか
OpenClaw(オープンクロー)は、PC上で動作するオープンソースの自律型 AI エージェント実行プラットフォームです。LLM を頭脳として、メール管理・ファイル操作・ブラウザ操作などを自動化し、Discord・Telegram・Slack などのチャットアプリ経由で外出先から自宅 PC を操作できます。
実用するうえで最初に直面するのが、「性能」と「安全性」のトレードオフです。
| 観点 | フル機能ローカルLLM運用 | 完全クラウドAPI運用 | 完全VM隔離 |
|---|---|---|---|
| プライバシー | ◎ 全部ローカル | △ クラウドへ送信 | ◎ |
| 推論速度 | ホストGPUで高速 | 高速 | CPU推論で遅い |
| 安全性 | △ ホストに直接エージェント | ◎ APIだけ | ◎ |
| API料金 | 0円 | 月数千〜万円 | 0円 |
エージェント系ツールは、プロンプトインジェクションでホストPCに対して意図しない操作をされるリスクが構造的に存在します。一方で、ホストGPUを使わないと実用的な推論速度が出ません。
そこで本記事では、両方を取りに行く構成を採用しました。
[スマホ Discord]
↓ インターネット
[ホスト Windows 11 Pro / RAM 32GB / GPU 8GB]
├─ Ollama (GPU推論で高速)
│ listen: 0.0.0.0:11434
│
└─ VMware Workstation Pro 25H2u1
└─ Ubuntu 26.04 LTS Server VM (隔離環境)
├─ NAT接続のみ・共有フォルダ無効
├─ UFW で送信制限
└─ OpenClaw (systemd 自動起動)
ポイント:
- LLM はホストで動かして GPU 推論の速度を取る
- エージェント本体は VM 内で動かして、ファイル操作の影響をホストから遮断する
- VM ↔ ホスト間は Ollama の HTTP API のみを許可
これで「LLM 推論は速い、でもエージェントの暴走はホストに届かない」状態を実現しています。
想定環境
筆者の環境です。これとほぼ同等以上であれば動きます。
| 項目 | スペック |
|---|---|
| CPU | Intel Core i7-10870H (8C16T) |
| RAM | 32GB |
| GPU | VRAM 8GB(NVIDIA) |
| ストレージ空き | 50GB以上推奨 |
| OS | Windows 11 Pro |
全体の流れ
- ホスト(Windows 11)に Ollama を導入
- VMware Workstation Pro で Ubuntu 26.04 VM を作成
- VM 内に OpenClaw をインストール、ホスト Ollama を参照する設定
- Discord Bot を作成して連携
- ペアリング承認とポリシー設定
- 動作確認
セットアップにかかる時間の目安は、ダウンロード時間込みで 2〜3時間 です。
本記事で使用するプレースホルダー
設定値の中に含める固有値はすべて以下のプレースホルダーで表記します。実際に作業するときは、ご自身の環境の値に置換してください。
| プレースホルダー | 意味 | 取得方法 |
|---|---|---|
<HOST_IP> |
VMware NAT のホスト側 IP(VMnet8) | 「Phase 1.5」で確認 |
<NAT_SUBNET> |
VMware NAT のサブネット(例: 192.168.x.0/24) |
「Phase 1.5」で確認 |
<VM_USER> |
Ubuntu VM のユーザー名 | VM 作成時に自分で設定 |
<VM_IP> |
Ubuntu VM の IP アドレス | 「Phase 2.5」で確認 |
<DISCORD_BOT_TOKEN> |
Discord Bot のトークン | 「Phase 4.3」で取得 |
<DISCORD_USER_ID> |
あなたの Discord User ID | 「Phase 4.7」で取得 |
<PAIRING_CODE> |
OpenClaw が発行するペアリングコード | 「Phase 6.1」で取得 |
これらは秘密情報・個別情報なので、ブログや SNS に貼る際は必ずマスク(xxxx)してください。特に Bot Token は漏れると他人がボットを乗っ取れるので最重要です。
Phase 1: ホスト(Windows 11)の準備
1.1 Hyper-V の状態確認
VMware Workstation Pro の最新版は Hyper-V との共存が改善されていますが、念のため。PowerShell(管理者)で:
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All
Enabled の場合は WSL2 等で必要でなければ無効化を検討します。
1.2 Ollama のインストール
-
https://ollama.com/download/windows から
OllamaSetup.exeをダウンロード - インストール(管理者権限不要)
- PowerShell で確認:
ollama --version
1.3 Ollama の環境変数設定
タスクトレイの Ollama を Quit してから、Windows の「環境変数」画面でユーザー環境変数に以下を追加します。
| 変数名 | 値 | 目的 |
|---|---|---|
OLLAMA_HOST |
0.0.0.0:11434 |
VMから接続できるようにする |
OLLAMA_CONTEXT_LENGTH |
32768 |
OpenClawが要求する長いコンテキスト |
OLLAMA_KEEP_ALIVE |
-1 |
モデルをメモリに常駐させる |
OLLAMA_NUM_PARALLEL |
2 |
並列リクエスト対応 |
設定後にスタートメニューから Ollama を再起動。
1.4 VMware Workstation Pro 25H2u1 のインストール
VMware Workstation Pro は商用・教育・個人すべて無料化されており、ライセンスキーは不要です。
- Broadcom Support Portal から VMware Workstation Pro 25H2u1(または最新版)をダウンロード
- 管理者でインストーラー実行
- インストール後、起動
1.5 VMnet8(NAT)のサブネット確認
VMware Workstation で「編集」→「仮想ネットワークエディタ」→「Change Settings」をクリックして管理者モードに切替。VMnet8 を選択して Subnet IP をメモします。
例: Subnet IP が 192.168.179.0 の場合
-
<NAT_SUBNET>=192.168.179.0/24 -
<HOST_IP>=192.168.179.1(末尾を.1に置き換えたもの)
この IP は後で何度も使うので必ず控えておきます。
1.6 Windowsファイアウォールで Ollama ポートを制限
PowerShell(管理者)で実行:
Remove-NetFirewallRule -DisplayName "Ollama VM Access" -ErrorAction SilentlyContinue
New-NetFirewallRule -DisplayName "Ollama VM Access" `
-Direction Inbound `
-LocalPort 11434 `
-Protocol TCP `
-RemoteAddress <NAT_SUBNET> `
-Action Allow `
-Profile Any `
-Enabled True
⚠️ ハマりポイント1: Ollama インストール時の自動 Block ルール
Ollama を最初に起動したとき、Windows Security のプロンプトで「キャンセル」や「アクセスを許可しない」を選んでいると、ollama.exe を Block する ファイアウォールルールが自動作成されます。
Windows ファイアウォールでは「Block ルールが Allow ルールより優先」されるため、上記 Allow ルールを作っても効きません。確認と削除:
# Block ルールが残っているか確認
Get-NetFirewallRule | Where-Object { $_.DisplayName -like "*ollama*" -and $_.Action -eq 'Block' } | Format-Table DisplayName, Direction, Action -AutoSize
# あれば削除
Get-NetFirewallRule -DisplayName "ollama.exe" | Where-Object Action -eq Block | Remove-NetFirewallRule
これに気づかず数時間ハマったので、最初に確認することを強く推奨します。
⚠️ ハマりポイント2: VMnet8 がネットワークプロファイルに表示されない
Get-NetConnectionProfile で VMnet8 が表示されないことがあります。表示されないとファイアウォールルールが効きません。表示されない場合は以下を実行:
Disable-NetAdapter -Name "VMware Network Adapter VMnet8" -Confirm:$false
Start-Sleep -Seconds 3
Enable-NetAdapter -Name "VMware Network Adapter VMnet8" -Confirm:$false
それでもダメなら、VMware の「仮想ネットワークエディタ」で「Restore Defaults」を実行。
1.7 モデルのダウンロード
# 推奨:軽量で agent 用途に最適化された Gemma 4 E2B
ollama pull gemma4:e2b
筆者は当初 qwen3:14b や qwen3:8b を試しましたが、コンテキスト不足やタイムアウトで安定動作しませんでした。OpenClaw は長いシステムプロンプトを送るため、軽量で tool-calling に対応した gemma4:e2b が最も安定します。
確認:
ollama list
ollama ps
netstat -ano | findstr 11434 # 0.0.0.0:11434 でリッスンしていることを確認
1.8 モデルのウォームアップ
メモリにロードしておくと、初回応答の遅延を防げます。
ollama run gemma4:e2b "hello"
# 応答が返ったら Ctrl+D で終了
ollama ps # gemma4:e2b がロード中であることを確認
Phase 2: Ubuntu 26.04 VM の作成
2.1 Ubuntu 26.04 LTS Server ISO のダウンロード
https://releases.ubuntu.com/ から ubuntu-26.04-live-server-amd64.iso を取得。
2.2 VM の新規作成
VMware Workstation Pro で「File → New Virtual Machine」:
| 項目 | 値 |
|---|---|
| ウィザード | Custom (advanced) |
| ハードウェア互換性 | Workstation 22.x |
| ゲストOS | Linux → Ubuntu 64-bit |
| 仮想マシン名 | OpenClaw-Ubuntu26 |
| プロセッサ | 2ソケット × 1コア |
| メモリ | 8192 MB |
| ネットワーク | NAT(重要) |
| ディスク | NVMe / 40GB / 単一ファイル |
LLM はホストで動くので、VM のスペックは控えめで十分です。
2.3 強力な隔離設定
VM 起動前に「Edit virtual machine settings」で:
Hardware タブで削除:
- USB Controller
- Sound Card
- Printer
Options タブ:
- Shared Folders → Disabled
- Guest Isolation → 「Drag and Drop」「Copy and Paste」両方ともチェックを外す
そして VM フォルダの .vmx ファイルをメモ帳で開き、末尾に追記:
isolation.tools.copy.disable = "TRUE"
isolation.tools.paste.disable = "TRUE"
isolation.tools.dnd.disable = "TRUE"
isolation.tools.hgfsServerSet.disable = "TRUE"
isolation.tools.guestInitiatedUpgrade.disable = "TRUE"
これで VM ↔ ホスト間のすべての共有経路が遮断されます。
2.4 Ubuntu インストール
| 項目 | 設定 |
|---|---|
| 言語 | English |
| キーボード | Japanese |
| インストール種別 | Ubuntu Server (minimized) |
| ネットワーク | DHCP |
| ストレージ | Use entire disk |
| ユーザー名 | 任意(以降 <VM_USER> と表記) |
| SSH | Install OpenSSH server にチェック |
2.5 VM の IP 確認
インストール完了後、VM 内で:
ip a
ens33 等のインターフェースに振られた 192.168.x.x が <VM_IP> です。
Phase 3: VM 内の基盤構築
ホストの PowerShell から SSH 接続が便利です:
ssh <VM_USER>@<VM_IP>
3.1 システム更新
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git build-essential ufw ca-certificates net-tools
3.2 ホスト Ollama への疎通確認(最重要)
# デフォルトゲートウェイ確認
ip route | grep default
# 例: default via 192.168.179.2 dev ens33
# → ホスト IP は通常 .1(<HOST_IP>)
# ホスト Ollama に接続テスト
curl --connect-timeout 10 http://<HOST_IP>:11434/api/tags
{"models":[...]} のような JSON が返ってくれば成功です。ここを通過しないと先に進めません。
繋がらない場合のチェックリスト:
- ホストの
OLLAMA_HOST=0.0.0.0:11434が設定されているか - Ollama を再起動したか
- Windows ファイアウォールに Allow ルールがあるか
-
ollama.exeの Block ルールが残っていないか - VMnet8 がネットワークプロファイルに表示されているか
3.3 UFW で送信制限
sudo ufw default deny incoming
sudo ufw default deny outgoing
# 必要な送信のみ許可
sudo ufw allow out 53 # DNS
sudo ufw allow out 80 # HTTP
sudo ufw allow out 443 # HTTPS
# ホスト Ollama への接続許可
sudo ufw allow out to <HOST_IP> port 11434
# SSH 受信(管理用)
sudo ufw allow from <NAT_SUBNET> to any port 22
sudo ufw enable
sudo ufw status verbose
3.4 Node.js 22 のインストール
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --version # v22.x.x
3.5 OpenClaw のインストール
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
npm install -g openclaw
openclaw --version
Phase 4: Discord Bot 作成
4.1 個人用サーバー作成
Discord アプリで新規サーバーを作成。「自分と友達のため」を選択し、自分のみ参加するプライベートサーバーにします。既存の他人がいるサーバーには絶対に Bot を入れないでください。
4.2 Discord Application 作成
- https://discord.com/developers/applications にアクセス
- 右上「New Application」→ 名前入力(例:
OpenClaw Agent)→ Create - 左メニュー「Bot」を開く
4.3 Bot Token の取得
「Bot」ページで Reset Token をクリック → 表示されるトークン文字列をコピーして安全な場所(パスワードマネージャーなど)に保管。これが <DISCORD_BOT_TOKEN> になります。
⚠️ 注意点:
- Token は 発行直後の一度しか表示されません。Reset するたびに古いものは無効化されます
- Token が漏れると Bot を乗っ取られます。GitHub・SNS・チャットなどに絶対に貼らないでください
- ブログやスクショで共有するときは
MTQ5xxx...xxxのようにマスクしてください
4.4 Privileged Gateway Intents の有効化(必須)
「Bot」ページの下部「Privileged Gateway Intents」で:
- ✅ Message Content Intent(必須・これがないと Bot がメッセージを読めません)
- ✅ Server Members Intent(推奨)
Save Changes を必ずクリック。
4.5 Default Install Settings の調整
「Installation」メニューで「Install Link」を None に設定して保存(これをしないと「プライベートアプリケーションはデフォルトの認証リンクを持つことはできません」エラーが出ます)。
4.6 Bot をサーバーに招待
- 左メニュー「OAuth2」→ 「URL Generator」
-
Scopes:
botにチェック -
Bot Permissions:
Send Messages、Read Message History、View Channels、Embed Links、Attach Filesにチェック - 一番下のURLをコピーしてブラウザで開く
- 自分のサーバーを選択して「認証」
⚠️ Administrator 権限は付与しないでください。
4.7 自分の Discord User ID を取得
Bot にメッセージできるユーザーを制限するために必要です。
- Discord アプリの「設定」→「詳細設定(Advanced)」→「開発者モード」を オン
- メイン画面に戻り、自分のアバターまたは名前を右クリック(スマホは長押し)
- メニューに「ユーザーIDをコピー」が表示されるので選択
- 数字の ID(19桁前後の数値)がクリップボードにコピーされます
これが <DISCORD_USER_ID> です。これも公開されると不便なので、ブログ等では xxxxxxxxxxxxxxxxxxx のようにマスクします。
4.8 サーバー ID の取得(任意)
特定サーバーだけに Bot を限定したい場合に使用します。
- サーバー名の左にあるサーバーアイコンを右クリック
- 「サーバーIDをコピー」を選択
Phase 5: OpenClaw の設定
5.1 OpenClaw 初期設定(onboard)
openclaw onboard
⚠️ 初回起動は最大5分ほどかかることがあります。プロンプトが返らなくても焦らず待ってください。
対話で以下を選択:
| プロンプト | 回答 |
|---|---|
I understand this is powerful and inherently risky. Continue? |
Yes |
| Onboarding mode | QuickStart |
| Channel | Discord |
| Bot Token |
<DISCORD_BOT_TOKEN> を貼り付け |
| Discord channels access | Allowlist (recommended) |
| Discord channels allowlist | チャンネル ID(または Skip) |
| Search provider | Ollama Web Search |
| Configure skills now? | Yes |
| Install missing skill dependencies | Skip for now にチェック |
| Hooks | command-logger と session-memory にチェック |
| Hatch in Terminal | recommended |
5.2 設定ファイルの編集
OpenClaw のデフォルト設定はローカル Ollama を見ているので、ホスト Ollama を指すように変更します。
systemctl --user stop openclaw-gateway
~/.openclaw/openclaw.json を Python で安全に編集(<HOST_IP> と <VM_USER> は自分の値に置換してください):
python3 << 'PYEOF'
import json
# 自分の値に置換
HOST_IP = "<HOST_IP>" # 例: 192.168.179.1
VM_USER = "<VM_USER>" # 例: ubuntu
config_path = f'/home/{VM_USER}/.openclaw/openclaw.json'
with open(config_path, 'r') as f:
config = json.load(f)
# プライマリモデルを gemma4:e2b に
config['agents']['defaults']['model']['primary'] = 'ollama/gemma4:e2b'
# 古い models マップは削除(auto-discovery と競合する)
if 'agents' in config and 'defaults' in config['agents']:
config['agents']['defaults'].pop('models', None)
# ホスト Ollama を指すように設定
if 'models' not in config:
config['models'] = {}
if 'providers' not in config['models']:
config['models']['providers'] = {}
config['models']['providers']['ollama'] = {
'baseUrl': f'http://{HOST_IP}:11434',
'apiKey': 'ollama-local',
'api': 'ollama',
'models': [
{
'id': 'gemma4:e2b',
'name': 'Gemma 4 E2B',
'reasoning': False,
'input': ['text'],
'cost': {'input': 0, 'output': 0, 'cacheRead': 0, 'cacheWrite': 0},
'contextWindow': 32768,
'maxTokens': 8192
}
]
}
# サーバーチャンネルでも反応するように groupPolicy を open に
config['channels']['discord']['groupPolicy'] = 'open'
with open(config_path, 'w') as f:
json.dump(config, f, indent=2)
print('OK')
PYEOF
⚠️ ハマりポイント3: baseUrl の置き場所
公式ドキュメントでも書き方が一貫していませんが、正しい構造は models.providers.ollama.baseUrl です(baseURL ではなく baseUrl に注意。camelCase)。plugins.entries.ollama.baseURL のような間違った場所に書くと Unrecognized key: "baseURL" エラーで起動失敗します。
⚠️ ハマりポイント4: groupPolicy: allowlist の罠
OpenClaw のデフォルト onboard では groupPolicy: allowlist になっていますが、allowFrom(または groupAllowFrom)が空の場合、サーバーチャンネルのメッセージは全部 silently drop されます。
openclaw doctor でこの警告が出ます:
channels.discord.groupPolicy is "allowlist" but groupAllowFrom (and allowFrom) is empty — all group messages will be silently dropped
DM だけは別の credentials ファイルで管理されるため動きます。サーバーチャンネルでも反応させたい場合は、上記の Python スクリプトのように groupPolicy: 'open' に変更するのが最も確実です。
5.3 サービス起動
systemctl --user start openclaw-gateway
sleep 30
systemctl --user status openclaw-gateway --no-pager | head -10
Active: active (running) を確認。エラーが出たら:
journalctl --user -u openclaw-gateway --since "2 minutes ago" --no-pager | tail -30
でログを確認します。
Phase 6: ペアリング承認
OpenClaw は許可されていない Discord ユーザーからのメッセージを処理しません。最初の接続でペアリングコードが発行されます。
6.1 Bot に DM を送る
スマホ Discord で Bot のプロフィールを開き、「メッセージを送信」で DM 送信:
こんにちは
Bot から以下のような応答が返ります(数値はマスクされた例):
OpenClaw: access not configured.
Your Discord user id: xxxxxxxxxxxxxxxxxxx
Pairing code: XXXXXXXX
Ask the bot owner to approve with:
openclaw pairing approve discord XXXXXXXX
ここで表示される Pairing code が <PAIRING_CODE>、Your Discord user id は Phase 4.7 で取得した <DISCORD_USER_ID> と一致しているはずです。
6.2 VM で承認コマンド実行
openclaw pairing approve discord <PAIRING_CODE>
成功メッセージ Approved discord sender ... が表示されます。
⚠️ ペアリングコードには有効期限(数分)があります。期限切れの場合は再度 DM して新しいコードを発行してから承認してください。
6.3 doctor で警告がないか確認
echo "" | timeout 10 openclaw doctor 2>&1 | grep -i "warning\|allowlist\|drop"
「No channel security warnings detected」だけ出れば OK。
Phase 7: 動作確認
7.1 ログ監視を起動
journalctl --user -u openclaw-gateway -f
7.2 Discord でメッセージ送信
スマホ Discord で:
DM の場合:
こんにちは、自己紹介してください
サーバーチャンネルの場合(メンション必須):
@<Bot 名> こんにちは
7.3 確認すべきもの
ログに以下が流れれば成功:
[discord] message received from ...[agent/embedded] embedded run agent start ...- 数秒〜30秒後
embedded run agent end: isError=false
ホスト Windows のタスクマネージャーで GPU 使用率が一瞬上がるのも確認できます(GPU 推論で動いている証拠)。
Ctrl+C でログ監視を抜けます。
動作確認後の必須作業
1. Discord Bot Token のリセット(公開した可能性があれば)
セットアップ中に Token を画面に出したり共有したりしている可能性があるので、念のためリセット:
- Discord Developer Portal で Application を開く
- Bot タブ → Reset Token → 新しい Token をコピー
- VM 内で nano で
~/.openclaw/openclaw.jsonの token を新しいものに置換 systemctl --user restart openclaw-gateway
2. VM スナップショット作成
VMware Workstation Pro で VM → Snapshot → Take Snapshot。「初期クリーン状態」として保存しておけば、何かあっても数秒で復旧できます。
3. ホスト Ollama Cloud アカウント連携(Web 検索を使う場合)
ホスト PowerShell で:
ollama signin
これで Ollama Web Search 機能が有効化されます。
トラブルシューティングまとめ
症状: VM からホスト Ollama に curl タイムアウト
- ホスト側
OLLAMA_HOST=0.0.0.0:11434設定確認 - ホスト側
netstat -ano | findstr 11434で0.0.0.0リッスン確認 -
ollama.exeの Block ルールがないか確認(最頻出原因) - Windows ファイアウォール一時無効化で切り分け
- VMnet8 のネットワークプロファイル状態確認
症状: OpenClaw 起動時 Config invalid エラー
plugins.entries.ollama: Unrecognized key: "baseURL"
→ baseUrl(camelCase)を models.providers.ollama 配下に置く
症状: 「I just came online. Who am I?」が繰り返し返る
→ LLM 応答タイムアウト。コンテキスト不足やモデル過大が原因。gemma4:e2b への切り替えと OLLAMA_KEEP_ALIVE=-1 でウォームアップを推奨
症状: サーバーチャンネルでメンションしても反応しない(DMだけ動く)
→ groupPolicy: allowlist で allowFrom が空なのが原因。openclaw doctor で警告が出ます。groupPolicy: open に変更で解決
症状: メモリ不足エラー
{"error":"model requires more system memory (X.X GiB) than is available (Y.Y GiB)"}
→ 軽量モデル(gemma4:e2b)に切り替え、または不要なアプリを閉じる
まとめ
OpenClaw + ローカル LLM の構築は、ステップ自体は多くないものの、ハマりポイントが点在しているのが厄介でした。特に:
- Windows ファイアウォールの Block ルール
- OpenClaw の
baseUrlの置き場所 -
groupPolicy: allowlistの silently drop - ペアリング承認の必要性
このあたりは事前に知っていれば数分で済む話なので、本記事が同じ構成を試す方の役に立てば幸いです。
完成すると、外出先からスマホで自宅 PC のエージェントを操作できるのは想像以上に便利です。ローカル LLM なので API 料金もかからず、隔離環境なので安心して試行錯誤できます。
エージェントの人格は ~/.openclaw/workspace/ 配下の Markdown ファイル(IDENTITY.md、USER.md、SOUL.md など)で育てていく形なので、ここから先は自分だけの AI 秘書を仕立てる楽しい作業が待っています 🦞