目次
1. はじめに
2. Hooksとは
3. 実践:ファイル命名規約の逸脱を即座に検出する
4. Before/After
5. 他のプロジェクトへの応用
6. まとめ
1.はじめに
前回(第6回)でステアリングファイルの設計思想について語りました。ステアリングは「第1防衛線」として有効です。でも、正直に言うと限界がありました。
1-1. 実際に起きたこと
ステアリングに「ファイル名はXxxService.javaとすること」と書きました。Kiroはだいたいルールに従います。でもたまに従わない。気づくのはレビューの時。そのころには5ファイルぐらい規約違反が溜まっていて、「命名直して」の指摘を毎回書く作業が発生していました。
1-2. 問題の本質
ステアリングは「こうしてね」と伝える仕組み。守らなかった時に止める仕組みがない。
今回は、Kiro Hooksを使って「ステアリングに書いたルールを、ファイルが作成された瞬間に検証する」仕組みを作ります。
AIエージェントの品質を決めるのは、モデルの性能だけではありません。「モデルの周囲にある仕組み」こそが品質の大部分を決めるという考え方があります(ハーネスエンジニアリング)。Hooksはその"仕組み"の最もシンプルな入口です。
2. Hooksとは
2-1. Steeringとの違い
| 観点 | Steering | Hooks |
|---|---|---|
| 役割 | 「こう書いてね」とルールを伝える | 「守ってなかったら止める」を自動化する |
| 発動タイミング | 常時(全会話に適用) | イベント駆動(特定の操作時のみ) |
| 強制力 | ない(ガイドラインのみ) | ある(操作を中断させることも可能) |
| 比喩 | 社訓・行動規範 | 監視カメラ+アラート |
SteeringとHooksは対立する仕組みではなく、補完し合う2層構造です。Steeringで「基準」を定義し、Hooksで「違反検出」を自動化する。この組み合わせが実用的です。
2-2. Hookの構造: when → then
Hookの定義はシンプルなJSONです。「いつ(when)」「何をする(then)」を宣言するだけ。
{ |
"name": "Hook名", |
"version": "1.0.0", |
"description": "このHookの説明", |
"when": { |
"type": "イベントの種類", |
"patterns": ["対象ファイルパターン"] |
}, |
"then": { |
"type": "アクションの種類", |
"prompt": "エージェントへの指示" |
} |
} |
• when.type: どのイベントで発火するか
• when.patterns: 対象ファイルのglobパターン(ファイル系イベントの場合)
• then.type: askAgent(エージェントに考えさせる)または runCommand(コマンド実行)
• then.prompt / then.command: 実行内容
2-3. 対応イベント一覧
| イベント | 発火タイミング | ユースケース |
|---|---|---|
| fileCreated | ファイルが作成された時 | 今回使う(命名規約チェック) |
| fileEdited | ファイルが保存された時 | Lint自動実行 |
| fileDeleted | ファイルが削除された時 | 依存関係の整合性確認 |
| preToolUse | ツール実行前 | 危険操作ブロック |
| postToolUse | ツール実行後 | 書き込み後レビュー |
| postTaskExecution | Specタスク完了後 | テスト自動実行 |
| promptSubmit | メッセージ送信時 | プロンプト検証 |
| serTriggered | ユーザーが手動実行 | オンデマンドチェック |
今回はfileCreatedを使います。ファイルが新規作成されるたびにHookが発火し、命名規約をチェックする仕組みです。
2-4. Hookファイルの配置場所
Hookの定義ファイルは .kiro/hooks/ フォルダに配置します。
.kiro/
├── hooks/
│ └── naming-convention-check.json ← 今回作るHook
├── steering/
│ └── coding-standards.md ← 命名規約を記載したSteering
└── specs/
└── ...
3. 実践:ファイル命名規約の逸脱を即座に検出する
3-1. 想定するルール
FileUploaderプロジェクト(本シリーズで題材にしているSpring Bootアプリケーション)の命名規約を使います。
| レイヤー | 命名パターン | 例 |
|---|---|---|
| Service | XxxService.java | FileUploadService.java |
| Controller | XxxController.java | FileUploadController.java |
| DAO | XxxDao.java | FileMetadataDao.java |
| DTO | XxxDto.java | FileUploadResultDto.java |
| Entity | テーブル名に対応 | FileMetadata.java |
| Config | XxxConfig.java | RetryConfig.java |
3-2. Hook定義の作成
.kiro/hooks/naming-convention-check.json に以下を配置します。
{ |
"name": "Naming Convention Check", |
"version": "1.0.0", |
"description": "新規Javaファイル作成時に命名規約の準拠を確認する", |
"when": { |
"type": "fileCreated", |
"patterns": ["**/*.java"] |
}, |
"then": { |
"type": "askAgent", |
"prompt": "作成されたJavaファイルの命名規約を確認してください。..." |
} |
} |
3-3. 動作の流れ(規約違反の場合)
Kiroがコードを生成する過程で、命名規約に合わないファイルが作られるケースです。
1. エージェントが DataManager.java を作成
2. fileCreated Hook が発火
3. エージェントが命名規約を確認 → 「DataManager.java はServiceに該当するため、DataManagerService.java にリネームすべき」
4. エージェントが自動リネーム → DataManager.java → DataManagerService.java
ポイント: 人間が気づいてレビューで指摘する前に、エージェント自身が即座に修正します。
3-4. 動作の流れ(規約準拠の場合)
1. エージェントが FileUploadService.java を作成
2. fileCreated Hook が発火
3. エージェントが命名規約を確認 → 「XxxService.java パターンに準拠。問題なし。」
4. そのまま続行(何も起きない)
規約に合っている場合は、チェックだけして即座に次の作業に戻ります。開発フローを邪魔しません。
4. Before/After
| 観点 | Steeringのみ | Steering + Hooks |
|---|---|---|
| 命名規約の遵守 | 「守ってね」と書いてあるだけ | 違反した瞬間に指摘+修正 |
| 見落とし | ある(レビューまで気づかない) | ない(作成時に即検出) |
| 新メンバー | 規約を読んでいないと違反する | 読んでいなくても自動で止まる |
| レビュー負荷 | 「命名直して」の指摘が毎回発生 | レビュー前に解決済み |
| 検出タイミング | 事後(PR時) | 即時(ファイル作成時) |
5. 他のプロジェクトへの応用
同じfileCreatedパターンで、他の技術スタックにも応用できます。
| プロジェクト種別 | チェックするルール | patterns設定 |
|---|---|---|
| React(フロントエンド) | XxxPage.tsx, useXxx.ts | **/*.tsx, **/*.ts |
| CloudFormation(IaC) | {環境}-{リソース種別}.yaml | **/*.yaml |
| テスト | XxxTest.java(漏れ検出) | **/*Test.java |
| Python | xxx_yyy.py(スネークケース) | **/*.py |
6. まとめ
6-1. 今回構築したもの
• fileCreated Hook(Javaファイルの命名規約チェック)
• Steering(ルールを伝える)+ Hooks(ルールを強制する)の2層構造
6-2. Steeringだけの世界との違い
ステアリングは「お願い」、Hooksは「強制」。この2つを組み合わせることで、エージェントの品質を実用レベルに引き上げることができます。
6-3. 次回予告
次回は「品質ゲート — タスク完了時にテストを自動で走らせる」を予定しています。ステアリングで「テストを書いてね」と伝えるのではなく、Hooksで「テストが通らなければ完了にさせない」仕組みを作ります。postTaskExecutionイベントを使って、Specタスクの完了時にJUnitテストを強制実行します。


