前回(第2回)は Kiro の spec 機能で requirements.md → design.md → tasks.md を作って、生成されたタスクを1つずつ実行するところまでやりました。で、実際に何日か使ってみて気づいたのが「毎回同じ前提を打ち直している」問題でして。「テストは pytest」「型ヒントは付けて」「print じゃなく logging」…このあたりを毎セッション説明していて、さすがに無駄だなと。
そこで今回は Steering と Custom Agent、それに Hooks を組み合わせて、この繰り返し部分をまるごとプロジェクト側に持たせる話を書きます。第3回にしてやっと「自動化」らしい回になってきました。
この記事でわかること
- Steering でコーディング規約を定義し、ファイル単位で自動適用する方法
- Custom Agent で エージェントの権限と役割を制限する設定
- Hooks でタスク実行前後に自動的に検査・実行を行う仕組み
- これら3つを組み合わせた実践的な自動化の設定例
Steering は「毎回貼っていた前提」をファイルに逃がす仕組み
Steering は .kiro/steering/ に置いた Markdown で、エージェントに常識を持たせるための仕組みです。公式ドキュメントを読むと、steering ファイルがやり取りの中で参照される(コンテキストとして使われる)という説明になっていました。つまり毎回説明していた規約を、静的なファイルとして一度書けば済むということですね。
面白いのが読み込みタイミングを front matter で制御できるところ。inclusion に always / fileMatch / manual を指定します。
---
inclusion: fileMatch
fileMatchPattern: "**/*.py"
---
# Python コーディング規約
- Python 3.12 前提。型ヒントは必須
- テストは pytest。1テスト1アサーションにこだわらない
- ログは logging。print はデバッグ以外で使わない
- 例外は握りつぶさず、最低限 logger.exception を通す
front matter はファイルの先頭でないとダメで、前に空行やコメントが1行でもあると効かない、とドキュメントにわざわざ書いてあります。自分は最初に改行を1つ入れていて「なんで無視されるんだ…」と10分ほど悩みました。あるあるだと思いたい。
あと AGENTS.md をワークスペースのルートか ~/.kiro/steering/ に置くと自動で拾ってくれるようになっていて、Claude Code なり他のエージェントと規約ファイルを共有したい人にはこれが一番楽かもしれません。なお AGENTS.md は inclusion modes には対応しておらず、常に含まれる扱いです。
グローバル steering の挙動は少し怪しい
ユーザー全体に効かせる ~/.kiro/steering/ も使えるんですが、GitHub の Issue で「グローバルの fileMatch がコンテキストに注入されない」という報告が上がっている、という話もあるようです。自分の環境でも、プロジェクト側に .kiro/steering/ があるときは確実に効くけどグローバルだけのときは怪しい、くらいの体感です。正直ここは切り分けきれてないので、当面プロジェクト直下に置く運用にしています。リポジトリに commit すれば共有もできるし、結果的にそのほうが都合が良かったです。
Custom Agent で役割ごとに権限を分ける
Steering が「考え方」を渡す仕組みなら、Custom Agent は「できることの範囲」を決める仕組みです。エージェント定義は ~/.kiro/agents/ 配下に置く、というのが少なくとも公式ドキュメント上の説明です(プロジェクト配下の .kiro/agents/ については環境によって扱いが違う可能性があるので、自分は断言しないでおきます)。
{
"name": "py-reviewer",
"description": "Python のレビュー専用。書き込みはさせない",
"prompt": "file://./prompts/py-reviewer.md",
"tools": ["fs_read", "execute_bash"],
"allowedTools": ["fs_read"],
"toolsSettings": {
"execute_bash": { "allowedCommands": ["pytest", "ruff"] }
},
"resources": [
"file://.kiro/steering/**/*.md",
"file://README.md"
]
}
tools で使える道具を絞り、allowedTools で確認なしに実行してよいものを指定する、という二段構えです。レビュー役から fs_write を外しておくと勝手にコードを直されないので、これは想像以上に精神衛生に良かった。resources に steering を書いておけば起動時からコンテキストに入るのも地味に便利です。
それと sub-agent。重いタスクを別コンテキストに切り出して並列で走らせられて、CLI では Ctrl+G で長時間動いてるサブエージェントの様子を見られるらしいです。ちなみに Web/モバイルからは組み込みのサブエージェントだけで、.kiro/agents/ の自作エージェントを呼べるのは IDE と CLI に限られるとのこと。自分はまだ並列で回すほど大きなタスクを持ってないので、ここは触っただけで終わっています。
Hooks でタスク実行の前後に処理を挟む
本題の自動化。Hooks は .kiro/hooks/<id>.json に単独ファイルとして置く形式で、スキーマはだいたいこんな感じ、とされています。
{
"version": "v1",
"hooks": [
{
"name": "format-on-save",
"trigger": "PostFileSave",
"matcher": "\\.py$",
"action": { "type": "command", "command": "ruff check --fix" }
},
{
"name": "test-after-task",
"trigger": "PostTaskExec",
"action": { "type": "agent", "prompt": "変更範囲の pytest を実行し、落ちたら原因だけ報告して。修正は勝手にしないこと" }
}
]
}
アクションは2種類あって、command はサブプロセスとしてシェルを叩き、コンテキストは JSON で標準入力に渡ってくる、という理解です。agent は会話にプロンプトを差し込むだけでプロセスは起こしません、という説明も見かけます。軽いガードレールは agent、確実にやりたい機械的処理は command、という切り分けになるかなと。
トリガーは PostFileSave のほか PreToolUse、UserPromptSubmit、Stop などがあり、CLI v3 で PreTaskExec / PostTaskExec / PostFileDelete / Manual が追加されています、という話もあるようです。spec のタスク実行の前後にフックできるのがこのシリーズ的には一番おいしいポイントで、上の test-after-task は「タスクを1つ消化したら必ずテストを回す」を人間の意志に頼らず実現できます。自分は「あとでまとめて実行しよう」と思って結局しないタイプなので、こういうのは仕組みで縛るほうが早い。
もうひとつ実用的なのが PreToolUse で、終了コード 2 を返すとその操作をブロックできる仕様になっています(UserPromptSubmit も同様)、という情報もあります。rm -rf や .env の読み書きをルールで止める、みたいな使い方ですね。プロンプトでお願いするのではなく、ルールとして止められるのが安心感あります。
#!/usr/bin/env python3
import json, sys
ctx = json.load(sys.stdin)
cmd = ctx.get("tool_input", {}).get("command", "")
if ".env" in cmd or "rm -rf" in cmd:
print("blocked by hook", file=sys.stderr)
sys.exit(2) # ここ注意: 2 でブロック、1 だと素通り扱い
なお古い記事だと when / then というキーのスキーマや、IDE の「Manual hook」が出てきますが、Manual hook は manual 指定の steering ファイルに置き換わっています、という話も見かけます。既存の agent 設定に埋め込んだ hook は kiro-cli agent migrate で新形式に変換できるとのことなので、去年の記事を見ながら設定してハマった人は一度確認するといいかもしれません(自分は変換で1回設定が吹き飛びました。バックアップ大事)。
実装例:Kiro の Steering、Agent、Hooks を組み合わせた自動化構成
今回いじっていたのは、S3 に置いたCSVを Lambda で集計するだけの小さな Python プロジェクトです。最終的な構成はこう。
.kiro/steering/python.md(fileMatch: **/*.py)— 規約とテスト方針.kiro/steering/aws.md(manual)— boto3 の書き方。必要なときだけ呼ぶ.kiro/agents/py-reviewer.json— 読み取り専用のレビュー役.kiro/hooks/quality.json— 保存時 ruff、タスク完了後 pytest、危険コマンドのブロック
体感として一番効いたのは Steering でした。Hooks は派手ですが、コンテキストが安定していないとフックで拾った指摘の質も安定しないので、順番としては steering → agent → hooks が良さそうです。逆に「always」の steering を増やしすぎるとコンテキストを食うので、fileMatch でスコープを切るのが前提かなと。ここの適切な分量はまだ掴めていません。
まとめ:Kiro でタスク自動化を実現するポイント
- Steering で規約を一元化すると、毎セッション説明する手間が消える
- Custom Agent で権限を制限すると、レビュー役が暴走しなくなる
- Hooks の PostTaskExec で、テスト実行を自動化できる
- 設定は steering → agent → hooks の順で段階的に追加するのが安定
- グローバル steering は当てにせず、プロジェクト直下に置く運用がおすすめ
余談ですが、hooks を仕込んだ状態で spec のタスクを連続実行すると、テストが落ちた瞬間に止まってくれるので、生成されたコードを全部読み返す時間がだいぶ減りました。逆にフックが多すぎるとタスク1個ごとに待ち時間が発生して、コーヒーを入れる余裕ができます。悪いことではない。

