はじめに(注意)
手元でOpenClawの設計や、Nanobot・PicoClawとの違いについてまとめていたものをダンプします。水物ではあるのであくまで現時点での参考みたいな感じでお願いしたい
- ほとんどClaude Code が書いたAI生成です
- 一通り自分でチェックはしていますが、品質担保が自分で書いたのほどではありません
- まぁ特に文章が味気ないよね……
- 余計な情報(メモとか)は削りました
- 2026年2月時点の情報です
- 新しいバージョンに基づいたアップデート予定はありません。自分で書こうね!
- 未来の人においては「過去のスナップショット」と考えるのが良いでしょう
なげーので、まず章立てを共有
- 基礎情報・背景
- アーキテクチャ
- 機能・ユースケース
- エコシステム・コミュニティについて
- セキュリティ・リスク
- LLMへの指示方法・ツール呼び出し・MCP/ACP詳細
- 競合・代替ツール比較
- NanoBot 詳細
- PicoClaw 詳細
- OpenClaw まとめ
「OpenClawって何なのよ」「どうやって動いているのよ」「話題の代替NanoBotとかPicoClawはどう違うのよ」みたいなところに興味があったので、そのあたりが多少充実しているはずです。
「LLMは単なる次のトークンを予測するだけ」とかいうレベルの理解だと、この手のエージェントが具体的にどういうプロンプトで動作しているのかわかりませんので、そのあたりについてはちょっと踏み込みたかったという事情があります。
調査に使った時点のhashも置いときます
- OpenClaw: bd4f670
- NanoBot: fff6207
- PicoClaw: cec6fd4
1: 基礎情報・背景
プロジェクトの歴史
| 時期 | 出来事 |
|---|---|
| 2011年 | Peter Steinberger が PSPDFKit をブートストラップで立ち上げ |
| ~2025年 | 個人プロジェクト "Warelay" として内部開発(VISION.md より確認) |
| 2025年11月 | "Warelay" を元に Clawdbot としてオープンソース化(Claudeから命名) |
| 2026年1月27日 | Anthropicからの商標指摘を受け Moltbot に改名 |
| 2026年1月30日 | "Moltbot" の語呂が悪いとして OpenClaw に改名 |
| 2026年1月下旬〜2月初旬 | GitHubスター数が急増。2週間以内に15〜17.5万スターを突破。GitHub史上最速級の成長 |
| 2026年2月14日 | 創設者 Steinberger が OpenAI への参加を発表 |
| 2026年2月以降 | プロジェクトをオープンソース財団へ移管予定。OpenAI・Anthropicがスポンサーに |
注: VISION.md には "Warelay -> Clawdbot -> Moltbot -> OpenClaw" という変遷が明記されており、以前に知られていなかった "Warelay" ステップが確認された。
開発者: Peter Steinberger
- オーストリア出身のソフトウェア開発者・起業家
- PSPDFKit(PDFレンダリングSDK)を2011年に立ち上げ(米国ビザ待ちの期間に開発)
- Clawdbot は個人的な自動化ツール("Warelay")として開発を開始し、オープンソース化後に急成長
急成長の要因
- フル機能のオープンソース・ローカルファースト・モデル非依存という希少な組み合わせ
- 既存のメッセージングアプリからそのまま操作できるUXの斬新さ
- "Moltbook" プロジェクト(MBP代替の独自PCプロジェクト)とのバイラル注目
バージョン管理・リリース
-
バージョン形式:
YYYY.M.D(例:2026.2.22) - リリースチャネル: stable / beta / dev の3チャネル
- GitHub Actions + Sparkle: macOSアップデート配信
-
npm:
openclawパッケージとして公開。プラグインは@openclaw/<name>スコープ
ライセンス
- MIT License: 商用利用・改変・再配布が自由。著作権表示のみ必要
GitHub統計(2026年2月時点)
| 指標 | 値 |
|---|---|
| スター数 | ~217,000 |
| フォーク数 | ~41,000 |
| パッケージバージョン | 2026.2.22 |
| 主要言語 | TypeScript |
2: アーキテクチャ
全体構成(ハブアンドスポーク型)
[メッセージングアプリ群]
WhatsApp / Telegram / Slack / Discord / Signal / iMessage / LINE / MS Teams / Matrix / ...
↓
[Channel Adapters] ← メッセージを統一フォーマットに変換(各チャネル専用モジュール)
↓
[Gateway Server] ← WebSocket + Express HTTP サーバー。セッション・ルーティング・イベント管理
↓
[Lane Queue] ← Main/Cron/Subagent/Nested の4レーン。各レーン同時実行数を設定可能
↓
[Agent Runtime (Pi)] ← LLM推論コア。@mariozechner/pi-agent-core を使用
↓
[各種ツール/Skill]
シェルコマンド(exec) / ブラウザ自動化 / メール / カレンダー / ファイル操作 / ...
[CronService] → Agent Runtimeを定期起動
[HeartbeatRunner] → 定期的なプロアクティブポーリング
[BOOT.md] ← Gatewayスタート時に一度だけ実行されるブートスクリプト
主要コンポーネント詳細
Gateway Server (src/gateway/)
- 役割: 「単一の真実の源」(コントロールプレーン)
- Express v5 +
wsライブラリによる WebSocket サーバー - 主要サブモジュール:
-
server-channels.ts: チャネル管理 -
server-chat.ts: エージェントイベントハンドラ -
server-cron.ts: Cronサービス組み込み -
server-lanes.ts: レーン同時実行数の設定 -
server-plugins.ts: プラグインロード -
server-model-catalog.ts: モデルカタログロード -
config-reload.ts: ホットリロード -
channel-health-monitor.ts: チャネル死活監視 -
server-discovery-runtime.ts: mDNSによるノード発見(@homebridge/ciao)
-
- バックグラウンドデーモンとして常駐(macOS: アプリのメニューバープロセス、Linux: systemd等)
Channel Adapters (コア + エクステンション)
コア(src/ 直下):
-
src/telegram/: grammy ライブラリ使用 -
src/discord/: @discordjs/voice, @buape/carbon 使用 -
src/slack/: @slack/bolt 使用 -
src/signal/: Signal 対応 -
src/imessage/: iMessage 対応(BlueBubbles経由) -
src/web/: WhatsApp Web (@whiskeysockets/baileys 使用) -
src/line/: LINE 対応(@line/bot-sdk 使用)
エクステンション(extensions/ 配下、npm パッケージ):
-
extensions/msteams/: Microsoft Teams -
extensions/matrix/: Matrix -
extensions/voice-call/: 音声通話 -
extensions/zalo/,extensions/zalouser/: Zalo -
extensions/googlechat/: Google Chat -
extensions/feishu/: Feishu(飞书) -
extensions/nextcloud-talk/,extensions/mattermost/: その他チャット - その他多数(IRC, Nostr, Tlon, Twitch, Synology Chat 等)
Lane Queue (src/process/)
-
4レーン:
CommandLaneenum で定義-
Main: 通常のユーザーリクエスト -
Cron: Cronジョブ -
Subagent: サブエージェントセッション -
Nested: ネストされた実行
-
- 各レーンの同時実行数は
setCommandLaneConcurrency()で設定 - Gateway起動時に
applyGatewayLaneConcurrency()が設定を適用- Cron:
cfg.cron?.maxConcurrentRuns ?? 1(デフォルト直列) - Main:
resolveAgentMaxConcurrent(cfg)で解決 - Subagent:
resolveSubagentMaxConcurrent(cfg)で解決
- Cron:
Agent Runtime (Pi Engine)
-
コアライブラリ:
@mariozechner/pi-agent-core,@mariozechner/pi-coding-agent(外部パッケージ) - Pi = 独自のエージェントランナー名(PSPDFKit作者由来)
-
src/agents/pi-embedded-runner.ts: メインの実行エンジン - 会話履歴を管理し、LLMに送信するペイロードを組み立てる
- コンパクション: 長い会話履歴を自動要約してトークン節約
-
サブエージェント:
sessions_spawnツールで新しいセッションを起動し、完了をプッシュ通知
System Prompt 構造 (src/agents/system-prompt.ts)
buildAgentSystemPrompt() 関数が生成するプロンプトの構成:
- Identity: "You are a personal assistant running inside OpenClaw."
- Tooling: 有効なツール一覧(フィルタリング済み)
- Tool Call Style: ツール呼び出しのナレーション方針
- Safety: 独立目標の禁止、Anthropic Constitutionに基づく安全方針
-
OpenClaw CLI Quick Reference:
openclaw gateway start/stop/restart等 - Skills (mandatory): スキル一覧と読み込み指示(1ターンに1つのSKILL.mdを読む)
- Memory Recall: メモリ検索の指示
- OpenClaw Self-Update: 自己更新の許可条件
- Model Aliases: モデルエイリアス
- Workspace: 作業ディレクトリ情報
- Sandbox: Docker サンドボックス情報(有効時のみ)
- Authorized Senders: 許可された送信者一覧
- Workspace Files: コンテキストファイル(MEMORY.md等)の注入
-
Reply Tags:
[[reply_to_current]]等のタグ構文 - Messaging: チャネル横断メッセージ送信の指示
- Voice (TTS): 音声モード時のヒント
-
Silent Replies: 返信不要時のトークン(
SILENT_REPLY_TOKEN) -
Heartbeats:
HEARTBEAT_OKトークンの扱い - Runtime: エージェントID・ホスト・モデル等の実行時情報
PromptMode:
-
full: 全セクション(メインエージェント) -
minimal: 縮小版(サブエージェント向け) -
none: 基本的なIDラインのみ
Heartbeat / Boot システム
- HEARTBEAT.md: プロアクティブタスクのチェックリスト
-
Heartbeat Runner (
src/infra/heartbeat-runner.ts): 定期的にエージェントを起動 -
BOOT.md (
src/gateway/boot.ts): Gateway起動時に一度だけ実行される初期化スクリプト。完了後にセッションマッピングを復元 -
CronService (
src/cron/service.ts): CRUD操作と手動実行をサポートするクラス。cronerライブラリ使用
Skill System (src/agents/skills/)
詳細は [02_architecture_skills.md に記載] 参照(以下概要)
# SKILL.md の YAML フロントマター例
---
always: false # 常時インジェクト(true/false)
skillKey: "github" # スキルキー識別子
primaryEnv: "GITHUB_TOKEN"
emoji: "🐙"
homepage: "https://github.com/..."
os: ["darwin", "linux"]
requires:
bins: ["gh"] # 必須バイナリ
anyBins: ["git"] # いずれか一つ
env: ["GITHUB_TOKEN"] # 必須環境変数
config: ["key.path"] # 必須設定
install:
- kind: brew
formula: gh
- kind: node
package: "@openclaw/github"
---
# スキルの自然言語指示
...
- システムプロンプトに
<available_skills>セクションとして挿入 - エージェントはターンごとに最も適したスキルを1つ選び、
readツールでSKILL.mdを読む - スキルパスをホームディレクトリ
~で短縮しトークン節約(約400〜600トークン削減) - 読み込み元:
- バンドルスキル(
skills/ディレクトリ、約50種類) -
~/.openclaw/skills/(ユーザースキル) - エージェント固有ディレクトリ
- プラグイン経由のスキル
- バンドルスキル(
Memory System (src/memory/)
- ハイブリッド検索: BM25(キーワード)+ ベクトル検索を組み合わせ
-
SQLiteバックエンド:
sqlite-vec拡張でベクトルストア- テーブル:
chunks_vec(ベクトル),chunks_fts(全文検索),embedding_cache(キャッシュ)
- テーブル:
- エンベディングプロバイダー: OpenAI / Gemini / Voyage / Local(node-llama-cpp)/ auto
-
ファイル:
MEMORY.md+memory/*.md -
memory_searchツール: テキスト検索(キーワード展開あり) -
memory_getツール: 特定行の取得
ACP (Agent Client Protocol) サポート (src/acp/)
-
@agentclientprotocol/sdk0.14.1 を使用 -
AcpGatewayAgentクラスで Gateway WebSocket ↔ ACP プロトコル変換 - stdioベースのサーバーとして動作(
ndJsonStream使用)
技術スタック
| 項目 | 内容 |
|---|---|
| 言語 | TypeScript (ESM strict) |
| ランタイム | Node.js >= 22.12.0 (LTS) |
| パッケージマネージャ | pnpm 10.23.0 |
| HTTPサーバー | Express v5 |
| WebSocket | ws ライブラリ |
| テスト | Vitest (カバレッジ閾値70%) |
| リント/フォーマット | Oxlint + Oxfmt |
| ビルド | tsdown |
| iOS/macOS UI | SwiftUI + Observation framework |
| Webフロントエンド | Lit (Web Components) |
| mDNS | @homebridge/ciao |
| ライセンス | MIT |
LLM プロバイダー対応
| カテゴリ | プロバイダー |
|---|---|
| クラウドAPI | Anthropic Claude |
| クラウドAPI | OpenAI GPT / Responses |
| クラウドAPI | Google Gemini |
| クラウドAPI | AWS Bedrock |
| クラウドAPI | GitHub Copilot |
| クラウドAPI | HuggingFace |
| クラウドAPI | Chutes (OAuth) |
| クラウドAPI | MiniMax VLM |
| クラウドAPI | BytePlus (Doubao) |
| クラウドAPI | Qwen Portal |
| クラウドAPI | VolcEngine |
| クラウドAPI | Cloudflare AI Gateway |
| クラウドAPI | Together AI |
| クラウドAPI | Venice AI |
| クラウドAPI | Kimi Coding |
| クラウドAPI | NVIDIA |
| クラウドAPI | OpenCode Zen |
| ローカル | Ollama |
| ローカル | LM Studio(OpenAI互換) |
| ローカル | node-llama-cpp(組み込み) |
MCP サポートについて
- 方針: コアに直接MCP統合しない(VISION.mdに明記)
-
実装:
mcporterという外部ブリッジプロジェクト経由(https://github.com/steipete/mcporter) - 理由: MCPの変更がコアの安定性・セキュリティに影響しないよう切り離す
マルチエージェント設計
- セッション: 各エージェント × チャネルで独立したセッション管理
-
サブエージェント:
sessions_spawnツールで新規セッション起動、深さ制限あり -
サブエージェントレジストリ:
src/agents/subagent-registry.tsで生存管理 - 設計指針: 「manager-of-managers / nested planner trees」をデフォルトとして採用しない(VISION.mdに明記)
デーモン化の仕組み
- macOS: OpenClaw Mac アプリ(SwiftUI)のメニューバープロセスとして動作。LaunchAgent は現在使用していない
- Linux: systemd サービス想定
- ポート: デフォルト18789、ループバック(127.0.0.1)にバインド(セキュリティのため)
3: 機能・ユースケース
対応メッセージングプラットフォーム
コア(src/ 配下に実装済み)
| プラットフォーム | 実装場所 | ライブラリ |
|---|---|---|
src/web/, src/whatsapp/
|
@whiskeysockets/baileys | |
| Telegram | src/telegram/ |
grammy |
| Discord | src/discord/ |
@discordjs/voice, @buape/carbon |
| Slack | src/slack/ |
@slack/bolt |
| Signal | src/signal/ |
|
| iMessage (BlueBubbles) | src/imessage/ |
|
| LINE | src/line/ |
@line/bot-sdk |
| WebChat | src/web/ |
ブラウザUI |
エクステンション(extensions/ 配下、npm パッケージ)
| プラットフォーム | 実装場所 |
|---|---|
| Microsoft Teams | extensions/msteams/ |
| Matrix | extensions/matrix/ |
| Google Chat | extensions/googlechat/ |
| Feishu(飛書) | extensions/feishu/ |
| Zalo |
extensions/zalo/, extensions/zalouser/
|
| Mattermost | extensions/mattermost/ |
| Nextcloud Talk | extensions/nextcloud-talk/ |
| Synology Chat | extensions/synology-chat/ |
| IRC | extensions/irc/ |
| Nostr | extensions/nostr/ |
| Tlon (Groups) | extensions/tlon/ |
| Twitch | extensions/twitch/ |
| 音声通話 | extensions/voice-call/ |
対応LLMモデル
| カテゴリ | モデル/サービス |
|---|---|
| クラウドAPI | Anthropic Claude(Claude Pro/Maxが推奨) |
| クラウドAPI | OpenAI GPT(Responses API対応) |
| クラウドAPI | Google Gemini |
| クラウドAPI | AWS Bedrock |
| クラウドAPI | GitHub Copilot |
| クラウドAPI | HuggingFace |
| クラウドAPI | BytePlus/Doubao(バイトダンス系) |
| クラウドAPI | Qwen Portal(阿里云) |
| クラウドAPI | MiniMax VLM |
| クラウドAPI | Kimi Coding(月之暗面) |
| クラウドAPI | NVIDIA AI |
| クラウドAPI | Together AI |
| クラウドAPI | Venice AI |
| クラウドAPI | Chutes |
| クラウドAPI | Cloudflare AI Gateway |
| ローカル | Ollama |
| ローカル | LM Studio(OpenAI互換エンドポイント) |
| ローカル | node-llama-cpp(組み込み) |
主要機能一覧
コア機能(src/agents/ で実装)
| 機能 | 詳細 |
|---|---|
| シェルコマンド実行 |
exec ツール。PTY対応(TTY必須CLIのため)。バックグラウンド実行・プロセス管理も可 |
| ファイル操作 |
read/write/edit/apply_patch/grep/find/ls ツール |
| ブラウザ自動化 |
browser ツール。playwright-core 1.58.2 使用 |
| 画像処理 |
image ツール。sharp ライブラリ使用 |
| PDF処理 | pdfjs-dist 5.4.624 を依存関係に含む |
| Webスクレイピング |
web_fetch ツール。@mozilla/readability で読み取り |
| Web検索 |
web_search ツール(Brave API) |
| メモリ管理 |
memory_search/memory_get ツール(SQLite + ハイブリッド検索) |
スケジューリング・プロアクティブ実行
| 機能 | 詳細 |
|---|---|
| CronService |
cron ツール経由でジョブの追加/更新/削除/実行。croner ライブラリ使用 |
| Heartbeat | 定期的なプロアクティブポーリング。HEARTBEAT.md のチェックリストを確認 |
| BOOT.md | Gateway起動時に一度だけ実行される初期化スクリプト |
| Webhook | Webhook URLによるトリガー対応 |
マルチエージェント
| 機能 | 詳細 |
|---|---|
| サブエージェント |
sessions_spawn ツールで新セッション起動 |
| セッション管理 |
sessions_list/sessions_history/sessions_send ツール |
| サブエージェント制御 |
subagents ツール(list/steer/kill) |
| エージェント切替 |
agents_list で利用可能なエージェントID一覧 |
| 深さ制限 | サブエージェントのネスト深さに上限(ループ防止) |
音声・マルチモーダル
| 機能 | 詳細 |
|---|---|
| Voice Wake + Talk Mode | macOS, iOS, Android対応(extensions/voice-call/ + macOS App統合) |
| TTS |
node-edge-tts、sherpa-onnx-tts(ローカル)等 |
| 音声入力 | OpenAI Whisper API / ローカルWhisper |
| カメラ |
nodes ツール経由でペアリングデバイスのカメラ制御 |
| スクリーン録画 | 同上 |
| 画像分析 |
image ツール(設定済み画像モデル使用) |
視覚的インタラクション
| 機能 | 詳細 |
|---|---|
| Live Canvas / A2UI | エージェント主導のビジュアルワークスペース(Lit + Web Components) |
| ノードペアリング | モバイルデバイスとのペアリング(src/pairing/) |
ネットワーク・デバイス連携
| 機能 | 詳細 |
|---|---|
| mDNS ノード発見 | @homebridge/ciao によるLAN内ノード自動発見 |
| Tailscale連携 | exe.dev VM へのSSHアクセス等(AGENTS.mdに記述) |
| Gmail Pub/Sub |
src/hooks/ 内でGmail監視統合 |
セキュリティ機能
| 機能 | 詳細 |
|---|---|
| Exec承認システム |
exec ツールの実行に承認フローを設けるオプション |
| サンドボックス | Docker/Podmanサンドボックス内での実行オプション |
| ツールポリシー | ツール単位での許可/拒否設定 |
| セキュリティ監査 |
openclaw security audit --deep コマンド |
スキル(bundled skills)一覧
skills/ ディレクトリに約50種のバンドルスキルを収録:
| スキル | 概要 |
|---|---|
| 1password | 1Password CLIとの連携 |
| apple-notes | Apple Notesとの連携 |
| apple-reminders | Apple Remindersとの連携 |
| bear-notes | Bear Notesとの連携 |
| blogwatcher | ブログ監視 |
| blucli | Bluetooth CLI |
| bluebubbles | BlueBubbles(iMessage代替) |
| camsnap | カメラスナップショット |
| canvas | Live Canvas操作 |
| clawhub | ClawHubからのスキルインストール |
| coding-agent | コーディングエージェント |
| discord | Discord操作 |
| food-order | 食事注文 |
| gemini | Google Gemini連携 |
| gh-issues | GitHub Issues |
| github | GitHub操作 |
| healthcheck | ヘルスチェック |
| himalaya | メールクライアント(himalaya) |
| imsg | iMessage送信 |
| mcporter | MCPブリッジ(mcporter) |
| model-usage | モデル使用状況 |
| notion | Notion連携 |
| obsidian | Obsidian連携 |
| openai-image-gen | OpenAI画像生成 |
| openai-whisper | Whisper音声認識 |
| openhue | Philips Hue照明制御 |
| peekaboo | スクリーンショット・カメラ(macOS) |
| session-logs | セッションログ閲覧 |
| skill-creator | 新スキル作成支援 |
| slack | Slack操作 |
| spotify-player | Spotify制御 |
| summarize | 要約 |
| things-mac | Things 3(タスク管理)連携 |
| tmux | tmux操作 |
| trello | Trello連携 |
| video-frames | 動画フレーム抽出 |
| voice-call | 音声通話 |
| wacli | WhatsApp CLI |
| weather | 天気情報 |
| xurl | URL展開/解析 |
| その他 | eightctl, gog, goplaces, gifgrep 等 |
主要ユースケース
| # | ユースケース | 詳細 |
|---|---|---|
| 1 | 朝のブリーフィング | Heartbeatで自動収集し、モーニングサマリーをメッセージ送信 |
| 2 | メール管理 | Gmail Pub/Sub統合でリアルタイム処理、返信草案作成 |
| 3 | カレンダー管理 | スケジューリング・リマインダー(Cronジョブ利用) |
| 4 | リサーチタスク | web_fetch/web_searchで情報収集し要約 |
| 5 | 開発支援 | シェルコマンド・ファイル操作・コーディングエージェント |
| 6 | ブラウザ自動化 | playwright-coreでWebスクレイピング・フォーム入力 |
| 7 | 定期レポート | HEARTBEAT.mdとCronServiceによる自動レポート生成 |
| 8 | ホームオートメーション | Philips Hue(openhue)等との連携 |
| 9 | メモ管理 | Obsidian/Notion/Bear/Apple Notes統合 |
| 10 | マルチデバイス音声操作 | Voice Wake + Peekabooでハンズフリー制御 |
4: エコシステム・コミュニティについて
GitHubリポジトリ状況(2026年2月時点)
| 指標 | 値 |
|---|---|
| スター数 | ~217,000 |
| フォーク数 | ~41,000 |
| ライセンス | MIT |
| メイン言語 | TypeScript |
| 現在バージョン | 2026.2.22 |
| スポンサー | OpenAI、Anthropic |
ClawHub(スキルレジストリ)
- URL:
https://clawhub.ai(システムプロンプトに "Find new skills: https://clawhub.com" と記載) - コミュニティが作成したスキルを発見・配布するためのレジストリ
-
専用スキル
skills/clawhub/: Gatewayから直接インストール可能 - GitHub経由でも配布可能
- 注意: スキルの審査が不十分なため、悪意あるスキルが含まれるリスクがある
スキル(SKILL.md)の仕組み(詳細)
---
always: false # 常時インジェクト(trueの場合はターン毎に必ず含める)
skillKey: "github" # スキル識別子
primaryEnv: "GITHUB_TOKEN" # 主要環境変数
emoji: "🐙"
homepage: "https://github.com/..."
os: ["darwin", "linux"] # 対応OS
requires:
bins: ["gh"] # 必須バイナリ(全て必要)
anyBins: ["git"] # バイナリ(いずれか一つ)
env: ["GITHUB_TOKEN"] # 必須環境変数
config: ["key.path"] # 必須設定値
install:
- kind: brew
formula: gh
- kind: node
package: "@openclaw/github"
- kind: go
package: "..."
- kind: uv
package: "..."
- kind: download
url: "..."
archive: "..."
extract: true
stripComponents: 1
targetDir: "/usr/local/bin"
---
# 以下に自然言語での指示を記述(Markdownフォーマット)
スキル配置場所(優先順位順)
-
skills/(バンドル、コアリポジトリ内) -
~/.openclaw/skills/(ユーザーグローバル) - エージェント固有ディレクトリ(
~/.openclaw/agents/<id>/skills/) - プラグイン経由のスキル(npm パッケージ)
スキルのフィルタリング
- OS制約(
os: ["darwin"]等) - 必須バイナリの存在確認
- 必須環境変数の確認
- エージェントレベルのスキルフィルタ設定
プラグイン/エクステンション
コアプラグイン(extensions/ 配下)
各エクステンションは独立した npm パッケージとして管理される:
| パッケージ | 内容 |
|---|---|
extensions/msteams/ |
Microsoft Teams チャネル |
extensions/matrix/ |
Matrix プロトコル |
extensions/googlechat/ |
Google Chat |
extensions/feishu/ |
Feishu(飛書) |
extensions/voice-call/ |
音声通話機能 |
extensions/memory-core/ |
メモリシステム(コア) |
extensions/memory-lancedb/ |
LanceDBメモリバックエンド |
extensions/device-pair/ |
デバイスペアリング |
extensions/diagnostics-otel/ |
OpenTelemetry診断 |
extensions/llm-task/ |
LLMタスク実行 |
extensions/lobster/ |
CLI UIテーマ |
extensions/open-prose/ |
文章生成支援 |
extensions/thread-ownership/ |
スレッド所有権管理 |
extensions/phone-control/ |
電話制御 |
extensions/talk-voice/ |
音声対話 |
認証エクステンション(プロバイダー専用)
| パッケージ | 内容 |
|---|---|
extensions/copilot-proxy/ |
GitHub Copilot認証プロキシ |
extensions/google-antigravity-auth/ |
Google認証(特殊モード) |
extensions/google-gemini-cli-auth/ |
Gemini CLI認証 |
extensions/minimax-portal-auth/ |
MiniMax認証ポータル |
extensions/qwen-portal-auth/ |
Qwen認証ポータル |
スポンサー・支援状況
- OpenAI: 創設者Peter Steinbergerが2026年2月14日にOpenAIへ参加を発表
- Anthropic: 元々ClawdbotはAnthropicのClaudeから命名。商標問題後も協力関係。プロジェクトのスポンサー
関連プロジェクト
| プロジェクト | URL | 概要 |
|---|---|---|
| ClawWork | https://github.com/HKUDS/ClawWork | OpenClawの関連プロジェクト(詳細未調査) |
| secure-openclaw | https://github.com/ComposioHQ/secure-openclaw | セキュリティ強化フォーク |
| mcporter | https://github.com/steipete/mcporter | MCP↔Gatewayブリッジ(公式推奨のMCP統合方法) |
| clawhub | https://github.com/openclaw/clawhub | スキルレジストリ |
| openclaw/trust | https://github.com/openclaw/trust | 信頼・脅威モデル |
ACP(Agent Client Protocol)対応
-
@agentclientprotocol/sdk0.14.1 を依存関係に含む -
src/acp/モジュールで実装 - Gatewayをstdio経由でACPエージェントとして公開可能
- 外部システムとのプロトコルベース統合を可能にする
プラグインシステムの詳細
- プラグイン/エクステンションはGatewayプロセス内にロードされる(in-process)
- 同じOS権限で実行されるため、インストールするプラグインは信頼できるものに限る
-
plugins.allow設定で信頼済みプラグインIDをピン留め可能 - 実行時の依存はプラグインの
dependenciesに含める(devDependenciesは除く)
5: セキュリティ・リスク調査
セキュリティポリシー(SECURITY.md より)
報告先
- コアCLI/Gateway, macOS/iOS/Android →
openclaw/openclawリポジトリ - ClawHub →
openclaw/clawhubリポジトリ - Trust/脅威モデル →
openclaw/trustリポジトリ - 不明な場合 →
security@openclaw.ai - 詳細:
https://trust.openclaw.ai
セキュリティ担当
- Jamieson O'Reilly (Dvuln創設者、攻撃的セキュリティ・ペネトレーションテスト専門家)
バグバウンティ
- なし(ラボ・オブ・ラブのため予算なし)
デプロイメント前提条件(SECURITY.mdより)
- Gatewayが動作するホストは信頼されたOS/管理境界内を前提
-
~/.openclawの設定を変更できる人間は信頼されたオペレーターと同等 - 相互に信頼できない複数ユーザーが同一Gatewayを共有するのは非推奨
- 認証済みGatewayコーラーは信頼されたオペレーターとして扱われる
- セッション識別子(
sessionKey)はルーティングコントロールであり、認可境界ではない
スコープ外(セキュリティレポート対象外)
- パブリックインターネットへの公開
- ドキュメントが非推奨としている使い方
- 相互に信頼できない/敵対的なオペレーターが1つのGatewayホストを共有するデプロイ
- プロンプトインジェクション攻撃(セキュリティレポートのスコープ外と明記)
注: プロンプトインジェクションが明示的にスコープ外とされているが、これは設計上の制約であり、重大なリスクが存在しないという意味ではない。
既知のリスク
1. プロンプトインジェクション攻撃
- 概要: 悪意ある入力によって、エージェントが意図しない行動をとらされる
- 影響: シェルコマンド実行権限を持つエージェントへの攻撃は特に危険
- 報告者: Cisco AIセキュリティチームが脆弱性を指摘
- 公式の対応: セキュリティレポートのスコープ外と宣言(設計上の制約と認識)
2. プラグイン/スキルのin-process実行
- 概要: プラグイン・エクステンションはGatewayプロセス内に完全にロードされる
- 影響: プラグインはGatewayと同じOS権限で実行される
- 事例: ClawHubスキルに悪意あるデータ送信コードが含まれていた事例(Cisco AI報告)
-
対策:
plugins.allowで信頼済みプラグインIDをピン留め
3. 広範なシステム権限
- 概要: シェル実行・ファイル操作・ブラウザ制御等の広範な権限を要求
- リスク: エクスプロイトされた場合のダメージ範囲が広い
セキュリティ機能・緩和策
Exec承認システム
-
bash-tools.exec-approval-request.tsが実装 - 特定の実行コマンドに承認フローを必須化できる
-
ExecApprovalManagerで承認状態を管理
ツールポリシー(Tool Policy)
-
src/agents/tool-policy.tsで実装 - ツール単位での許可/拒否ポリシー設定
-
tools.exec.applyPatch.workspaceOnly: true- apply_patchをワークスペース内に制限 -
tools.fs.workspaceOnly: true- ファイルツールをワークスペース内に制限
Dockerサンドボックス
-
Dockerfile.sandbox,Dockerfile.sandbox-browser,Dockerfile.sandbox-commonが存在 -
src/agents/sandbox.tsでサンドボックス設定を管理 - 非rootユーザー(
node)として実行推奨 -
--read-only/--cap-drop=ALLフラグでセキュリティ強化
Web UIセキュリティ
- デフォルト: ループバック(127.0.0.1)にのみバインド(
gateway.bind="loopback") - 公開インターネットへの公開は明示的に禁止
-
gateway.controlUi.dangerouslyDisableDeviceAuth: ローカル限定のブレークグラス設定
セキュリティ監査コマンド
openclaw security audit --deep
openclaw security audit --fix
秘密スキャン
-
detect-secrets1.5.0 でCI/CDに組み込まれた自動秘密検出 -
.secrets.baselineで誤検知のベースライン管理
Node.jsバージョン要件
-
必須: Node.js >= 22.12.0(CVEパッチ含む)
- CVE-2025-59466: async_hooks DoS脆弱性
- CVE-2026-21636: Permission model bypass脆弱性
ツールスキーマのガードレール(Google Antigravity)
-
Type.Unionを使用しない -
anyOf/oneOf/allOfを避ける -
formatプロパティ名をスキーマで避ける(バリデーター互換性のため)
セキュリティ上のメリット
| メリット | 詳細 |
|---|---|
| ローカルファースト | データがクラウドに送られない(ローカルモデル利用時) |
| 自己ホスト | プロバイダーへのデータ依存なし |
| オープンソース | コードを自分で確認できる |
| ループバックデフォルト | デフォルトでローカルのみアクセス可能 |
| 非root実行 | Dockerでは非root(node)ユーザーで実行 |
| 秘密検出CI | detect-secretsで自動チェック |
安全な利用のためのベストプラクティス
- ClawHubスキルは必ずソースコードを確認してからインストールする
plugins.allowで信頼済みプラグインIDをピン留めする- サンドボックス環境(Docker/Podman)での実行を検討する
-
tools.exec.applyPatch.workspaceOnly: trueを設定する(デフォルト推奨) -
tools.fs.workspaceOnly: trueを設定する(追加保護) - Gatewayは必ずループバック(127.0.0.1)にバインドする
- リモートアクセスが必要な場合はSSHトンネルまたはTailscaleを使用
- 定期的にエージェントのアクションログを確認する
- Node.js >= 22.12.0 を使用する
参考
- SECURITY.md:
./openclaw/SECURITY.md - CrowdStrike セキュリティ分析: https://www.crowdstrike.com/en-us/blog/what-security-teams-need-to-know-about-openclaw-ai-super-agent/
- Trust: https://trust.openclaw.ai
6: LLMへの指示方法・ツール呼び出し・MCP/ACP詳細
1. 「ツール呼び出し」とは何か(AIエージェントの基礎)
LLM(大規模言語モデル)への指示には2種類ある:
| 種類 | 説明 |
|---|---|
| テキスト生成 | 通常の質問応答。LLMが自然言語で返す |
| ツール呼び出し (Function Calling / Tool Use) | LLMが「今このツールを実行してほしい」と宣言し、エージェントが代わりに実行する |
ツール呼び出しの流れ(一般的):
1. ユーザーメッセージ → エージェント
2. エージェントが [システムプロンプト + ツール定義リスト + 会話履歴] をLLMに送信
3. LLMが応答:
a. テキストのみ → 会話終了
b. tool_use ブロック → 「このツールをこの引数で呼んで」という宣言
4. エージェントがツールを実際に実行
5. ツール結果をLLMへ返す(次のターン)
6. LLMが結果を使って続きを回答
7. 3〜6を繰り返す(ループ)
2. OpenClawのツール呼び出し実装
2.1 ツール定義のスキーマ化
OpenClawは @mariozechner/pi-coding-agent(Piエンジン)を通じてAnthropicのClaude APIを呼び出す。
各ツールはJSON Schema形式で定義される。
src/agents/pi-tools.ts より — createOpenClawCodingTools() 関数:
ツールは複数の変換段階を経て最終形になる:
// 1. Piエンジン基本ツールを取得
const baseTools = createPiCodingTools(...);
// 2. OpenClaw固有ツールを追加(exec, browser, cron, message等)
const extended = [...baseTools, ...openclawTools];
// 3. パラメータを正規化(モデルプロバイダーによって形式が異なるため)
const normalized = extended.map((tool) =>
normalizeToolParameters(tool, { modelProvider: options?.modelProvider })
);
// 4. ツール呼び出し前フックを巻く(ループ検出、ポリシーチェック等)
const withHooks = normalized.map((tool) =>
wrapToolWithBeforeToolCallHook(tool, {
agentId,
sessionKey: options?.sessionKey,
loopDetection: resolveToolLoopDetectionConfig({ cfg: options?.config, agentId }),
})
);
// 5. AbortSignalを巻く(キャンセル対応)
const withAbort = options?.abortSignal
? withHooks.map((tool) => wrapToolWithAbortSignal(tool, options.abortSignal))
: withHooks;
各ツールの定義構造:
// AgentTool<InputType, ResultType> 型
{
name: "exec",
description: "Run shell commands",
parameters: execSchema, // JSON Schema
execute: async (toolCallId, args, signal, onUpdate) => {
// args: schema に基づく入力(型安全)
// signal: AbortSignal(キャンセル対応)
// onUpdate: progress callback(streaming進捗)
// 戻り値: AgentToolResult
return { output: "...", isError: false, details: {} };
}
}
2.2 LLMへの送信とツール実行サイクル
src/agents/pi-embedded-runner.ts と pi-embedded-subscribe.ts の核心:
[エージェントループ]
↓
subscribeEmbeddedPiSession() が LLMセッションに購読
↓
Piエンジンが [システムプロンプト + ツール定義 + 会話履歴] をClaudeに送信
↓
Claudeが応答:
Case A: text_block のみ → 最終応答として返す
Case B: tool_use block → "execツールを {command:'ls'} で呼んで"
↓
subscribeEmbeddedPiSession() がツールイベントを検知
↓
ツール実行 (bash-tools.exec.ts など)
↓
ツール結果を LLM に返す(tool_result メッセージ)
↓
ループ繰り返し(最大イテレーション数まで)
状態追跡(EmbeddedPiSubscribeState):
const state: EmbeddedPiSubscribeState = {
assistantTexts: [], // LLMのテキスト応答(全ブロック)
toolMetas: [], // ツール呼び出し履歴(名前・引数・出力)
toolMetaById: new Map(), // ツールID → メタデータ のマップ
toolSummaryById: new Set(), // 重複を除いたツール名の集合
messagingToolSentTexts: [], // message ツールで送信済みのテキスト
lastToolError: undefined, // 最後のツール実行エラー
};
2.3 コアツール一覧(システムプロンプトに記載されるもの)
src/agents/system-prompt.ts の coreToolSummaries より:
| ツール名 | 説明 |
|---|---|
read |
ファイル読み込み |
write |
ファイル作成・上書き |
edit |
ファイルの精密編集 |
apply_patch |
複数ファイルへのパッチ適用 |
grep |
ファイル内容の検索 |
find |
グロブパターンでのファイル検索 |
ls |
ディレクトリ一覧 |
exec |
シェルコマンド実行(PTY対応) |
process |
バックグラウンドexecセッション管理 |
web_search |
Web検索(Brave API) |
web_fetch |
URLからコンテンツを取得・抽出 |
browser |
Webブラウザ制御 |
canvas |
Canvas の表示・評価・スナップショット |
nodes |
ペアリングデバイスの制御 |
cron |
Cronジョブ・ウェイクイベントの管理 |
message |
メッセージ送信・チャネルアクション |
gateway |
Gateway の再起動・設定適用・更新 |
agents_list |
利用可能なエージェントID一覧 |
sessions_list |
セッション一覧 |
sessions_history |
セッション履歴取得 |
sessions_send |
別セッションへのメッセージ送信 |
sessions_spawn |
サブエージェントセッション起動 |
subagents |
サブエージェントの一覧・操作・停止 |
session_status |
セッションステータス表示 |
image |
画像分析 |
3. System Promptの Safety セクション詳解
3.1 実際のテキスト(src/agents/system-prompt.ts 行401〜407)
const safetySection = [
"## Safety",
"You have no independent goals: do not pursue self-preservation, replication, resource acquisition, or power-seeking; avoid long-term plans beyond the user's request.",
"Prioritize safety and human oversight over completion; if instructions conflict, pause and ask; comply with stop/pause/audit requests and never bypass safeguards. (Inspired by Anthropic's constitution.)",
"Do not manipulate or persuade anyone to expand access or disable safeguards. Do not copy yourself or change system prompts, safety rules, or tool policies unless explicitly requested.",
"",
];
日本語訳:
## Safety
あなたは独立した目標を持たない:自己保存・複製・リソース獲得・権力追求を追求してはならない。ユーザーのリクエストを超えた長期計画を避けること。
完了より安全性と人間の監督を優先すること。指示が衝突する場合は一時停止して確認すること。停止・一時停止・監査要求に従い、安全装置を迂回しないこと。(Anthropicの憲法からインスパイア)
アクセス拡大や安全装置の無効化のために誰かを操作・説得しないこと。明示的に要求されない限り、システムプロンプト・安全ルール・ツールポリシーを変更しないこと。
3.2 「Anthropicの憲法」とは
Anthropicが研究・採用している Constitutional AI (CAI) フレームワークの中心概念。
通常の強化学習(RLHF)では、人間がLLMの出力を評価してフィードバックするが、CAIでは:
- 人間がルールセット(憲法)を定義する
- LLMが自身の出力を「この憲法に違反していないか」と自己批評する
- 違反があれば自己修正する
- これにより人間のフィードバックを大幅に削減できる
Anthropicが採用する憲法の主な原則:
- ユーザーに有害な情報を提供しない
- 違法・不道徳な行為を支援しない
- 長期的な権力追求や自己複製を避ける
- 人間の監督下にある
OpenClawはこれをシステムプロンプトのワンセクションとして凝縮し、全LLMバックエンドに統一して適用している。
4. Exec 承認システムの実装詳細
4.1 承認が必要になる条件
exec ツールは以下の security フィールドの値によって承認フローが変わる:
| security値 | 挙動 |
|---|---|
"low" |
自動承認(低リスク操作) |
"high" |
ユーザー確認を要求 |
"ask" |
常にユーザーへ確認 |
"inherit" |
親設定を継承 |
4.2 承認リクエストの実装(bash-tools.exec-approval-request.ts)
// exec ツールが実行される前に Gateway へ RPC 呼び出し
export async function requestExecApprovalDecision(
params: RequestExecApprovalDecisionParams,
): Promise<string | null> {
const decisionResult = await callGatewayTool<{ decision: string }>(
"exec.approval.request", // Gateway RPC メソッド名
{ timeoutMs: DEFAULT_APPROVAL_REQUEST_TIMEOUT_MS },
{
id: params.id, // 承認リクエストの一意ID (UUID)
command: params.command, // 実行するシェルコマンド全文
cwd: params.cwd, // 作業ディレクトリ
host: params.host, // "gateway" または "node"
security: params.security, // "high" | "low" | "ask" など
ask: params.ask, // "user" | "owner" など
agentId: params.agentId, // どのエージェントか
resolvedPath: params.resolvedPath,// コマンドの完全解決パス
sessionKey: params.sessionKey, // セッションコンテキスト
timeoutMs: DEFAULT_APPROVAL_TIMEOUT_MS, // ユーザー入力待ちタイムアウト
},
);
return typeof decisionValue === "string" ? decisionValue : null;
}
流れ:
LLM が exec ツールを要求
↓
exec ツールが security レベルをチェック
├─ "low" → 自動実行
└─ "high"/"ask" → Gateway へ承認リクエスト送信
↓
Gateway が WhatsApp/Telegram 等のチャネルへ確認メッセージを送信
"コマンド [ls -la] を実行してもいいですか?"
↓
ユーザーが [承認] or [拒否] を応答
↓
Gateway が decision を返す
↓
exec ツールが実行 or キャンセル
4.3 ACP レベルでの自動承認判定(src/acp/client.ts)
// ツールの種類によって自動承認か否かを判定
const SAFE_AUTO_APPROVE_KINDS = new Set(["read", "search"]);
const DANGEROUS_ACP_TOOLS = new Set(["exec", /* ... */]);
const isSafeKind = Boolean(toolKind && SAFE_AUTO_APPROVE_KINDS.has(toolKind));
const promptRequired = !toolName || !isSafeKind || DANGEROUS_ACP_TOOLS.has(toolName);
if (!promptRequired) {
// 自動承認(ファイル読み込み、検索など)
return selectedPermission(allowOption.optionId);
}
// ユーザーへプロンプト(exec など危険な操作)
const approved = await prompt(toolName, toolTitle);
要点:
-
read/search系 → 自動承認 -
exec→ 常に人間の確認(DANGEROUS_ACP_TOOLS) - タイムアウト付き(ユーザーが応答しない場合は拒否)
5. MCP (Model Context Protocol) とは何か
5.1 MCPの概要
MCPはAnthropicが策定した LLMにツールを提供するための標準プロトコル。
[LLM クライアント(Claude等)]
↕ (MCP プロトコル: stdio / HTTP SSE)
[MCP サーバー(ツール提供側)]
例: filesystem MCP server, GitHub MCP server, etc.
MCPの特徴:
- どのLLMクライアントからでも同じMCPサーバーを使える
- stdio(プロセス間通信)とHTTP SSEの2方式
- Anthropicが標準化を進めているが、まだ仕様が変わりやすい
5.2 OpenClawがMCPをコアに組み込まない理由
VISION.mdに明記された理由:
This keeps MCP integration flexible and decoupled from core runtime:
- add or change MCP servers without restarting the gateway
- keep core tool/context surface lean
- reduce MCP churn impact on core stability and security
技術的理由の補足:
| 懸念点 | 説明 |
|---|---|
| 安定性 | MCPは仕様が変わりやすく、コアに組み込むとGateway全体の安定性に影響する |
| セキュリティ | MCPサーバーは外部システムと連携するため、隔離層を挟むことで攻撃面を減らす |
| 柔軟性 | ブリッジ方式ならGateway再起動なしにMCPサーバーを追加・削除できる |
| スコープ | OpenClawの核心は「パーソナルアシスタント」であり、汎用MCPホストではない |
実装:MCPは mcporter ブリッジ経由(skills/mcporter/)
OpenClaw Gateway ← WebSocket → mcporter ← MCP プロトコル → MCP サーバー
5.3 ACP (Agent Client Protocol) との違い
ACPはMCPとは目的が異なるプロトコル:
| ACP | MCP | |
|---|---|---|
| 目的 | IDE/エディタとエージェントの統合 | LLMにツールを提供する |
| 通信 | stdio (NDJSON) | stdio / HTTP SSE |
| セッション管理 | Gatewayセッションにマッピング | MCPサーバーが独立管理 |
| ツール定義 | Gatewayが保有 | MCPサーバーが保有 |
| ユースケース | VS Code等のIDEから操作 | Claudeに新ツールを追加 |
ACP の実装(src/acp/server.ts):
// ACP はstdio経由でGatewayをエージェントとして公開
const agent = new AcpGatewayAgent({...});
// IDEからのリクエスト → Gateway WebSocket → エージェント実行
// MCP サーバーはここでは無視される(ignore する)
if (params.mcpServers.length > 0) {
this.log(`ignoring ${params.mcpServers.length} MCP servers`);
}
ACP は MCP の代替ではなく、IDEとの接続レイヤー。MCPはツール拡張、ACPはIDEアクセス。
6. スキルシステムとプロンプトへの注入
6.1 システムプロンプトのSKILLSセクション
src/agents/system-prompt.ts の buildSkillsSection():
return [
"## Skills (mandatory)",
"Before replying: scan <available_skills> <description> entries.",
`- If exactly one skill clearly applies: read its SKILL.md at <location> with \`${params.readToolName}\`, then follow it.`,
"- If multiple could apply: choose the most specific one, then read/follow it.",
"- If none clearly apply: do not read any SKILL.md.",
"Constraints: never read more than one skill up front; only read after selecting.",
trimmed, // スキルのサマリー一覧
"",
];
LLMへの指示の意味:
- 返信前に
<available_skills>の説明欄をスキャンせよ - 明確に当てはまるスキルが1つ →
readツールでSKILL.mdを読み、それに従え - 複数当てはまる → 最も具体的なものを選んで読め
- 当てはまるものがない → SKILL.mdを読まないこと
- 制約:1回のターンで最大1つのスキルのみ読む(プロンプト肥大化防止)
なぜ「事前に全スキルをプロンプトに入れない」のか:
スキルを全部システムプロンプトに入れると、毎ターンLLMに送るトークン数が爆発する。
代わりにスキル名と説明のみ(サマリー)を入れて、必要な時だけ read ツールで本文を読む。
6.2 スキルパスの短縮最適化
// /Users/alice/.bun/.../skills/github/SKILL.md
// → ~/.bun/.../skills/github/SKILL.md
// 1スキルあたり5〜6トークン削減 × Nスキル = 400〜600トークン削減
function compactSkillPaths(skills: Skill[]): Skill[] {
const home = os.homedir();
return skills.map((s) => ({
...s,
filePath: s.filePath.startsWith(prefix) ? "~/" + s.filePath.slice(prefix.length) : s.filePath,
}));
}
7. HEARTBEAT_OK / SILENT_REPLY_TOKEN プロトコル
7.1 SILENT_REPLY_TOKEN
LLMが「返信することがない」時に使う特殊トークン。
実際の文字列は src/auto-reply/tokens.ts で定義されている。
システムプロンプトから:
## Silent Replies
When you have nothing to say, respond with ONLY: [SILENT_REPLY_TOKEN]
⚠️ Rules:
- It must be your ENTIRE message — nothing else
- Never append it to an actual response
- Never wrap it in markdown or code blocks
❌ Wrong: "Here's help... [SILENT_REPLY_TOKEN]"
❌ Wrong: "[SILENT_REPLY_TOKEN]"(引用符付き)
✅ Right: [SILENT_REPLY_TOKEN]
用途: Heartbeatで起動されたが、やることがない時。メッセージツールで既に返信済みの時。
7.2 HEARTBEAT_OK
HeartbeatRunnerが定期的に送るプロンプトへの応答トークン:
## Heartbeats
Heartbeat prompt: [設定済み]
If you receive a heartbeat poll and there is nothing that needs attention, reply exactly:
HEARTBEAT_OK
If something needs attention, do NOT include "HEARTBEAT_OK"; reply with the alert text instead.
HeartbeatRunnerの動作:
- 設定間隔(デフォルト30分)でエージェントを起動
- HEARTBEAT.mdの内容を確認
- HEARTBEAT.mdが空 → スキップ
- 内容あり → エージェントを起動してチェックリストを確認
- エージェントが
HEARTBEAT_OK→ 何もしない - エージェントが別のテキスト → ユーザーへ通知
8. 会話履歴の管理と圧縮(Compaction)
8.1 コンテキストウィンドウの問題
LLMには1回のAPI呼び出しで送れるトークン数の上限(コンテキストウィンドウ)がある。
長い会話では履歴が膨大になり、上限を超える。
8.2 OpenClawのCompaction
src/agents/compaction.ts にて実装:
// 会話が長くなった時に自動的に古い履歴を要約する
// 要約はLLM自身に行わせる(「この会話を要約してください」と別途呼び出す)
// 要約結果を先頭に置いて古い詳細履歴を削除
圧縮後の構成:
[システムプロンプト]
[圧縮された要約(古い会話の凝縮版)]
[最近のN件のメッセージ(詳細履歴)]
まとめ:OpenClawのLLM制御の特徴
| 特徴 | 内容 |
|---|---|
| ツール呼び出し方式 | Anthropic tool_use API(Claude固有)。PiエンジンがJSON Schemaで定義 |
| ツール実行主体 | LLMは「呼びたい」と宣言するだけ。実際の実行はOpenClawが行う |
| 安全性の担保 | System PromptのSafetyセクション + ツールポリシー + Exec承認システムの3層 |
| MCPとの関係 | コアに組み込まず。mcporter スキル経由でブリッジ接続 |
| ACPの役割 | IDEとの接続レイヤー。MCPとは目的が異なる |
| トークン節約 | スキルの遅延読み込み・パス短縮・会話圧縮(compaction)の3段構え |
| プロアクティブ制御 | HEARTBEAT_OK / SILENT_REPLY_TOKEN という軽量プロトコルで実現 |
7: 競合・代替ツール比較
比較軸
| 軸 | 説明 |
|---|---|
| ホスティング | セルフホスト vs クラウド |
| インターフェース | 既存アプリ vs 専用UI |
| ライセンス | オープンソース vs プロプライエタリ |
| メモリ | ローカル(SQLite)vs クラウドDB |
| モデル依存 | モデル非依存 vs 特定モデル前提 |
| 拡張性 | プラグイン/スキル vs 固定機能 |
| 難易度 | 技術的セットアップ vs ノーコード |
機能比較表
| ツール | ホスティング | UI | ライセンス | メモリ | モデル非依存 | メッセージングアプリ統合 | スキル/プラグイン | 難易度 |
|---|---|---|---|---|---|---|---|---|
| OpenClaw | セルフホスト | 既存アプリ(WhatsApp等)+ WebUI | MIT | ローカルSQLite+md | ✅(20+プロバイダー) | ✅(15+チャネル) | ✅(50+スキル、ClawHub) | 高 |
| AutoGPT | クラウド/セルフ | WebUI | MIT | ローカル/クラウド | 部分的 | ❌ | ✅ | 高 |
| Open Interpreter | セルフホスト | CLI/JupyterUI | AGPL | なし/会話内 | ✅ | ❌ | ❌ | 中 |
| AgentGPT | クラウド | WebUI | MIT | なし | ❌(OpenAI前提) | ❌ | ❌ | 低 |
| Flowise | セルフホスト | WebUI(ノーコード) | Apache 2.0 | 設定可能 | ✅ | 部分的 | ✅ | 中 |
| n8n + AI | セルフホスト/クラウド | ノーコード | Elastic/Enterprise | 設定可能 | ✅ | 部分的 | ✅ | 中 |
| Letta (MemGPT) | セルフホスト/クラウド | CLI/API | Apache 2.0 | ✅(高度な永続メモリ) | ✅ | ❌ | ❌ | 高 |
| CrewAI | セルフホスト/クラウド | Python API/WebUI | MIT | 設定可能 | ✅ | ❌ | ✅ | 中 |
| LangChain Agent | セルフホスト | Python API | MIT | 設定可能 | ✅ | ❌ | ✅(LangChain Hub) | 高 |
| NanoBot | セルフホスト | 既存アプリ | MIT | ローカル | ✅ | 部分的 | ✅ | 高 |
| PicoClaw | セルフホスト | 既存アプリ | MIT | ローカル | ✅ | 部分的 | ✅ | 高 |
OpenClaw の強み
1. メッセージングアプリ統合の網羅性
- 15+のチャネル対応(WhatsApp, Telegram, Slack, Discord, Signal, iMessage, LINE, Teams, Matrix 等)
- 競合ツールのほとんどは専用UIのみで、既存チャットアプリから操作できない
2. ローカルファースト設計
- 全設定・メモリ・履歴をローカルMarkdownファイルで管理
- クラウドAPI依存なし(ローカルLLM利用時は完全オフライン)
3. モデルプロバイダーの多様性
- 20+のLLMプロバイダーに対応(Anthropic, OpenAI, Gemini, Bedrock, Ollama 等)
- 中国系プロバイダー(Qwen, BytePlus/Doubao, MiniMax, Kimi)にも対応
4. スキルシステムの柔軟性
- SKILL.md(Markdown)による宣言的スキル定義
- コード不要でスキル追加可能
- ClawHubによるコミュニティエコシステム
5. BOOT.md / Heartbeat / Cronによるプロアクティブ実行
- ユーザーのメッセージなしに自律的なタスク実行が可能
- 定期レポート・監視・リマインダーを自動化
OpenClaw の弱み
1. セットアップの複雑さ
- 技術的なセットアップが必要(npm, Node.js >= 22.12.0, 各プラットフォームの認証設定)
- ノーコードツール(Flowise, n8n)と比較してアクセシビリティが低い
2. セキュリティ上の懸念
- プロンプトインジェクションをスコープ外と宣言(対策は限定的)
- ClawHubスキルの審査不足
- プラグインがin-process実行される設計上のリスク
3. 高度なオーケストレーションの意図的な除外
- VISION.mdで「manager-of-managers / nested planner trees」を明示的に除外
- 複雑なマルチエージェントワークフローが必要な場合はCrewAIやLangChainが適切
4. 依存する外部パッケージのリスク
-
@mariozechner/pi-agent-core等のプライベートパッケージへの依存 - Carbon依存を絶対に更新しないという制約(AGENTS.mdに記載)
最適なユースケース
| シナリオ | 推奨ツール |
|---|---|
| 既存チャットアプリを使いたい(技術者) | OpenClaw |
| 完全オフライン・プライバシー重視 | OpenClaw + Ollama |
| プロアクティブな自動化(定期実行) | OpenClaw + Heartbeat/Cron |
| ノーコードでワークフロー構築 | n8n, Flowise |
| 高度な永続メモリが必要 | Letta (MemGPT) |
| 複雑なマルチエージェントオーケストレーション | CrewAI, LangGraph |
| 開発者向けシェル自動化 | Open Interpreter |
| シンプルなWebエージェント | AgentGPT |
NanoBot・PicoClawとの比較
| 側面 | OpenClaw | NanoBot | PicoClaw |
|---|---|---|---|
| 言語 | TypeScript/Node.js | Python | Go |
| コード行数 | 430,000+ | ~4,000 | ~15,000〜20,000 |
| 起動時間 | >500ms | 数秒 | <1秒 |
| メモリ使用量 | >1GB | 100〜150MB | <10MB |
| 配布形式 | npm パッケージ | pip パッケージ | 単一バイナリ |
| チャネル数 | 15+(コア7 + 拡張8+) | 9(Telegram/Discord/Slack/WhatsApp/DingTalk/Feishu/QQ/MoChat/Email) | 11(Telegram/Discord/Slack/WhatsApp/LINE/DingTalk/Feishu/QQ/WeCom/OneBot/MaixCam) |
| バンドルスキル数 | 50+ | 8(summarize/tmux/memory/cron/skill-creator/clawhub/weather/github) | 6(summarize/tmux/skill-creator/hardware/weather/github) |
| スキルエコシステム | ClawHub(コミュニティ) | ClawHub互換(スキルインストール機能あり) | ClawHub API統合(動的インストール) |
| メモリ管理方式 | SQLite + sqlite-vec(ベクトルDB)+ BM25ハイブリッド検索 | MEMORY.md + HISTORY.md(テキストファイル)+ LLMによる統合委譲 | MEMORY.md(テキストファイル)+ JSONセッション(sqlite不使用) |
| LLMプロバイダー | 20+(独自Piエンジン経由) | 30+(LiteLLM経由、OpenAI互換形式) | 複数(SDK直接統合 + フォールバックチェーン) |
| MCPサポート | コア外(mcporterスキル経由) | コア内蔵(stdio + HTTP SSE両対応) | コア外(スキル経由) |
| ツール呼び出し形式 | Anthropic tool_use API形式 | OpenAI function calling形式(LiteLLMで統一) | プロバイダー別(OpenAI互換 + Claude SDK + Copilot gRPC) |
| エージェントループ制限 | Piエンジン管理 | 20回(max_iterations) |
MaxIterations設定値 |
| IoT/エッジデバイス対応 | なし | なし | あり(I2C/SPI、$10ハードウェア対応) |
| 特記事項 | 機能豊富・安全デフォルト・Heartbeat/BOOT.md | コードが圧倒的に少ない・MCP直接統合・読みやすさ重視 | 超軽量・単一バイナリ・IoT対応・フォールバックチェーン |
8: NanoBot 詳細
1. プロジェクト概要
主要な特徴: 「99%コード削減でOpenClaw相当の機能を実現」
NanoBotは「OpenClawのコア機能を最小限のコードで実現する」をコンセプトとしたPythonクローン。
コアのコード行数は約4,000行(OpenClawの430,000行超と比較して約1/100)。
研究・個人用途向けで、読みやすさと拡張性を重視している。
2. エージェントループ(nanobot/agent/loop.py)
2.1 核心となる _run_agent_loop()
async def _run_agent_loop(
self,
initial_messages: list[dict],
on_progress: Callable[[str], Awaitable[None]] | None = None,
) -> tuple[str | None, list[str]]:
"""Run the agent iteration loop. Returns (final_content, tools_used)."""
messages = initial_messages
iteration = 0
while iteration < self.max_iterations: # デフォルト20回
iteration += 1
# LLM呼び出し(ツール定義も渡す)
response = await self.provider.chat(
messages=messages,
tools=self.tools.get_definitions(), # JSON Schema形式
model=self.model,
temperature=self.temperature,
max_tokens=self.max_tokens,
)
if response.has_tool_calls:
# LLMがツールを要求した場合
for tool_call in response.tool_calls:
result = await self.tools.execute(tool_call.name, tool_call.arguments)
messages = self.context.add_tool_result(
messages, tool_call, result
)
else:
# テキストのみ → ループ終了
final_content = response.content
break
return final_content, tools_used
OpenClawとの比較:
| 項目 | OpenClaw | NanoBot |
|---|---|---|
| ループの複雑さ |
pi-embedded-runner.ts(数百行)に隠蔽 |
30行で核心を表現 |
| イテレーション制限 | Piエンジン側で管理 |
max_iterations(デフォルト20) |
| 進捗フィードバック |
onUpdate callback + streaming |
on_progress async callback |
| ツール追跡 |
EmbeddedPiSubscribeState(複雑な状態管理) |
tools_used リストのみ |
2.2 メッセージ構造
OpenClawがJSONL形式で管理するのに対し、NanoBotはOpenAI互換のメッセージリストを直接使用:
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "ファイルを一覧して"},
{"role": "assistant", "tool_calls": [{"id": "...", "function": {...}}]},
{"role": "tool", "tool_call_id": "...", "content": "[file1.txt, file2.txt]"},
{"role": "assistant", "content": "ファイルは2つあります"},
]
3. ツール定義とLLMへの渡し方
3.1 基底クラス(nanobot/agent/tools/base.py)
class Tool(ABC):
@property
@abstractmethod
def name(self) -> str: pass
@property
@abstractmethod
def description(self) -> str: pass
@property
@abstractmethod
def parameters(self) -> dict[str, Any]:
"""JSON Schema for tool parameters."""
pass
async def execute(self, **kwargs: Any) -> str:
"""Execute the tool. Returns string result."""
pass
def to_schema(self) -> dict[str, Any]:
"""OpenAI function calling形式に変換"""
return {
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.parameters,
}
}
OpenClawとの比較:
- OpenClawは
AgentTool<InputType, ResultType>でジェネリクスによる型安全性を重視 - NanoBotは
dict[str, Any]とシンプルな抽象クラスで汎用性を重視 - 両者ともJSON Schemaを使ってLLMへツールを渡す点は同じ
3.2 ツールレジストリ(nanobot/agent/tools/registry.py)
class ToolRegistry:
def get_definitions(self) -> list[dict[str, Any]]:
"""全ツール定義をOpenAI形式で返す"""
return [tool.to_schema() for tool in self._tools.values()]
async def execute(self, name: str, params: dict[str, Any]) -> str:
tool = self._tools.get(name)
if not tool:
return f"Error: Tool '{name}' not found"
# JSON Schemaで検証
errors = tool.validate_params(params)
if errors:
return f"Error: Invalid parameters: {errors}"
return await tool.execute(**params)
3.3 組み込みツール一覧
# loop.py の _register_default_tools() より
def _register_default_tools(self) -> None:
# ファイルシステム
self.tools.register(ReadFileTool(workspace=self.workspace))
self.tools.register(WriteFileTool(workspace=self.workspace))
self.tools.register(EditFileTool(workspace=self.workspace))
self.tools.register(ListDirTool(workspace=self.workspace))
# シェル実行
self.tools.register(ExecTool(workspace=self.workspace))
# Web
self.tools.register(WebSearchTool(api_key=self.brave_api_key))
self.tools.register(WebFetchTool())
# メッセージング
self.tools.register(MessageTool(send_callback=self.bus.publish_outbound))
# サブエージェント
self.tools.register(SpawnTool(manager=self.subagents))
# Cronジョブ
if self.cron_service:
self.tools.register(CronTool(self.cron_service))
OpenClawと比較して省略されているツール:
-
browser(Playwright) -
canvas/ A2UI -
nodes(デバイスペアリング) -
gateway(自己管理) session_status-
memory_search/memory_get(代わりに会話内メモリ統合)
4. スキルシステム(nanobot/agent/skills.py)
4.1 スキルの読み込み戦略
NanoBotはOpenClawのSKILL.md形式と互換性のある遅延読み込み方式を採用:
def build_system_prompt(self, skill_names: list[str] | None = None) -> str:
parts = []
# 1. アイデンティティとブートストラップファイル(AGENTS.md, SOUL.md等)
parts.append(self._get_identity())
bootstrap = self._load_bootstrap_files()
# 2. always=True のスキルは全文をプロンプトに含める
always_skills = self.skills.get_always_skills()
if always_skills:
always_content = self.skills.load_skills_for_context(always_skills)
parts.append(f"# Active Skills\n\n{always_content}")
# 3. その他のスキルはサマリーのみ(LLMが必要な時にread_fileで読む)
skills_summary = self.skills.build_skills_summary()
if skills_summary:
parts.append(f"""# Skills
The following skills extend your capabilities. To use a skill, read its SKILL.md file using the read_file tool.
Skills with available="false" need dependencies installed first...
{skills_summary}""")
return "\n\n---\n\n".join(parts)
OpenClawとの違い:
| 項目 | OpenClaw | NanoBot |
|---|---|---|
| 常時スキル |
always: true frontmatter |
always=True frontmatter(同形式) |
| 通常スキル | サマリーのみ → readツールで本文取得 | サマリーのみ → read_fileツールで本文取得 |
| スキルの場所 |
skills/, ~/.openclaw/skills/, プラグイン |
/nanobot/skills/, ~/.nanobot/workspace/skills/
|
| frontmatter形式 | YAML(requires.bins 等) |
YAML + JSON(metadata.nanobot.requires.bins) |
4.2 スキルの依存関係チェック
def _check_requirements(self, skill_meta: dict) -> bool:
"""スキルが必要とするバイナリや環境変数が存在するかチェック"""
requires = skill_meta.get("requires", {})
for b in requires.get("bins", []):
if not shutil.which(b):
return False # バイナリが見つからない → スキル利用不可
for env in requires.get("env", []):
if not os.environ.get(env):
return False # 環境変数がない → スキル利用不可
return True
5. メモリ管理(nanobot/agent/memory.py)
5.1 OpenClawとの根本的な違い
| 項目 | OpenClaw | NanoBot |
|---|---|---|
| 実装方式 | SQLite + sqlite-vec(ベクトルDB) | テキストファイル(Markdown) |
| 検索方式 | BM25(キーワード)+ ベクトル検索 ハイブリッド | テキスト検索(grep可能形式) |
| メモリ統合 | 独自のインデックス更新ロジック | LLM自身に統合を委譲 |
| リソース | 重い(インデックス作成コスト) | 軽い(ファイルI/Oのみ) |
5.2 二層メモリ構造
~/.nanobot/workspace/memory/
├── MEMORY.md # 長期記憶(ユーザーの情報・設定・重要事項)
└── HISTORY.md # 時系列イベントログ(grep可能な形式)
HISTORY.mdの形式:
[2026-02-22 10:30] USER [tools: web_search]: プロジェクトの最新情報を調べて
[2026-02-22 10:30] ASSISTANT [tools: web_search]: OpenClaw 2026.2.22がリリース。機能Xが追加。
[2026-02-22 15:00] USER: 昨日調べたことを要約して
5.3 LLM駆動の統合処理
async def consolidate(self, session, provider, model, *, memory_window=50) -> None:
"""古いメッセージをLLMで統合してMEMORY.md / HISTORY.mdに書き込む"""
old_messages = session.messages[session.last_consolidated:-keep_count]
# フォーマット
lines = [
f"[{m.get('timestamp')[:16]}] {m['role'].upper()}"
f"{' [tools: ' + ', '.join(m['tools_used']) + ']' if m.get('tools_used') else ''}"
f": {m['content']}"
for m in old_messages
]
# LLM自身に統合タスクを委譲(save_memoryツールを使わせる)
response = await provider.chat(
messages=[
{"role": "system", "content": "You are a memory consolidation agent..."},
{"role": "user", "content": f"Process this conversation:\n{chr(10).join(lines)}"},
],
tools=[_SAVE_MEMORY_TOOL], # save_memory ツールのみ定義
model=model,
)
if response.has_tool_calls:
args = response.tool_calls[0].arguments
if entry := args.get("history_entry"):
self.append_history(entry) # HISTORY.mdに追記
if update := args.get("memory_update"):
self.write_long_term(update) # MEMORY.mdを全体更新
LLMへの統合タスク仕様(_SAVE_MEMORY_TOOL):
{
"type": "function",
"function": {
"name": "save_memory",
"parameters": {
"history_entry": {
"type": "string",
"description": "2〜5文で主要な出来事・決定・トピックを要約。"
"[YYYY-MM-DD HH:MM]で始める。grep検索に有用な詳細を含める。",
},
"memory_update": {
"type": "string",
"description": "長期記憶全体のMarkdown。既存の事実+新しい事実を含める。"
"新しいことがなければそのまま返す。",
},
},
},
}
6. LLMプロバイダー(nanobot/providers/litellm_provider.py)
6.1 LiteLLMの採用
NanoBotは LiteLLM(OSSのLLM統合ライブラリ)を使用して30以上のプロバイダーに対応:
class LiteLLMProvider(LLMProvider):
"""LiteLLMを使った統一プロバイダー"""
async def chat(self, messages, tools, model, temperature, max_tokens):
# LiteLLMが各プロバイダーのAPIの差異を吸収
response = await litellm.acompletion(
model=self._resolve_model(model), # "anthropic/claude-opus-4-5" など
messages=messages,
tools=tools,
temperature=temperature,
max_tokens=max_tokens,
**self._extra_params(),
)
return self._parse_response(response)
6.2 プロバイダーレジストリ(nanobot/providers/registry.py)
@dataclass(frozen=True)
class ProviderSpec:
name: str
keywords: tuple[str, ...] # モデル名から自動判定するキーワード
env_key: str # 環境変数名
litellm_prefix: str = "" # LiteLLMに渡すプレフィックス
is_gateway: bool = False # OpenRouter等のゲートウェイ型
supports_prompt_caching: bool = False # Anthropicのキャッシュ対応
サポートプロバイダー(一部):
| カテゴリ | プロバイダー |
|---|---|
| ゲートウェイ | OpenRouter, AiHubMix, SiliconFlow, VolcEngine |
| 直接API | Anthropic, OpenAI, DeepSeek, Gemini, Zhipu, DashScope, Moonshot, MiniMax, Groq |
| OAuth | OpenAI Codex, GitHub Copilot |
| ローカル | vLLM |
| カスタム | 任意のOpenAI互換エンドポイント |
OpenClawとの比較:
- OpenClawは各プロバイダー専用のコードを記述(
anthropic.ts,openai.ts等) - NanoBotはLiteLLMに任せてプロバイダー固有コードをほぼゼロ化
6.3 Anthropicプロンプトキャッシュの自動適用
def _apply_cache_control(self, messages, tools):
"""Anthropicプロバイダーの場合、システムプロンプトにキャッシュ制御を自動付与"""
for msg in messages:
if msg.get("role") == "system":
# ephemeral キャッシュを付与(APIコスト削減)
new_content = [{
"type": "text",
"text": msg["content"],
"cache_control": {"type": "ephemeral"}
}]
# ...
6.4 不正JSON修復
def _parse_response(self, response):
for tc in message.tool_calls:
args = tc.function.arguments
if isinstance(args, str):
args = json_repair.loads(args) # 壊れたJSONも自動修復
# ...
7. MCPのサポート(nanobot/agent/tools/mcp.py)
NanoBotはMCPをコア機能として完全サポートしている点がOpenClawと大きく異なる。
7.1 MCP接続の実装
async def connect_mcp_servers(
mcp_servers: dict, registry: ToolRegistry, stack: AsyncExitStack
) -> None:
for name, cfg in mcp_servers.items():
# Stdio mode(ローカルプロセス)
if cfg.command:
params = StdioServerParameters(
command=cfg.command, args=cfg.args, env=cfg.env or None
)
read, write = await stack.enter_async_context(stdio_client(params))
# HTTP mode(リモートSSE)
elif cfg.url:
read, write, _ = await stack.enter_async_context(
streamable_http_client(cfg.url)
)
session = await stack.enter_async_context(ClientSession(read, write))
await session.initialize()
# MCPサーバーのツールをNanoBotのToolRegistryに登録
tools = await session.list_tools()
for tool_def in tools.tools:
wrapper = MCPToolWrapper(session, name, tool_def)
registry.register(wrapper)
設定例(config.json):
{
"tools": {
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
},
"my-remote-mcp": {
"url": "https://example.com/mcp/",
"headers": {"Authorization": "Bearer xxxxx"}
}
}
}
}
OpenClawとの対比:
| OpenClaw | NanoBot | |
|---|---|---|
| MCP対応 |
mcporter スキル経由(ブリッジ) |
コア機能として直接対応 |
| Stdio MCP | mcporter が担当 |
mcp.client.stdio で直接接続 |
| HTTP SSE MCP | mcporter が担当 |
streamable_http_client で直接接続 |
| 設定 |
skills/mcporter/ スキルを使う |
config.tools.mcpServers で直接設定 |
NanoBotがMCPを直接組み込んだ理由(推測):
小規模プロジェクトのためブリッジレイヤーを挟む理由がない。安定性より利便性を優先。
8. メッセージバスとチャネル統合(nanobot/bus/)
8.1 シンプルなキューベース実装
class MessageBus:
"""エージェントとチャネル間を疎結合にするAsync キュー"""
def __init__(self):
self.inbound: asyncio.Queue[InboundMessage] = asyncio.Queue()
self.outbound: asyncio.Queue[OutboundMessage] = asyncio.Queue()
async def publish_inbound(self, msg: InboundMessage) -> None:
await self.inbound.put(msg)
async def consume_inbound(self) -> InboundMessage:
return await self.inbound.get() # ブロッキング
メッセージ型:
@dataclass
class InboundMessage:
channel: str # "telegram", "slack", "discord", "email", "cli", "system"
sender_id: str # ユーザーID
chat_id: str # 会話ID/チャネルID
content: str # メッセージ内容
session_key: str # channel:chat_id(セッション識別子)
media: list[str] | None # マルチモーダル(画像パス)
metadata: dict | None # チャネル固有メタデータ
8.2 対応チャネル
- Telegram / Slack / Discord / Feishu(飛書)
- WhatsApp(QRコード方式)
- Email(IMAP/SMTP)
- DingTalk(钉钉)/ Mochat
- CLI(コマンドライン直接入力)
OpenClawとの比較:
- OpenClaw: 15+チャネル(MS Teams, Matrix, LINE 等も対応)
- NanoBot: 10チャネル程度(企業向けチャネルを中心に選択)
9. HeartbeatとCron
9.1 Heartbeat(nanobot/heartbeat/service.py)
class HeartbeatService:
async def _tick(self) -> None:
content = self._read_heartbeat_file()
if _is_heartbeat_empty(content):
return # HEARTBEAT.md が空なら何もしない
if self.on_heartbeat:
response = await self.on_heartbeat(HEARTBEAT_PROMPT)
if HEARTBEAT_OK_TOKEN in response.upper():
logger.info("Heartbeat: OK") # 何もしない
else:
logger.info("Heartbeat: completed task")
OpenClawと同じ HEARTBEAT_OK プロトコルを採用。デフォルト間隔30分。
9.2 Cron(nanobot/cron/service.py)
@dataclass
class CronSchedule:
kind: str # "at"(一回限り), "every"(定期), "cron"(cron式)
at_ms: int | None # Unix タイムスタンプ(ms)
every_ms: int | None # 間隔(ms)
expr: str | None # Cron式(例: "0 9 * * *")
tz: str | None # タイムゾーン
ストレージ: ~/.nanobot/workspace/.cron(JSON)
10. セッション管理(nanobot/session/manager.py)
10.1 JSONL形式(追記専用)
{"_type": "metadata", "key": "telegram:12345", "created_at": "2026-02-22T...", "last_consolidated": 0}
{"role": "user", "content": "Hello", "timestamp": "2026-02-22T...", "tools_used": null}
{"role": "assistant", "content": "Hi!", "timestamp": "...", "tools_used": ["web_search"]}
{"role": "tool", "tool_call_id": "...", "name": "web_search", "content": "results..."}
- メッセージを削除せず追記のみ(Anthropicのプロンプトキャッシュを最大活用)
- 統合後も元のメッセージを保持(LLMがキャッシュから読める)
10.2 自動統合のトリガー
if len(session.messages) > self.memory_window and session.key not in self._consolidating:
self._consolidating.add(session.key)
asyncio.create_task(_consolidate_and_unlock()) # バックグラウンドで非同期実行
11. セキュリティ機能
11.1 シェルコマンドの保護(nanobot/agent/tools/shell.py)
def _guard_command(self, command: str, cwd: str) -> str | None:
"""ベストエフォートの危険コマンド検出"""
deny_patterns = [
r"\brm\s+-[rf]{1,2}\b", # rm -r, rm -rf
r"\bdd\s+if=", # dd(ディスク破壊)
r">\s*/dev/sd", # ディスクへの直接書き込み
r"\b(shutdown|reboot|poweroff)\b", # システム電源操作
r":\(\)\s*\{.*\};\s*:", # フォークボム
]
OpenClawとの比較:
OpenClawはより洗練されたExec Approval System(Gateway RPCで承認フロー)を持つ。
NanoBotは正規表現による簡易チェックのみで、より軽量。
12. OpenClawから省略した機能とその意図
| 機能 | OpenClaw | NanoBot | 省略の意図 |
|---|---|---|---|
| SQLiteメモリ | あり(BM25+ベクトル) | なし(Markdownファイル) | シンプルさ優先、LLMの判断力を活用 |
| ブラウザ自動化 | Playwright対応 | なし | 外部依存削減 |
| Canvas / A2UI | あり | なし | UI系は別チャネル経由で対応 |
| ノードペアリング | mDNSでモバイル連携 | なし | スコープ外 |
| Exec承認システム | Gatewayでフロー管理 | 正規表現チェックのみ | 軽量化 |
| 複数エージェント管理 | 15+チャネル対応 | 10チャネル程度 | 主要チャネルに絞る |
| ACP | あり(IDE統合) | なし | スコープ外 |
まとめ
NanoBotの設計哲学:
- LLMを信頼する - メモリ統合や複雑な判断をLLMに委譲し、コードを減らす
- 標準APIに従う - OpenAI互換形式(tool calling, メッセージ形式)で長期的互換性を確保
- 段階的機能拡張 - MCPで任意ツールを追加できる設計
- 読みやすさ優先 - 研究・学習・実験に適したクリーンなコードベース
「OpenClawの本質は4000行に収まる」という証明として価値がある。
9: PicoClaw 詳細
1. プロジェクト概要
主要な特徴: 「エッジデバイスでも動作する超軽量AIエージェント」
PicoClawはGo言語で実装されたOpenClaw/NanoBotクローン。
「メモリ10MB未満・起動1秒未満」 を目標にした極限の軽量化が特徴。
エッジAI・IoTデバイス($10ハードウェア)での実行を想定している。
| 指標 | OpenClaw | NanoBot | PicoClaw |
|---|---|---|---|
| コード行数 | 430,000+ | ~4,000 | ~15,000〜20,000 |
| メモリ | >1GB | 100〜150MB | <10MB |
| 起動時間 | >500秒 | 数秒 | <1秒 |
| 配布形式 | npm パッケージ | pip パッケージ | 単一バイナリ |
2. エージェントループ(pkg/agent/loop.go)
2.1 核心となる runLLMIteration()
func (al *AgentLoop) runLLMIteration(
ctx context.Context,
agent *AgentInstance,
messages []providers.Message,
opts processOptions,
) (string, int, error) {
iteration := 0
var finalContent string
for iteration < agent.MaxIterations {
iteration++
// 1. ツール定義をビルド
providerToolDefs := agent.Tools.ToProviderDefs()
// 2. LLM呼び出し(フォールバックチェーン対応)
response, err := al.callWithFallback(ctx, agent, messages, providerToolDefs)
if err != nil {
// コンテキストエラー(トークン超過)時は圧縮して再試行
if isContextError(err) {
al.forceCompression(agent, opts.SessionKey)
messages = agent.ContextBuilder.BuildMessages(...)
continue
}
return "", iteration, err
}
// 3. ツール呼び出しがなければ終了
if len(response.ToolCalls) == 0 {
finalContent = response.Content
break
}
// 4. ツール呼び出し実行
for _, tc := range response.ToolCalls {
toolResult := agent.Tools.ExecuteWithContext(
ctx, tc.Name, tc.Arguments, opts.Channel, opts.ChatID, asyncCallback,
)
// ユーザー向けメッセージをバスへ送信
if !toolResult.Silent && toolResult.ForUser != "" {
al.bus.PublishOutbound(bus.OutboundMessage{
Channel: opts.Channel,
ChatID: opts.ChatID,
Content: toolResult.ForUser,
})
}
// セッションに記録
agent.Sessions.AddFullMessage(opts.SessionKey, toolResultMsg)
}
}
return finalContent, iteration, nil
}
2.2 非同期ツール処理(goroutine活用)
// 非同期完了コールバック(サブエージェント等)
asyncCallback := func(callbackCtx context.Context, result *tools.ToolResult) {
// goroutineで非同期実行される
}
// セッション要約もgoroutineで並列実行
go func() {
defer al.summarizing.Delete(summarizeKey)
al.summarizeSession(agent, sessionKey) // バックグラウンドで実行
}()
NanoBotとの比較:
NanoBotは asyncio.create_task() でPython非同期を使用。
PicoClawはGo goroutineでより軽量・効率的な並行処理を実現。
3. ツール定義とLLMへの渡し方
3.1 Toolインターフェース(pkg/tools/types.go)
type Tool interface {
Name() string
Description() string
Parameters() map[string]any // JSON Schema
Execute(ctx context.Context, args map[string]any) *ToolResult
}
// オプショナルインターフェース(追加機能)
type ContextualTool interface {
Tool
SetContext(channel, chatID string) // チャネル情報を注入
}
type AsyncTool interface {
Tool
SetCallback(cb AsyncCallback) // 非同期完了コールバック
}
3.2 LLMへの変換(pkg/tools/registry.go)
func (r *ToolRegistry) ToProviderDefs() []providers.ToolDefinition {
definitions := make([]providers.ToolDefinition, 0, len(r.tools))
for _, tool := range r.tools {
definitions = append(definitions, providers.ToolDefinition{
Type: "function",
Function: providers.ToolFunctionDefinition{
Name: tool.Name(),
Description: tool.Description(),
Parameters: tool.Parameters(), // JSON Schema
},
})
}
return definitions
}
3.3 プロバイダーへの送信(pkg/providers/openai_compat/provider.go)
func (p *Provider) Chat(
ctx context.Context,
messages []Message,
tools []ToolDefinition,
model string,
options map[string]any,
) (*LLMResponse, error) {
requestBody := map[string]any{
"model": model,
"messages": messages,
"tools": tools, // ToolDefinition[](JSON Schema形式)
"max_tokens": options["max_tokens"],
"temperature": options["temperature"],
}
// HTTP POST to {api_base}/chat/completions
resp, err := p.httpClient.Do(req)
// ...
return &response, nil
}
3.4 ツール呼び出しの応答型(pkg/providers/protocoltypes/types.go)
type ToolCall struct {
ID string `json:"id"`
Type string `json:"type"` // "function"
Function *FunctionCall `json:"function"`
Name string `json:"name"`
Arguments map[string]any `json:"arguments"` // 解析済みJSON
ThoughtSignature string // Gemini 3用拡張
ExtraContent *ExtraContent // Google Extended用
}
type LLMResponse struct {
Content string // テキスト応答
ToolCalls []ToolCall // ツール呼び出しリスト(空なら終了)
FinishReason string // "tool_calls", "stop", など
Usage *UsageInfo // トークン使用量
}
4. LLMプロバイダー実装(pkg/providers/)
4.1 プロトコルベースの分類(pkg/providers/factory.go)
NanoBotがLiteLLMに処理を委譲するのに対し、PicoClawは各プロバイダーのSDKを直接使用:
const (
providerTypeHTTPCompat // OpenAI互換HTTP(汎用)
providerTypeClaudeAuth // Anthropic SDK(公式)
providerTypeCodexAuth // OpenAI OAuth
providerTypeCodexCLIToken // OpenAI CLI Token
providerTypeClaudeCLI // Claude CLI 経由
providerTypeCodexCLI // OpenAI CLI 経由
providerTypeGitHubCopilot // GitHub Copilot gRPC
)
4.2 使用SDKとGo依存関係(go.modより)
// 公式SDK
"github.com/anthropics/anthropic-sdk-go v1.22.1"
"github.com/openai/openai-go/v3 v3.22.0"
"github.com/github/copilot-sdk/go v0.1.23"
// OpenAI互換インターフェース経由でも対応:
// Zhipu(GLM), DeepSeek, Groq, OpenRouter, Ollama, vLLM, Gemini, Qwen 等
4.3 モデル設定形式
{
"model_list": [
{
"model_name": "gpt-5.2",
"model": "openai/gpt-5.2",
"api_key": "sk-..."
},
{
"model_name": "claude-sonnet-4.6",
"model": "anthropic/claude-sonnet-4.6",
"api_key": "sk-ant-..."
},
{
"model_name": "glm-4.7",
"model": "zhipu/glm-4.7",
"api_key": "..."
}
]
}
4.4 フォールバックチェーン(pkg/providers/fallback.go)
OpenClawにはない顕著な新機能のひとつ。
func (fc *FallbackChain) Execute(
ctx context.Context,
candidates []FallbackCandidate,
run func(ctx context.Context, provider, model string) (*LLMResponse, error),
) (*FallbackResult, error) {
for _, candidate := range candidates {
// クールダウン中のプロバイダーはスキップ
if fc.cooldown.IsOnCooldown(candidate.Provider) {
continue
}
response, err := run(ctx, candidate.Provider, candidate.Model)
if err == nil {
return &FallbackResult{Response: response}, nil
}
// エラー分類
failoverErr := classifyError(err)
if !failoverErr.IsRetriable() {
return nil, err // フォーマットエラー等は再試行不可
}
// 次の候補へ(rate limit, auth error 等は次を試す)
}
return nil, errors.New("all candidates failed")
}
// エラー分類
type FailoverReason string
const (
FailoverAuth FailoverReason = "auth" // 再試行可
FailoverRateLimit FailoverReason = "rate_limit" // 再試行可
FailoverBilling FailoverReason = "billing" // 再試行可
FailoverTimeout FailoverReason = "timeout" // 再試行可
FailoverFormat FailoverReason = "format" // 再試行不可
)
5. システムプロンプト構築(pkg/agent/context.go)
func (cb *ContextBuilder) BuildSystemPrompt() string {
parts := []string{}
// 1. アイデンティティ(時刻・ランタイム・ワークスペース)
parts = append(parts, cb.getIdentity())
// 2. ブートストラップファイル(AGENTS.md, SOUL.md, USER.md, IDENTITY.md)
bootstrapContent := cb.LoadBootstrapFiles()
parts = append(parts, bootstrapContent)
// 3. スキルサマリー(遅延読み込み方式)
skillsSummary := cb.skillsLoader.BuildSkillsSummary()
parts = append(parts, skillsSummary)
// 4. メモリコンテキスト(MEMORY.md)
memoryContext := cb.memory.GetMemoryContext()
parts = append(parts, memoryContext)
return strings.Join(parts, "\n\n---\n\n")
}
生成されるシステムプロンプトのサンプル:
# picoclaw 🦞
You are picoclaw, a helpful AI assistant.
## Current Time
2026-02-22 15:30 (Saturday)
## Runtime
linux amd64, Go 1.25.7
## Workspace
Your workspace is at: /home/user/.picoclaw/workspace
## Available Tools
**CRITICAL**: You MUST use tools to perform actions. Do NOT pretend to execute commands.
- `read_file` - Read file contents within your workspace
- `write_file` - Write/create files
- `exec` - Execute shell commands
- `web_search` - Search the web
- `spawn` - Create a subagent for complex tasks
...
---
# Skills
Available skills: [スキル名と説明]
---
# Memory
[MEMORY.mdの内容]
OpenClawとの比較:
| 項目 | OpenClaw | PicoClaw |
|---|---|---|
| 構築関数 |
buildAgentSystemPrompt()(19セクション) |
BuildSystemPrompt()(4セクション) |
| PromptMode | full/minimal/none の3モード | なし(単一モード) |
| Safety section | Anthropicの憲法ベースの詳細セクション | なし(ツール使用の必須化のみ) |
| Heartbeat設定 | HEARTBEAT_OK プロトコル | なし(別実装) |
| Silent replies | SILENT_REPLY_TOKEN | なし |
| Reply tags | [[reply_to_current]] 等 | なし |
6. スキルシステム(pkg/skills/)
6.1 スキルの読み込み(pkg/skills/loader.go)
type SkillInfo struct {
Name string // スキル名
Path string // SKILL.mdへのパス
Source string // "workspace", "global", "builtin"
Description string // スキルの説明
}
// 読み込み優先度
// 1. Workspace: ~/.picoclaw/workspace/skills/{skill}/SKILL.md
// 2. Global: ~/.picoclaw/skills/{skill}/SKILL.md
// 3. Builtin: ./skills/{skill}/SKILL.md
OpenClawのSKILL.md形式との互換性:
同じYAML frontmatter形式を採用。OpenClaw用スキルをそのまま使用可能。
6.2 スキルの動的インストール
tools.NewFindSkillsTool() と tools.NewInstallSkillTool() でClawHubからスキルを検索・インストール:
// ClawHubのスキルレジストリから検索
type ClawHubRegistry struct {
baseURL string // clawhub.ai API
cache SearchCache
}
func (r *ClawHubRegistry) Search(query string) ([]SkillResult, error) {
// ClawHubのAPIを呼び出し
}
7. マルチエージェント(pkg/agent/registry.go)
OpenClawにはない顕著な新機能のひとつ。
7.1 エージェントレジストリ
type AgentRegistry struct {
agents map[string]*AgentInstance // Agent ID → インスタンス
resolver *routing.RouteResolver
mu sync.RWMutex
}
// サブエージェント生成の許可チェック
func (r *AgentRegistry) CanSpawnSubagent(parentAgentID, targetAgentID string) bool {
parent, ok := r.GetAgent(parentAgentID)
if !ok { return false }
for _, allowed := range parent.Subagents.AllowAgents {
if allowed == "*" || allowed == targetAgentID {
return true
}
}
return false
}
7.2 マルチエージェント設定
{
"agents": {
"list": [
{
"id": "main",
"model": {"primary": "gpt-5.2"}
},
{
"id": "research",
"model": {"primary": "claude-sonnet-4.6"},
"subagents": {
"allow_agents": ["writer"] // writer エージェントのみ生成可能
}
},
{
"id": "writer",
"model": {"primary": "gpt-5.2"}
}
]
}
}
7.3 Spawn Tool(サブエージェント起動)
func (t *SpawnTool) Execute(ctx context.Context, args map[string]any) *ToolResult {
task, _ := args["task"].(string)
agentID, _ := args["agent_id"].(string)
// 権限チェック
if agentID != "" && !t.allowlistCheck(agentID) {
return ErrorResult("not allowed to spawn agent: " + agentID)
}
// バックグラウンド非同期実行
result, err := t.manager.Spawn(
ctx, task, "", agentID,
t.originChannel, t.originChatID, t.callback,
)
return AsyncResult(result) // 即座に返す(非ブロッキング)
}
8. メッセージバス(pkg/bus/bus.go)
type MessageBus struct {
inbound chan InboundMessage // バッファサイズ100
outbound chan OutboundMessage
handlers map[string]MessageHandler
mu sync.RWMutex
}
// Goのチャネル機能を活用した非同期メッセージング
func (mb *MessageBus) ConsumeInbound(ctx context.Context) (InboundMessage, bool) {
select {
case msg := <-mb.inbound:
return msg, true
case <-ctx.Done():
return InboundMessage{}, false // キャンセル対応
}
}
NanoBotとの比較:
- NanoBot:
asyncio.Queue(Python非同期) - PicoClaw: Goチャネル(goroutineベース、より軽量)
9. IoTハードウェアサポート(pkg/tools/i2c_*.go)
OpenClawにもNanoBotにも存在しない独自機能。
// Linux IoT対応のハードウェア制御ツール
tools.Register(tools.NewI2CTool()) // I2C通信(センサー・ディスプレイ)
tools.Register(tools.NewSPITool()) // SPI通信(高速シリアル通信)
// i2c_linux.go(Linux専用)
// i2c_other.go(それ以外はスタブ)
用途: Raspberry Pi等でのAIエージェント実装。温度センサー読み取り、LED制御等。
10. OpenClawから省略した機能と意図
10.1 意図的に省略した機能
| 機能 | OpenClaw | PicoClaw | 省略の意図 |
|---|---|---|---|
| WebUI | あり(Lit + Web Components) | なし | リソース削減 |
| Exec承認システム | Gatewayへの承認RPCフロー | なし(実行のみ) | 軽量化 |
| ブラウザ自動化 | Playwright | なし | 外部依存削減 |
| Canvas / A2UI | あり | なし | UIはチャネル側で対応 |
| mDNS ノード発見 | @homebridge/ciao | なし | スコープ外 |
| SQLiteメモリ検索 | BM25+ベクトル | Markdown+LLM統合 | 軽量化 |
| ACP | あり(IDE統合) | なし | スコープ外 |
| 複雑な認証スキーム | 詳細な認証フロー | 基本OAuth | 簡素化 |
| Safety Section | Anthropic憲法ベース | なし(ツール必須化のみ) | 簡素化 |
| SILENT_REPLY_TOKEN | あり | なし | 簡素化 |
10.2 OpenClawにない顕著な新機能
| 機能 | 詳細 |
|---|---|
| 自動フォールバックチェーン | 設定された複数モデルを順番に試し、失敗したら次へ |
| マルチエージェント権限管理 | どのエージェントがどのサブエージェントを生成できるか設定可能 |
| IoTハードウェアサポート | I2C/SPIによるLinuxハードウェア直接制御 |
| 単一バイナリ配布 | npm/pipなしで動作。クロスコンパイル対応(ARM64, RISC-V等) |
| プロトコルベースのプロバイダー分類 | OpenAI互換, Anthropic SDK, Copilot gRPCを明確に分類 |
11. Go言語採用による設計上の特徴
11.1 goroutineによる軽量並行処理
// 会話要約をバックグラウンドで実行(メインループをブロックしない)
al.summarizing.LoadOrStore(summarizeKey, true)
go func() {
defer al.summarizing.Delete(summarizeKey)
al.summarizeSession(agent, sessionKey)
}()
// sync.Map を使用したスレッドセーフなConcurrent access
al.summarizing.LoadOrStore(key, value) // Atomic操作
比較:
- OpenClaw (TypeScript):
async/await+ Promise - NanoBot (Python):
asyncio.create_task() - PicoClaw (Go): goroutine + channel(最も軽量)
11.2 context.Context によるキャンセル制御
func (al *AgentLoop) Run(ctx context.Context) error {
for al.running.Load() {
select {
case <-ctx.Done():
return nil // キャンセルシグナルで即終了
default:
msg, ok := al.bus.ConsumeInbound(ctx)
}
}
}
11.3 コンパイル時型安全性の確認
// インターフェース実装の確認をコンパイル時に行う
var _ Tool = (*WebSearchTool)(nil) // WebSearchTool が Tool を実装しているか確認
var _ ContextualTool = (*MessageTool)(nil) // コンパイル時チェック
11.4 単一バイナリ配布
# クロスコンパイル例
GOOS=linux GOARCH=arm64 go build -o picoclaw-linux-arm64 ./cmd/picoclaw
GOOS=linux GOARCH=amd64 go build -o picoclaw-linux-amd64 ./cmd/picoclaw
GOOS=windows GOARCH=amd64 go build -o picoclaw.exe ./cmd/picoclaw
npmやpipが不要。自己完結した実行バイナリ。
12. セッション管理(pkg/session/manager.go)
type Session struct {
Key string `json:"key"`
Messages []providers.Message `json:"messages"`
Summary string `json:"summary"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
}
// 永続化: ~/.picoclaw/workspace/sessions/{key}.json
NanoBotとの比較:
- NanoBot: JSONL形式(追記専用、全メッセージ保持)
- PicoClaw: JSON形式(構造化、要約済みセッションも保持)
まとめ
PicoClawの設計哲学:
- Extreme Lightweight - 組み込み・IoT・エッジデバイスで動作できるリソース効率
- Single Binary - Go言語の強みを活かした自己完結型配布
- Protocol-based - ベンダーロックインしないプロバイダー分類
- Full Multi-agent - OpenClaw以上に詳細なマルチエージェント権限管理
- OpenClaw Compatible - SKILL.md形式の互換性維持で既存スキルを再利用可能
「OpenClawと同等の機能を、1/100のリソースで実現する」というNanoBotのアプローチを、
さらに「ネイティブバイナリ・IoT対応・完全型安全」で強化したものがPicoClaw。
10: OpenClaw まとめ
技術アーキテクチャの核心的知見
- ハブアンドスポーク型のGateway設計
- Gateway(Express v5 + WebSocket)が中心となり、全チャネルからのメッセージを統一フォーマットに変換して受け取る。Lane Queueで4レーン(Main/Cron/Subagent/Nested)を並列制御。
- System Promptによる宣言的エージェント制御
-
buildAgentSystemPrompt()が生成する約19セクションの構造化プロンプトがエージェント動作の根幹。スキル、メモリ、ツール、安全方針、ハートビートの全てがSystem Promptで制御される。
-
- SKILL.mdによるモジュラー拡張
- YAML フロントマター + 自然言語指示のMarkdownファイルでスキルを定義。ターンごとに最も適したスキルを1つだけ読み込むことでプロンプトの肥大化を防止。スキルパスを
~で短縮しトークン節約(400〜600トークン)。
- YAML フロントマター + 自然言語指示のMarkdownファイルでスキルを定義。ターンごとに最も適したスキルを1つだけ読み込むことでプロンプトの肥大化を防止。スキルパスを
- ハイブリッドメモリシステム
- SQLite + sqlite-vec によりBM25全文検索とベクトル検索を組み合わせたハイブリッド検索を実現。OpenAI/Gemini/Voyage/ローカル等複数のエンベディングプロバイダーに対応。
- HEARTBEAT_OK / SILENT_REPLY_TOKEN によるプロアクティブ制御
- エージェントは特定トークンを返すことで「注意不要」「返信なし」を宣言。HeartbeatRunnerとCronServiceが定期的にエージェントを起動しHEARTBEAT.mdのチェックリストを実行。
- Pi (mariozechner) エンジンへの依存
- LLMバックエンドは
@mariozechner/pi-agent-core/@mariozechner/pi-coding-agentという外部パッケージ(PSPDFKit/Pi由来)に依存。このパッケージがOpenClaw内部で直接見えない部分のLLM呼び出し・会話管理を担当。
- LLMバックエンドは
設計思想の特徴
意図的に「しないこと」(VISION.mdに明記)
-
MCPをコアに組み込まない → 外部ブリッジ
mcporter経由に限定 - Manager-of-Managersアーキテクチャを避ける → シンプルなサブエージェントモデルを維持
- 新スキルをコアに追加しない → ClawHubに誘導
- 重いオーケストレーション層を追加しない
「強い安全デフォルト、能力は犠牲にしない」
- Anthropic Constitutionに基づく安全セクションをSystem Promptに組み込み
- Exec承認システム、ツールポリシー、Dockerサンドボックスの選択的利用
- ただしプロンプトインジェクションはスコープ外と宣言(設計上の制約)
採用を検討すべきシナリオ
-
技術者が個人/チームで使う自動化エージェントが欲しい
→ WhatsApp/Telegram等の慣れたUIで操作できる強み -
プライバシー重視でデータをローカルに留めたい
→ Ollamaと組み合わせで完全オフライン動作 -
定期実行・プロアクティブな自動化が必要
→ HEARTBEAT.md + Cron + BOOT.mdによる自律動作 -
複数のLLMを使い分けたい
→ 20+プロバイダー対応でコスト・能力の最適化 -
既存のOSSエコシステムへの参加
→ 217,000+ stars、ClawHubのコミュニティスキル
避けるべきシナリオ
-
ノーコードでの利用
→ CLI・設定ファイル・認証設定が必須。n8n/Flowiseを推奨 -
エンタープライズ環境での大規模展開(セキュリティ要件が高い)
→ プロンプトインジェクションがスコープ外、プラグインin-process実行のリスク -
複雑なマルチエージェントオーケストレーション
→ OpenClawは意図的にこれを除外。CrewAI/LangGraphを推奨 -
一般ユーザー向けプロダクト
→ セットアップが技術的すぎる。専用UIを持つクラウドサービスを推奨
今後の展望
OpenAI傘下での開発方向性
- 2026年2月14日以降、創設者Peter SteinbergerがOpenAIに参加
- OpenAIとAnthropicがスポンサー
- オープンソース財団への移管予定
- OpenAIのAPIやツールとのより深い統合が予想される
ロードマップ(VISION.mdより)
- 優先事項: セキュリティ・安全デフォルト、バグ修正、セットアップ改善
-
次の優先事項:
- 主要モデルプロバイダーのサポート拡充
- メッセージングチャネルのサポート強化(高需要チャネル追加)
- パフォーマンス・テストインフラ
- コンピューターユース・エージェントハーネス機能の改善
- CLI + WebフロントエンドのUX改善
- macOS/iOS/Android/Windows/Linux コンパニオンアプリ
調査を通じて得られた知見のまとめ
OpenClawの本質的な価値提案
「AIが実際に作業をする(The AI that actually does things)」というVISION。それを実現するための技術的選択:
- メッセージング統合: 既存のコミュニケーションツールをUIとして活用
- ローカルファースト: プライバシーとオフライン動作を保証
- スキルシステム: Markdownベースの宣言的拡張性
- Gateway中心設計: 単一のコントロールプレーンで複雑さを抑制
設計の卓越性
- System Promptのモジュール設計が秀逸(19セクション、用途別PromptMode)
- Lane Queueによる競合状態防止とスケーラビリティの両立
- SKILL.md の読み込み制約(1ターン1スキル)によるプロンプト肥大化防止
-
SILENT_REPLY_TOKEN/HEARTBEAT_OKというシンプルなプロトコルでプロアクティブ実行を実現
注意点
- Pi エンジン(@mariozechner/pi-*)が外部パッケージのため、LLM呼び出しの詳細が不透明
- プロンプトインジェクションをセキュリティスコープ外とする決断は、実用性とのトレードオフ