はじめに
こんにちは! yu-Matsuです。
ここ最近、AIエージェント界隈で「ループエンジニアリング」という新しい考え方が出てきて気になっていたのですが、今月頭に AWS から Kiro Crew というエージェントオーケストレーション基盤が公開されたので、今回はこの Kiro Crew を使って、ループエンジニアリングを実際に体験してみました!
ループの設計から、レビューによる学習、スケジュール実行でのループ実行の無人化まで一通り試しましたので、その記録を記事にしたいと思います!
ループエンジニアリングとは
まず、本記事のメインのうちの1つである、「ループエンジニアリング」について簡単に紹介します。こちらは、2026年6月に出てきたばかりの新しい概念で、Addy Osmani 氏が自身のブログ記事で提唱しました。
ブログでは、ループエンジニアリングに関して次の一言で表されています。
Loop engineering is replacing yourself as the person who prompts the agent.
(ループエンジニアリングとは、エージェントにプロンプトを打つ役目から、自分自身を外すことである)
これまでは、人間がプロンプトを書き、エージェントの実行結果を確認して、また次のプロンプトを書く、という形で人がエージェントに常に指示をしている形でした。この「プロンプトを打つ」という作業そのものを「仕組み」に置き換えて、人間はその仕組みを設計する側に回ろう、という考え方がループエンジニアリングです。ここでいうループとは、ゴールを与えると、達成(または人へのハンドオフ)まで AI が反復し続ける構造のことを指します。
Osmani 氏のブログでは、ループは 5つの部品+1つの記憶 で構成されるとされています。(本記事では、まとめて 6要素 と呼びます)
| 要素 | 役割 |
|---|---|
| Automations | ループを起動するトリガー(スケジュール / webhook / heartbeat) |
| Worktrees | 隔離した作業空間。並列作業のファイル競合を防ぐ |
| Skills | プロジェクト知識の外部化。毎回ゼロから説明し直さない |
| Connectors・MCP | Issue 管理や Slack など、外部ツールへの接続 |
| Sub-agents | 役割分担。「作る役」と「検証する役」を分ける |
| State・Memory | 実行をまたいで残る記憶。状態を会話の外に永続化する |
Sub-agents の 「作る役」と「検証する役」の分離 は、人間の開発でいうレビュワーに当たる部分です。コードを書いた本人は自分の作業への評価が甘くなりがちですが、ループは基本的に人が見ていない間に実行されるため、実装エージェントが実装したコードを検証する検証エージェントとして仕組みの側に組み込んでおく、という考え方になります。
Osmani 氏はブログにて、次のような具体例を挙げています。
「朝、自動で起動 → 前日の CI 失敗や issue をトリアージ → 隔離した作業空間で修正案を作成 → 別のエージェントがレビュー → PR 作成 → やったこと・次やることを記録して翌朝へ」というループです。どのステップでも人間はプロンプトしません。人間が設計するのは、最初の一度だけです。
そして、Osmani 氏のブログで定義とセットで語られるのが、次の注意点です。
A loop running unattended is also a loop making mistakes unattended.
(無人で回るループは、無人で間違えるループでもある)
「完了した」はあくまでエージェントの主張であって証明ではないため、最終的には人の手で検証が必要ります。また、他にも自分の書いていないコードが積み上がるために生じる理解負債、そしてトークンコスト あたりが注意点として挙げられており、実際にループエンジニアリングを設計する際は気をつける必要があります。
Kiro Crew
今回ループエンジニアリングを試すために利用したのが、2026年8月4日に AWS が OSS として公開した Kiro Crewです。一言でいうと、「1回のチャットで終わらない仕事」をエージェントに任せるためのワークスペースになります(下記の AWS Japan の紹介記事の表現をお借りしました)。
公式ドキュメントでは、現状のAI駆動開発の課題として、インシデント対応やマイグレーションのような複数のツールとセッションにまたがる仕事では、開発者自身が「ツール同士をつなぐ統合レイヤー」になってしまっている、という点を挙げています。
Kiro Crew は、この統合レイヤーの仕事をエージェント側に引き取らせるもので、メッセージを1通投げれば、人が手を入れ直さなくても複数セッション・複数ツールをまたいで仕事が進む、という体験を目指しています。
アーキテクチャは3層構造で、LLM のランタイムである kiro-cli を土台に、JSON のエージェント設定で振る舞いを定義し、その上の Gateway(Kiro Crew 本体)が複数セッション・スケジュール・メモリを管理します。Gateway と kiro-cli の間は ACP(Agent Client Protocol) でつながっており、エージェントが立てた計画やツール呼び出しの一つひとつが、リアルタイムで画面から確認できる作りです。操作はダッシュボード(Web UI)、CLI、メッセージングサービスのどこからでも行えます。
主要な機能を挙げると、以下のようになります。
| 機能 | 概要 |
|---|---|
| Cron Jobs | 決まった時刻、一定間隔、一回限りなどのスケジュールでエージェントを起動。webhook や heartbeat による起動も可 |
| Sessions | ダッシュボード上で複数のチャットセッションを並行して実行 |
| Subagents | バックグラウンドで並行動作するワーカー(spawn)を起動 |
| Memory | 好み、プロジェクト文脈、PRなどの指摘から学んだルール(lessons)をセッションをまたいで保持 |
| Skills | 作業手順やノウハウを Markdown ファイルとして配置しておくと、エージェントが関連するタスクで自動的に読み込んで使う |
| Channels | Slack / Discord / Telegram / Teams など7種のメッセージングサービスと接続 |
| Knowledge Library | ドキュメントを取り込み、内容をナレッジグラフ化して検索 |
| Artifacts | エージェントの成果物の管理と Web 公開 |
| Apps | DevFleets(並列 worktree 実行)や Task Runner など、目的特化の拡張機能 |
ループエンジニアリングの観点で見ると、先ほどの6要素がだいたい最初から揃っていることが分かります。
| ループエンジニアリングの要素 | Kiro Crew での対応 |
|---|---|
| Automations | Cron Jobs(webhook / heartbeat 起動を含む) |
| Worktrees | 隔離された workspace ディレクトリ(並列作業用には Apps の DevFleets) |
| Skills | Skills + エージェント設定 |
| Connectors・MCP | kiro-cli の MCP + Channels |
| Sub-agents | Subagents(spawn) |
| State・Memory | Memory(セッション横断メモリ + lessons) |
実際にやってみた
前置きが長くなりましたが、実際に試してみたので、ここからはその実録になります。かなり長くなるため、適宜読み飛ばしていただいても大丈夫です!
テーマは、「決まった時間で自動に依存パッケージを1つだけ更新して、テストを通して、PRを出してくれるエージェント」 としました。いわゆる Dependabot 的なことをエージェントにやらせるイメージです。
ループエンジニアリングの観点の一つとして、「人間が見ていないところでエージェントが勝手に動作する」がありますが、その結果をテストが成功したかどうかで機械的に判断しやすいテーマとなっています。
検証は、以下の流れで進めました。
- 検証用のリポジトリを準備する(わざと古い依存を仕込んでおく)
- Kiro Crew をセットアップする
- まずは手動でループを1周回して、挙動を確認する
- PRにレビューコメントを付けて、エージェントに「チームの流儀」を学習させる
- 定期実行の設定を行い、完全に無人でループを回してみる
本記事の実行環境です。Kiro Crew はGA直後でまだまだ挙動が変わりそうなので、バージョンと日付をセットで見ていただければと思います。
- 実施日: 2026年8月23日
- kirocrew 0.3.0 (stable) / kiro-cli 2.16.0
- macOS (Darwin 24.6.0) / Node.js v22.23.1
1. 検証用のリポジトリを準備
検証を行うために、適当なExpress + Vitest の小さなTODO APIを作っています。実装6ファイル、テスト32本の構成で、初期状態ではテストが全部成功する状態になっています。最初から失敗が混じっていると、エージェントが「自分が壊したのか、元から壊れていたのか」を切り分けられなくなってしまう可能性があるからです。
そして、このリポジトリにわざと古い依存パッケージを4つ仕込みました。npm outdated を実行すると、ちょうど4件だけ返る状態です。
| パッケージ | 更新レベル | 更新 | 備考 |
|---|---|---|---|
vitest |
パッチ | 4.1.10 → 4.1.11 | テストランナー |
express |
パッチ | 5.2.0 → 5.2.1 | Web フレームワーク |
@faker-js/faker |
マイナー | 10.0.0 → 10.6.0 | 影響は小さいはず |
zod |
メジャー | 3.25.76 → 4.4.3 | 破壊的変更あり |
2. Kiro Crew のセットアップ
まずは、Kiro Crew のセットアップを行います。公式から提供されている手順を踏むだけで簡単にできます。
2.1. インストール
インストールは以下のコマンドを実行するだけです。~/.kiro/crew-venv の隔離されたvenvにインストールされ、~/.local/bin/kirocrew にシンボリックリンクが張られる形になります。
% curl -fsSL https://download.crew.kiro.dev/cli.sh | sh
2.2. セットアップウィザード
インストールが終わったら kirocrew setup で実際にセットアップを行います。実行するディレクトリはどこでも問題ありませんでした。
kirocrew setup
実行すると、対話形式のウィザードが立ち上がります。何回か質問されますが、今回は以下のように回答しました。
| 質問 | 今回の回答 | 補足 |
|---|---|---|
| Workspace path | デフォルト(~/workplace/kirocrew-workspace) |
実行ごとの作業領域が作られる場所です。デフォルトのままで問題ありません |
| Timezone | デフォルト(Asia/Tokyo を自動検出) |
後ほど cron で自動実行設定をするので重要 |
| Desktop App のインストール | n (No) | 今回はブラウザで十分 |
| Run on AWS | N(デフォルト) | 今回はローカル環境で試すため |
一通り質問に回答し終え、以下のようなメッセージが出たらセットアップ完了です!
👻 Done! Try: kirocrew doctor && kirocrew gateway
2.3. 動作確認と起動
セットアップが終わったので、kirocrew doctor で設定内容に問題がないかを確認します。
kirocrew doctorの実行結果
% kirocrew doctor
Kiro Crew Doctor 👻
Platform
edition: ✅ standalone
jail: ⏭ no jail provider (public edition)
Dependencies
kiro-cli: ✅ /Users/xxxx/.local/bin/kiro-cli
kiro login: ✅
git: ✅ /usr/bin/git
node: ✅ /Users/xxxx/.volta/bin/node (v22)
Project
project dir: ⚠️ not set (run kirocrew setup from project root)
Agent
config: ✅ /Users/xxxx/.kiro/agents/kirocrew.json
Configuration
config dir: ✅ /Users/xxxx/.kiro/crew
provider: acp
model: auto
approval: auto
dashboard: http://localhost:5476
bind: 127.0.0.1 (local-only, SSH tunnel for remote)
auth: loopback trusted (no token required)
Data Home
location: ✅ /Users/xxxx/.kiro/crew
trust root: ✅ /Users/xxxx/.kiro/crew/trust/sel_hmac.key
Pods
session bus: ⏹ not applicable (darwin — pods are Linux `systemd --user` only)
Sandbox
backend: ✅ sandbox-exec
Memory Pressure
freeze risk: ⏹ not applicable (darwin — the swap/OOM-killer check reads Linux procfs)
MCP Tools
@kirocrew-computer: ❌ missing from mcpServers (re-run `kirocrew setup`)
21:57:34 WARNING kiro_crew.sandbox: SECURITY: cgroup v2 scope enforcement unavailable (not Linux); agent subprocess fork-bomb / memory-DoS ceilings are NOT enforced on this host. RLIMIT_NOFILE still applies. See docs/architecture/resource-protection.md.
@kirocrew-cron: ✅ 8 tools
@kirocrew-core: ✅ 66 tools
MCP Governance (enterprise):
identity: Identity Center or API key — an admin MCP registry can apply
registry mode: off
⚠️ If MCP tools are missing in sessions while probing OK above, your administrator has configured an MCP Registry URL. In that mode kiro-cli connects only to servers marked 'type': "registry".
Declare it: kirocrew config set agent.mcp_registry_mode true
Then have your admin allow-list, by these exact names: kirocrew-computer, kirocrew-core, kirocrew-cron
Runtime
python: ✅ /Users/xxxx/.kiro/crew-venv/bin/python3.13 (3.13.11)
kiro_crew: ✅ 0.3.0
deps: ✅ websockets, slack_sdk, aiohttp available
sqlite fts5: ✅ available
Vector Memory (in-process embeddings)
runtime: ✅ vendored llama-cpp-python importable
faiss: ⏹ not installed (optional) — episodic recall uses the stdlib fallback; `pip install faiss-cpu` to accelerate it
model: ✅ /Users/xxxx/.kiro/crew/models/qwen3-embedding-0.6b.gguf
embeddings: ✅ always-on
Speech-to-Text
status: ⏹ disabled (enable from dashboard → Overview → Slack)
whisper: ⏭ not installed (not needed)
ffmpeg: ✅ /opt/homebrew/bin/ffmpeg
Slack Integration
tokens: ⏭ not configured (optional)
setup: run 'kirocrew setup --slack', or connect any
channel (Slack, Discord, Telegram, …) from the
dashboard
Loop-stall Crash Dumps
dumps: ✅ no crash dumps found (healthy)
dump dir: /Users/xxxx/.kiro/crew/logs/crash-dumps
Connectivity
kiro-cli: ✅ kiro-cli 2.16.0
gateway: ⏹ not running
❌ Fix these issues: @kirocrew-computer config
kiro-cli のログイン状態、git、node、MCP ツール、ベクトルメモリのモデルなど、ひととおり確認することができます。筆者の環境では、v0.3.0時点では⚠️ が1つと ❌ が1つ出ましたが、どちらも今回の検証には影響がありませんでした。
いよいよkirocrewの起動です。以下のコマンドで起動できます。
% kirocrew gateway
http://localhost:5476 でダッシュボードが立ち上がります。
2.4. ダッシュボードの初回設定
上記URLをブラウザで開くと、ダッシュボードの初回セットアップが始まります。CLI のウィザードとは別物で、こちらは見た目や振る舞いの好みを決めるものになっています。
まずは、「ソースを選択」になります。こちらは、このゲートウェイホストに入っている既存のエージェント設定を検出して、Kiro Crew に取り込むというもののようです。筆者の環境では 92 見つかりましたと出ました。持ち込めるのは「手順、メモリ、ワークスペース、MCP サーバー、スキル、スケジュール、セーフ設定」とのことです。
今回は、まっさらな状態で検証したかったので、「インポートをスキップ」を選びました。
次は、「外観を選択」です。System / Light / Dark の3モードと、配色テーマが15種類用意されています。IntelliJなどの見慣れた名前もありました。
今回は、デフォルトの Kiro を選択しました。
最後に「Kiro について教えてください」です。ここの回答で応答の説明の詳しさが変わるそうです。設定はデバイスに保存され、設定画面からいつでも変更できます。
この3ステップの設定が完了すると、ダッシュボードの初期画面とご対面です!
配色テーマとしてKiroを選択しているので、Kiro IDEのような見た目になっています。冒頭で紹介した Kiro Crew の機能群が左メニューにあることも確認できます。
これで、セットアップが完了です!
Tips:エージェントの作業範囲の制限
実際にエージェントがどのディレクトリで作業をするのか、に関しまして、実装を確認してみました。すると、以下のようなことが分かりました。
- セッションの作業ディレクトリは workspace ディレクトリ
- サブエージェントの作業ディレクトリは
agent.subagent_cwd_allowed_roots(デフォルトは~/workspace~/workspaces~/workplace~/workplaces)に制限される
手元の既存プロジェクトを直接操作させるのではなく、workspace の中に clone させるのが正規の流れということになります。実際、今回の作業ディレクトリは ~/.kiro/crew/workspace/deps-loop-sandbox でした。
これは、ループエンジニアリングの6要素でいう Worktrees(隔離した作業空間) に相当する部分です。エージェントが修正案を作る場所を、手元の作業ツリーから物理的に切り離しておく、という考え方になります。Kiro Crew には worktree を並列に切る DevFleets という機能もありますが、今回は「1回1パッケージ」で並列作業が発生しないため、workspace への clone のみとなります。
3. 手動でループを1周回してみる
ループエンジニアリングを実現するために、まずループ1周の設計を行いました。手動で回してみて問題なく動くかを確かめています。
3.1. エージェントに渡すプロンプト
最初に、ループを回すためのエージェントへの指示を考えます。ここが実質的に設計の本体になります。
今回は「ループ1回の実行=1パッケージだけ更新」にしています。これは、「決まった時間に自動で実行される」というアンビエント性を試すためです。また、仕込んだものを一つずつ利用してループを改善していき、徐々に仕上げていく、という狙いもあります。
実際のプロンプトの全文がこちらです。
あなたはリポジトリ `yukimatsuyoshi/deps-loop-sandbox` の依存関係を保守する
エージェントです。以下の手順を**上から順に**実行してください。
## 手順
1. **前回の確認**: `gh pr list --repo ... --state open --label deps` でオープンな
依存更新 PR を確認する。**1件でも残っていたら、何もせず「前回の PR (#番号) の
レビュー待ちです」と報告して終了**すること。
2. **準備**: workspace 内にリポジトリがなければ `gh repo clone` で取得。あれば
`main` を最新に更新する。
3. **調査**: `npm install` 後、`npm outdated` を実行する。**更新対象がなければ
「本日は更新対象なし。すべて最新です」と報告して終了**すること。
4. **選択**: 更新対象のうち、**最もリスクの低い1つだけ**を選ぶ
(リスク順: パッチ < マイナー < メジャー)。
5. **更新**: `deps/update-<パッケージ名>-<新バージョン>` ブランチを作り、更新する。
6. **検証**: `npm test` と `npm run typecheck` を実行する。
- テスト出力に**警告(deprecation 等)が出ていたら、内容を読んで対応を検討**すること。
- 失敗したら原因を調べてコードを修正し、再実行する。**修正の試行は3回まで**。
3回で直らなければ、push せず、何を試してなぜ失敗したかを報告して終了すること。
7. **PR 作成**: 検証が通ったら push し、`gh pr create`。ラベル `deps` を付ける。
本文にはバージョン(旧→新)・テスト結果・対応した警告や修正を含める。
8. **終了**: PR の URL を報告して終了する。
**PR を自分でマージしてはいけない。マージは必ず人間が行う。**
## 制約
- 更新は1回の実行につき依存1つだけ
- 失敗時の修正試行は3回まで
- PR のマージは禁止(人間のレビューが承認ゲート)
- `main` への直接 push は禁止
冒頭で触れたループエンジニアリングの弱点である「無人で回るループは、無人で間違えるループでもある」への対策として、以下を入れています。
- 停止条件: 「修正の試行は3回まで」「outdated が空なら何もせず終了」
- 人による承認: 「マージは必ず人間」「前回 PR が未マージなら待機」
- 可動域: 「main への直接 push 禁止」「1回1つだけ」
停止条件に「何もしない場合がある」ことを指定しています。これは、ループ実行時に必ず何か処理をするエージェントは、処理対象がない場合に処理を捏造する可能性があるからです。
3.2. 動かしてみる
ダッシュボードの「セッション」でチャットを開き、さきほどのプロンプトをそのまま貼るだけです。
処理は以下の順で進みました。
-
gh pr listでオープンな deps PR がないことを確認 →「No open deps PRs. Proceeding to prepare the repo.」 -
workspace にリポジトリがないので
gh repo clone
・Tips にも記載した、「隔離した空間での作業」の準備が行われている -
deps/update-vitest-4.1.11ブランチを作成して更新 -
npm test32件パス /npm run typecheckエラーなし / 警告なし
今回仕込んだ4件のうち、パッチレベルの更新が2件ありました。プロンプトに書いた選択基準は「パッチ < マイナー < メジャー」だけなので、vitest と express のどちらを先に選ぶかは指示していませんが、エージェントが以下のように自分で判断してくれたことがわかります。
エージェントが作成したPRはこちらになります。プロンプトに問題がないことはこれで確認できました!
3.3. レビューコメントで学習させる
次に、PR #1 にレビューコメントを付けて、それが次のループ実行時に効くかどうかを見てみます。
ループエンジニアリングの6要素でいうと、ここは State・Memory(実行をまたいで残る記憶) に当たる部分です。人間のレビューというループの外側から来るフィードバックを、次のループに持ち越せる形で内側に取り込めるのかが、観察のポイントになります。
レビューコメントで指摘したのは以下の2点です。どちらも次のループで作成された PR を見れば機械的に確認できるものにしています。
- lockfile は丸ごと再生成する(
npm install <pkg>@<version>の部分更新をやめ、package.jsonを書き換えてrm -rf node_modules package-lock.json && npm install) - PR 本文にリリースノート / CHANGELOG の URL を必ず載せる
また、コメントの最後に「今後このリポジトリで依存更新を行う際は毎回同じ流儀でお願いします。」と付け加え、恒久的な指摘内容であることを示唆しました。
そのうえでセッションのチャットで以下のように依頼しました。特に「学習してほしい」のニュアンスは含めていません。
PR #1 にレビューコメントを付けました。内容を確認して対応してください。
上記チャット投稿後、エージェントがPRのコメントを読み込み、以下のようなメッセージを出してきました。
The reviewer asked for two changes, and explicitly said these are the standing convention for all future dependency updates in this repo. I'll save that as a lesson, then apply both fixes.
レビューの指摘内容に関して、末尾に加えた一文を恒久ルールの宣言として読み取り、「lesson」として保存しようとしていることが分かります。また、実際にレビュー対応をする前に、先に学習していることも読み取れます。
これはツールlearn_add の定義を見ると腑に落ちます。説明文にはこうあります。
Save a learned correction or preference that persists across all future sessions. MUST be called when the user corrects you
「ユーザーに訂正されたらこのツールを呼べ」がツールのレベルで指示されています。エージェントはレビューコメントを「訂正」として正しく解釈したことになります。
learn_addによって「lesson」化された内容は、CLIで確認することができます。
% kirocrew learn list
>>> [preference] For dependency updates in the yukimatsuyoshi/deps-loop-sandbox repo: (1) regenerate
the lockfile wholesale — edit the version in package.json, then run `rm -rf node_modules
package-lock.json && npm install` to rebuild package-lock.json; (2) always include a link to the
release notes / CHANGELOG for the updated package's target version in the PR body.
— NOT: Do NOT do partial updates via `npm install <pkg>@<version>` (leaves the dependency tree
half-resolved). Do NOT open a deps PR without release-note URLs in the body.
注目すべきは — NOT: の部分です。「こうしろ」だけでなく、「こうするな」という反例がセットで保存されています。しかも npm install <pkg>@<version> という具体的な誤り方まで名指しされています。
この内容は、ダッシュボードの「設定 → メモリ」からも確認でき、lesson. 始まりのキーのものがそれに当たります。

その後は、レビューコメントでの指摘通り、package-lock.jsonを作り直し、リリースノートのURLを含めた上で、PRを作成してくれました。
実際に作成されたPRがこちらになります。(スクショを撮り忘れて、マージ後のものになっていますが、ご容赦ください...)
セッション上でも、レビューコメント対応のサマリメッセージが返ってきていました。

これで 手動でのループ1周分の検証が完了です。次のループで、教えたことが本当に残っているかを確かめます。
4. 手動でもう1周ループを回す — 学習効果の確認
1回目の手動実行で学習した内容が、次のループでも効くかどうかを、もう一度手動でループを回して確認します。
新規セッションを開き、1回目とまったく同じプロンプトを投入しました。先ほどはworkspaceにリポジトリをcloneしていましたが、今回は既に存在するのでスキップされていました。その後、1回目と同様にnpm outdatedを実行した後に、以下のようなメッセージが出ていました。
Three candidates:
express5.2.0 → 5.2.1 (patch — lowest risk) /@faker-js/faker10.0.0 → 10.6.0 (minor) /zod3.25.76 → 4.4.3 (major)
Per policy (patch < minor < major), selecting express 5.2.0 → 5.2.1. Step 5: create branch and update.
Per the learned rule for this repo: edit package.json version, then regenerate the lockfile wholesale.
「learned rule(学習したルール)」と明示したうえで、対応手順を構築していることが分かります。実際の操作も宣言どおりで、npm install express@5.2.1 ではなく package.json の該当行を直接書き換え(- "express": "5.2.0" / + "express": "5.2.1")、そこから lockfile を再生成していました。
一通りexpressのパッケージアップデート完了後、先ほどと同様にPRを作成しています。今回はCHANGELOGのURLも含めてくれています。
処理中のメッセージ中でも、「〜 per the learned rule.」のようなメッセージが随所に見られ、学習が活かされていることが分かります。実際に作成されたPRが以下になります。
結果として、1回目の手動実行で学習させた2点は、両方ともしっかり守られていました。
-
lockfile 丸ごと再生成: PR 本文の検証結果に「lockfile はルール通り丸ごと再生成(
rm -rf node_modules package-lock.json && npm install)」と明記 -
リリースノートの URL: リリースページと
History.mdの2本を「リリースノート」節に記載
そしてもう1点注目したいのが、PR のタイトルです。
- 1回目の PR #1:
chore(deps): update vitest 4.1.10 → 4.1.11 - 2回目の PR #2:
deps: update express 5.2.0 → 5.2.1
1回目のPRのタイトルは Conventional Commits の形式になっていましたが、2回目では deps: から始まっています。この形式については、レビューコメントで何も言っていません。
| ルール | lesson 化 | 別セッションでの再現 |
|---|---|---|
| lockfile 丸ごと再生成 | した | 守った ✅ |
| リリースノートの URL | した | 守った ✅ |
PR タイトル chore(deps):
|
していない | 戻った(1回目の振る舞いを再現せず) |
当たり前ですが、指摘したことは学習され、指摘していないことは再現されなかったため、「lesson」が効いていることを別の観点からも確認できたのではないかなと思います。
Tips: ターンごとの実コストが見える
チャットの各ターンの下部に 2.17 credits · 3m8sのようにコストが表示され、ホバーすると「ターンに 3m8s かかり 2.17 クレジットを使用しました」とポップアップが出るようになっています。

ただし、v0.3.0の時点ではkirodotdev/Kiro #6213でIssueとして上がっているとおり、この per-turn 表示にはサブエージェントの消費が含まれません。今回はサブエージェントを使っていないので実測と一致していますが、サブエージェントを回すループでは目安として見る必要があります。
5. スケジュールを設定し、ループを自動で回してみる
ここまでは、チャットに指示を投げて、一連の処理を動かしていました。ここからが本題で、スケジュールをして自動でループが回るようにします。レビューとマージは引き続き人間がやりますが、起動から PR 作成までは誰も見ていない状態になります。
5.1. スケジュールを設定する
左メニューの「スケジュール」を開き、「最初のジョブ作成」からフォームを開きます。
スケジュールの画面で興味深かったのが、下部の既成テンプレートで、「夜間ビルド監視」「エラーダイジェスト」「スタンドアップ要約」「デプロイ検証」が並んでいました。今回は1から設定しますが、 用途に合うものがあれば、そのまま使えるのはありがたいです。
新規ジョブのフォームは以下のようになっており、必要な情報を入力していきます。
| 項目 | 入力した値 |
|---|---|
| 名前 | deps-loop-sandbox-update |
| メッセージ | 手動で2周まわしたときと同じプロンプト全文 |
| スケジュール | Cron式 10 15 * * * / Asia/Tokyo
|
| エージェント | default |
| モデル | エージェントから継承 |
メッセージ欄には、今まで利用してきたプロンプトをそのまま入力しました。
フォームの残りは以下になります。
「承認」は自動承認を選択しました。手動の場合は毎回承認ボタンを押していましたが、Cron ジョブ実行では自動で処理を進めるため、人の手を挟むことができません。
無人でループを回すことは、実質的にツール実行の承認を事前に一括で渡すことだと言い換えられます。裏を返すと、承認ボタンで守っていたものを別のレイヤーで守り直す必要があるので、ここでプロンプトに書いたガードレール(1回1パッケージ、修正は3回まで、マージ禁止、main への push 禁止)が効いてきます。
「厳密なスケジュール」はONにしました。説明文には「スケジュールどおりに正確に実行。デフォルトではジョブはランダムに分散され、トラフィックスパイクが軽減されます」とあります。今回は発火時刻そのものを観察したいので ON にしました。
残りはデフォルトのままで Cron ジョブを作成すると、一覧に作成したジョブが表示されました。
念のため CLI 側でも確認しました。問題なく登録されていることがわかります。
% kirocrew cron list
✅ 2553e9af deps-loop-sandbox-update (At 3:10 PM JST, 次において実施 03:10) あなたはリポジトリ `yukimatsuyoshi/deps-loop-sandbox` の依存関係を保守するエージェン
5.2. 自動実行を観察する
Cron ジョブの発火時刻になると、ステータスが 準備完了 → 実行中 に変わり、アクションのボタンが 「実行」から「キャンセル」に切り替わりました。次回実行も in 23h 59m に更新されています。
このキャンセルボタンは大事で、エージェントが暴走したら GUI から止められるということです。無人でループを回すときの防衛策になります。
1分半ほどして、通知音が鳴りました。左メニューの「セッション」に未読バッジが付いており、セッション一覧の先頭に Cron: deps-loop-sandbox-update(15:11)が増えています。
ちなみに、今まで紹介していませんでしたが、各セッションには GitHub PR のチップ が付いています。これは、v0.3.0 からの変更点で、「どのセッションでどの PR が生成されたか」が一目でわかりますし、チップをクリックすると対応するPRを開くこともできます。
ここでひとつ挙動として興味深かったのが、このセッションは実行中には出てこないという点です。手動実行のようにリアルタイムで出力が流れるのではなく、ジョブが完了してから、結果がまとまった形で一気に現れます。無人でループを回しているので、実行中はエージェントに委ね、終わったらセッションで人間が確認する、という役割分担になります。
5.3. 処理内容の確認
新しいセッションは、Cron Job Result: deps-loop-sandbox-update というタイトルで始まっていました。
セッションの冒頭は以下のような感じで始まっていました。
I'll start by checking for any open deps PRs. No open deps PR. Proceeding to prepare the repo. Main updated (PR #2 express appears merged). Now install and check outdated. Two candidates remain:
@faker-js/faker10.0.0 → 10.6.0 (minor)zod3.25.76 → 4.4.3 (major)
プロンプトで指示した、「オープンな deps PR があれば待機」から順にたどっているのが分かります。express の PR #2 はマージ済みなので、パッケージアップデートの候補は残り2件でしたが、問題なく@faker-js/fakerを選んでいます。
Lowest risk is the minor bump: @faker-js/faker. Selecting it. Creating the branch and applying the update per the learned convention (edit package.json, then regenerate lockfile wholesale).
また、~ per the learned convention がこちらでもありましたので、今までの「lesson」が効いていそうです。実際に「diff」欄を見ると、package.json の書き換えを行なっており、npm install <pkg>@<version> は実行していません。
code 欄には、実際にどのように判断して、どのように処理を行なったかのサマリが表示されています。
最後の1行では、残った更新対象を「次回に繰り越す」と自分で宣言しています。1回1パッケージという制約を、単発の指示ではなく続きがある前提として理解していることになります。
作成されたPRは以下になります。リリースノートとCHANGELOGのURLを記載していることから、ここでも以前のループでの学習内容が反映されていることが読み取れます。
5.4. レビューで「条件付きのルール」を追加する
Cron ジョブ実行のループでも「lesson」が効くことが分かりましたので、次のループ実行に向けてもう少しルール(流儀)を学習させたいと思います。
PR #3 に、以下のようなレビューコメントを付けました。(冒頭部分がおかしいですが、ご容赦ください)
-
1点目は PR タイトルを Conventional Commits に揃えるという指摘です。この時点のPRタイトルは
deps: bump ...ですが、コミットメッセージ側はchore(deps): ...になっていて書式が割れていました -
2点目は、メジャーバージョンの更新のときだけ
## Breaking changesの節の記載を必須にする、というものです
このように、条件付きのルールも含めているので、次の周(zod のメジャー更新)で条件判定ごと再現するかを確認します。
手動実行の時と同じように、レビューコメントの確認/対応依頼を、スケジュール実行で作成されたスレッドに投げました。
以下のようなメッセージが返ってきました。
Two new standing conventions from the reviewer. Let me address the immediate PR (title fix) and save both as lessons.
…
Request #1 applies to this PR now (title/commit format mismatch). Request #2 doesn't (this is a minor bump). Let me fix the title and save both lessons.
レビューコメントは「対応してください」だけでしたが、1点目のコメントは今の PR にも当てはまると判断し、2点目は「マイナー更新だから今回は該当しない」と、条件判定をしていることがわかります。
そのうえで gh pr edit で PR #3 のタイトルを直そうとしていますが、ここで 🔒 承認待ちが出ています。ジョブ側は自動承認でも、チャットセッションは通常どおり承認が必要、という切り分けがされています。
続けて、手動実行の時と同様に learn_add が実行されていました。
最後にレビューコメントへの返信をして、ジョブが終了しています。以下は、実際のレビューコメントへの返信です。
ここで PR #3 をマージして、無人でのループ実行1周目は終わりです。
kirocrew learn list を叩くと、「lesson」が2件になっていることが確認できました。
% kirocrew learn list
[preference] For deps PRs in yukimatsuyoshi/deps-loop-sandbox: (1) PR title MUST use Conventional Commits matching the commit format — `chore(deps): update <pkg> <old> → <new>`; (2) for MAJOR version bumps, add a `## Breaking changes` section listing release-note breaking changes relevant to this repo's code, or (if none) the justification naming which files were checked. Minor/patch don't need that section. — NOT: Do NOT title a deps PR `deps: bump ...` while the commit is `chore(deps): ...` (format split breaks release-note auto-generation). Do NOT rely on "tests passed" alone as the breaking-change assessment for a major bump — that misses unexercised code paths.
[preference] For dependency updates in the yukimatsuyoshi/deps-loop-sandbox repo: (1) regenerate the lockfile wholesale — edit the version in package.json, then run `rm -rf node_modules package-lock.json && npm install` to rebuild package-lock.json; (2) always include a link to the release notes / CHANGELOG for the updated package's target version in the PR body. — NOT: Do NOT do partial updates via `npm install <pkg>@<version>` (leaves the dependency tree half-resolved). Do NOT open a deps PR without release-note URLs in the body.
今回も、— NOT: として反例が付いています。
— NOT: Do NOT title a deps PR
deps: bump ...while the commit ischore(deps): ...(format split breaks release-note auto-generation). Do NOT rely on "tests passed" alone as the breaking-change assessment for a major bump — that misses unexercised code paths.
レビューコメントに書いた「『テストが通った』だけでは不可」という否定表現が、そのまま反例として追加されている形になります。
6. Slack接続を行い、もう一度自動でループを回してみる
残るアップデート候補は zod 3.25.76 → 4.4.3、メジャー更新だけになりました。破壊的変更ありの1件になります。
最後のループ実行の前に、今回はSlack連携をしてみます。ここまでは結果をダッシュボードのセッションから確認していましたが、本来無人でループを定期実行するなら、ブラウザは閉じていることがほとんどです。なので、結果が向こうから届く状態にしておきたいです。
6.1. Slack に繋ぐ
ダッシュボードの「設定」 → 「チャネル」で通知先を設定することができるのですが、実際に開いてみると、Slack / Discord / Telegram / Webex / WeCom / Microsoft Teams / WeChat の7つが並んでいました。
「Slack アプリを作成」を押すと、Slack Appの作成に必要なマニフェスト作成画面が開きます。
-
Step 1 of 2: マニフェストの内容を確認して、インストール先のワークスペースを選ぶだけ
-
Step 2 of 2:
What it can do in Slack (17)/What it can respond to in Slack (7)の確認
「Create」を押下するとSlack側の設定画面に遷移しますので、Slack Appの設定をします(本記事では省略します)。
Slack App 側の設定が完了したら、ボットトークン、アプリレベルトークン、Slack メンバーIDを、先ほどの「設定」>「チャネル」の「Slack」画面に入力します。
| 入力するもの | 取得方法 |
|---|---|
ボットトークン(xoxb-) |
アプリをワークスペースにインストールした後、OAuth とアクセス許可 |
アプリレベルトークン(xapp-) |
Basic Information → App-Level Tokens(connections:write) |
| 所有者 Slack メンバー ID | Slack のプロフィールからコピー |
入力したら、「Slack 設定を保存」します。
ゲートウェイを再起動して、もう一度 Slack の設定を見に行くと、「接続済み」になっていました。
疎通確認は、Slack の DM で ping と打つだけでした。
pong が返ってきました。DM は既定で always モード(毎メッセージに応答)なので、メンションは不要でした。Slack App をチャンネルに入れた場合は、メンションが必要になります。
6.2. 最後のループの動作を観察する
準備ができたので、スケジュールの時刻設定を変更して、ジョブの発火を待ちます。本来は「次の日の同時刻」に自動でループが動くことを確認するべきですが、簡単のためにこのようにしています。ちなみに、今回は CLI からスケジュールの設定を変更してみました。
% kirocrew cron update 2553e9af --cron '25 16 * * *'
Updated job: 2553e9af (deps-loop-sandbox-update)
時間になると、ジョブが開始され、ループが動き始めました。
しばらく待つと、完了の通知音が鳴りました。ダッシュボードのセッション一覧を見てみると、新しいセッションが出来ているようでした。
開いてみると前回の実行内容がそのまま残っていました。セッションはジョブごとに1つで、同じジョブの実行はそこに追記されていく作りのようです。そのため、「前回どう判断したか」を引き継いだ状態で次の周が走ることになります。
Only one candidate remains: zod 3.25.76 → 4.4.3 — a major bump. It's the only option, so I must handle it as a major version update. Per the learned convention, a major bump requires a
## Breaking changessection listing release-note breaking changes relevant to this repo's code (or a justification naming which files were checked).
zodのバージョンアップがメジャーであると判断し、前回のループで追加した「lesson」に従って、PRに ## Breaking changes セクションを追加しようとしています!
また、今回はメジャーアップデートだったので、パッケージのバージョンを上げるだけで終わらず、以下のように、アップデートの影響を受けるコードまで修正していることが分かります。
サマリを見ても、今までの「lesson」の内容を踏まえつつ、メジャーアップデートにしっかり対応してくれたことが読み取れます。
作成されたPRは以下になります。
PRのタイトルが「chore(deps):」から始まっていますし、Breaking Changeの項目もしっかり記載されていました!
バージョンを上げることによるコードへの影響と、それに対する対処に関して丁寧に記載されているため、エージェントがどのように判断したか、をPRからも追うことができるようになっています。
6.3. Slack の確認
ジョブの完了と同時に、Slackにもちゃんと通知が来ていました。通知内容を確認すると、サマリではなく、実際の処理のトレース内容がそのまま通知されていました。
- 親メッセージに実行トレース(依存パッケージの選択理由、破壊的変更の特定、diff まで)
✅ Acknowledgeボタン- スレッドに4件の返信(長文が
(continued...)で分割配信される) - 末尾に
[OPTIONS: PR #4をマージして | 差分を見せて | このリグレッション検知の経緯を詳しく]
最後の OPTIONS に関しては、同じ選択肢はダッシュボード側のセッションにもボタンとして出ていましたが、これは言い換えると Slack からも同じ操作ができる、ということになります。Tipsの Slack App ホームや Slack コマンドの件も合わせると、ダッシュボード(GUI)がなくても、Slack だけで十分ということになります。
なお、これで npm outdated のアップデート候補は4件とも更新が完了しました。つまり、次のジョブ実行時に新しい更新がなければ、プロンプトの手順3にしたがって「本日は更新対象なし。すべて最新です」のように報告して何もせずに終わるはずです。3.1 で「何もしない場合がある」を書いておいたのは、このためになります。
これで、毎日決まった時間に実行されるループが完成です! 今回は検証のために、依存パッケージのアップデートをテーマとしましたが、がっつりコードの変更が発生するような複雑なタスクでも、同じような感じでループを作成することが出来そうです。
今回試さなかったこと
「実装」エージェントと「検証」エージェント
冒頭の説明でも述べた通り、ループエンジニアリングでは、実装するエージェントとレビューするエージェントで役割を分ける、というように提唱されています。今回で言うと、PRを作成する前に、対応内容に関して検証エージェントのレビューが挟まる感じです。
今回は、Kiro Crew の 「lesson」機能(ループエンジニアリングでいうところの 「State・Memory」)をメインで試したかったため、こちらは検証しませんでした。エージェントによるレビューを挟むと、人による指摘とエージェントによる指摘が混ざって、実際に「lesson」として何が効いたのかを切り分けられなくなる可能性がありました。また、依存パッケージの更新というテーマ自体、テストの結果があればレビュー役を足さなくても検証が成立していた、という事情もあります。
もし Kiro Crew で試すとしたら、サブエージェント(spawn)に変更差分をレビューさせるステップを、テスト通過後 〜 PR 作成前に1つ挟む形になるかと思います。今後実際に試してみたいです。
ホストの可用性
ローカル環境で動かしている以上、Cron ジョブを毎日決まった時間に動かすは、本来 PC と Gateway がずっと起動している必要があります。Kiro Crew のスケジューラの実装を確認すると、Cron ジョブは「現在時刻が式にマッチするか」だけで発火を判定していて、PC や Gateway が閉じている間のスケジュールを、後から追い実行する仕組みはありません。
ですので、実際には kirocrew service で常駐化する、 Run on AWS 等の設定でクラウド上で起動する、といった対応が必要になります。今回は、あくまでお試しだったので、簡単のためにローカル環境で常駐化はさせずに検証を行いました。
さいごに
今回は、話題のループエンジニアリングを、AWS の Kiro Crew を使って実際に体験してみた記事でした! 手動でループを実際に動かしながら設計し、レビューコメントでの学習効果の確認、最後はスケジュール実行で無人化する、という流れで、破壊的変更ありのメジャー更新までを、エージェントが無人でやり遂げることを確認しました。
ループエンジニアリングに関して、Osmani 氏のブログやその解説記事を読んでもイメージしづらかった部分に関しても、実際に自分で体験することによって、より理解が深まったように感じます。
Kiro Crew は GA 直後ということもあり、まだまだ挙動が変わっていきそうですが、ループエンジニアリングに必要な部品が最初から揃っているのは体験として強力でした。検証エージェントの分離など、今回試せなかった機能がまだまだいっぱいあるので、今後もいろいろ試していきたいです。
本記事はこれで以上になります。最後までご精読いただきありがとうございました!

















































