AIに実装を頼んだあと、同じ会話でレビューもお願いすることがあります。この順番を毎回説明するのではなく、再利用できる手順にできないかと思い、Kiro workflowsを試しました。
今回はPythonの小さな関数を題材に、implement→reviewの2段階だけに絞っています。手順は実際に順番どおり動きました。ただ、完了表示を見ただけでは見落とす点もありました。
検証日は2026年10月6日です。macOSのApple Silicon環境で、Kiro CLI 2.27.1のV3エンジンとPython 3.13.5を使いました。Kiroのモデル指定はAutoです。
Kiro workflowsとは?
Kiro workflowsは、複数のエージェントがどの順番で作業するかを定義する機能です。各ステップは別のセッションで動き、順番の実行をKiroのランタイムが担当します。定義をJSONやYAMLのレシピとして保存できます。公式発表
今回気になったのは、実装したときの会話をそのまま引き継がずにレビューできる点です。ただし、レビュー役に何を渡すかは自分で決めます。別セッションだから何も共有しない、という意味ではありません。
Web版から始めようとして止まった
最初はWeb版で済ませようとしました。ログインまではできましたが、設定画面にUpgrade to unlock Kiro Webと表示されました。今回のアカウントでは、そのままWeb版の検証に進めませんでした。

画面にはCLIの案内もあったので、ローカルにKiro CLIを入れました。
CLI / インストールと起動
brew install --cask kiro-cli
kiro-cli --version
# kiro-cli 2.27.1
kiro-cli chat --v3CLIの/settingsでFeaturesを開き、Workflowsを有効にします。私の環境では、この項目が表示されました。有効化した直後に再起動が必要という案内が出たため、CLIを起動し直しています。
先にワークスペース設定へ値を書いただけの状態では、/workflowは認識されませんでした。今回は設定画面のスイッチまで確認して進めました。公式の有効化手順でも、CLIでは設定変更後の再起動が必要とされています。項目がない場合は、アカウントへの提供状況を確認する必要があります。
題材はページサイズを変換する関数にした
検証用フォルダーに、要件、未実装の関数、標準ライブラリのunittestを置きました。既存の業務コードを渡す必要はないので、独立した小さな環境にしています。
関数はparse_page_size(raw)です。例えば、Noneなら20、" 42 "なら42、"101"なら上限の100を返します。"0"や全角数字はValueError、文字列でもNoneでもない値はTypeErrorとしました。
既存テストは6メソッドで、複数の入力をサブテストにしています。実装役にはテストを変更しないこと、レビュー役には実装も変更しないことを伝えました。今回は修正ループやPR作成まで入れると観察しにくいため、2段階で止めます。
実装とレビューをレシピに並べる
レシピは.kiro/workflows/implement-review.workflow.jsonに保存しました。最初に使ったのは、組み込みのwf-coderとsemantic_reviewerです。
以下は、実行したレシピの構造が分かるようにプロンプトを短くした抜粋です。
JSON / レシピ(抜粋)
{
"name": "implement-review",
"inputs": {"task": "prompt", "run_dir": "string"},
"steps": [
{
"type": "step",
"id": "implement",
"agent": "wf-coder",
"prompt": "{{task}}。要件に従って実装し、テストを実行する。記録を{{run_dir}}/implementation.mdに保存する。",
"artifacts": {
"implementation": "{{run_dir}}/implementation.md"
}
},
{
"type": "step",
"id": "review",
"agent": "semantic_reviewer",
"prompt": "要件と実装をレビューする。申し送り: {{implement.output}}。実装記録: {{artifacts.implementation}}。結果を{{run_dir}}/review.mdに保存する。",
"artifacts": {"review": "{{run_dir}}/review.md"}
}
]
}実際のプロンプトには、テストのコマンド、記録先、レビュー時に要件と実ファイルを読み直すことも書いています。run_dirを入力にしたのは、再実行で前の記録を上書きしないためです。
実装役の最終応答は{{implement.output}}、保存したファイルのパスは{{artifacts.implementation}}で渡します。レビュー役が実装役の説明だけで判断しないよう、要件とコードの確認も明示しました。レシピの公式仕様
実行前にはKiroのvalidate_workflowで検証しました。この定義ではエラー・警告ともにありませんでした。
最初は書き込みの承認で止まった
記録をファイルに残したかったので、今回はCLIの非対話モードから起動しました。ここで詰まりました。レシピが有効でも、ステップが必要な操作を実行できるとは限りません。
最初の実行では、ファイル書き込みやコマンド実行の承認を非対話モードで受けられずに止まりました。ツールの許可指定も試しましたが、自分の環境では書き込みが進んでも、テストコマンドが拒否される組み合わせがありました。
非対話モードの公式説明には、必要なツールの許可をあらかじめ指定する方法が載っています。ただ、今回は指定を追加しただけで完了と判断せず、各ツールの結果まで確認しました。
実装の完了後に、別セッションのレビューが始まった
組み込みエージェントで2段階が完了した実行のIDは、wf_363fac69731510f8でした。イベント記録の時刻を日本時間に直すと、次の順番です。
| ステップ | 開始 | 終了 | 状態 |
|---|---|---|---|
| implement | 19:10:57.029 | 19:11:57.660 | completed |
| review | 19:11:57.671 | 19:12:49.758 | completed |
レビューの開始は、実装の終了より後でした。両ステップのセッションIDも別です。途中で私がレビュー開始の指示を追加する必要はありませんでした。
保存されたのは、implementation.md、tests.txt、review.mdです。ワークフロー全体の状態と、ステップごとの状態・開始終了時刻・成果物の場所も記録に残りました。
一方、この実行ではレビュー側のcapturedOutputが空でした。review.mdには内容が残っていたので、会話の最終応答とファイルの成果物は別々に確認する必要があると感じました。
completedでも、テストを実行した証拠にはならなかった
今回いちばん引っかかったのはここです。
実装役のtests.txtには、テスト成功に見える出力が書かれていました。しかし末尾を読むと、コマンドが拒否されたため手動トレースで確認したこと、終了コードは推定であることが書かれていました。実際のテスト実行ログではありません。
レビュー役もこの制約を記録していましたが、最終判定はAPPROVEDでした。ワークフローのcompleted、レビューのAPPROVED、テストを実行して成功したことは、同じ意味にはできません。
そこで、Kiroの記録とは分けて、私の側でも実際にテストを実行しました。
CLI / テスト実行
python3 -m unittest discover -s tests -v既存の6テストは成功しました。ただ、要件には数字列の長さの上限を設けていなかったため、追加で長い入力も渡しました。
Python / 長い入力での確認
from pagination import parse_page_size
parse_page_size("9" * 5000)
# 期待値: 100
# 実際: ValueError
# Exceeds the limit (4300 digits) for integer string conversion実装は、入力全体をint()に変換してから上限を適用していました。自分のPython環境では、その変換で例外になりました。Pythonのドキュメントにも、10進数の文字列と整数の変換に桁数制限があることが説明されています。
レビューを別セッションにしても、この入力までは拾えていませんでした。今回の一例だけでレビュー全体の性能は判断できませんが、少なくともAPPROVEDだけを見て検証を終えるのは避けたいと思いました。
再実行するときは、レシピと記録先を分ける
同じレシピファイルを指定し、run_dirを変えて新しい実行を開始できることは確認できました。毎回、実装とレビューの順番を会話で組み立て直す必要はありません。
ただし、既に実装されたファイルに対する再実行は、未実装の状態からの実行とは条件が違います。今回は未実装の雛形と実行ごとの成果物を別に保存しています。
また、新しい実行の開始と、途中で止まった実行のResumeやRetryも分けて考えています。実行管理の公式説明には復旧操作もありますが、今回確認したのはレシピを指定して新しい実行を作る操作です。
非対話モードの承認設定だけでは切り分けきれなかったため、最後は対話モードで同じレシピを実行しました。記録先はrun-06です。長い入力の問題もタスクに追加し、ファイル操作とコマンドを個別に承認しました。
この実行では、Kiro側でも"9" * 5000の例外を再現しました。その後にコードを修正し、既存の6テストを実行して終了コード0を確認しています。最初の推定記録と違い、ツールの実行結果まで確認できました。
続くレビュー役は、先頭にゼロが続く入力も実行していました。"0001"は期待値1に対して100、"0000"は期待するValueErrorが出ずに100でした。長い入力への修正で、文字数だけを見て上限値を返すようになったためです。
| 入力 | 期待値 | 実際 |
|---|---|---|
"9" × 5000 | 100 | 100 |
"0001" | 1 | 100 |
"0000" | ValueError | 100 |
既存テストの成功だけでは拾えなかった不具合を、今回はレビュー段階で指摘できました。私の側で同じ入力を実行しても結果は一致しました。
最終判定はCHANGES_REQUESTEDでした。ここでレビュー作業を完了し、自動の修正ループには進めていません。指摘がある状態でも、レビューという工程を終えたことは記録に残せます。
次は完了条件まで決めたい
実装のあとに別セッションのレビューを動かす、という順番はレシピに残せました。記録先も入力として渡せるので、手順を再利用する部分は扱いやすいと感じました。
最初は検証を実行できないまま完了し、再実行では実テストと追加の指摘まで残せました。次は、実測のテスト結果がない場合やレビューで修正を求められた場合に、次の工程へ進めない完了条件を考えたいです。
ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。
- 選考ではありません
- 履歴書不要
- 技術の話が中心
- 所要時間30分程度
- オンラインOK