Upgrade to Pro — share decks privately, control downloads, hide ads and more …

オブザーバビリティ研修のための観測対象-教材-をBobに作ってもらう計画

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 オブザーバビリティ研修のための観測対象-教材-をBobに作ってもらう計画

AIで生成したアプリをクラウド環境にデプロイする作業。これをAIに実行してもらう話

Avatar for 1kano

1kano

June 27, 2026

More Decks by 1kano

Other Decks in Technology

Transcript

  1. 自己紹介 ◼ 所属/経歴 • 電機メーカー勤務 • 経歴 1. サーバーのグローバル製造技術/営業 2.

    データセンター・プロジェクト 3. マネージドサービス(マルチクラウド・ハイブリッドクラウド) ◼ 個人活動 • 副業:FunnyGeek ITサービス(ファニーギーク) • ボランティア:CoderDojo青梅(主宰/Champion) • IBM チャンピオン:IBM Champion 2018-2026 • Datadog アンバサダー:Datadog Ambassador 2024-2026 • 特定非営利活動法人 青梅こども未来 プログラミング講師 • 特定非営利活動法人 青梅の虹any, Rainbow Room プログラミング講師 • 特定非営利活動法人 多摩川流域生活支援ネットワーク, ポラリスキッズ プログラミング講師 • 一般財団法人 科学技術継承財団 理事 KANO Ichiro 鹿野 市郎
  2. 背景:なぜ今オブザーバビリティなのか 私の担当領域 • マルチクラウド & プライベートクラウドのマネージドサービス • 運用代行の現場で見えてきた課題 ①監視から “オブザーバビリティ”へ

    • 「インフラのアラートだけ」でなく、 ユーザー体験・アプリ・DBも横断して可視化する時代 • 顧客の興味も急速にオブザーバビリティへシフト ②技術者育成の必要性 • 運用チームが先駆的に取り組んできたが、 設計構築チームにも横展開 • “実体験できる教材”が必要になった AWS Azure Oracle IBM NTTdB Google [問題なし] ・[アラート発生] どれくらい正常か どれくらい影響あるか
  3. シーン:教材としての「障害を仕込んだアプリ」 体験型オブザーバビリティ教育を作りたい • ただ座学するのではなく、 「実際に障害が起きるアプリを見て、Datadogで原因を突き止める」 という実践型トレーニングを作る アプリ要件 • 三層アーキテクチャ(WEB /

    API / DB) • どこでも動くようにコンテナ化。まず、Ubuntuサーバーで動作確認 • 障害を意図的に仕込む(DB不整合、API遅延、バリデーションエラー) WEB API DB *: Datadog = モニタリングツール
  4. 解決策:AI駆動開発で教材を作る 生成AIでアプリを作るというチャンス • Claude Code / GitHub Copilot はプログラミング教室で使い慣れていた まずはClaude

    Codeで「フラッシュ クイズ」を開発 • 三層構造アーキテクチャ • 障害を5%混入。100問の昭和レトロクイズを自動生成 • ほぼAIだけでアプリが完成 • Datadog APM / DBM / RUM / Logs
  5. IBM Bobでも作る! Bobで作るチャンス • 新サービス IBM Bob を使って「クイズフラッシュ_Bob編」 を開発 •

    Claude Codeとの違いを比較する絶好の機会 IBM Bobとは? • Bobの特徴(要点だけ) • Plan / Ask / Code / Advanced / Orchestrator の5モード • コード生成だけでなく、アーキテクチャ検討まで含む • MCP連携でVS Codeと深く統合 • Bobcoinで生産性を可視化 Claude Code / Copilotとの違い(実体験ベース) • Claude:設計図生成が強い • Copilot:既存コードの修正が強い • Bob:アプリ全体を“計画→実装→検証”まで一気通貫で進める
  6. 実録:Bobで「クイズフラッシュ_Bob編」を作ってみた Planモードで設計書を作らせる • 要件定義を渡すと、基本設計書が自動 生成 • コンテナ構成、API設計、DBスキーマまで 一気に出てくる 途中で発生したAIトラブル •

    ポート競合(既存Nginxと衝突) • 文字化け • Datadog設定の微妙なズレ → これらをBobに相談しながら修正 Codeモードで実装フェーズへ • docker-compose • Nginx • Node.js API • MySQL初期化SQL • フロントエンドHTML/CSS/JS → ほぼ連続で自動生成 完成したアプリ • 昭和レトロのクイズ • 障害が5%混入 • Datadogで可視化 • ちゃんと“教材”として使えるレベルに 1 2 3 4
  7. 01. 要件定義(Claude code, IBM Bob 共通) アプリ「フラッシュクイズ」をつくる ・目的:Datadogで情報システム全体をモニタリングする教材である。 ・コンテナ3個で動かす -

    WEBサーバー(Nginx)port443 - APIアプリ(Node.js)port3012 - DBサーバー(MySQL) ・DBのデータ - クイズデータ(設問、回答選択肢、正解) - 成績データ(ニックネーム、回答速度、正解数) ・WEB/APIアプリ - タイトル画面(タイトル「フラッシュクイズ」、ニックネームを入力したら [スタート]ボタン有効化、もしくは成績ランク表示) - クイズスタート(かっこいいカウントダウン5秒前から) - 設問を表示し、回答選択肢から選ぶ。5秒間、正誤を表示する。 次に進む5秒カウントダウンは同時に動く。 - 10問回答したら、合計回答速度と正解数、およびランキングを表 示する。Top3内ならわー わー と賑やかに紙吹雪(p5.js)とか。 ・設問と回答 - クイズのジャンルは「昭和レトロの想い出」とする。ダミーで「令和トレ ンド」や「海外トラベル」などメニュー5つ。だが選べるのは昭和のみ。 - 例:自宅前に置かれた黄色い木箱は何に使ってた?[1]郵便 受け[2]家庭ゴミの収集[3]牛乳配達[4]幸せの黄色いハン カチ入れ - 設問と回答は上記例を参考に100問生成してほしい。 ・ソースコードは、Githubプライベートにpushする。 ・ubuntuサーバー側で、Githubコードをpullして、コンテナをbuildす る。 ・オブザーバビリティ - コンテナホスト(Infrastructure - container) - APM - DBM - RUM - ログ - 監視アラートは,NginxのURL ・障害トレーニング - DBデータは、5%に正解カラムが空なので正誤判定ができないエ ラーが発生する - APIアプリは、5%で応答時間が2秒を超える(タイムアウトエラーに はならない) - ニックネームは、8文字以下の場合はエラーが発生する(8文字以 上必要であることは表示しない) 以上、設計のための質問があれば確認してほしい。 31行
  8. 02基本設計書.md ## 1. システム概要 ### 1.1 アプリ概要 「フラッシュクイズ」は、昭和レトロをテーマにした4択クイズWebアプリケーションである。プレイヤーはニックネームを入 力し、10問のクイズに回答速度を競いながら挑戦する。スコアは成績ランキングとして保存・表示される。 ###

    1.2 開発目的 ### 1.3 技術スタック | レイヤー | 技術 | バージョン | |---------|------|-----------| | Webサーバー | Nginx | 1.25系(Alpine) | | APIアプリ | Node.js | 20 LTS | | APIフレームワーク | Express | 4.x | | DBサーバー | MySQL | 8.0 | | フロントエンド | HTML5 / CSS3 / JavaScript (ES2022) | - | | UIフレームワーク | Bootstrap | 5.3 | | アイコン | Bootstrap Icons | 1.11 | | アニメーション | p5.js(紙吹雪) | 1.9 | | APM | dd-trace (Datadog) | 5.x | | コンテナ管理 | Docker Compose | v2 | | ソース管理 | GitHub(プライベートリポジトリ) | - | | 本番環境 | Ubuntu Server | 22.04 LTS | ``` [クライアントブラウザ] │ HTTPS :443 ▼ ┌─────────────────────┐ │ nginx コンテナ │ ← 静的ファイル配信 + リバースプロキシ │ (port 443) │ SSL終端(自己署名証明書) └──────────┬──────────┘ │ HTTP :3012 (/api/*) ▼ ┌─────────────────────┐ │ api コンテナ │ ← Node.js / Express │ (port 3012) │ Datadog APM (dd-trace) └──────────┬──────────┘ │ TCP :3306 ▼ ┌─────────────────────┐ │ db コンテナ │ ← MySQL 8.0 │ (port 3306) │ Datadog DBM └─────────────────────┘ ┌─────────────────────┐ │ dd-agent コンテナ │ ← Datadog Agent │ │ Infrastructure / APM / DBM / Log収集 └─────────────────────┘ ``` 画面間データ受け渡しはブラウザの `sessionStorage` を使用する。 ``` ┌──────────────────────────────────┐ │ フラッシュクイズ │ ← h1 │ 〜昭和レトロの想い出〜 │ ← サブタイトル │ │ │ ニックネーム: [____________] │ ← input[text] │ │ │ [スタート] │ ← button(初期disabled) │ │ │ ── 成績ランキング ── │ │ 1位 yamamoto123 10問 12,500ms │ │ 2位 hanako2024 9問 14,200ms │ │ ... │ └──────────────────────────────────┘ ``` - ニックネーム入力欄が空の場合、スタートボタンは `disabled` - 文字入力のたびに `input` イベントでボタン有効化チェック - **8文字未満の場合はAPIでエラーが発生するが、エラーメッセージは画面に表示しない(障害トレーニング仕 様)** - ページ下部に全ジャンル共通のランキング上位10件を表示 #### 3.4.2 ジャンル選択画面(genre.html) - 「昭和レトロの想い出」以外のカードはクリックしても遷移しない(`pointer-events: none`) - 将来の拡張を想定した表示のみのダミーメニュー #### 3.4.3 カウントダウン画面(countdown.html) - APIへの `/api/quizzes/:genreId` リクエストはこの画面でバックグラウンド実行 - カウントダウン中に10問のデータを取得してsessionStorageに保存 - 5秒後に自動でquiz.htmlへ遷移 #### 3.4.4 設問・回答画面(quiz.html) ┌──────────────────────────────────┐ │ 問題 3 / 10 3.2s │ ← 問題番号 + 回答時間 │ │ │ 自宅前に置かれた黄色い木箱は │ │ 何に使ってた? │ │ │ │ [1] 郵便受け │ ← Bootstrap btn │ [2] 家庭ゴミの収集 │ │ [3] 牛乳配達 │ │ [4] 幸せの黄色いハンカチ入れ │ │ │ │ ──── 回答後 ──── │ │ 正解!「牛乳配達」 │ ← 5秒間表示 │ 次の問題まで... [== ] 3秒 │ ← カウントダウンバー └──────────────────────────────────┘ ``` - 選択肢ボタンをクリックした時刻から回答時間を計測(問題表示時刻との差) - 回答後、全ボタンを `disabled` にして正誤表示 - 正解ボタンを緑(`btn-success`)、誤答ボタンを赤(`btn-danger`)でハイライト - 5秒のプログレスバーカウントダウンと同時に次の問題へ自動進行 - 10問完了後、result.htmlへ遷移 #### 3.4.5 結果・ランキング画面(result.html) ``` ┌──────────────────────────────────┐ │ 結果発表! │ │ │ │ yamamoto123 さんの成績 │ │ 正解数:8 / 10 │ │ 合計回答時間:23,450 ms │ │ │ │ ── ランキング ── │ │ 1位 yamamoto123 8問 23,450ms│ ← 自分ならハイライト │ 2位 hanako2024 7問 28,100ms│ │ 3位 taro_showa 7問 31,200ms│ │ 4位 quiz_master 6問 19,800ms│ │ ...(10位まで) │ │ │ │ [もう一度] │ └──────────────────────────────────┘ ※ Top3の場合: p5.jsで紙吹雪アニメーション(全画面オーバーレイ) ``` - ランキング表示は同ジャンルの全プレイヤースコアを正解数降順・合計時間昇順でソート - 自分のスコアは `/api/scores` でPOST後、`/api/rankings/:genreId` でGET - Top3の場合、p5.jsによる紙吹雪を3秒間表示してから「もう一度」ボタンを表示 --- ## 4. API設計 ### 4.1 エンドポイント一覧 | Method | パス | 説明 | |--------|------|------| | GET | /api/health | ヘルスチェック | | GET | /api/genres | ジャンル一覧取得 | | GET | /api/quizzes/:genreId | クイズ10問ランダム取得 | | POST | /api/scores | スコア保存 | | GET | /api/rankings/:genreId | ランキング取得(上位10件) | ベースURL:`https://<ホスト名>/api` 共通レスポンスヘッダー:`Content-Type: application/json` ### 4.2 ヘルスチェック **GET /api/health** ```json 859行
  9. 実装フェーズ フェーズ1:インフラファイル作成(docker-compose.yml, .env.example, .gitignore) フェーズ2:Nginx設定(Dockerfile, nginx.conf) フェーズ3:DB初期化SQL(01_schema.sql, 02_seed.sql) フェーズ4:Node.js API(app.js,

    routes, db接続) フェーズ5:フロントエンド(HTML×5, CSS×1, JS×7) フラッシュクイズ(コンテナ)/ ├── docker-compose.yml ← 3コンテナ + dd-agentはprofile:monitoring ├── .env.example ├── .gitignore ├── nginx/ │ ├── Dockerfile ← ビルド時に自己署名SSL証明書を自動生成 │ └── nginx.conf ← HTTPS:443、JSONアクセスログ、/api/リバースプロキシ ├── db/init/ │ ├── 01_schema.sql ← genres/quizzes/scoresテーブル │ └── 02_seed.sql ← ジャンル5件 + クイズ10問(Q5はNULL障害) ├── api/ │ ├── Dockerfile │ ├── package.json ← express, mysql2, dd-trace │ └── src/ │ ├── app.js ← dd-trace.init()→Expressルート登録 │ ├── logger.js ← JSON形式ログ出力 │ ├── db/connection.js ← mysql2プール │ └── routes/ ← health/genres/quizzes/scores/rankings └── public/ ├── index.html / genre.html / countdown.html / quiz.html / result.html ├── css/style.css ← 昭和レトロ風ダークテーマ └── js/ ← common.js + 各画面JS [+] up 6/7 Image flash-quiz-nginx Built 13.2s Image flash-quiz-api Built 13.2s Network flash-quiz_default Created 0.1s Volume flash-quiz_db_data Created 0.0s Container flash-quiz-db-1 Healthy 10.7s Container flash-quiz-api-1 Started 10.9s ⠼ Container flash-quiz-nginx-1 Starting 11.2s Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint flash-quiz-nginx-1 (7ed66e7dc5d78bc288bcf2e7028054556782fa21ed560734631014b0a29b1b4b) : failed to bind host port 0.0.0.0:80/tcp: address already in use kano@ome:~/flash-quiz$
  10. コードデプロイ GitHub Ubuntuホスト Windows PC <//// ////> <//// ////> <////

    ////> Windows PC でコーディングし、Github経由で、サーバーにデプロイ VS Code (Claude code) IBM Bob IDE
  11. 02基本設計書.md の作成 # フラッシュクイズ - 基本設計書 ## 1. システムアーキテクチャ ###

    1.1 全体構成 ```mermaid graph TB subgraph "Docker Environment" Client[ブラウザ] -->|HTTPS:443| Nginx[Nginx Container] Nginx -->|Proxy| API[Node.js API Container:3012] API -->|SQL| DB[MySQL Container:3306] end subgraph "Datadog Monitoring" API -->|APM Traces| DD[Datadog Agent] Client -->|RUM| DD Nginx -->|Logs| DD DB -->|DBM| DD Docker[Container Metrics] -->|Infrastructure| DD end ``` ### 1.2 コンテナ構成 | コンテナ名 | ベースイメージ | ポート | 役割 | |-----------|--------------|--------|------| | nginx | nginx:alpine | 443 | Webサーバー、リバースプロキシ | | api | node:18-alpine | 3012 | APIサーバー(Express) | | mysql | mysql:8.0 | 3306 | データベースサーバー | ### 1.3 技術スタック **フロントエンド:** - HTML5/CSS3/JavaScript(ES6+) - p5.js(紙吹雪エフェクト) - Datadog RUM **バックエンド:** - Node.js 18 - Express.js - MySQL2(Node.js MySQL driver) - dd-trace(Datadog APM) **インフラ:** - Docker & Docker Compose - Nginx(リバースプロキシ、静的ファイル配信) - MySQL 8.0 - #### QUIZZES(クイズ設問) - | カラム名 | 型 | NULL | キー | 説明 | - |---------|-----|------|------|------| - | id | INT | NO | PK | クイズID | - | category_id | INT | NO | FK | カテゴリID | - | question | TEXT | NO | | 設問文 | - | correct_answer | INT | YES | | 正解番号(1-4)※5%はNULL | - | created_at | DATETIME | NO | | 作成日時 | - **障害トレーニング:** 5%のレコードで`correct_answer`がNULLになる - #### QUIZ_OPTIONS(回答選択肢) - | カラム名 | 型 | NULL | キー | 説明 | - |---------|-----|------|------|------| - | id | INT | NO | PK | 選択肢ID | - | quiz_id | INT | NO | FK | クイズID | - | option_number | INT | NO | | 選択肢番号(1-4) | - | option_text | VARCHAR(200) | NO | | 選択肢テキスト | - | created_at | DATETIME | NO | | 作成日時 | - #### SCORES(成績) - | カラム名 | 型 | NULL | キー | 説明 | - |---------|-----|------|------|------| - | id | INT | NO | PK | 成績ID | - | nickname | VARCHAR(50) | NO | | ニックネーム | - | category_id | INT | NO | FK | カテゴリID | - | total_correct | INT | NO | | 正解数 | - | total_time_ms | INT | NO | | 合計回答時間(ミリ秒) | - | created_at | DATETIME | NO | IDX | 作成日時 | - **障害トレーニング:** ニックネームが8文字未満の場合、APIでエラーを発生させる - #### SCORE_DETAILS(成績詳細) - | カラム名 | 型 | NULL | キー | 説明 | - |---------|-----|------|------|------| - | id | INT | NO | PK | 詳細ID | - | score_id | INT | NO | FK | 成績ID | - | quiz_id | INT | NO | FK | クイズID | - | selected_answer | INT | NO | | 選択した回答番号 | - | is_correct | BOOLEAN | NO | | 正誤フラグ | - | response_time_ms | INT | NO | | 回答時間(ミリ秒) | - | created_at | DATETIME | NO | | 作成日時 | - ### 2.3 インデックス設計 - ```sql - -- QUIZZES - CREATE INDEX idx_category_id ON QUIZZES(category_id); - -- QUIZ_OPTIONS - CREATE INDEX idx_quiz_id ON QUIZ_OPTIONS(quiz_id); - -- SCORES - CREATE INDEX idx_created_at ON SCORES(created_at DESC); - CREATE INDEX idx_category_ranking ON SCORES(category_id, total_correct DESC, total_time_ms ASC); - -- SCORE_DETAILS - CREATE INDEX idx_score_id ON SCORE_DETAILS(score_id); - ``` - ## 7. デプロイメント設計 - ### 7.1 ディレクトリ構造 - ``` - flash-quiz/ - ├── docker-compose.yml - ├── .env.example - ├── README.md - ├── docs/ - │ ├── 01要件定義.md - │ ├── 02基本設計.md - │ └── datadog-setup.md - ├── nginx/ - │ ├── Dockerfile - │ ├── nginx.conf - │ └── ssl/ - │ ├── cert.pem - │ └── key.pem - ├── frontend/ - │ ├── index.html - │ ├── css/ - │ │ └── style.css - │ ├── js/ - │ │ ├── app.js - │ │ ├── quiz.js - │ │ └── confetti.js - │ └── assets/ - │ └── images/ - ├── api/ - │ ├── Dockerfile - │ ├── package.json - │ ├── package-lock.json - │ ├── src/ - │ │ ├── index.js - │ │ ├── config/ - │ │ │ ├── database.js - │ │ │ └── datadog.js - │ │ ├── routes/ 703行 Claude code : 859行
  12. アプリ完成(成果物一覧) 完成した主要コンポーネント 設計ドキュメント • 02基本設計.md - 完全なシステム設計書(738行) • docs/datadog-setup.md -

    Datadog監視設定ガイド データベース(MySQL) mysql/init/01-schema.sql - テーブル定義 mysql/init/02-categories.sql - カテゴリデータ mysql/init/03-quizzes-part1.sql - 昭和レトロクイズ100問 mysql/init/04-quiz-options-part1.sql - 選択肢データ(Q1-50) mysql/init/05-quiz-options-part2.sql - 選択肢データ(Q51-100) APIサーバー(Node.js + Express) • Datadog APM統合済み • 障害トレーニング機能実装済み(5%遅延、DB不整合、ニックネームエラー) • 全エンドポイント実装完了 フロントエンド • frontend/index.html - メインHTML • frontend/css/style.css - レスポンシブデザイン • frontend/js/app.js - アプリケーションロジック • frontend/js/quiz.js - クイズ管理 • frontend/js/confetti.js - 紙吹雪エフェクト • Datadog RUM統合済み Docker構成 • docker-compose.yml - 3コンテナ構成 • 各コンテナのDockerfile完備 • ヘルスチェック設定済み ドキュメント • README.md - セットアップガイド、API仕様 • .env.example - 環境変数テンプレート 起動方法 実装済み機能 • 完全なクイズシステム(100問) • ランキング機能 • Datadog完全統合(APM、DBM、RUM、Logs) • 障害トレーニング機能 • レスポンシブデザイン • HTTPS対応
  13. 実際に使ってみての比較(Claude Code vs. IBM Bob) 設計フェーズ • Claude:文章生成、設計書が美しい • Bob:アーキテクチャの整合性が高い

    3rd Party 連携(Datadog) • Claude/Copilot:初期設定/変更も可 • Bob:同じくらい初期設定/変更も可 インフラ連携 • Claude/Bob:コンテナなので同じ 実装フェーズ • Copilot:細かい修正に強い • Bob:プロジェクト全体を俯瞰した生成 まとめ • Claude Code:設計と一括開発に強い • Copilot:ステップ毎の修正に強い • Bob:プロジェクト全体の駆動に強い 1 2 3 4
  14. 成果:オブザーバビリティ研修の教材 Datadogでの可視化 • APM • DBM • RUM • Logs

    • Infrastructure → すべてが一つのアプリで体験できる 障害トレーニングが成立 • DBの正解NULL問題 • APIの遅延 • ニックネームのバリデーションエラー → Datadogで原因を追える 教育コンテンツとしての価値 • “教材”が完成 • 新人教育ワークショップに活用できた
  15. 次のステップ:IBM Cloud へデプロイ IBM Cloud で動かす • コンテナ駆動なので IBM Cloud

    - Code Engine どうせなら他のサービスも • IBM Cloud - Functions • IBM Cloud - DB2 • IBM Cloud - Cloudant 今回の気づき • アプリ開発がゴールじゃない • 目的をAIで時短化できる/爆速 どんな所が時短化するのか • 学習コストを大幅カット – 学習時間が不要 – 知識不足を補ってくれる – 検査時間が不要
  16. まとめ ✓ 目的:アプリ開発ではなく、オブザーバビリティ教育の準備 ✓ 効果:生成AIを使うことで、設計〜実装〜検証が圧倒的に時短 ✓ 気づき:Claude / Copilot /

    IBM Bob は役割・使い分けがよい ✓ Bob:“計画から実装・検査まで”一気通貫で進められるのが強み • Datadogと組み合わせて“動く教材”が短期間で完成 • AI駆動開発は、教育コンテンツ作りにも大きな価値がある