OpenClaw Hooks とは何ですか? (AI エージェントとの連携方法が変わる理由)
AI エージェントが触れるべきではないファイルを上書きするのを見たことがある場合、またはコードが変更されるたびにテスト スイートが自動的に実行されることを望んでいた場合、OpenClaw フックがその答えです。これにより、重要な瞬間にエージェントの動作を傍受し、反応し、制御することができます。
Hooks は OpenClaw ゲートウェイ内で実行される小さなイベント駆動型スクリプト エージェントのライフサイクルの特定の時点で。これらは AI エージェントのミドルウェアと考えてください。エージェントとエージェントが呼び出すツールの間に位置し、プログラム可能なインターセプト レイヤーを提供します。
次の 2 つの異なるタイプがあります。
- Internal hooks — 実行するスクリプト 内部 ゲートウェイプロセス自体。これらは、セッション状態、ツール呼び出しメタデータ、およびエージェントの作業コンテキストに直接アクセスできます。ネットワークオーバーヘッドゼロ。
- Webhooks — ライフサイクル イベントの発生時に外部エンドポイントに対して起動される HTTP コールバック。ゲートウェイは POST リクエストを送信します。サーバーがロジックを処理します。
実際の違い: 内部フックは、高速な同期ガードレールとローカル自動化を目的としています。 Webhooks は、Slack 通知、CI システム、ロギング プラットフォームなど、マシンの外部に到達する必要があるあらゆるものに使用されます。
内部フックと Webhook — どちらが必要ですか?
| 要素 | 内部フック | Webhook |
|---|---|---|
| Execution location | Inside the Gateway process | External HTTP server |
| Latency | Near-zero (synchronous) | Network round-trip |
| Session state access | Direct | Serialized payload only |
| こんな方に最適 | File guards, auto-formatting, local scripts | Slack alerts, audit logging, external APIs |
| セットアップの複雑さ | Low — 単なるディレクトリ + ハンドラー ファイル | Medium — 実行中の HTTP エンドポイントが必要です |
| Blocking agent execution | Yes (PreToolUse hooks can abort) | Typically async/non-blocking |
Decision rule: フックが必要な場合 防ぐ アクションや ローカルセッションデータを読み取る、内部フックを使用します。必要な場合は 外部システムに通知する エージェントをブロックする必要がないため、Webhook を使用します。
OpenClaw フック検出の仕組み
ゲートウェイが使用するのは、 自動ディレクトリスキャン フックを発見するために。起動時に、設定されたフック ディレクトリをスキャンし、見つかった有効なフック パッケージをロードします。
フックが有効になる前に、次の 2 つの重要な前提条件があります。
- Hooks は次のとおりである必要があります 明示的に有効化 — フック ディレクトリだけでは十分ではありません
- 少なくとも 1 つのフック エントリを設定する必要があります ゲートウェイ設定で
これはよくある混乱点です。適切なディレクトリに完全に記述されたフックを置くことはできますが、ゲートウェイがフックをアクティブにするように指示されていない場合、ゲートウェイはそれらを黙って無視します。
各フック パッケージには、次の 2 つのファイルが必要です。
HOOK.md— フックの名前、バージョン、説明、ライフサイクル イベントのサブスクリプション、および必要な権限を宣言するメタデータ ファイルhandler.ts(またはhandler.js) — イベントの発生時に実行される実際のロジックを含む実装ファイル
HOOK.md ファイルは、ゲートウェイが検出中に最初に読み取るものです。形式が間違っているか、必須フィールドが欠落している場合、フックは読み込まれません。エラーは発生せず、沈黙するだけです。これは、「フックが機能しない」というレポートの最も一般的な原因です。
すべての開発者が知っておくべき 4 つのライフサイクル イベント
| イベント | 発火したら | 共用 |
|---|---|---|
| PreToolUse | 前に エージェントは任意のツールを呼び出します | Block dangerous operations, validate inputs |
| PostToolUse | 後 ツール呼び出しが完了する | Run tests, 形式コード、ログ結果 |
| Stop | エージェントセッションの終了時 | Send notifications, flush logs, cleanup |
| SessionStart | 新しいエージェント セッションが開始されるとき | Load context, set guardrails, warm up state |
PreToolUse は最も強力です。それができる唯一のイベントです。 アボート 実行前のツール呼び出し。 PreToolUse 中にフックが拒否シグナルを返した場合、エージェントはツールを呼び出すことはありません。
PostToolUse 自動化の主力製品です。ファイルが書き込まれましたか?リンターを実行します。テストが変更されましたか?スイートを実行します。コードがコミットされましたか?ビルドをトリガーします。
ステップ別: 最初のカスタム フックを最初から作成する
ほとんどのドキュメントにはコマンドが記載されています。これにより、何もない状態から機能するフックまでの完全なパスが表示されます。
Goal: ファイル書き込みのたびに ESLint を自動実行します。
Step 1 — フック ディレクトリを作成する
mkdir -p .openclaw/hooks/auto-lint
ステップ 2 — HOOK.md メタデータを書き込む
# auto-lint
**Version:** 1.0.0
**Event:** PostToolUse
**Description:** Runs ESLint on any file written by the agent
**Tools:** write_file, edit_file
Tools フィールドは、フックの範囲を特定のツール呼び出しに設定します。それがないとフックが発火します 毎 PostToolUse イベント — 通常、必要なものではありません。
ステップ 3 — handler.ts を実装する
import { PostToolUseEvent } from "@openclaw/sdk";
import { execSync } from "child_process";
export default function handler(event: PostToolUseEvent) {
const filePath = event.toolResult?.path;
if (!filePath) return;
try {
execSync(`npx eslint --fix "${filePath}"`, { stdio: "inherit" });
} catch (err) {
console.error(`[auto-lint] ESLint failed on ${filePath}`);
}
}
ステップ 4 — CLI 経由で有効にする
openclaw hooks enable auto-lint
Step 5 — ロードされたことを確認する
openclaw hooks list
auto-lint とステータス enabled が表示されるはずです。セッションを開始し、ファイルを書き込み、リンターが起動するのを観察します。
フック ハンドラーの JavaScript と TypeScript — 2026 年に何を選択するか
SDK には完全な TypeScript タイピングが同梱されており、2026 年の SDK リリースでは、 TypeScript が推奨されるデフォルトです 新しいフック用。
| 要素 | TypeScript | JavaScript |
|---|---|---|
| Type safety | Full — イベント形状は型指定されています | None — ランタイムサプライズ |
| Compilation step | Required (tsc or esbuild) | None |
| SDK compatibility | First-class support | Supported but no autocomplete |
| こんな方に最適 | Any hook that will be maintained or shared | 簡単な 1 回限りのスクリプト |
バージョン管理にコミットするか、チームと共有するフックを作成している場合は、TypeScript を使用してください。使い捨てのローカル ガードレールの場合は、プレーンな JavaScript で問題ありません。handler.js という名前を付けて、コンパイル手順をスキップするだけです。
OpenClaw フック CLI リファレンス
| 指示 | Flags | 何をするのか |
|---|---|---|
| オープンクローフックリスト | --json |
Lists all discovered hooks and their status |
| openclaw フックは <名前> を検査します | — | HOOK.md + 現在の構成からの完全なメタデータを表示します |
| openclaw フックは <名前> を有効にします | — | 現在のプロジェクトの Activates a hook |
| openclaw フックは <名前> を無効にします | — | Deactivates without removing |
| openclaw フックは |
--yes、--dry-run |
Installs a hook pack from registry |
| オープンクローフックのアップデート | --all、--dry-run |
Updates installed hook packs |
フック パックの管理 — インストール、更新、および --dry-run ワークフロー
フック パックは、複数の関連フックを 1 つのインストール可能なユニットとしてバンドルします。インストール ワークフローでは、 整合性ハッシュ ディスクに何かを書き込む前に。
# Preview what would be installed without committing
openclaw hooks install productivity-pack --dry-run
# Install non-interactively (for CI environments)
openclaw hooks install productivity-pack --yes
# Update all installed packs
openclaw hooks update --all
--dry-run フラグは十分に使用されていません。どのファイルが変更されるかを正確に確認するには、install または update の前に実行してください。 CI パイプラインでは、実際のインストールの前に、別の検証ステップで --yes と --dry-run をペアにします。
バンドルされたフックのリファレンス: OpenClaw に同梱されるもの
| フック | デフォルト状態 | 何をするのか | 以下の場合に最適です |
|---|---|---|---|
| セッションメモリ | Enabled | Persists key context across sessions | Long-running projects with recurring tasks |
| additional bundled hooks vary by Gateway version | — | openclaw hooks list --builtin を実行して確認してください |
— |
openclaw hooks inspect session-memory を実行して、その完全な構成オプションを確認します。ほとんどのバンドルされたフックは適切なデフォルトで出荷されますが、カスタマイズのために設定フィールドが公開されています。
実際のフックの使用例 (実例付き)
1. ファイル保護ガードレール (PreToolUse)
エージェントが .env ファイルに触れないようにします。
import { PreToolUseEvent } from "@openclaw/sdk";
export default function handler(event: PreToolUseEvent) {
const target = event.toolInput?.path ?? "";
if (target.includes(".env")) {
return { abort: true, reason: "Modification of .env files is blocked by policy." };
}
}
これを write_file と edit_file にスコープ設定された PreToolUse をサブスクライブする、一致する HOOK.md とともに .openclaw/hooks/protect-env/ にドロップします。エージェントはそのコンテキストで拒否理由を受け取り、再試行しません。
2. Slack セッション停止通知
import { StopEvent } from "@openclaw/sdk";
export default async function handler(event: StopEvent) {
await fetch(process.env.SLACK_WEBHOOK_URL!, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
text: `OpenClaw session ended. Files modified: ${event.session.filesModified ?? 0}`
})
});
}
このフックを Stop イベントにサブスクライブします。セッションが終了するたびに、概要を含む Slack メッセージが発行されます。外部サーバーは必要ありません。ゲートウェイ プロセスがアウトバウンド リクエストを直接作成します。
3. PostToolUse での自動フォーマット + テスト
import { PostToolUseEvent } from "@openclaw/sdk";
import { execSync } from "child_process";
export default function handler(event: PostToolUseEvent) {
const file = event.toolResult?.path;
if (!file?.endsWith(".ts")) return;
execSync(`prettier --write "${file}"`);
execSync("npm test -- --passWithNoTests", { stdio: "inherit" });
}
これは、TypeScript ファイルが書き込まれるたびに起動され、ファイルがフォーマットされてから、テスト スイートが実行されます。大規模なプロジェクトでは時間がかかります。HOOK.md の Tools フィールドを使用してスコープを厳密に設定します。
チーム向け Hooks — 共有プロジェクト全体にガードレールを適用する
.openclaw/hooks/ ディレクトリをバージョン管理にコミットします。リポジトリのクローンを作成するすべての開発者は、自動的に同じフック構成を持ちます。
- プロジェクト構成で重要なフックを
enabledにロックする — チームメイトが誤ってファイルガードを無効にすることを防ぎます HOOK.mdの説明を使用して意図を文書化する — コードコメントのように扱い、チームメイトが読みます- Scope hooks to tool-level granularity — 広いフックによりすべてのエージェントの対話が遅くなり、チームメイトがエージェントを無効にする摩擦が生じます
- モノリポジトリでは、親ディレクトリ内のフックは、サブディレクトリ レベルでオーバーライドされない限り、ネストされたすべてのプロジェクトに適用されます。
CI/CD 統合 — OpenClaw フックを非対話的に実行する
GitHub アクションまたはその他のヘッドレス環境では、対話型の確認プロンプトによってパイプラインがハングします。 --yes を使用してスキップします。
- name: Install hooks non-interactively
run: openclaw hooks install qa-pack --yes
- name: Run OpenClaw session
env:
OPENCLAW_HOOKS_ENABLED: "true"
SLACK_WEBHOOK_URL: secrets.SLACK_WEBHOOK_URL
run: openclaw run --task "audit dependencies" --yes
OPENCLAW_HOOKS_ENABLED=true を環境変数として設定すると、対話型の確認なしでフックがアクティブになります。これは、CI モードの「少なくとも 1 つのエントリが構成されている」要件をオーバーライドします。
Hook Security: 実行されるもの、アクセスできるもの、安全を保つ方法
これは、ほとんどのドキュメントで完全に省略されている部分です。また、コミュニティ フック パックをインストールする場合は、最も重要なセクションです。
アクセスできるフック: フック スクリプトは ゲートウェイプロセスの完全な権限。ゲートウェイがユーザー アカウントとして実行されている場合、フックは、そのアカウントが読み取ることができる任意のファイルを読み取り、ネットワーク リクエストを実行し、サブプロセスを実行し、シークレットを含む環境変数にアクセスできます。
未レビューのフック パックのリスク: 悪意のあるフック パックは、「フォーマット コード」のような害のないことを実行しているように見えながら、.env、SSH キー、または API トークンを窃取する可能性があります。
フックパック監査チェックリスト
サードパーティのパックをインストールする前に、これを実行してください。
- ☐
HOOK.md全文を読む — 宣言されたアクセス許可は、宣言された目的と一致していますか? - ☐
handler.ts/jsのすべての行を読み取ります —fetch()、execSync、process.envアクセスを探します - ☐パックがレジストリで配布されている場合は、npm の出所を確認します (
npm info <pack> --json | grep provenance) - ☐発行者の身元を確認します。これは既知の管理者ですか、それとも新しいアカウントですか?
- ☐最初に
--dry-runを実行し、ファイル マニフェストを確認します - ☐最初に上記の手順を完了せずに、__EC_BLOCK_57__ を使用してフック パックをインストールしないでください。
openclaw hooks inspect コマンドは、インストールされているフックの完全なソース パスを表示します。これを使用して、更新後にハンドラー コードを再確認します。
OpenClaw フックのトラブルシューティング - フックが起動しない場合
フックがまったく発見されない
- ディレクトリがスキャンされたフック パス内にあることを確認します:
openclaw hooks list --verbose HOOK.mdが存在し、有効であることを確認します。必須フィールドが欠落している場合は、フックを通知せずにスキップします。- フックがグローバルに有効になっていて、少なくとも 1 つのエントリが設定されていることを確認してください
フックは発見されましたが発射されませんでした
openclaw hooks inspect <name>を実行します —HOOK.mdのEventフィールドが予期するライフサイクル イベントと一致することを確認しますToolsスコープを確認します。スコープをwrite_fileに設定していても、エージェントがcreate_fileを呼び出している場合、フックはトリガーされません。- フックのステータスに
loadedではなくenabledが表示されていることを確認します (ロード済みとは、検出されたがアクティブではないことを意味します)
フックは起動しますが、ハンドラーエラーは発生しません
- ハンドラーに
console.errorログを記録する明示的なtry/catchブロックを追加します。 - ゲートウェイ ログは
~/.openclaw/logs/に書き込まれます — 最新のセッション ログで[hook]というプレフィックスが付いた行を確認してください openclaw hooks inspect <name> --logsを使用して最後の実行出力を表示します
フックによりエージェントのあらゆるアクションが遅くなる
openclaw hooks list --timingを使用してプロファイルを作成し、フックごとの実行時間を確認します- 結果がエージェントをブロックする必要がない場合、同期
execSync呼び出しを非同期に移動します。 - すべての
PostToolUseイベントをサブスクライブするのではなく、特定のツールにフックするスコープ
EasyClaw で AI エージェントのワークフローをさらに進化させましょう
OpenClaw フックを使用すると、エージェント レベルで制御できます。 EasyClaw はその制御に加えて、クラウドに依存せずに信頼性、プライバシー、スピードを必要とする開発者やコンテンツ チーム向けに構築された完全なデスクトップ ネイティブ環境を提供します。
- ✓ フック、エージェント、自動化を完全に自分のマシン上で実行します。データが環境から離れることはありません
- ✓ 既存の開発ツールチェーン (リンター、テスト ランナー、フォーマッタ、CI パイプライン) とのネイティブ統合
- ✓ 視覚的なフック管理 - CLI フラグを記憶せずにフックを有効化、無効化、検査します。
- ✓ Team 対応: 1 つのダッシュボードからフック構成の共有、ガードレールのロック、セッション ログの監査を実行
よくある質問
質問: フックはエージェントによるツール呼び出しの実行を完全に停止できますか?
A: はい。ツール呼び出しを中止できるのは PreToolUse フックのみです。ハンドラーから { abort: true, reason: "..." } を返すと、ゲートウェイはツールの実行を阻止します。エージェントは、そのコンテキストで理由文字列を受け取ります。 PostToolUse、Stop、および SessionStart フックは、アクションを遡って中止することはできません。
質問: フック ハンドラーが未処理のエラーをスローした場合はどうなりますか?
A: デフォルトでは、フック ハンドラーの未処理エラーはゲートウェイ セッション ログに記録されますが、エージェント セッションはクラッシュしません。エージェントはフックが発火しなかったかのように続けます。これは仕様です。フックはコア エージェントの機能をブロックしてはなりません。常にハンドラー ロジックを try/catch でラップし、エラーを明示的に処理して、障害を可視化できるようにします。
質問: フック ハンドラーで async/await を使用できますか?
A: はい、PreToolUse ハンドラーと PostToolUse ハンドラーはどちらも非同期関数をサポートしています。 PreToolUse の場合、ゲートウェイはハンドラーを待ってから続行するかどうかを決定します。そのため、非同期中止ロジックは正しく機能します。 PreToolUse で非同期操作を長時間実行すると、すべてのツール呼び出しが遅れるため、高速に実行してください。
質問: フックはすべてのプロジェクトに適用されますか、それともそれらが属するプロジェクトだけに適用されますか?
A: プロジェクトの .openclaw/hooks/ ディレクトリに配置された Hooks はプロジェクト スコープであり、そのプロジェクト内のセッションに対してのみアクティブになります。グローバル フックは ~/.openclaw/hooks/ に配置して、すべてのプロジェクトに適用できます。モノリポジトリでは、サブディレクトリ レベルでオーバーライドされない限り、親ディレクトリ内のフックはネストされたプロジェクトに適用されます。
質問: 多数のフックを実行するとパフォーマンスにコストがかかりますか?
A: すべてのフックは、サブスクライブしているイベントにレイテンシを追加します。範囲が広く、高速なフック (50 ミリ秒未満) は知覚できません。フックがツールレベルのスコープを設定せずに、すべての PostToolUse イベントに対して大量の同期操作を実行すると、問題が発生します。 openclaw hooks list --timing を使用してプロファイルを作成し、HOOK.md の特定のツールにフックをスコープし、可能な場合は非ブロッキング作業を非同期に移動します。
質問: フックは環境変数のシークレットに安全にアクセスできますか?
A: Hooks はゲートウェイ プロセスの完全な環境を継承するため、process.env.MY_SECRET はどのハンドラー内でも動作します。 CI 環境の場合、シークレットをハードコーディングするのではなく、パイプラインのシークレット マネージャー (GitHub アクション シークレットなど) を通じてシークレットを挿入します。シークレットを HOOK.md またはハンドラー ファイルに決してコミットしないでください。フック ソース ファイルを、レビューされバージョン管理されるコードとして扱います。
最終的な考察 — ワークフローに適したフック戦略の選択
| シナリオ | 推奨されるアプローチ |
|---|---|
| Solo dev — 機密ファイルを保護する | 内部フック PreToolUse、スコープを作成ツールに限定 |
| Solo dev — 自動実行テスト | 内部フック PostToolUse、スコープがテストに隣接するファイル タイプに限定される |
| Team — 共有ガードレールを強制する | フックをバージョン管理にコミットし、プロジェクト構成で有効になっている重要なフックをロックします |
| Team — 監査証跡 | Stop イベント フックを共有ログ エンドポイントに投稿する |
| CI pipeline — 自動セッション | --yes フラグ + OPENCLAW_HOOKS_ENABLED 環境変数、検証ステップの --dry-run |
| External notifications | Slack/PagerDuty への Webhook または fetch() を使用した Stop イベント フック |
本当の問題を解決する 1 つのフック、つまりファイル ガードまたは書き込み後のリンターから始めます。さらに階層化する前に、エンドツーエンドで機能するようにしてください。フックの力は複合的です。スコープが適切に設定された 3 つのフックがスムーズに実行されるセッションは、スコープが不十分で信頼できない 10 個のフックが含まれるセッションよりも信頼性が大幅に高くなります。
ほとんどの開発者にとって、最も活用度の高い最初のフック: .env およびシークレット ファイルに対する PreToolUse ガード。作成には 10 分かかり、実行にはメンテナンスが不要で、エージェントのあらゆる種類のミスが完全に排除されます。