TL;DR
• 対象読者:AI駆動開発で「設計書(Layer 2)〜実装(Layer 1)」を一気通貫で管理したい人
• この記事でできること:IBM Project Bob の Plan → Code を使い、実装計画とコードを再現可能な手順として生成・検証できる
前回の振り返り
第1回では、IBM Project Bobを使って5分でエコーバックWebアプリを作成しました。Bobに具体的な要件を伝えるだけで、動くコードが生成される体験をしました。
今回は、もっと実践的な課題に挑戦します。マイクロサービスアーキテクチャで、レジリエンス機能(リトライ、サーキットブレーカー、フォールバック)とChaos Engineeringを実装します。
この記事では、IBM Project Bobを使った実装プロセスを詳細に記録しています。生成AIの性質上、全く同じコードが生成されるとは限りませんが、GitHubリポジトリには実際に生成・動作確認済みのコードを公開しており、読者の方も同じアプローチで試すことができます。
Project as Codeとの出会い
実は、「Project as Code」という考え方には、Bobに出会う前から興味を持っていました。
きっかけは、熊井さんの記事です。
この記事で、AI時代においてProject as Codeがいかに重要かを理解し、「プロジェクト全体をコード化して管理する」という思想に深く共感しました。そして、自分のプロジェクトでも実践を始めていました。
自分で実践していた流れ
Layer 3: Vision(構想) ← 人間が作成
Layer 2: Flow/Design(設計) ← 人間が作成(ここに労力がかかる)
├─ 処理フロー
├─ 要件定義
└─ 実装計画書
Layer 1: Code(実装) ← AIに任せていた
この方法自体は、プロジェクトの全体像が明確になるので気に入っていました。特にLayer 1(実装)は、すでにAI(watsonx、Claude、ChatGPT等)に任せていました。
でも、Layer 2の実装計画書を書くのには労力がかかります。実装計画書には、以下を詳細に記載する必要があります:
- システムアーキテクチャ図
- 処理フロー図(正常時、異常時、フォールバック時)
- 技術スタック詳細
- 実装項目の詳細仕様
- ディレクトリ構成
- 実装手順(タスク単位)
- テスト計画
- コード例
IBM Project BobのPlanモードという機能が登場したとき、これを試す絶好の機会だと思いました。
今回の実験:Layer 2もAI化できるか?
プロジェクトの全体構成
本プロジェクトは、CI/CD、Observability、Resilienceを学ぶための実践的な教材として、以下の4つのPhaseで構成されています:
- Phase A:マイクロサービス基盤とレジリエンス機能(今回)
- Phase B:Ansible自動デプロイとJenkinsパイプライン(次回予定)
- Phase C:Instanaによるオブザーバビリティ
- Phase D:本番運用とスケーリング
今回の記事では、Phase Aの実装を通じて、以下の問いへの答えを探ります:
実験の問い
- Bobに要件を読ませたら、実装計画書(Layer 2)を自動生成できるか?
- 生成された実装計画書の品質は、人間が書くのと同等か?
- その実装計画書を使って、実際のコード(Layer 1)も生成できるか?
Phase Aで作るもの:全体像
[ユーザー]
↓ HTTPリクエスト
[サービスA:ショッピングカートAPI(ポート5000)]
↓ 内部HTTP通信
[サービスB:数値変換API(ポート5001)]
実装する機能
サービス間のHTTP通信
- サービスA → サービスB
レジリエンス機能
- リトライ(tenacity、最大3回)
- サーキットブレーカー(pybreaker、失敗5回で開放)
- フォールバック(固定値を返却)
Chaos Engineering
- 20%の確率で2〜5秒の遅延
- 10%の確率でHTTP 500エラー
起動・停止・テスト用のシェルスクリプト
詳細なREADME.md(349行)
最終的な成果物
| カテゴリ | ファイル数 | 合計行数 |
|---|---|---|
| サービスB | 3ファイル | 157行 |
| サービスA | 4ファイル | 430行 |
| スクリプト | 3ファイル | 274行 |
| ドキュメント | 1ファイル | 349行 |
| その他 | 3ファイル | 56行 |
| 合計 | 14ファイル | 1,266行 |
Step 1: 過去の資産を準備
今回のプロジェクトでは、以前から以下の文書を作成していました:
docs/vision.md(Layer 3:Vision)
# プロジェクトの目的と背景(Vision)
このプロジェクトは、「アプリがちゃんと動き続けるしくみ」を学ぶための、
やさしくて実用的な教材です。
そこで大切になるのが、次の3つの考え方です。
- CI/CD(自動でアプリを作って公開)
- Observability(今どうなってるか見えるしくみ)
- Resilience(トラブルが起きても持ちこたえる力)
これは、プロジェクト全体の構想です。全Phase(A、B、C、D)で共通で使います。
docs/demo-flow.md(Layer 2:処理フロー)
## 正常時の流れ
サービスA:
└─ update()
└─ update_cart()
└─ parse_quantity()
└─ convert_params()
└─ RestClient.invoke_conversion()
↓
サービスB:
└─ /convert?number=5 → JSONレスポンスで返却
## Chaos(障害)のシナリオ
| 発生する事象 | 発生条件 |
| ------------- | ------ |
| 遅延(2〜5秒ほど) | 20%の確率 |
| エラー(HTTP 500) | 10%の確率 |
これは、システム全体の処理フローです。こちらも全Phaseで共通です。
Step 2: Phase A固有の要件を書く(人間)
過去の資産を再利用しながら、Phase A固有の要件を35行で作成しました:
Requirement_Phase_A.md(35行)
## 全般的なルール
英語で考えてから、日本語で出力して
## プロジェクト概要
@docs/vision.md の内容を理解し、CI/CD、Observability、Resilienceの学習を
目的とした教材であることを把握してください。
## 今回の実装範囲(Phase A)
@docs/demo-flow.md に記載されたFlaskサービスA/Bの実装のみを対象とします。
## 技術スタック(明示指定)
- Python 3.11以上
- Flask 2.x
- tenacity(リトライ制御)
- pybreaker(サーキットブレーカー)
- requests(HTTP通信)
- 環境変数による動作制御(ENABLE_CHAOS)
## 機能要件
@docs/demo-flow.md から以下を実装:
1. サービスA: /check_cart エンドポイント
2. サービスB: /convert エンドポイント
3. サービスA→Bの内部HTTP通信
4. Chaosモード時の遅延・エラー発生(20%遅延、10%エラー)
5. リトライ(最大3回)、フォールバック、サーキットブレーカーの実装
## 実行環境
- ローカル開発環境での動作確認を優先
- サービスA: ポート5000
- サービスB: ポート5001
- python app_a.py、python app_b.py で起動可能にする
## 制約条件
- Instana連携は今回は対象外(ログ出力で代用)
- シンプルで理解しやすい実装を優先
- 過度な最適化は避ける
重要なポイント:
-
@docs/vision.mdで過去の資産を参照 -
@docs/demo-flow.mdで過去の資産を参照 - Phase A固有の技術スタックと機能要件だけを記載
Step 3: Planモードで実装計画書を生成(Bob)
Bobへの指示
@Requirement_Phase_A.mdから実装計画 implement_plan_A.mdを作成して
たったこれだけです。
Bobの動き(実際のログ)
[15:06:28] read_file: Requirement_Phase_A.md (35行)
[15:06:33] read_file: docs/vision.md (32行) ← 自動で読み取り!
[15:06:33] read_file: docs/demo-flow.md (97行) ← 自動で読み取り!
[15:09:58] write_to_file: implement_plan_A.md (847行)
Bobは、Requirement_Phase_A.mdに含まれる@docs/vision.mdと@docs/demo-flow.mdへの参照を見つけて、自動的にこれらのファイルも読み取りました。
生成された実装計画書
implement_plan_A.md(847行)
目次:
1. プロジェクト概要
1.1 Phase Aの目的
1.2 Phase Aの範囲
2. システムアーキテクチャ
2.1 システム構成図(Mermaid)
2.2 処理フロー(3つのMermaid図)
3. 技術スタック
3.1 言語・フレームワーク
3.2 主要ライブラリ
3.3 環境変数
4. 実装項目詳細
4.1 サービスB(数値変換API)
- エンドポイント仕様
- Chaos機能
- ログ出力
4.2 サービスA(ショッピングカートAPI)
- エンドポイント仕様
- 内部処理フロー
- レジリエンス機能(リトライ、フォールバック、サーキットブレーカー)
5. ディレクトリ構成
6. 実装手順(4フェーズ、5日間)
6.1 フェーズ1: 環境準備(1日目)
6.2 フェーズ2: サービスBの実装(2日目)
6.3 フェーズ3: サービスAの実装(3-4日目)
6.4 フェーズ4: テストとドキュメント(5日目)
7. テスト計画
7.1 単体テスト
7.2 統合テスト(4シナリオ)
7.3 性能テスト
7.4 テスト結果の記録
8. 実装時の注意事項
9. トラブルシューティング(4つの問題と解決方法)
10. 次フェーズへの展望
11. 参考資料
12. 付録A: コード例
- サービスBの基本構造(完全なapp_b.py)
- サービスAのレジリエンス実装(完全なresilience.py)
Bobが生成した実装計画書:6つの驚き
**implement_plan_A.md(847行)**を開いた瞬間、驚きの連続でした。
Bobは、164行の入力(要件35行 + 過去資産129行)から、847行の詳細な実装計画書を生成しました。しかも、単なるテンプレートではありませんでした。
以下、6つの「発見」をご紹介します。
発見1:過去の資産を完全に理解
vision.mdからの理解:
## 1. プロジェクト概要
本プロジェクトは、CI/CD、Observability、Resilienceの学習を目的とした教材です。
Phase Aでは、マイクロサービスアーキテクチャの基礎となるFlaskサービスA/Bの実装を行い、
レジリエンス設計の基本を体験します。
Bobは、vision.mdに記載された「CI/CD、Observability、Resilience」という3つの考え方を理解して、実装計画書の冒頭に反映していました。
demo-flow.mdからの理解:
## 4.2.2 内部処理フロー
**関数呼び出し階層:**
/check_cart
└─ update()
└─ update_cart()
└─ parse_quantity()
└─ convert_params()
└─ RestClient.invoke_conversion()
└─ HTTP通信(サービスB)
Bobは、demo-flow.mdに記載された関数階層(update → update_cart → parse_quantity → convert_params → invoke_conversion)を完全に理解して、実装計画書に反映していました。
発見2:Mermaid図の自動生成
過去の資産には図がありませんでしたが、Bobは自動的に4つのMermaid図を生成しました:
1. システム構成図
2. 正常時の処理フロー
他にも、Chaos時の処理フロー、フォールバック発生時の処理フローが自動生成されました。
「図を作って」とは指示していないのに、Bobが自動的に4つの図を生成してくれました。
発見3:完全なコード例
実装計画書の付録には、完全なコード例が含まれていました。これが次のCodeモードでの実装精度を大きく向上させた理由です。
サービスBの基本構造(app_b.py):
from flask import Flask, request, jsonify
import os
import logging
from chaos import inject_chaos
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.route('/convert', methods=['GET'])
def convert():
try:
# パラメータ取得
number = request.args.get('number', type=int)
if number is None:
return jsonify({"error": "Missing parameter: number"}), 400
logger.info(f"Received request: /convert?number={number}")
# Chaos注入
inject_chaos()
# 変換処理(今回は単純に返却)
result = {"result": number, "timestamp": "2024-01-01T12:00:00Z"}
logger.info(f"Response sent: {result}")
return jsonify(result), 200
except Exception as e:
logger.error(f"Error occurred: {e}")
return jsonify({"error": "Internal server error"}), 500
if __name__ == '__main__':
port = int(os.getenv('PORT', 5001))
app.run(host='0.0.0.0', port=port, debug=False)
このコードの注目ポイント:
- Chaos注入のタイミング(バリデーション後、処理前)
- エラーハンドリングの構造
- ログ出力の配置
サービスAのレジリエンス実装(resilience.py):
from tenacity import retry, stop_after_attempt, wait_exponential
from pybreaker import CircuitBreaker
import logging
logger = logging.getLogger(__name__)
# サーキットブレーカー設定
breaker = CircuitBreaker(
fail_max=5,
reset_timeout=60,
name='service_b_breaker'
)
# リトライ設定
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=1, max=10),
reraise=True
)
@breaker
def call_service_b_with_resilience(url):
"""
レジリエンス機能付きでサービスBを呼び出す
"""
import requests
logger.info(f"Calling Service B: {url}")
response = requests.get(url, timeout=10)
response.raise_for_status()
return response.json()
def call_with_fallback(url):
"""
フォールバック付きでサービスBを呼び出す
"""
try:
return call_service_b_with_resilience(url)
except Exception as e:
logger.warning(f"Fallback triggered: {e}")
return {"result": 0, "fallback": True}
このコードの注目ポイント:
- tenacityとpybreakerの組み合わせ方
- フォールバック処理の実装パターン
- サーキットブレーカーの設定値
これらの完全なコード例は、次のCodeモードでの実装精度を大きく向上させました。
発見4:詳細なテストシナリオ
実装計画書には、4つの詳細なテストシナリオが含まれていました:
シナリオ1: 正常系エンドツーエンド
# サービス起動
./scripts/start_services.sh
# テスト実行
curl "http://localhost:5000/check_cart?quantity=5"
# 期待結果: {"status": "success", "converted": 5}
シナリオ2: Chaosモード(リトライ成功)
# Chaosモードで起動
ENABLE_CHAOS=true ./scripts/start_services.sh
# 複数回テスト実行(リトライ動作確認)
for i in {1..10}; do
curl "http://localhost:5000/check_cart?quantity=$i"
sleep 1
done
# ログ確認
tail -f logs/service_a.log | grep "Retry"
シナリオ3: Chaosモード(フォールバック発動)
# 連続テスト実行
./scripts/test_chaos.sh
# 期待結果: 一部のリクエストで {"status": "fallback"}
シナリオ4: サーキットブレーカー動作確認
# サービスBを停止してテスト
./scripts/stop_services.sh service_b
# 連続リクエスト
for i in {1..10}; do
curl "http://localhost:5000/check_cart?quantity=$i"
done
# ログ確認
tail -f logs/service_a.log | grep "Circuit"
これらのテストシナリオは、実行可能なコマンド付きで記載されていました。
発見5:シェルスクリプトの完成度
scripts/start_services.sh(105行)
#!/bin/bash
# 色付き出力用
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== Starting Services ===${NC}"
# 環境変数の設定
export ENABLE_CHAOS=${ENABLE_CHAOS:-false}
export LOG_LEVEL=${LOG_LEVEL:-INFO}
echo -e "${YELLOW}Configuration:${NC}"
echo " ENABLE_CHAOS: $ENABLE_CHAOS"
echo " LOG_LEVEL: $LOG_LEVEL"
# サービスBの起動
echo -e "${GREEN}Starting Service B (Port 5001)...${NC}"
python3 services/service_b/app_b.py > logs/service_b.log 2>&1 &
SERVICE_B_PID=$!
# サービスBの起動待機とヘルスチェック
for i in {1..10}; do
if curl -s http://localhost:5001/health > /dev/null 2>&1; then
echo -e "${GREEN}Service B is ready!${NC}"
break
fi
echo "Waiting... ($i/10)"
sleep 2
done
# サービスAの起動
echo -e "${GREEN}Starting Service A (Port 5000)...${NC}"
python3 services/service_a/app_a.py > logs/service_a.log 2>&1 &
SERVICE_A_PID=$!
# PIDファイルの保存
echo $SERVICE_A_PID > logs/service_a.pid
echo $SERVICE_B_PID > logs/service_b.pid
echo -e "${GREEN}=== Services Started Successfully ===${NC}"
注目ポイント:
- 色付き出力(GREEN/YELLOW/RED)
- ヘルスチェック(最大10回リトライ)
- PIDファイルの管理
- エラーハンドリング
- ログファイルの自動作成
これらすべてを、実装計画書に明記していなくても、Bobが「あるべき姿」として実装してくれました。
発見6:README.mdの完成度
Bobは、349行の詳細なREADME.mdを自動生成しました。
含まれている内容:
- 📋 目次(8セクション)
- 🎯 概要とシステム構成図
- ✨ 機能説明(レジリエンス、Chaos Engineering)
- 🚀 セットアップ手順(詳細なコマンド)
- 📖 使い方(通常モード、Chaosモード)
- 🧪 テストシナリオと実行コマンド
- 🔧 トラブルシューティング(4つの問題と解決方法)
注目ポイント:
- 絵文字を使った見やすい構成
- コードブロックが適切に配置
- テストシナリオへの参照リンク
## 🔧 トラブルシューティング
[よくある問題と解決方法]
349行の詳細なドキュメントが自動生成されました。絵文字、目次、コードブロック、テストシナリオへの参照、すべて含まれています。
実験の結果:Layer 2もAI化できた!
答え:Yes、しかも期待以上!
| 項目 | 入力 | 出力 |
|---|---|---|
| 人間 | - | Requirement_Phase_A.md (35行) |
| Bob(Planモード) | Requirement + 過去の資産 (164行) | implement_plan_A.md (847行) |
入力164行から、847行の詳細な実装計画書が生成されました。これは約5.2倍の拡張です。
期待以上だった点:
過去の資産を完全に理解
- vision.mdからプロジェクトの目的を理解
- demo-flow.mdから関数階層とChaos仕様を理解
Mermaid図の自動生成(4つ)
- システム構成図
- 正常時、Chaos時、フォールバック時の処理フロー
完全なコード例(2ファイル、約100行)
- app_b.pyの完全な実装
- resilience.pyの完全な実装
詳細なテストシナリオ(4シナリオ)
- 実行可能なコマンド付き
トラブルシューティングガイド(4つの問題と解決方法)
人間が書くのに労力がかかる実装計画書を、Bobはより詳細に生成しました。
Step 4: Codeモードで実装(Bob)
実装計画書が完成したら、次はCodeモードで実際のコードを生成します。
Bobへの指示
@implement_plan_A.mdを実行して
Bobの動き
[15:18:59] read_file: implement_plan_A.md (847行)
[15:20:35] mkdir: services/service_a, service_b, tests, scripts, logs
[15:20:52] write_to_file: services/service_b/requirements.txt
[15:21:02] write_to_file: services/service_a/requirements.txt
[15:22:04] write_to_file: services/service_b/chaos.py
[15:22:14] write_to_file: services/service_b/config.py
[15:22:29] write_to_file: services/service_b/app_b.py
[15:22:41] write_to_file: services/service_a/config.py
[15:23:21] write_to_file: services/service_a/resilience.py
[15:23:54] write_to_file: services/service_a/rest_client.py
[15:24:14] write_to_file: services/service_a/app_a.py
[15:24:27] write_to_file: scripts/start_services.sh
[15:24:38] write_to_file: scripts/stop_services.sh
[15:24:53] write_to_file: scripts/test_chaos.sh
[15:25:39] write_to_file: README.md
[15:25:47] write_to_file: .gitignore
Bobは14個のファイルを生成しました。
生成されたコードの確認:答え合わせ
生成が完了したら、まずChaos機能から確認してみました。
実装計画書に書かれていたコード例:
def inject_chaos():
if os.getenv('ENABLE_CHAOS', 'false').lower() == 'true':
rand = random.random()
if rand < 0.1: # 10%の確率でエラー
raise Exception("Chaos: Simulated error")
elif rand < 0.3: # 20%の確率で遅延
delay = random.uniform(2, 5)
time.sleep(delay)
Bobが生成したコード(services/service_b/chaos.py):
"""
Chaos Engineering機能モジュール
ランダムに遅延やエラーを注入してシステムのレジリエンスをテストする
"""
import random
import time
import os
import logging
logger = logging.getLogger(__name__)
def inject_chaos():
"""
Chaosを注入する関数
環境変数ENABLE_CHAOSがtrueの場合のみ有効
- 10%の確率でHTTP 500エラーを発生
- 20%の確率で2-5秒の遅延を発生
"""
if os.getenv('ENABLE_CHAOS', 'false').lower() != 'true':
return
rand = random.random()
# 10%の確率でエラー
if rand < 0.1:
logger.warning("Chaos injected: Simulated error")
raise Exception("Chaos: Simulated error")
# 20%の確率で遅延(10%〜30%の範囲)
elif rand < 0.3:
delay = random.uniform(2, 5)
logger.warning(f"Chaos injected: delay {delay:.2f}s")
time.sleep(delay)
完璧に一致しています! それどころか、日本語のコメントと適切なログ出力まで追加してくれていました。
実装プロセスの確認:この記事を読んだ方へ
この記事では、IBM Project Bobを使った実装プロセスを詳細に記録しています。GitHubリポジトリには実際に生成されたコードを公開しており、読者の方は同じアプローチを試すことができます。
基本動作の確認(Step 1-5)
まず、生成されたコードが正常に動作することを確認します。
Step 1: リポジトリのクローン
git clone https://github.com/daihiraoka/cicd-demo-ansible-phase-a.git
cd cicd-demo-ansible-phase-a
Step 2: 依存関係のインストール
pip install -r services/service_a/requirements.txt
pip install -r services/service_b/requirements.txt
Step 3: サービスの起動
./scripts/start_services.sh
期待される出力:
===========================================
=== Starting Services ===
===========================================
Configuration:
ENABLE_CHAOS: false
LOG_LEVEL: INFO
Starting Service B (Port 5001)...
Service B started with PID: 12345
Waiting for Service B to be ready...
Service B is ready!
Starting Service A (Port 5000)...
Service A started with PID: 12346
Waiting for Service A to be ready...
Service A is ready!
=== Services Started Successfully ===
Step 4: ヘルスチェック
curl http://localhost:5000/health
# {"service":"service_a","status":"healthy","circuit_breaker_state":"closed"}
curl http://localhost:5001/health
# {"service":"service_b","status":"healthy"}
Step 5: 実際のリクエスト
curl "http://localhost:5000/check_cart?quantity=5"
期待されるレスポンス:
{
"status": "success",
"quantity": 5,
"converted": 10,
"circuit_breaker_state": "closed",
"service": "service_a"
}
完璧に動作しています! サービスAがサービスBを呼び出し、数値(5)を2倍(10)に変換して返しています。
Chaos Engineeringの実践(Step 6-8)
ここからが本番です。Chaosモードで、意図的に障害を起こしてみます。
Step 6: Chaosモードで再起動
# サービスを停止
./scripts/stop_services.sh
# Chaosモードで再起動
ENABLE_CHAOS=true ./scripts/start_services.sh
期待される出力:
===========================================
⚠️ Chaosモードが有効です
===========================================
Configuration:
ENABLE_CHAOS: true
Step 7: リクエストを送信
curl "http://localhost:5000/check_cart?quantity=5"
ターミナルに出るログ:
INFO:rest_client:Calling service B with number=5
[CHAOS] Injecting delay: 3.42s
INFO:rest_client:Calling service B with number=5
INFO:rest_client:Calling service B with number=5
INFO:rest_client:Successfully converted: {'converted': 10}
何が起きたのか:
- サービスBが3.42秒の遅延を注入
- サービスAがタイムアウトを検知
- リトライが自動実行(ログに3回分の呼び出し)
- 最終的に成功
レジリエンス機能が正常に動作しています!
Step 8: Chaosテストの実行
./scripts/test_chaos.sh
期待される出力:
=== Chaos Testing ===
Configuration:
Number of requests: 20
Service A URL: http://localhost:5000
Starting test requests...
Request 1/20: quantity=42
✓ Success - Converted: 84, Circuit Breaker: closed
Request 2/20: quantity=17
⚠ Fallback - Converted: 0, Circuit Breaker: closed
Request 3/20: quantity=63
✓ Success - Converted: 126, Circuit Breaker: closed
[...]
=== Test Results ===
Total requests: 20
Success: 15
Fallback: 5
Error: 0
Success rate: 75%
✓ Test passed (success rate >= 70%)
20回のリクエスト中、成功15回(75%)、フォールバック5回(25%)。合格基準(70%以上)をクリア!
問題解決のプロセス:完璧ではないけど協働で解決
実は、最初からすべてが完璧だったわけではありません。いくつか問題に遭遇しましたが、Bobとの対話で解決できました。
問題1: CircuitBreakerのパラメータエラー
最初の起動で、こんなエラーが:
TypeError: CircuitBreaker.__init__() got an unexpected keyword argument 'timeout_duration'
実装計画書でtimeout_duration=60と指定しましたが、pybreakerの正しいパラメータ名はreset_timeoutでした。
Bobに「CircuitBreakerのパラメータをreset_timeoutに修正して」と依頼すると、すぐに対応してくれました:
# 修正後
self.breaker = CircuitBreaker(
fail_max=5,
reset_timeout=60, # 修正完了
name='service_b_breaker'
)
問題2: pybreaker と tenacity の互換性問題
@retryデコレータとbreaker.call()メソッドに互換性問題がありました。
Bobに問い合わせると、手動でリトライロジックを実装する提案をしてくれました:
def _call_with_retry(self, url: str) -> dict:
"""リトライ付きでサービスBを呼び出す"""
last_exception = None
wait_time = Config.RETRY_MIN_WAIT
for attempt in range(Config.RETRY_MAX_ATTEMPTS):
try:
result = self.breaker.call(self._call_service_b_raw, url)
return result
except Exception as e:
last_exception = e
logger.warning(f"Attempt {attempt + 1}/{Config.RETRY_MAX_ATTEMPTS} failed: {e}")
if attempt < Config.RETRY_MAX_ATTEMPTS - 1:
logger.info(f"Waiting {wait_time}s before retry...")
time.sleep(wait_time)
wait_time = min(wait_time * Config.RETRY_MULTIPLIER, Config.RETRY_MAX_WAIT)
raise last_exception
これらの問題も、Bobとの対話を通じて解決できました。完璧ではないけど、協働すれば解決できる。これがAI駆動開発の面白さです。
実験の結論:Layer 2もAI化できる!
実証できたこと
Layer 2(実装計画書)をAI化できる
- 要件定義(35行)+ 過去の資産(164行合計)→ 実装計画書(847行)
- 約5.2倍の拡張
過去の資産を活用できる
-
@docs/vision.md、@docs/demo-flow.mdで参照 - Bobが自動的に読み取って、実装計画書に反映
AI生成の実装計画書は、人間が書くより詳細
- 完全なコード例(100行以上)
- Mermaid図(4つ自動生成)
- 詳細なテスト計画(4シナリオ)
- トラブルシューティングガイド
Layer 1(コード実装)もAI化できる
- 実装計画書(847行)→ コード(1,266行)
- 14ファイルを自動生成
最終テスト結果
- ユニットテスト:24/24 PASSED (100%)
- 統合テスト:11/12 PASSED (91.7%)
- コードカバレッジ:70%
AI協働のProject as Code
今回の実験で確立できた新しいアプローチ:
Layer 3: Vision(人間、過去の資産を再利用)
└─ docs/vision.md
Layer 2: Flow/Design(人間 + Bob)
├─ docs/demo-flow.md ← 過去の資産を再利用
├─ Requirement_Phase_A.md ← 人間が作成(35行)
└─ implement_plan_A.md ← Bobが生成(847行)← ここが新しい!
Layer 1: Code(Bob)
└─ 14ファイル、1,266行
変わったこと:
- Layer 2の実装計画書(詳細部分)をAI化
- 入力:164行(要件35行 + 過去資産129行)
- 出力:847行(約5.2倍の拡張)
変わらないこと:
- Layer 3(Vision)は人間が作成
- プロジェクトの目的と背景
- 全Phaseで共通
- Layer 2の基礎(処理フロー)は人間が作成
- システムの構成と処理の流れ
- 全Phaseで共通
- Layer 2の要件(何を作るか)は人間が作成
- Phase固有の技術スタックと機能要件
- これは人間が判断すべき
- 問題解決には人間の判断が必要
- AIは完璧ではないが、協働で解決できる
まとめ
今回の実験で実証できたこと:
- Layer 2(実装計画書)もAI化できる
- 過去の資産を活用しながら、新しいPhaseを高速で立ち上げ
- 14ファイル、約1,266行のコードを自動生成
- Chaos Engineeringが仕様通りに動作
- GitHubで実際のコードと実行手順を公開
AI駆動開発は、「AIに丸投げ」ではなく「AIと協働」することで真価を発揮します。Project as Codeという思想があってこそ、AIの力を最大限に引き出せると実感しました。
この記事が、皆さんのAI駆動開発の一助となれば幸いです。
Call to Action:IBM Project Bob を試してみたい方へ
本記事で紹介した IBM Project Bob は、現在 登録制の Private Preview(早期アクセス) として提供されています。
「Project as Code」を実際に体験してみたい方、Plan(設計)から Code(実装)までを AI と協働して進めたい方は、以下のリンクからお申し込みください。
👉 IBM Project Bob 早期アクセス登録
https://ibm.biz/Try-Bob
参考リンク
GitHubリポジトリ: https://github.com/daihiraoka/cicd-demo-ansible-phase-a



