Kiro で AWS AI-DLC を実践する
概要
AI を普段から補助的に使っているソフトウェアエンジニアにとって、次の壁は「補完は速いが、開発全体はあまり変わっていない」という点ではないでしょうか。
コード補完、テスト生成、ドキュメント下書きは速くなっても、要件整理、設計の合意、実装のレビュー、デプロイ判断のような重要な流れは、依然として人間主導のまま分断されがちです。
AWS が提唱する AI-DLC (AI-Driven Development Life Cycle) は、その分断を減らし、AI を開発ライフサイクル全体の協働者として扱うための考え方です。
この記事では、以下をまとめます。
-
AI-DLCの考え方 - なぜ通常の
AI-assisted developmentより踏み込んでいるのか -
Kiroを前提にawslabs/aidlc-workflowsを導入する手順 -
Workflowを使って具体的に開発を進める流れ - 生成される
aidlc-docsの見方
なお、この記事では AI がすべてを自律的に決める運用は前提にしません。あくまで 人間が意思決定し、AI が計画と実行を加速する という立場で整理します。
AI-DLC とは何か
AI-DLC は、AI を単なる補助ツールではなく、計画を作り、必要な確認を求め、承認後に実装を進める主体 として開発プロセスに組み込む方法論です。
ポイントは 2 つあります。
人間の監督を前提とした AI 主導の実行動的なチームコラボレーション
つまり、AI に作業を任せるのではなく、AI が提案し、人間が判断する というループを明示的に開発プロセスへ埋め込みます。
従来の開発との違いを雑にまとめると次のとおりです。
| 観点 | 典型的な AI 活用 | AI-DLC |
|---|---|---|
| AI の役割 | 補完、生成、要約など個別作業の支援 | 計画、確認、実装、成果物生成を横断して支援 |
| 人の関わり方 | 必要に応じてレビュー | 各フェーズで承認と方向付けを担う |
| 開発の流れ | 人が工程を管理し AI を都度呼ぶ | AI が状況に応じて工程の深さと順序を提案 |
| 成果物 | その場限りになりやすい | リポジトリ内に文書化され継続利用しやすい |
なぜソフトウェアエンジニアに適しているのか
AI を日常的に使っていると、次のような経験が増えます。
- ちょっとした修正なのに、毎回プロンプトの前提を説明し直す
- 生成コードは速いが、設計判断の根拠が薄い
- セッションを跨ぐと文脈が切れる
- 要件、設計、実装、テストのつながりが弱い
AI-DLC は、この問題を プロンプトの工夫 ではなく ワークフローの定義 で扱おうとします。
特に重要なのは、どの工程を実行するか と 各工程をどこまで深くやるか を固定しないことです。小さなバグ修正と、新機能開発や既存システムのモダナイゼーションでは、必要な工程が違います。AI-DLC はそこを前提にしています。
AI-DLC の全体像
AI-DLC は大きく Inception、Construction、Operations の 3 フェーズで考えます。
それぞれの役割は次のイメージです。
-
Inception: 何を作るか、なぜ必要か、どの粒度で進めるかを固める -
Construction: 設計、実装、テストを進める -
Operations: インフラ、デプロイ、運用上の観点を扱う
ただし、毎回すべてをフルで実行するわけではありません。AI-DLC が重視しているのは adaptive workflow です。つまり、課題の性質に応じて必要な工程だけを選び、必要な深さで実行します。
Human-in-the-loop のループ
AI-DLC の核は、AI が勝手に進めることではなく、承認ポイントを明示した協働ループです。
このループが各フェーズで繰り返されます。AWS の説明では、要件を詰める段階を Mob Elaboration、実装や設計を詰める段階を Mob Construction と表現しています。
AI-DLC の何が実務向きなのか
実務で使いやすいと感じる理由は、次の 3 点です。
1. One-size-fits-all を避ける
AI コーディングツールの中には、何をやるにも同じ手順を踏ませるものがあります。
しかし実際には、以下の作業で最適な流れは違います。
- 小さな不具合修正
- 既存システムのリファクタリング
- 新機能の追加
- インフラ移行
AI-DLC は、この差を前提にして 今の意図に対して必要なフェーズだけを選ぶ 方針です。
2. 工程ごとの深さを可変にする
軽微な API 修正に大規模な設計文書は不要です。一方で、複数サービスに影響する変更なら NFR や設計の議論を省くと危険です。
AI-DLC では、工程を実行するかどうか だけでなく、どこまで深くやるか も状況に応じて変えます。
3. 人の責任を薄めない
AI に全部任せると速そうに見えますが、あとでレビューコストや手戻りが増えやすくなります。
AI-DLC は、人間の責任を減らすのではなく、人間が判断すべき場所を明確にする 方向です。ここが、単なる自動化より現実的です。
Kiro と AI-DLC の関係
AI-DLC 自体は方法論であり、実際に動かすには各ツール向けのルールやステアリングが必要です。
今回使う awslabs/aidlc-workflows は、その実装をオープンソース化したものです。リポジトリには複数のツール向け設定がありますが、この記事では Kiro を前提にします。
Kiro では Steering Files を使って AI-DLC のワークフローを読み込ませます。ポイントは次の 2 つです。
-
.kiro/steering/にコアワークフローを置く -
.kiro/aws-aidlc-rule-details/に詳細ルールを置く
Kiro IDE でも Kiro CLI でも考え方は同じです。README では、Kiro IDE は Vibe mode で使う想定とされていて、Spec mode へ誘導されても切り替えず進める案内があります。
Kiro で AI-DLC Workflow を導入する
ここでは、awslabs/aidlc-workflows のリリース ZIP を使う最短手順を示します。
1. Workflow を配置する
macOS / Linux では次のように配置できます。
mkdir -p .kiro/steering
cp -R ~/Downloads/aidlc-rules/aws-aidlc-rules .kiro/steering/
cp -R ~/Downloads/aidlc-rules/aws-aidlc-rule-details .kiro/
配置後のイメージは次のとおりです。
<project-root>/
├── .kiro/
│ ├── steering/
│ │ └── aws-aidlc-rules/
│ └── aws-aidlc-rule-details/
└── ...
2. 読み込みを確認する
Kiro CLI なら kiro-cli を起動して /context show を実行し、.kiro/steering/aws-aidlc-rules が見えているかを確認します。
3. 使い始める
README では、開発の開始時に AI-DLC を使って、 ... で意図を伝える使い方が案内されています。ここが重要で、単に「このコードを書いて」ではなく、意図、制約、期待する成果 を AI-DLC に渡します。
たとえば次のような入り方です。
AI-DLC を使って、シンプルな電卓 Web アプリを作成してください。
HTML、CSS、JavaScript はバニラのみを使用してください。
基本的な四則演算、小数入力、
キーボードショートカット、ゼロ除算のハンドリングに対応してください。
静的なフロントエンドプロジェクトとして完結させてください。
具体例: Kiro で電卓アプリを開発する
ここからは、awslabs/aidlc-workflows を Kiro で使って、実際にシンプルな電卓アプリを作成した例を扱います。
今回は、作成時に保存しておいた Kiro の Vibe モードの履歴スクリーンショットどおり、チャットの開始時点でかなり小さなスコープを渡しています。
まずは、AI-DLC ワークフロー開始直後の様子です。ルール詳細ファイルを読み込み、ワークスペース検出へ進んでいることが分かります。
最初の依頼は次の趣旨です。
AI-DLC を使ってシンプルな電卓アプリを作成する- グリーンフィールドで始める
- 静的な Web アプリとして完結させる
実際の成果物は、ワークスペース直下に次の 3 ファイルとして生成されました。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>電卓</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="calculator" role="application" aria-label="電卓">
<div
class="display"
data-testid="calculator-display"
aria-live="polite"
aria-atomic="true"
>
<span class="display-value" data-testid="calculator-display-value"
>0</span
>
</div>
<div class="buttons" role="group" aria-label="電卓ボタン">
<button
class="btn btn-function"
data-testid="calculator-clear-button"
data-action="clear"
aria-label="クリア"
>
C
</button>
<button
class="btn btn-function"
data-testid="calculator-sign-button"
data-action="sign"
aria-label="符号反転"
>
±
</button>
<button
class="btn btn-function"
data-testid="calculator-percent-button"
data-action="percent"
aria-label="パーセント"
disabled
>
%
</button>
<button
class="btn btn-operator"
data-testid="calculator-divide-button"
data-action="operator"
data-value="/"
aria-label="除算"
>
÷
</button>
<button
class="btn btn-number"
data-testid="calculator-7-button"
data-action="number"
data-value="7"
>
7
</button>
<button
class="btn btn-number"
data-testid="calculator-8-button"
data-action="number"
data-value="8"
>
8
</button>
<button
class="btn btn-number"
data-testid="calculator-9-button"
data-action="number"
data-value="9"
>
9
</button>
<button
class="btn btn-operator"
data-testid="calculator-multiply-button"
data-action="operator"
data-value="*"
aria-label="乗算"
>
×
</button>
<button
class="btn btn-number"
data-testid="calculator-4-button"
data-action="number"
data-value="4"
>
4
</button>
<button
class="btn btn-number"
data-testid="calculator-5-button"
data-action="number"
data-value="5"
>
5
</button>
<button
class="btn btn-number"
data-testid="calculator-6-button"
data-action="number"
data-value="6"
>
6
</button>
<button
class="btn btn-operator"
data-testid="calculator-subtract-button"
data-action="operator"
data-value="-"
aria-label="減算"
>
−
</button>
<button
class="btn btn-number"
data-testid="calculator-1-button"
data-action="number"
data-value="1"
>
1
</button>
<button
class="btn btn-number"
data-testid="calculator-2-button"
data-action="number"
data-value="2"
>
2
</button>
<button
class="btn btn-number"
data-testid="calculator-3-button"
data-action="number"
data-value="3"
>
3
</button>
<button
class="btn btn-operator"
data-testid="calculator-add-button"
data-action="operator"
data-value="+"
aria-label="加算"
>
+
</button>
<button
class="btn btn-number btn-zero"
data-testid="calculator-0-button"
data-action="number"
data-value="0"
>
0
</button>
<button
class="btn btn-number"
data-testid="calculator-decimal-button"
data-action="decimal"
aria-label="小数点"
>
.
</button>
<button
class="btn btn-equals"
data-testid="calculator-equals-button"
data-action="equals"
aria-label="等号"
>
=
</button>
</div>
</main>
<script src="script.js"></script>
</body>
</html>
script.js
/**
* 電卓アプリ - メインロジック
* 基本的な四則演算をサポートするシンプルな電卓
*/
(function () {
"use strict";
// 状態管理
const state = {
currentValue: "0",
previousValue: null,
operator: null,
waitingForOperand: false,
hasDecimal: false,
};
// DOM 要素
const displayValue = document.querySelector(
'[data-testid="calculator-display-value"]',
);
const buttons = document.querySelector(".buttons");
/**
* ディスプレイを更新する
*/
function updateDisplay() {
let value = state.currentValue;
// 長い数値の場合はフォントサイズを調整
if (value.length > 9) {
displayValue.style.fontSize = "2rem";
} else if (value.length > 7) {
displayValue.style.fontSize = "2.5rem";
} else {
displayValue.style.fontSize = "3.2rem";
}
displayValue.textContent = value;
}
/**
* 数値を入力する
* @param {string} digit - 入力する数字
*/
function inputNumber(digit) {
if (state.waitingForOperand) {
state.currentValue = digit;
state.waitingForOperand = false;
state.hasDecimal = false;
} else {
if (state.currentValue === "0" && digit !== "0") {
state.currentValue = digit;
} else if (state.currentValue !== "0") {
state.currentValue += digit;
}
}
updateDisplay();
}
/**
* 小数点を入力する
*/
function inputDecimal() {
if (state.waitingForOperand) {
state.currentValue = "0.";
state.waitingForOperand = false;
state.hasDecimal = true;
updateDisplay();
return;
}
if (!state.hasDecimal) {
state.currentValue += ".";
state.hasDecimal = true;
updateDisplay();
}
}
/**
* 演算を実行する
* @param {number} a - 左オペランド
* @param {number} b - 右オペランド
* @param {string} op - 演算子
* @returns {number|string} 計算結果またはエラーメッセージ
*/
function calculate(a, b, op) {
switch (op) {
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
if (b === 0) {
return "エラー";
}
return a / b;
default:
return b;
}
}
/**
* 演算子を設定する
* @param {string} nextOperator - 次の演算子
*/
function handleOperator(nextOperator) {
var current = parseFloat(state.currentValue);
// アクティブな演算子ボタンのスタイルをリセット
document.querySelectorAll(".btn-operator").forEach(function (btn) {
btn.classList.remove("active");
});
if (state.operator && !state.waitingForOperand) {
var result = calculate(state.previousValue, current, state.operator);
if (result === "エラー") {
state.currentValue = "エラー";
state.previousValue = null;
state.operator = null;
state.waitingForOperand = true;
state.hasDecimal = false;
updateDisplay();
return;
}
// 浮動小数点の丸め処理
result = Math.round(result * 1e10) / 1e10;
state.currentValue = String(result);
state.previousValue = result;
} else {
state.previousValue = current;
}
state.operator = nextOperator;
state.waitingForOperand = true;
state.hasDecimal = false;
// アクティブな演算子ボタンをハイライト
var activeBtn = document.querySelector(
'[data-value="' + nextOperator + '"]',
);
if (activeBtn) {
activeBtn.classList.add("active");
}
updateDisplay();
}
/**
* 等号を処理する
*/
function handleEquals() {
if (state.operator === null) {
return;
}
var current = parseFloat(state.currentValue);
var result = calculate(state.previousValue, current, state.operator);
// アクティブな演算子ボタンのスタイルをリセット
document.querySelectorAll(".btn-operator").forEach(function (btn) {
btn.classList.remove("active");
});
if (result === "エラー") {
state.currentValue = "エラー";
state.previousValue = null;
state.operator = null;
state.waitingForOperand = true;
state.hasDecimal = false;
updateDisplay();
return;
}
// 浮動小数点の丸め処理
result = Math.round(result * 1e10) / 1e10;
state.currentValue = String(result);
state.previousValue = null;
state.operator = null;
state.waitingForOperand = true;
state.hasDecimal = state.currentValue.includes(".");
updateDisplay();
}
/**
* クリアする
*/
function handleClear() {
state.currentValue = "0";
state.previousValue = null;
state.operator = null;
state.waitingForOperand = false;
state.hasDecimal = false;
// アクティブな演算子ボタンのスタイルをリセット
document.querySelectorAll(".btn-operator").forEach(function (btn) {
btn.classList.remove("active");
});
updateDisplay();
}
/**
* 符号を反転する
*/
function handleSign() {
if (state.currentValue === "0" || state.currentValue === "エラー") {
return;
}
if (state.currentValue.startsWith("-")) {
state.currentValue = state.currentValue.slice(1);
} else {
state.currentValue = "-" + state.currentValue;
}
updateDisplay();
}
/**
* ボタンクリックイベントを処理する
* @param {Event} event - クリックイベント
*/
function handleButtonClick(event) {
var target = event.target;
if (!target.matches(".btn")) {
return;
}
var action = target.dataset.action;
var value = target.dataset.value;
// エラー状態の場合、クリア以外は無視
if (state.currentValue === "エラー" && action !== "clear") {
return;
}
switch (action) {
case "number":
inputNumber(value);
break;
case "decimal":
inputDecimal();
break;
case "operator":
handleOperator(value);
break;
case "equals":
handleEquals();
break;
case "clear":
handleClear();
break;
case "sign":
handleSign();
break;
}
}
/**
* キーボードイベントを処理する
* @param {KeyboardEvent} event - キーボードイベント
*/
function handleKeyboard(event) {
var key = event.key;
// エラー状態の場合、Escape 以外は無視
if (state.currentValue === "エラー" && key !== "Escape") {
return;
}
// 数字キー
if (key >= "0" && key <= "9") {
event.preventDefault();
inputNumber(key);
return;
}
switch (key) {
case ".":
event.preventDefault();
inputDecimal();
break;
case "+":
event.preventDefault();
handleOperator("+");
break;
case "-":
event.preventDefault();
handleOperator("-");
break;
case "*":
event.preventDefault();
handleOperator("*");
break;
case "/":
event.preventDefault();
handleOperator("/");
break;
case "Enter":
case "=":
event.preventDefault();
handleEquals();
break;
case "Escape":
case "c":
case "C":
event.preventDefault();
handleClear();
break;
case "Backspace":
event.preventDefault();
if (!state.waitingForOperand && state.currentValue.length > 1) {
state.currentValue = state.currentValue.slice(0, -1);
state.hasDecimal = state.currentValue.includes(".");
updateDisplay();
} else if (!state.waitingForOperand) {
state.currentValue = "0";
state.hasDecimal = false;
updateDisplay();
}
break;
}
}
// イベントリスナーの登録
buttons.addEventListener("click", handleButtonClick);
document.addEventListener("keydown", handleKeyboard);
// 初期表示
updateDisplay();
})();
style.css
/* 電卓アプリ - iOS/Windows 電卓風デザイン */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #222;
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.calculator {
width: 320px;
background-color: #000;
border-radius: 20px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
/* ディスプレイ */
.display {
background-color: #000;
padding: 20px 16px;
text-align: right;
min-height: 100px;
display: flex;
align-items: flex-end;
justify-content: flex-end;
}
.display-value {
color: #fff;
font-size: 3.2rem;
font-weight: 300;
line-height: 1;
word-break: break-all;
overflow: hidden;
}
/* ボタングリッド */
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
/* ボタン共通 */
.btn {
width: 100%;
aspect-ratio: 1;
border: none;
border-radius: 50%;
font-size: 1.5rem;
font-weight: 400;
cursor: pointer;
transition:
opacity 0.1s ease,
transform 0.05s ease;
outline: none;
}
.btn:hover {
opacity: 0.85;
}
.btn:active {
transform: scale(0.95);
}
.btn:focus-visible {
box-shadow:
0 0 0 3px #fff,
0 0 0 5px #007aff;
}
/* 数字ボタン */
.btn-number {
background-color: #333;
color: #fff;
}
.btn-number:hover {
background-color: #555;
}
/* 0 ボタン(横長) */
.btn-zero {
grid-column: span 2;
border-radius: 40px;
aspect-ratio: auto;
padding: 0 28px;
text-align: left;
}
/* 機能ボタン(C, ±, %) */
.btn-function {
background-color: #a5a5a5;
color: #000;
}
.btn-function:hover {
background-color: #c8c8c8;
}
.btn-function:disabled {
opacity: 0.4;
cursor: not-allowed;
}
/* 演算子ボタン */
.btn-operator {
background-color: #ff9f0a;
color: #fff;
}
.btn-operator:hover {
background-color: #ffb340;
}
.btn-operator.active {
background-color: #fff;
color: #ff9f0a;
}
/* 等号ボタン */
.btn-equals {
background-color: #ff9f0a;
color: #fff;
}
.btn-equals:hover {
background-color: #ffb340;
}
Kiro への最初の依頼
Kiro では次のように依頼すると、AI-DLC の流れに乗せやすくなります。
AI-DLC を使ってシンプルな電卓アプリを作成します。
今回のスクリーンショットでも、Kiro はいきなり HTML を書き始めるのではなく、まずルール詳細を読み込み、ワークスペースを確認し、.kiro しか存在しないグリーンフィールドだと判断してから aidlc-state.md や audit.md を作っています。
ここで見ておきたいのは、AI-DLC が まず状況把握をしてから進める ことです。小さいアプリでもこの挙動が見えるのは、実務上かなり重要です。
要件分析の段階では、いきなり実装に進まず、対象プラットフォーム、使用技術、機能範囲、UI 方針などを質問として切り出して確認していました。
AI-DLC がどう進めるか
この例では、おおむね次のような流れになります。
実際の execution-plan.md でも、Inception では Requirements Analysis と Workflow Planning が完了し、Construction では Code Generation と Build and Test のみが実行対象になっています。逆に、アプリケーション設計、NFR 設計、インフラ設計はスキップされました。
これは、今回の題材が 単一コンポーネントの静的 Web アプリ で、複雑な設計ドキュメントを増やす必要がなかったからです。AI-DLC の 必要な工程だけ通す という性質がよく出ています。
コード生成に入る前には、生成対象ファイルとステップを明示した計画を提示し、レビューを要求していました。ここでも、AI が勝手に突っ走るのではなく、承認を挟んでいることが分かります。
生成される成果物
AI-DLC Workflow を使うと、成果物は aidlc-docs/ に蓄積されます。
今回の電卓アプリでは、概ね次のような構成になりました。
aidlc-docs/
├── aidlc-state.md
├── inception/
│ ├── plans/
│ ├── requirements/
│ └── audit/
├── construction/
│ ├── code-generation/
│ └── build-and-test/
└── operations/
重要なのは、AI が何を考えてその実装に至ったか を後から追いやすいことです。今回も Kiro の最終メッセージでは、ワークスペースルートに index.html、style.css、script.js を置き、aidlc-docs/ には要件定義、実行計画、コード生成関連文書、ビルド&テスト手順を出力したことが確認できます。
完了時点のサマリーも残っていて、生成されたファイル、実装済み機能、ドキュメント出力が一覧できました。
普段の AI チャットだけだと、要件と設計の文脈は会話に埋もれます。AI-DLC では、少なくとも次の追跡がしやすくなります。
- なぜその工程を選んだのか
- どの要件からその設計になったのか
- どの前提でそのコードやテストを書いたのか
Execution Plan で確認したいこと
最初に出てくる execution-plan.md は特に重要です。ここで最低限、次を見ます。
どのフェーズが実行対象になっているかどの工程がスキップされているかMVP として必要十分な深さかセキュリティや NFR が早い段階で消えていないか
たとえば今回の電卓アプリなら、軽量な実装でも次は確認したいところです。
- 本当に静的ファイルだけで完結できるか
- 四則演算と小数計算だけにスコープが絞られているか
- ゼロ除算の扱いが定義されているか
- キーボード操作や ARIA の要件が落ちていないか
ここを見ずに承認すると、あとで「速く作れたが運用できない」状態になりやすいです。
Construction フェーズでの見方
Construction に入ると、Kiro は設計文書とコード生成を進めます。ここで大事なのは、AI が作った実装を眺めることより、設計上の判断が自分たちの現場に合っているか を見ることです。
たとえば今回なら以下を確認します。
-
index.htmlに適切な ARIA ラベルとdata-testidが入っているか -
script.jsが四則演算、小数入力、連続計算、ゼロ除算を扱えているか - キーボード操作が意図どおりか
-
style.cssが iOS / Windows 風の見やすい UI になっているか
AI-DLC の利点は、これらの判断材料が設計文書として先に出る点です。コードだけをレビューするより、修正コストが低くなります。
Operations フェーズでの見方
今回のような静的アプリでは Operations の重みは軽くなりますが、それでも確認する価値はあります。
今回の build-and-test-summary.md では、次の点が明示されていました。
- ビルドツール不要で、
index.html、style.css、script.jsが成果物 - ユニットテストと統合テストの手動テスト観点が整理されている
- 静的ファイルホスティングで公開可能
つまり、この規模のアプリでは Operations を重く設計するより、どこへ置けば配信できるか、どこまでテスト観点を残すか を整理するほうが現実的です。
AI-DLC では、この運用観点もワークフローの一部として扱えます。ここが、コード生成止まりの運用との差です。
実務で使うときの進め方
普段から AI を使っているエンジニアほど、AI-DLC は次のように使うと噛み合いやすいと思います。
1. 最初の入力を雑にしすぎない
AI-DLC を使って、 ... の後に入れるべきなのは、実装指示だけではありません。
- 何を達成したいか
- 何を今回はやらないか
- 既存資産があるか
- どこにリスクがあるか
この情報が薄いと、AI-DLC の適応力も活かしにくくなります。
2. 承認ポイントを省略しない
速く作りたくなるほど、計画レビューを飛ばしたくなります。ただ、AI-DLC はそこを飛ばさない前提の方法論です。
特に次は飛ばさないほうが安全です。
- Inception の execution plan
- Application design
- NFR に関する設計
- Build/Test の結果
3. aidlc-docs を成果物として扱う
aidlc-docs/ を単なる中間ファイルにしないほうが、後続開発で役立ちます。
たとえば次の用途があります。
- 新メンバーへのオンボーディング資料
- 設計レビューのベース
- 変更理由の監査ログ
- 次回の AI セッションへの文脈入力
4. 小さく始める
いきなり全社標準にするより、まずは次のようなテーマで試すのが無難です。
- 小規模な新機能追加
- 独立した内部ツール
- Brownfield の限定的な改修
AI-DLC は強力ですが、最初から最大深度で回す必要はありません。
AI-DLC でエンジニアは成長できるのか
AI が計画して実装まで進める比率が上がると、エンジニアの成長機会が減るのではないか、という懸念はあります。
実際、AI をただのコード自動生成装置として使い、出てきた結果をほぼ無批判に受け入れる運用をすると、学習機会は薄くなります。
ただし、AI-DLC が目指しているのはその運用ではありません。
AI-DLC で増えるのは、単にコードを書く量ではなく、何を作るべきかを定義する力、生成された計画や設計を評価する力、品質と運用まで含めて判断する力 です。
言い換えると、AI-DLC は、より上流から下流まで一貫して判断できるエンジニア を求める考え方です。
実装しなくなるわけではない
まず前提として、AI-DLC を導入したからといって、人がコードから完全に離れるわけではありません。
この記事の電卓アプリの例でも、人が見るべき点は多く残っています。
- 要件が過不足なく整理されているか
- execution plan の深さは適切か
- 生成コードが要件を正しく満たしているか
- アクセシビリティや操作性の観点が落ちていないか
- Build and Test の観点が十分か
つまり、AI がコードを書く場面が増えても、エンジニアには 読む力、評価する力、修正方針を決める力 が引き続き必要です。
成長の軸が変わる
従来は、成長の中心を「自分でどれだけ多くの実装を書いたか」に置きやすかったと思います。
AI-DLC では、その比重が少し変わります。重要になるのは次のような力です。
-
問題設定の力
何を作るのか、何を作らないのか、どこに制約があるのかを明確にする力です。AI が優秀でも、問題設定が曖昧なら出力も曖昧になります。 -
要件分解の力
ビジネス要件を、実装可能な要件、設計上の判断点、テスト観点に分解する力です。AI-DLC では Inception でここを丁寧に扱うので、この力がそのまま成果物の質に出ます。 -
ドメイン理解
AI は一般的な実装案を出せても、職場固有の業務知識や優先順位までは自動で補えません。だからこそ、人間側がドメイン知識を深める価値はむしろ高まります。 -
設計レビューの力
AI が出した設計やコードを見て、どこが妥当でどこが危ないかを判断する力です。これは単なるレビューではなく、技術的な目利きに近い能力です。 -
品質判断の力
動くかどうかだけでなく、テスト観点、運用性、保守性、変更容易性まで含めて妥当かを判断する力です。 -
説明責任を果たす力
なぜこの要件なのか、なぜこの設計なのか、なぜこの生成物を承認したのかを説明する力です。AI-DLC は成果物が文書として残るぶん、この力も重要になります。
ドメイン知識の重要性はむしろ上がる
重要なのはここです。
AI-DLC では、ビジネス要件やドメイン知識の重要性は下がるのではなく、むしろ上がります。
理由は単純で、AI が一般化された実装や設計を素早く提案できるようになるほど、自分たちの現場では何が正しいか を決める人間側の知識が差になるからです。
たとえば同じ機能追加でも、次の違いは AI だけでは埋めにくい部分です。
- この業務ではどの例外ケースが本当に重要か
- 法務、監査、セキュリティ上どこが地雷か
- 利用者が重視する操作感は何か
- 組織としてどの品質水準を許容するか
こうした判断は、コード量ではなくドメイン理解の深さに依存します。AI-DLC はその理解を不要にするのではなく、より重要なものにします。
成長しなくなるケースはある
一方で、AI-DLC を導入すれば自動的に成長できるわけでもありません。
次のような使い方をすると、たしかに成長しにくくなります。
- AI の提案を読まずに承認する
- execution plan を確認しない
- 設計文書を飛ばしてコードだけ眺める
- なぜその実装になったかを追わない
- テスト結果を見ずに完了扱いにする
この使い方は、AI-DLC の思想というより、単なる丸投げ運用です。成長を支えるのは AI の有無ではなく、どこで立ち止まって考えるか です。
AI-DLC は成長の機会を別の場所へ移す
結局のところ、AI-DLC は学習機会を消すのではなく、場所を変えます。
減りやすいものは、反復的な実装作業の比率です。
増えやすいものは、次のような学習です。
- 要件整理の学習
- ドメイン理解の学習
- 設計レビューの学習
- テスト観点の学習
- 運用や保守を見据えた判断の学習
一方で、実装経験の減少が成長機会の減少につながるのではないか、という不安は残るかもしれません。
ただ、実務では、実装そのものに加えて、何を作るべきかを見極め、設計を判断し、品質を担保し、説明責任を果たすことも重要です。AI-DLC は、そうした力をより強く求めるやり方です。
AI-DLC を使うときの注意点
AI が正しいとは限らない
これは当たり前ですが、AI-DLC でも変わりません。むしろ、工程全体へ AI を広げるぶん、誤った前提が広く伝播する リスクがあります。
そのため、以下は必須です。
- 計画の承認
- 設計のレビュー
- テスト結果の確認
- コストとセキュリティの確認
文書の量を増やしすぎない
AI-DLC の価値は文書を増やすことではなく、必要な判断を追跡可能にすること です。軽微な修正に重厚な成果物を求めると逆効果です。
ツール導入より運用設計が大事
awslabs/aidlc-workflows を入れるだけで急に開発文化が変わるわけではありません。
次をチームで合わせておくほうが効果が出ます。
- 誰がどこで承認するか
- どの成果物を保存するか
- どこまでを AI に委ねるか
- セキュリティや監査の基準をどう適用するか
まとめ
AWS の AI-DLC は、AI を補助ツールから 開発ライフサイクルを前に進める協働者 へ引き上げるための方法論です。
特に実務で重要なのは次の点です。
- 固定ワークフローではなく、課題に応じて工程を変えられる
- 人間の承認を前提にしている
- 要件、設計、実装、運用のつながりを成果物として残せる
そして awslabs/aidlc-workflows を使えば、その考え方を Kiro 上で具体的に試せます。
普段から AI を使っているエンジニアほど、次の順で試すと差が見えやすいはずです。
- 小さな題材で
AI-DLC を使って、 ...から始める -
aidlc-docs/の execution plan と design artifacts を丁寧にレビューする - 承認ポイントを飛ばさず、どこまで深くやるべきかをチームで調整する
コード生成の速さだけでなく、開発の流れそのものをどう再設計するか に関心があるなら、AI-DLC は十分に試す価値があります。
Discussion