Gemini CLI 使いどころマップ:自動化・解析・生成を横断するユースケース 30
AI を活用した開発ワークフローが当たり前になりつつある今、コマンドラインから直接 AI モデルにアクセスできる「Gemini CLI」が注目を集めています。ブラウザを開かずにターミナル上で完結できる開発体験は、一度使うと手放せない便利さです。
本記事では、Gemini CLI の具体的な使いどころを「自動化」「解析」「生成」の 3 つの軸で整理し、30 のユースケースをマップ化してご紹介します。日々の開発業務で「こんなときに使える」という実践的な活用シーンを、図解とサンプルコードを交えながら解説していきますね。
背景
Gemini CLI とは
Gemini CLI は、Google が提供する Gemini API をコマンドラインから操作できる公式ツールです。2024 年にリリースされて以来、開発者の間で急速に普及しています。
typescript// Gemini CLIの基本的な呼び出し
import { execSync } from 'child_process';
const result = execSync(
'gemini "コードレビューをお願いします"',
{
encoding: 'utf-8',
}
);
console.log(result);
このコードは、シェルから Gemini CLI を呼び出し、結果を取得する基本パターンです。execSyncを使うことで、Node.js スクリプト内から CLI ツールを同期的に実行できます。
CLI ツールが開発フローに与える影響
従来の AI 活用では、ブラウザを開いてチャット画面にアクセスする必要がありました。しかし、CLI ツールを使うことで、開発フローを中断せずに AI の力を借りられるようになったのです。
以下の図は、従来のワークフローと CLI ベースのワークフローを比較したものです。
mermaidflowchart LR
dev["開発者"] -->|コード編集| editor["エディタ"]
editor -->|疑問発生| browser["ブラウザ起動"]
browser -->|AI質問| chatui["チャットUI"]
chatui -->|回答確認| browser
browser -->|戻る| editor
dev2["開発者"] -->|コード編集| editor2["エディタ"]
editor2 -->|疑問発生| terminal["ターミナル"]
terminal -->|gemini コマンド| api["Gemini API"]
api -->|即座に回答| terminal
terminal -->|継続作業| editor2
subgraph traditional["従来のフロー"]
dev
editor
browser
chatui
end
subgraph cli_flow["CLIベースのフロー"]
dev2
editor2
terminal
api
end
この図から、CLI ベースのワークフローでは画面遷移が不要となり、開発の集中力を保ったまま AI を活用できることがわかります。コンテキストスイッチが減少することで、作業効率が大幅に向上するのです。
なぜ今「使いどころマップ」が必要なのか
Gemini CLI は強力なツールですが、「どんな場面で使えるのか」が明確でないと宝の持ち腐れになってしまいます。実際、導入したものの活用しきれていない開発者も多いのではないでしょうか。
そこで本記事では、実務で即活用できる 30 のユースケースを体系的に整理しました。自動化・解析・生成という 3 つの切り口から、あなたの開発シーンに合った使い方が見つかるはずです。
課題
従来の AI 活用における課題
開発現場で AI を活用しようとすると、いくつかの壁に直面します。
mermaidflowchart TD
start["AI活用の検討"] --> issue1["課題1:<br/>コンテキスト<br/>スイッチ"]
start --> issue2["課題2:<br/>自動化の<br/>困難さ"]
start --> issue3["課題3:<br/>バッチ処理<br/>非対応"]
issue1 -->|影響| result1["集中力の<br/>低下"]
issue2 -->|影響| result2["手動作業<br/>増加"]
issue3 -->|影響| result3["大量ファイル<br/>処理困難"]
result1 --> problem["生産性の<br/>ボトルネック"]
result2 --> problem
result3 --> problem
この図が示すように、従来の AI 活用には 3 つの主要な課題がありました。それぞれ詳しく見ていきましょう。
課題 1:コンテキストスイッチの多さ
エディタでコードを書いている最中に疑問が生じたとき、ブラウザを開いてチャット UI にアクセスする必要があります。この画面遷移が集中力を削ぐのです。
javascript// 例:エラーメッセージの意味を調べたいとき
// 従来の方法
// 1. エラーメッセージをコピー
// 2. ブラウザを開く
// 3. チャットUIにペースト
// 4. 回答を待つ
// 5. エディタに戻る
このコメントは、従来の手順がいかに煩雑かを示しています。開発者は 1 つの疑問を解決するために、5 つものステップを踏まなければなりませんでした。
課題 2:自動化への組み込みが困難
ブラウザベースの UI は、CI/CD パイプラインやスクリプトに組み込むことができません。人間が手動で操作する前提の設計だからです。
yaml# CI/CDパイプラインの例(従来は不可能)
# .github/workflows/review.yml
name: AI Code Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# ここでAIレビューを自動化したいが、UIベースでは不可能
この設定ファイルは、GitHubActions でのワークフロー定義です。従来の UI ベースツールでは、このような自動化が実現できませんでした。
課題 3:バッチ処理への非対応
複数のファイルを一括で処理したい場合、UI ベースでは 1 つずつ手動でアップロードする必要があります。100 個のファイルをレビューしたい場合、100 回の操作が必要になるのです。
| # | 課題 | 影響 | 具体例 |
|---|---|---|---|
| 1 | コンテキストスイッチ | 集中力低下 | コーディング中に画面切り替え |
| 2 | 自動化困難 | 手動作業増加 | CI/CD への組み込み不可 |
| 3 | バッチ処理非対応 | 大量処理困難 | 100 ファイルのレビューに 100 回操作 |
この表は、3 つの課題とその影響を整理したものです。どの課題も開発者の生産性を大きく損なう要因となっていました。
Gemini CLI が解決するポイント
これらの課題に対して、Gemini CLI は明確な解決策を提供します。
typescript// Gemini CLIによる解決例
// 1. コンテキストスイッチの解消
const quickAnswer = execSync(
'gemini "TypeErrorの原因は?"',
{
encoding: 'utf-8',
}
);
// 2. 自動化への組み込み
const autoReview = execSync(
'gemini "このPRをレビューして" < changes.diff',
{
encoding: 'utf-8',
}
);
// 3. バッチ処理の実現
const files = ['file1.ts', 'file2.ts', 'file3.ts'];
files.forEach((file) => {
const review = execSync(
`gemini "レビューして" < ${file}`,
{
encoding: 'utf-8',
}
);
console.log(`${file}: ${review}`);
});
このコードは、Gemini CLI がどのように 3 つの課題を解決するかを示しています。ターミナル上で完結するため、画面遷移が不要で、スクリプトにも組み込め、ループ処理も簡単に実現できるのです。
解決策
Gemini CLI の導入手順
まずは、Gemini CLI をセットアップしましょう。以下の手順で、すぐに使い始められます。
ステップ 1:API キーの取得
Google AI Studio から API キーを取得します。
bash# ブラウザでGoogle AI Studioにアクセス
# https://makersuite.google.com/app/apikey
# 新しいAPIキーを作成してコピー
このコメントは、API キー取得の流れを示しています。無料枠でも十分に活用できるので、まずは試してみることをお勧めします。
ステップ 2:CLI ツールのインストール
Yarn を使って Gemini CLI をインストールします。
bash# グローバルインストール
yarn global add @google/generative-ai-cli
# または、プロジェクトごとにインストール
yarn add -D @google/generative-ai-cli
このコマンドは、Gemini CLI をシステム全体またはプロジェクト単位でインストールする方法です。開発環境に応じて選択してください。
ステップ 3:環境変数の設定
取得した API キーを環境変数に設定します。
bash# .bashrc または .zshrc に追加
export GEMINI_API_KEY="your-api-key-here"
# 設定を反映
source ~/.bashrc
# または
source ~/.zshrc
この設定により、毎回 API キーを指定する必要がなくなります。セキュリティのため、.envファイルには含めず環境変数として管理することが推奨されます。
ステップ 4:動作確認
インストールが完了したら、動作を確認しましょう。
bash# シンプルな質問で確認
gemini "Hello, Gemini!"
# ファイル入力のテスト
echo "console.log('test');" | gemini "このコードを説明して"
これらのコマンドで正常に応答が返ってくれば、セットアップは完了です。
3 つの活用軸:自動化・解析・生成
Gemini CLI の使いどころは、大きく 3 つの軸で整理できます。
mermaidflowchart TB
gemini["Gemini CLI"] --> axis1["自動化<br/>(Automation)"]
gemini --> axis2["解析<br/>(Analysis)"]
gemini --> axis3["生成<br/>(Generation)"]
axis1 --> auto1["CI/CD統合"]
axis1 --> auto2["定期実行タスク"]
axis1 --> auto3["フック処理"]
axis2 --> ana1["コード品質チェック"]
axis2 --> ana2["ログ分析"]
axis2 --> ana3["依存関係調査"]
axis3 --> gen1["ドキュメント生成"]
axis3 --> gen2["テストコード作成"]
axis3 --> gen3["ボイラープレート"]
この図は、Gemini CLI の 3 つの活用軸とその代表的なユースケースを示しています。それぞれの軸で 10 個ずつ、合計 30 のユースケースを次のセクションで詳しく解説していきます。
具体例
カテゴリ 1:自動化(Automation)の 10 ユースケース
自動化の軸では、開発ワークフローに Gemini CLI を組み込むことで、手動作業を削減します。
ユースケース 1:PR の自動レビュー
プルリクエストが作成されたときに、自動でコードレビューを実行します。
yaml# .github/workflows/ai-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
このワークフロー定義は、PR の作成・更新時にトリガーされます。fetch-depth: 0により、全履歴を取得して差分を正確に抽出できます。
yaml- name: Get PR diff
id: diff
run: |
git diff origin/${{ github.base_ref }}...HEAD > pr_diff.txt
このステップでは、ベースブランチとの差分を取得してファイルに保存します。この差分ファイルを Gemini CLI に渡すことで、変更内容をレビューさせられます。
yaml- name: AI Review
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
run: |
yarn global add @google/generative-ai-cli
gemini "以下の変更をレビューしてください" < pr_diff.txt > review.md
この部分が実際の AI レビュー実行です。環境変数で API キーを渡し、差分ファイルを入力として与えています。
yaml- name: Comment PR
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## AI Code Review\n\n${review}`
});
最後に、レビュー結果を PR にコメントとして投稿します。これにより、レビュー内容が開発者に即座に通知されます。
ユースケース 2:コミット前のリント強化
Git フックを使って、コミット前に自動でコード品質チェックを実行します。
bash# .git/hooks/pre-commit
#!/bin/bash
# ステージングされたファイルを取得
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.ts$\|\.tsx$')
このスクリプトは、ステージングされた TypeScript ファイルのみを抽出します。--diff-filter=ACMにより、追加・変更・移動されたファイルだけを対象とします。
bashif [ -n "$STAGED_FILES" ]; then
echo "🤖 AI品質チェックを実行中..."
for FILE in $STAGED_FILES; do
# ファイルごとにAIチェック
RESULT=$(gemini "このコードの問題点を指摘してください" < "$FILE")
# 警告があればコミットを停止
if echo "$RESULT" | grep -i "warning\|error\|問題"; then
echo "❌ $FILE に問題が検出されました:"
echo "$RESULT"
exit 1
fi
done
echo "✅ すべてのファイルが品質チェックを通過しました"
fi
このループ処理では、各ファイルに対して AI チェックを実行し、問題が見つかった場合はコミットを中断します。これにより、品質の低いコードがリポジトリに混入するのを防げます。
ユースケース 3:定期的なセキュリティスキャン
cron や GitHub Actions のスケジュール機能を使って、定期的にセキュリティチェックを実行します。
yaml# .github/workflows/security-scan.yml
name: Weekly Security Scan
on:
schedule:
# 毎週月曜日の午前9時(UTC)に実行
- cron: '0 9 * * 1'
workflow_dispatch: # 手動実行も可能に
このスケジュール設定により、毎週自動でセキュリティスキャンが実行されます。workflow_dispatchを追加することで、必要に応じて手動実行もできます。
yamljobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Scan dependencies
run: |
yarn audit --json > audit.json
依存パッケージの脆弱性情報を取得します。JSON 形式で出力することで、次のステップでパースしやすくなります。
yaml- name: AI Analysis
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
run: |
yarn global add @google/generative-ai-cli
gemini "以下のセキュリティ監査結果を分析し、優先度順に対応策を提案してください" < audit.json > security-report.md
AI が監査結果を分析し、優先度付きの対応策を提案します。これにより、どの脆弱性から対応すべきかが明確になるのです。
yaml- name: Create Issue
if: failure() || success()
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('security-report.md', 'utf8');
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `週次セキュリティレポート ${new Date().toISOString().split('T')[0]}`,
body: report,
labels: ['security', 'automated']
});
分析結果を自動で issue として作成します。これにより、チーム全体でセキュリティ状況を共有できます。
ユースケース 4:デプロイ前の互換性チェック
本番デプロイ前に、API の後方互換性を自動チェックします。
typescript// scripts/compatibility-check.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
interface CompatibilityResult {
compatible: boolean;
issues: string[];
recommendations: string[];
}
この型定義は、互換性チェックの結果構造を表します。compatibleフラグで互換性の有無を判定し、issuesで問題点、recommendationsで推奨対応を格納します。
typescriptasync function checkCompatibility(): Promise<CompatibilityResult> {
// 現在のAPIスキーマ
const currentSchema = readFileSync('api/schema/current.json', 'utf-8');
// 前バージョンのスキーマ
const previousSchema = readFileSync('api/schema/previous.json', 'utf-8');
2 つのスキーマファイルを読み込みます。デプロイ時には、これらのファイルをバージョン管理システムから取得することになります。
typescript// AIによる互換性分析
const prompt = `
以下の2つのAPIスキーマを比較し、後方互換性を評価してください。
JSON形式で結果を返してください。
現在のスキーマ:
${currentSchema}
前バージョンのスキーマ:
${previousSchema}
出力形式:
{
"compatible": true/false,
"issues": ["問題点1", "問題点2"],
"recommendations": ["推奨対応1", "推奨対応2"]
}
`;
このプロンプトでは、AI に対して明確な出力形式を指示しています。構造化された出力を求めることで、後続処理でのパースが容易になります。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
maxBuffer: 10 * 1024 * 1024 // 10MB
});
return JSON.parse(result) as CompatibilityResult;
}
maxBufferオプションを指定することで、大きなスキーマファイルにも対応できます。デフォルトの 1MB では不足する場合があるためです。
typescript// メイン処理
checkCompatibility()
.then((result) => {
console.log('互換性チェック結果:', result);
if (!result.compatible) {
console.error('⚠️ 後方互換性の問題が検出されました');
result.issues.forEach((issue) =>
console.error(` - ${issue}`)
);
process.exit(1);
}
console.log('✅ 後方互換性が確認されました');
})
.catch((error) => {
console.error('チェック実行エラー:', error);
process.exit(1);
});
互換性がない場合は、エラーコード 1 で終了します。これにより、CI/CD パイプラインでデプロイを自動的に停止できます。
ユースケース 5:ドキュメントの自動更新
コードの変更に応じて、関連ドキュメントを自動更新します。
typescript// scripts/update-docs.ts
import { execSync } from 'child_process';
import {
readFileSync,
writeFileSync,
readdirSync,
} from 'fs';
import { join } from 'path';
const sourceDir = 'src';
const docsDir = 'docs/api';
ソースコードディレクトリとドキュメントディレクトリのパスを定義します。プロジェクト構造に応じて調整してください。
typescriptfunction extractFunctions(filePath: string): string[] {
const content = readFileSync(filePath, 'utf-8');
// エクスポートされた関数を抽出(簡易版)
const functionPattern =
/export\s+(async\s+)?function\s+(\w+)/g;
const matches = content.matchAll(functionPattern);
return Array.from(matches).map((match) => match[2]);
}
この関数は、ファイルからエクスポートされた関数名を抽出します。正規表現を使った簡易版ですが、実際のプロジェクトでは AST パーサーを使うとより正確です。
typescriptfunction generateDocumentation(filePath: string): void {
const code = readFileSync(filePath, 'utf-8');
const functions = extractFunctions(filePath);
if (functions.length === 0) {
return; // 関数がなければスキップ
}
ドキュメント化する関数が存在しない場合は、処理をスキップします。これにより、不要な API 呼び出しを削減できます。
typescriptconst prompt = `
以下のTypeScriptコードのドキュメントを生成してください。
各関数について、以下を含めてください:
- 概要
- パラメータの説明
- 戻り値の説明
- 使用例
コード:
${code}
`;
const documentation = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
});
AI にドキュメント生成を依頼します。プロンプトで明確な構造を指示することで、一貫性のあるドキュメントが生成されます。
typescript // ドキュメントファイルを保存
const docFileName = filePath
.replace(sourceDir, docsDir)
.replace('.ts', '.md');
writeFileSync(docFileName, documentation, 'utf-8');
console.log(`✅ ドキュメント生成完了: ${docFileName}`);
}
生成されたドキュメントを、ソースファイルに対応するパスで保存します。.tsを.mdに置換することで、ファイル構造を維持できます。
typescript// すべてのTSファイルを処理
function processAllFiles(dir: string): void {
const files = readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = join(dir, file.name);
if (file.isDirectory()) {
processAllFiles(fullPath); // 再帰的に処理
} else if (file.name.endsWith('.ts')) {
generateDocumentation(fullPath);
}
}
}
processAllFiles(sourceDir);
ディレクトリを再帰的に走査し、すべての TypeScript ファイルに対してドキュメントを生成します。大規模プロジェクトでは、並列処理を検討するとよいでしょう。
ユースケース 6:エラーログの自動トリアージ
本番環境のエラーログを定期的に分析し、優先度付けします。
typescript// scripts/error-triage.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface ErrorSummary {
severity: 'critical' | 'high' | 'medium' | 'low';
category: string;
count: number;
message: string;
recommendation: string;
}
エラーサマリーの構造を定義します。重要度、カテゴリ、発生回数などを含めることで、効果的なトリアージが可能になります。
typescriptasync function analyzeErrors(logFilePath: string): Promise<ErrorSummary[]> {
const logs = readFileSync(logFilePath, 'utf-8');
const prompt = `
以下のエラーログを分析し、以下の形式でJSON配列として返してください:
[
{
"severity": "critical/high/medium/low",
"category": "エラーカテゴリ",
"count": 発生回数,
"message": "エラーメッセージの要約",
"recommendation": "推奨対応"
}
]
重要度の基準:
- critical: システムダウンや大規模なデータ損失
- high: 主要機能の停止
- medium: 一部機能の不具合
- low: 軽微な問題
ログ:
${logs}
`;
このプロンプトでは、重要度の判断基準を明示しています。AI に基準を与えることで、一貫性のある評価が得られます。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
maxBuffer: 50 * 1024 * 1024 // 50MB(ログファイルは大きくなりがち)
});
return JSON.parse(result) as ErrorSummary[];
}
ログファイルは非常に大きくなる可能性があるため、maxBufferを大きめに設定しています。必要に応じて調整してください。
typescript// 分析結果を優先度順に表示
analyzeErrors('logs/production.log').then((summaries) => {
// 重要度順にソート
const sorted = summaries.sort((a, b) => {
const severityOrder = {
critical: 0,
high: 1,
medium: 2,
low: 3,
};
return (
severityOrder[a.severity] - severityOrder[b.severity]
);
});
console.log('📊 エラーログ分析結果\n');
sorted.forEach((summary, index) => {
console.log(
`${index + 1}. [${summary.severity.toUpperCase()}] ${
summary.category
}`
);
console.log(` 発生回数: ${summary.count}`);
console.log(` メッセージ: ${summary.message}`);
console.log(` 推奨対応: ${summary.recommendation}\n`);
});
});
分析結果を視覚的にわかりやすく表示します。重要度順にソートすることで、対応すべき順序が明確になります。
ユースケース 7:パフォーマンスレポートの自動生成
Lighthouse などの計測結果を AI が分析し、改善提案をレポートします。
bash# scripts/performance-report.sh
#!/bin/bash
# Lighthouseでパフォーマンス計測
lighthouse https://your-app.com \
--output json \
--output-path ./lighthouse-report.json \
--chrome-flags="--headless"
このコマンドは、対象 URL のパフォーマンスを計測して JSON 形式で保存します。ヘッドレスモードで実行するため、CI 環境でも動作します。
bash# AIによる分析
gemini "以下のLighthouseレポートを分析し、パフォーマンス改善の具体的な施策を優先度順に提案してください。各施策について、期待される効果とKPIを含めてください。" < lighthouse-report.json > performance-recommendations.md
Lighthouse の生データを AI が解釈し、具体的なアクションプランに変換します。技術的な指標を開発者にもわかりやすい言葉で説明してくれるのが利点です。
bash# Slackに通知
curl -X POST $SLACK_WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"📈 パフォーマンスレポートが生成されました\",
\"attachments\": [{
\"text\": \"$(cat performance-recommendations.md)\"
}]
}"
分析結果を Slack に自動投稿することで、チーム全体に即座に共有できます。定期実行と組み合わせることで、継続的なパフォーマンス監視が実現します。
ユースケース 8:依存関係の更新提案
package.json の依存関係を分析し、安全な更新プランを提案します。
typescript// scripts/dependency-update.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface UpdatePlan {
package: string;
currentVersion: string;
latestVersion: string;
updateType: 'major' | 'minor' | 'patch';
breakingChanges: string[];
recommendation: 'safe' | 'caution' | 'risky';
}
更新プランの構造を定義します。バージョンタイプや破壊的変更の情報を含めることで、安全性を評価できます。
typescriptasync function analyzeUpdates(): Promise<UpdatePlan[]> {
// 古いパッケージをチェック
const outdated = execSync('yarn outdated --json', {
encoding: 'utf-8'
});
yarn outdatedコマンドで、更新可能なパッケージの一覧を取得します。JSON 形式で出力することで、プログラムから扱いやすくなります。
typescript// package.jsonとchangelogを読み込み
const packageJson = readFileSync('package.json', 'utf-8');
const prompt = `
以下の情報をもとに、依存関係の更新計画を立ててください:
1. 現在のpackage.json:
${packageJson}
2. 更新可能なパッケージ:
${outdated}
各パッケージについて、以下の形式でJSON配列を返してください:
{
"package": "パッケージ名",
"currentVersion": "現在のバージョン",
"latestVersion": "最新バージョン",
"updateType": "major/minor/patch",
"breakingChanges": ["破壊的変更のリスト"],
"recommendation": "safe/caution/risky"
}
`;
このプロンプトでは、現在の依存関係と更新候補の両方をコンテキストとして提供しています。これにより、AI はプロジェクト固有の状況を考慮した提案ができます。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
return JSON.parse(result) as UpdatePlan[];
}
// 実行
analyzeUpdates().then(plans => {
console.log('📦 依存関係更新プラン\n');
plans.forEach(plan => {
const emoji = {
safe: '✅',
caution: '⚠️',
risky: '❌'
}[plan.recommendation];
console.log(`${emoji} ${plan.package}: ${plan.currentVersion} → ${plan.latestVersion}`);
console.log(` 更新タイプ: ${plan.updateType}`);
if (plan.breakingChanges.length > 0) {
console.log(` 破壊的変更:`);
plan.breakingChanges.forEach(change => {
console.log(` - ${change}`);
});
}
console.log();
});
});
更新プランを視覚的にわかりやすく表示します。絵文字で安全性を示すことで、一目で判断できるようにしています。
ユースケース 9:コードカバレッジレポートの解釈
テストカバレッジの数値だけでなく、どこを優先的にテストすべきかを AI が提案します。
typescript// scripts/coverage-analysis.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface CoveragePriority {
file: string;
currentCoverage: number;
priority: 'high' | 'medium' | 'low';
reason: string;
suggestedTests: string[];
}
カバレッジ優先度の構造です。単なる数値ではなく、理由と具体的なテスト提案を含めることで、実行可能なインサイトを提供します。
typescriptasync function analyzeCoverage(): Promise<CoveragePriority[]> {
// カバレッジレポート生成
execSync('yarn test --coverage --json', {
encoding: 'utf-8'
});
const coverage = readFileSync('coverage/coverage-summary.json', 'utf-8');
const sourceFiles = JSON.parse(coverage);
Jest のカバレッジレポートを生成し、JSON 形式で読み込みます。他のテストフレームワークでも同様のアプローチが可能です。
typescriptconst prompt = `
以下のコードカバレッジレポートを分析し、優先的にテストを追加すべきファイルを特定してください。
考慮すべき要因:
1. カバレッジの低さ
2. ファイルの重要性(認証、決済など)
3. 変更頻度の高さ
4. 複雑度
カバレッジレポート:
${JSON.stringify(sourceFiles, null, 2)}
JSON配列で返してください:
[
{
"file": "ファイルパス",
"currentCoverage": 現在のカバレッジ(%),
"priority": "high/medium/low",
"reason": "優先度の理由",
"suggestedTests": ["追加すべきテストケース1", "テストケース2"]
}
]
`;
このプロンプトでは、単なるカバレッジ数値だけでなく、ビジネスロジックの重要性も考慮するよう指示しています。これにより、より実用的な優先順位付けが可能になります。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
return JSON.parse(result) as CoveragePriority[];
}
// 実行
analyzeCoverage().then(priorities => {
console.log('🎯 テスト追加の優先度\n');
priorities
.sort((a, b) => {
const order = { high: 0, medium: 1, low: 2 };
return order[a.priority] - order[b.priority];
})
.forEach((item, index) => {
console.log(`${index + 1}. [${item.priority.toUpperCase()}] ${item.file}`);
console.log(` 現在のカバレッジ: ${item.currentCoverage}%`);
console.log(` 理由: ${item.reason}`);
console.log(` 推奨テスト:`);
item.suggestedTests.forEach(test => {
console.log(` - ${test}`);
});
console.log();
});
});
分析結果を優先度順に表示し、具体的なテストケースの提案も示します。これにより、すぐにテスト作成に着手できます。
ユースケース 10:リリースノートの自動生成
コミット履歴からリリースノートを自動生成します。
bash# scripts/generate-release-notes.sh
#!/bin/bash
# 前回のタグから現在までのコミットログを取得
PREV_TAG=$(git describe --tags --abbrev=0)
COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"%h %s" --no-merges)
このコマンドは、前回のリリースタグから現在までのコミットを取得します。マージコミットは除外することで、実質的な変更のみを抽出します。
bash# AIでリリースノートを生成
RELEASE_NOTES=$(gemini "以下のコミット履歴から、ユーザー向けのリリースノートを生成してください。
カテゴリ分け(新機能、改善、バグ修正、破壊的変更)をして、各項目は簡潔にまとめてください。
技術的な詳細ではなく、ユーザーにとっての価値を強調してください。
コミット履歴:
$COMMITS")
このプロンプトでは、技術的なコミットメッセージをユーザー向けの言葉に変換するよう指示しています。カテゴリ分けすることで、読みやすいリリースノートになります。
bash# GitHubリリースを作成
gh release create v$(date +%Y%m%d-%H%M%S) \
--title "Release $(date +%Y-%m-%d)" \
--notes "$RELEASE_NOTES"
echo "✅ リリースノートが生成されました"
GitHub CLI を使ってリリースを作成し、生成されたノートを添付します。タイムスタンプをバージョンに使うことで、一意性を保証しています。
カテゴリ 2:解析(Analysis)の 10 ユースケース
解析の軸では、既存のコードやデータを分析し、インサイトを抽出します。
ユースケース 11:技術的負債の可視化
コードベース全体を分析し、技術的負債をスコアリングします。
typescript// scripts/tech-debt-analysis.ts
import { execSync } from 'child_process';
import { readdirSync, readFileSync, statSync } from 'fs';
import { join } from 'path';
interface DebtScore {
file: string;
score: number;
issues: string[];
refactoringPriority: 'high' | 'medium' | 'low';
estimatedHours: number;
}
技術的負債のスコア構造です。単なる評価だけでなく、リファクタリングの優先度と見積もり時間を含めることで、計画が立てやすくなります。
typescriptfunction analyzeFile(filePath: string): DebtScore | null {
const code = readFileSync(filePath, 'utf-8');
const stats = statSync(filePath);
// 大きすぎるファイルはスキップ
if (stats.size > 100000) {
console.log(`⚠️ スキップ(大きすぎる): ${filePath}`);
return null;
}
ファイルサイズが大きすぎる場合は処理をスキップします。API の制限を回避しつつ、効率的に分析を進められます。
typescript const prompt = `
以下のコードの技術的負債を評価してください。
評価基準:
1. コードの複雑度
2. 重複コードの存在
3. 命名の適切さ
4. テスタビリティ
5. 保守性
JSON形式で返してください:
{
"score": 0-100のスコア(100が最悪),
"issues": ["問題点1", "問題点2"],
"refactoringPriority": "high/medium/low",
"estimatedHours": リファクタリング見積もり時間
}
コード:
${code}
`;
try {
const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
timeout: 30000 // 30秒でタイムアウト
});
const analysis = JSON.parse(result);
return {
file: filePath,
...analysis
};
} catch (error) {
console.error(`エラー: ${filePath}`, error);
return null;
}
}
タイムアウトを設定することで、処理が長時間ハングするのを防ぎます。エラーハンドリングも適切に行い、1 つのファイルの失敗が全体に影響しないようにしています。
typescriptfunction analyzeDirectory(dir: string): DebtScore[] {
const results: DebtScore[] = [];
const files = readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = join(dir, file.name);
if (file.isDirectory() && !file.name.startsWith('.')) {
// ディレクトリを再帰的に処理
results.push(...analyzeDirectory(fullPath));
} else if (
file.name.endsWith('.ts') ||
file.name.endsWith('.tsx')
) {
const score = analyzeFile(fullPath);
if (score) {
results.push(score);
}
}
}
return results;
}
ディレクトリを再帰的に走査し、すべての TypeScript ファイルを分析します。隠しディレクトリは除外することで、node_modulesなどの不要な分析を避けられます。
typescript// 分析実行
const scores = analyzeDirectory('src');
// 結果をソートして表示
const sortedScores = scores.sort(
(a, b) => b.score - a.score
);
console.log('🔍 技術的負債レポート\n');
console.log(`総ファイル数: ${scores.length}`);
console.log(
`平均スコア: ${(
scores.reduce((sum, s) => sum + s.score, 0) /
scores.length
).toFixed(2)}\n`
);
console.log('ワーストトップ10:\n');
sortedScores.slice(0, 10).forEach((item, index) => {
console.log(`${index + 1}. ${item.file}`);
console.log(` スコア: ${item.score}/100`);
console.log(` 優先度: ${item.refactoringPriority}`);
console.log(` 見積もり: ${item.estimatedHours}時間`);
console.log(` 問題点:`);
item.issues.forEach((issue) =>
console.log(` - ${issue}`)
);
console.log();
});
分析結果を統計情報と共に表示します。ワーストトップ 10 に絞ることで、優先的に対応すべきファイルが明確になります。
ユースケース 12:API エンドポイントの使用状況分析
アクセスログから API の使用パターンを分析します。
typescript// scripts/api-usage-analysis.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface ApiUsagePattern {
endpoint: string;
totalRequests: number;
uniqueUsers: number;
avgResponseTime: number;
errorRate: number;
recommendation: string;
}
API 使用パターンの構造です。リクエスト数だけでなく、ユーザー数やエラー率も含めることで、総合的な評価が可能になります。
typescriptasync function analyzeApiLogs(logPath: string): Promise<ApiUsagePattern[]> {
const logs = readFileSync(logPath, 'utf-8');
const prompt = `
以下のAPIアクセスログを分析し、各エンドポイントの使用状況を評価してください。
分析項目:
1. リクエスト数
2. ユニークユーザー数
3. 平均レスポンスタイム
4. エラー率
5. 改善提案(キャッシュ導入、最適化など)
JSON配列で返してください:
[
{
"endpoint": "エンドポイントパス",
"totalRequests": リクエスト総数,
"uniqueUsers": ユニークユーザー数,
"avgResponseTime": 平均レスポンスタイム(ms),
"errorRate": エラー率(%),
"recommendation": "改善提案"
}
]
ログ:
${logs}
`;
このプロンプトでは、定量的な分析だけでなく、具体的な改善提案も求めています。これにより、分析結果が実行可能なアクションにつながります。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
maxBuffer: 100 * 1024 * 1024 // 100MB
});
return JSON.parse(result) as ApiUsagePattern[];
}
// 実行
analyzeApiLogs('logs/api-access.log').then(patterns => {
console.log('📊 API使用状況レポート\n');
// 使用率トップ10
const topUsed = patterns
.sort((a, b) => b.totalRequests - a.totalRequests)
.slice(0, 10);
console.log('使用率トップ10:\n');
topUsed.forEach((pattern, index) => {
console.log(`${index + 1}. ${pattern.endpoint}`);
console.log(` リクエスト数: ${pattern.totalRequests.toLocaleString()}`);
console.log(` ユニークユーザー: ${pattern.uniqueUsers.toLocaleString()}`);
console.log(` 平均レスポンス: ${pattern.avgResponseTime}ms`);
console.log(` エラー率: ${pattern.errorRate.toFixed(2)}%`);
console.log(` 推奨: ${pattern.recommendation}\n`);
});
// エラー率の高いエンドポイント
const highError = patterns
.filter(p => p.errorRate > 5)
.sort((a, b) => b.errorRate - a.errorRate);
if (highError.length > 0) {
console.log('⚠️ エラー率が高いエンドポイント:\n');
highError.forEach(pattern => {
console.log(` ${pattern.endpoint}: ${pattern.errorRate.toFixed(2)}%`);
console.log(` 推奨: ${pattern.recommendation}\n`);
});
}
});
使用状況を多角的に表示します。使用率トップとエラー率が高いエンドポイントを別々に表示することで、それぞれに適した対応が取れます。
ユースケース 13:データベーススキーマの最適化提案
スキーマ定義とクエリログから、最適化の機会を見つけます。
typescript// scripts/schema-optimization.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface OptimizationSuggestion {
table: string;
issue: string;
suggestion: string;
impact: 'high' | 'medium' | 'low';
estimatedImprovement: string;
}
最適化提案の構造です。影響度と期待される改善効果を含めることで、投資対効果を判断できます。
typescriptasync function analyzeSchema(): Promise<OptimizationSuggestion[]> {
// スキーマ定義を取得
const schema = readFileSync('db/schema.sql', 'utf-8');
// スロークエリログを取得
const slowQueries = readFileSync('logs/slow-queries.log', 'utf-8');
スキーマ定義とスロークエリログの両方をコンテキストとして使用します。この組み合わせにより、AI は具体的で実行可能な提案ができます。
typescript const prompt = `
以下のデータベーススキーマとスロークエリログを分析し、最適化の機会を特定してください。
分析ポイント:
1. インデックスの不足
2. 正規化/非正規化の機会
3. データ型の最適化
4. パーティショニングの可能性
スキーマ:
${schema}
スロークエリ:
${slowQueries}
JSON配列で返してください:
[
{
"table": "テーブル名",
"issue": "問題点",
"suggestion": "具体的な最適化提案",
"impact": "high/medium/low",
"estimatedImprovement": "期待される改善効果"
}
]
`;
const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
return JSON.parse(result) as OptimizationSuggestion[];
}
プロンプトで具体的な分析ポイントを指示することで、網羅的な提案が得られます。
typescript// 実行
analyzeSchema().then((suggestions) => {
console.log('🗄️ データベース最適化提案\n');
const sorted = suggestions.sort((a, b) => {
const order = { high: 0, medium: 1, low: 2 };
return order[a.impact] - order[b.impact];
});
sorted.forEach((suggestion, index) => {
console.log(
`${index + 1}. [${suggestion.impact.toUpperCase()}] ${
suggestion.table
}`
);
console.log(` 問題: ${suggestion.issue}`);
console.log(` 提案: ${suggestion.suggestion}`);
console.log(
` 期待効果: ${suggestion.estimatedImprovement}\n`
);
});
});
提案を影響度順に表示することで、どこから手を付けるべきかが明確になります。
ユースケース 14:ユーザー行動パターンの抽出
アプリケーションログからユーザーの典型的な行動パターンを発見します。
typescript// scripts/user-behavior-analysis.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface BehaviorPattern {
name: string;
description: string;
frequency: number;
userSegment: string;
businessImplication: string;
}
行動パターンの構造です。ビジネスへの影響も含めることで、技術的な発見をビジネス価値に結びつけられます。
typescriptasync function analyzeUserBehavior(logPath: string): Promise<BehaviorPattern[]> {
const logs = readFileSync(logPath, 'utf-8');
const prompt = `
以下のユーザーアクションログから、典型的な行動パターンを抽出してください。
発見すべきパターン:
1. よくある操作フロー
2. 離脱ポイント
3. 特定セグメントの特徴的な行動
4. 予期しない使い方
各パターンについて、ビジネス上の意味も解釈してください。
ログ:
${logs}
JSON配列で返してください:
[
{
"name": "パターン名",
"description": "詳細説明",
"frequency": 発生頻度(%),
"userSegment": "どのユーザーセグメントか",
"businessImplication": "ビジネス上の意味"
}
]
`;
このプロンプトでは、単なるデータの集計ではなく、ビジネス価値の解釈も求めています。これにより、技術チームと業務チームの橋渡しができます。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
maxBuffer: 100 * 1024 * 1024
});
return JSON.parse(result) as BehaviorPattern[];
}
// 実行
analyzeUserBehavior('logs/user-actions.log').then(patterns => {
console.log('👥 ユーザー行動パターン分析\n');
patterns
.sort((a, b) => b.frequency - a.frequency)
.forEach((pattern, index) => {
console.log(`${index + 1}. ${pattern.name} (${pattern.frequency}%)`);
console.log(` 説明: ${pattern.description}`);
console.log(` セグメント: ${pattern.userSegment}`);
console.log(` ビジネス影響: ${pattern.businessImplication}\n`);
});
});
発見されたパターンを頻度順に表示します。ビジネス影響を明示することで、プロダクトの改善につなげやすくなります。
ユースケース 15:セキュリティ脆弱性のスキャン
コードベースから潜在的なセキュリティ脆弱性を検出します。
typescript// scripts/security-scan.ts
import { execSync } from 'child_process';
import { readFileSync, readdirSync } from 'fs';
import { join } from 'path';
interface SecurityIssue {
file: string;
line: number;
severity: 'critical' | 'high' | 'medium' | 'low';
category: string;
description: string;
remediation: string;
}
セキュリティ問題の構造です。行番号を含めることで、すぐに該当箇所にジャンプできます。
typescriptfunction scanFile(filePath: string): SecurityIssue[] {
const code = readFileSync(filePath, 'utf-8');
const prompt = `
以下のコードをセキュリティの観点から分析してください。
チェック項目:
1. SQLインジェクションのリスク
2. XSSの可能性
3. 認証/認可の不備
4. 機密情報のハードコード
5. 安全でない暗号化
6. CSRF脆弱性
JSON配列で返してください:
[
{
"line": 行番号,
"severity": "critical/high/medium/low",
"category": "脆弱性カテゴリ",
"description": "問題の説明",
"remediation": "修正方法"
}
]
問題がない場合は空配列を返してください。
コード:
${code}
`;
具体的なチェック項目を列挙することで、網羅的なスキャンが実現します。問題がない場合の処理も明示することで、パースエラーを防げます。
typescript try {
const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
timeout: 30000
});
const issues = JSON.parse(result);
return issues.map((issue: any) => ({
file: filePath,
...issue
}));
} catch (error) {
console.error(`スキャンエラー: ${filePath}`);
return [];
}
}
エラーハンドリングを適切に行い、1 つのファイルの失敗が全体のスキャンを止めないようにしています。
typescriptfunction scanDirectory(dir: string): SecurityIssue[] {
const issues: SecurityIssue[] = [];
const files = readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = join(dir, file.name);
if (file.isDirectory() && !file.name.startsWith('.')) {
issues.push(...scanDirectory(fullPath));
} else if (file.name.match(/\.(ts|tsx|js|jsx)$/)) {
issues.push(...scanFile(fullPath));
}
}
return issues;
}
// スキャン実行
const issues = scanDirectory('src');
// 重要度別に集計
const bySeverity = {
critical: issues.filter((i) => i.severity === 'critical'),
high: issues.filter((i) => i.severity === 'high'),
medium: issues.filter((i) => i.severity === 'medium'),
low: issues.filter((i) => i.severity === 'low'),
};
console.log('🔒 セキュリティスキャン結果\n');
console.log(`総検出数: ${issues.length}\n`);
Object.entries(bySeverity).forEach(([severity, items]) => {
if (items.length > 0) {
console.log(
`[${severity.toUpperCase()}] ${items.length}件\n`
);
items.forEach((issue) => {
console.log(` ${issue.file}:${issue.line}`);
console.log(
` ${issue.category}: ${issue.description}`
);
console.log(` 修正方法: ${issue.remediation}\n`);
});
}
});
重要度別に結果を表示することで、緊急度の高い問題から対応できます。
ユースケース 16:コードレビューコメントの分析
過去のレビューコメントからチームの傾向を分析します。
typescript// scripts/review-comment-analysis.ts
import { execSync } from 'child_process';
interface ReviewInsight {
category: string;
frequency: number;
examples: string[];
recommendation: string;
}
レビューのインサイト構造です。頻度と具体例を含めることで、チームの傾向が可視化されます。
typescriptasync function analyzeReviewComments(): Promise<ReviewInsight[]> {
// GitHubからPRのコメントを取得
const comments = execSync(
'gh api repos/:owner/:repo/pulls/comments --paginate --jq ".[].body"',
{ encoding: 'utf-8' }
);
GitHub CLI を使って PR コメントを取得します。--paginateオプションで全コメントを取得できます。
typescript const prompt = `
以下のコードレビューコメント履歴を分析し、チームのレビュー傾向を特定してください。
分析項目:
1. よく指摘される問題のカテゴリ
2. 各カテゴリの頻度
3. 代表的なコメント例
4. チームへの改善提案
コメント履歴:
${comments}
JSON配列で返してください:
[
{
"category": "カテゴリ名",
"frequency": 発生頻度(%),
"examples": ["コメント例1", "コメント例2"],
"recommendation": "チームへの提案"
}
]
`;
const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
return JSON.parse(result) as ReviewInsight[];
}
// 実行
analyzeReviewComments().then(insights => {
console.log('📝 コードレビュー分析\n');
insights
.sort((a, b) => b.frequency - a.frequency)
.forEach((insight, index) => {
console.log(`${index + 1}. ${insight.category} (${insight.frequency}%)`);
console.log(` 代表例:`);
insight.examples.forEach(ex => console.log(` "${ex}"`));
console.log(` 提案: ${insight.recommendation}\n`);
});
});
レビュー傾向を分析することで、チームのコーディングガイドラインや lint ルールの改善につなげられます。
ユースケース 17:バンドルサイズの最適化分析
Webpack のバンドル分析結果から、最適化の機会を見つけます。
bash# scripts/bundle-analysis.sh
#!/bin/bash
# バンドル分析を実行
yarn build --analyze
webpack-bundle-analyzer build/stats.json --mode static -O -r bundle-report.html
Webpack のバンドルアナライザーを使って、依存関係のサイズを可視化します。
bash# AIで分析
yarn webpack-bundle-analyzer build/stats.json --mode json > bundle-stats.json
gemini "以下のWebpackバンドル分析結果から、サイズ削減の具体的な施策を提案してください。
特に以下を重視:
1. 大きすぎる依存パッケージ
2. 重複している依存関係
3. tree-shakingの機会
4. code-splittingの最適化
各提案に期待される削減サイズも含めてください。" < bundle-stats.json > optimization-plan.md
cat optimization-plan.md
AI が分析結果を解釈し、具体的な最適化プランを生成します。期待される削減サイズを含めることで、優先順位付けができます。
ユースケース 18:Git 履歴からのホットスポット検出
変更頻度が高いファイルを特定し、リファクタリング候補を見つけます。
bash# scripts/hotspot-analysis.sh
#!/bin/bash
# 過去6ヶ月の変更履歴を取得
git log --since="6 months ago" --name-only --pretty=format: | \
sort | uniq -c | sort -rn | head -20 > hotspots.txt
このコマンドは、変更頻度の高いファイルトップ 20 を抽出します。変更が多いファイルは、リファクタリングの優先候補です。
bash# AIで分析
gemini "以下は変更頻度が高いファイルのリストです。
各ファイルについて、なぜ変更が多いのか推測し、安定化のための提案をしてください。
可能性として考えられるのは:
1. ビジネスロジックの中心でやむを得ない
2. 設計が悪く修正が多い
3. 複数の責務を持ちすぎている
優先的にリファクタリングすべきファイルを特定してください。" < hotspots.txt
変更頻度だけでなく、その理由と対策まで提案してもらうことで、実行可能なアクションプランになります。
ユースケース 19:環境変数の整合性チェック
複数環境の環境変数定義を比較し、不整合を検出します。
typescript// scripts/env-consistency-check.ts
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
interface EnvInconsistency {
variable: string;
issue: string;
environments: string[];
recommendation: string;
}
環境変数の不整合構造です。どの環境で問題があるかを明示することで、対応がスムーズになります。
typescriptasync function checkEnvConsistency(): Promise<EnvInconsistency[]> {
const envFiles = {
development: readFileSync('.env.development', 'utf-8'),
staging: readFileSync('.env.staging', 'utf-8'),
production: readFileSync('.env.production', 'utf-8')
};
すべての環境ファイルを読み込みます。環境が増えた場合は、この配列に追加するだけです。
typescript const prompt = `
以下の環境変数ファイルを比較し、不整合や問題を特定してください。
チェック項目:
1. 片方にしか存在しない変数
2. 値の形式が異なる変数
3. セキュリティ上問題のある設定
4. 命名規則の不統一
開発環境:
${envFiles.development}
ステージング環境:
${envFiles.staging}
本番環境:
${envFiles.production}
JSON配列で返してください:
[
{
"variable": "変数名",
"issue": "問題の説明",
"environments": ["影響する環境"],
"recommendation": "修正方法"
}
]
`;
const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
return JSON.parse(result) as EnvInconsistency[];
}
// 実行
checkEnvConsistency().then(inconsistencies => {
if (inconsistencies.length === 0) {
console.log('✅ 環境変数の整合性に問題はありません');
return;
}
console.log('⚠️ 環境変数の不整合が検出されました\n');
inconsistencies.forEach((item, index) => {
console.log(`${index + 1}. ${item.variable}`);
console.log(` 問題: ${item.issue}`);
console.log(` 影響環境: ${item.environments.join(', ')}`);
console.log(` 推奨: ${item.recommendation}\n`);
});
});
不整合が検出された場合は、具体的な修正方法も提示されるため、すぐに対応できます。
ユースケース 20:アクセシビリティ監査
HTML や React コンポーネントのアクセシビリティ問題を検出します。
typescript// scripts/a11y-audit.ts
import { execSync } from 'child_process';
import { readFileSync, readdirSync } from 'fs';
import { join } from 'path';
interface A11yIssue {
file: string;
severity: 'critical' | 'serious' | 'moderate' | 'minor';
rule: string;
description: string;
fix: string;
}
アクセシビリティ問題の構造です。WCAG 準拠のルール名を含めることで、標準に沿った対応ができます。
typescriptfunction auditFile(filePath: string): A11yIssue[] {
const code = readFileSync(filePath, 'utf-8');
const prompt = `
以下のReactコンポーネントをアクセシビリティの観点から監査してください。
WCAG 2.1 AA基準に基づいてチェック:
1. セマンティックHTML
2. ARIA属性の適切な使用
3. キーボード操作
4. フォーカス管理
5. 色のコントラスト
6. 代替テキスト
JSON配列で返してください:
[
{
"severity": "critical/serious/moderate/minor",
"rule": "WCAG基準(例: 1.1.1)",
"description": "問題の説明",
"fix": "具体的な修正コード"
}
]
問題がない場合は空配列を返してください。
コード:
${code}
`;
try {
const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8',
timeout: 30000,
});
const issues = JSON.parse(result);
return issues.map((issue: any) => ({
file: filePath,
...issue,
}));
} catch (error) {
return [];
}
}
function auditDirectory(dir: string): A11yIssue[] {
const issues: A11yIssue[] = [];
const files = readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = join(dir, file.name);
if (file.isDirectory() && !file.name.startsWith('.')) {
issues.push(...auditDirectory(fullPath));
} else if (file.name.match(/\.(tsx|jsx)$/)) {
issues.push(...auditFile(fullPath));
}
}
return issues;
}
// 監査実行
const issues = auditDirectory('src/components');
console.log('♿ アクセシビリティ監査結果\n');
console.log(`総検出数: ${issues.length}\n`);
// 重要度別に表示
['critical', 'serious', 'moderate', 'minor'].forEach(
(severity) => {
const filtered = issues.filter(
(i) => i.severity === severity
);
if (filtered.length > 0) {
console.log(
`[${severity.toUpperCase()}] ${filtered.length}件\n`
);
filtered.forEach((issue) => {
console.log(` ${issue.file}`);
console.log(
` ${issue.rule}: ${issue.description}`
);
console.log(` 修正: ${issue.fix}\n`);
});
}
}
);
WCAG 基準に基づいた監査により、標準準拠のアクセシブルなアプリケーションを構築できます。
カテゴリ 3:生成(Generation)の 10 ユースケース
生成の軸では、AI に新しいコードやドキュメントを作成させます。
ユースケース 21:テストコードの自動生成
既存の関数からテストコードを生成します。
typescript// scripts/generate-tests.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
function generateTests(sourceFilePath: string): void {
const sourceCode = readFileSync(sourceFilePath, 'utf-8');
const prompt = `
以下のTypeScriptコードに対して、Jestを使った包括的なテストコードを生成してください。
テスト要件:
1. すべてのエクスポート関数をカバー
2. 正常系と異常系の両方をテスト
3. エッジケースも含める
4. モックが必要な場合は適切に使用
5. describeブロックで論理的にグループ化
ソースコード:
${sourceCode}
`;
このプロンプトでは、テストの品質基準を明確に指示しています。これにより、実用的なテストコードが生成されます。
typescript const testCode = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
// テストファイルを保存
const testFilePath = sourceFilePath.replace(/\.ts$/, '.test.ts');
writeFileSync(testFilePath, testCode, 'utf-8');
console.log(`✅ テスト生成完了: ${testFilePath}`);
}
// 使用例
generateTests('src/utils/validation.ts');
生成されたテストファイルは、すぐに実行可能な状態で保存されます。人間がレビューして微調整することを前提としています。
ユースケース 22:TypeScript 型定義の生成
JSON スキーマや API レスポンスから型定義を生成します。
typescript// scripts/generate-types.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
async function generateTypes(schemaPath: string, outputPath: string): Promise<void> {
const schema = readFileSync(schemaPath, 'utf-8');
const prompt = `
以下のJSONスキーマから、TypeScriptの型定義を生成してください。
要件:
1. interfaceを使用
2. オプショナルプロパティは?を使う
3. ネストした構造も適切に型定義
4. ユニオン型やジェネリクスも活用
5. JSDocコメントを付与
JSONスキーマ:
${schema}
`;
型定義生成では、コーディング規約も指示しています。チームの規約に合わせてカスタマイズできます。
typescript const types = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
writeFileSync(outputPath, types, 'utf-8');
console.log(`✅ 型定義生成完了: ${outputPath}`);
}
// 使用例
generateTypes('api/schema/user.json', 'src/types/user.ts');
API 仕様から型定義を自動生成することで、フロントエンドとバックエンドの型の整合性が保たれます。
ユースケース 23:マイグレーションスクリプトの生成
データベーススキーマの変更から、マイグレーションスクリプトを生成します。
typescript// scripts/generate-migration.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
interface MigrationPlan {
up: string;
down: string;
warnings: string[];
}
マイグレーションプランの構造です。up/down の両方と警告メッセージを含めることで、安全な移行が可能になります。
typescriptasync function generateMigration(
oldSchema: string,
newSchema: string
): Promise<MigrationPlan> {
const oldSchemaContent = readFileSync(oldSchema, 'utf-8');
const newSchemaContent = readFileSync(newSchema, 'utf-8');
const prompt = `
以下の2つのデータベーススキーマを比較し、マイグレーションスクリプトを生成してください。
旧スキーマ:
${oldSchemaContent}
新スキーマ:
${newSchemaContent}
JSON形式で返してください:
{
"up": "適用時のSQL(改行は\\nで)",
"down": "ロールバック時のSQL",
"warnings": ["注意事項の配列"]
}
考慮事項:
- データ損失の可能性がある変更は警告に含める
- インデックスの追加/削除も含める
- 外部キー制約の変更も処理
`;
このプロンプトでは、マイグレーションの安全性を重視した指示を出しています。データ損失のリスクを警告として検出できます。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
return JSON.parse(result) as MigrationPlan;
}
// 実行
generateMigration('db/schema-v1.sql', 'db/schema-v2.sql')
.then(plan => {
const timestamp = new Date().toISOString().replace(/[^0-9]/g, '').slice(0, 14);
const filename = `migrations/${timestamp}_auto_generated.sql`;
const content = `
-- Migration: ${timestamp}
-- Generated by AI
-- UP
${plan.up}
-- DOWN
${plan.down}
-- WARNINGS:
${plan.warnings.map(w => `-- ⚠️ ${w}`).join('\n')}
`;
writeFileSync(filename, content, 'utf-8');
console.log(`✅ マイグレーション生成完了: ${filename}\n`);
if (plan.warnings.length > 0) {
console.log('⚠️ 以下の警告を確認してください:');
plan.warnings.forEach(w => console.log(` - ${w}`));
}
});
生成されたマイグレーションファイルには、タイムスタンプと警告が含まれます。本番適用前に必ず人間がレビューすることが推奨されます。
ユースケース 24:README の自動生成
プロジェクトのコードベースから README を生成します。
bash# scripts/generate-readme.sh
#!/bin/bash
# プロジェクト構造を取得
tree -L 3 -I 'node_modules|dist|build' > project-structure.txt
# package.jsonから情報取得
cat package.json > package-info.json
# メインファイルの内容を抽出
cat src/index.ts > main-code.txt
プロジェクトの全体像を把握するための情報を収集します。ディレクトリ構造、依存関係、メインコードを組み合わせることで、正確な README が生成できます。
bash# AIでREADME生成
gemini "以下の情報をもとに、プロジェクトのREADME.mdを生成してください。
必須セクション:
1. プロジェクト概要
2. 主な機能
3. インストール方法
4. 使用方法(コード例を含む)
5. API リファレンス
6. 開発環境のセットアップ
7. テストの実行方法
8. コントリビューション方法
9. ライセンス
プロジェクト構造:
$(cat project-structure.txt)
依存関係:
$(cat package-info.json)
メインコード:
$(cat main-code.txt)
" > README.md
echo "✅ README.md が生成されました"
生成された README は、プロジェクトの実態に基づいた正確な内容になります。定期的に再生成することで、常に最新の状態を保てます。
ユースケース 25:Docker 設定の生成
プロジェクトの特性に合わせた Dockerfile と docker-compose.yml を生成します。
typescript// scripts/generate-docker-config.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
async function generateDockerConfig(): Promise<void> {
const packageJson = readFileSync('package.json', 'utf-8');
const prompt = `
以下のpackage.jsonをもとに、最適化されたDockerfileとdocker-compose.ymlを生成してください。
要件:
1. マルチステージビルドを使用
2. 本番環境用の最小イメージ
3. 開発環境用のホットリロード対応
4. 必要なサービス(DB、Redisなど)も含める
5. セキュリティベストプラクティスに従う
package.json:
${packageJson}
2つのファイルをJSON形式で返してください:
{
"dockerfile": "Dockerfileの内容",
"compose": "docker-compose.ymlの内容"
}
`;
このプロンプトでは、ベストプラクティスを明示的に要求しています。セキュリティや効率性を考慮した設定が生成されます。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
const config = JSON.parse(result);
writeFileSync('Dockerfile', config.dockerfile, 'utf-8');
writeFileSync('docker-compose.yml', config.compose, 'utf-8');
console.log('✅ Docker設定を生成しました');
console.log(' - Dockerfile');
console.log(' - docker-compose.yml');
}
generateDockerConfig();
生成された設定ファイルは、すぐに使える状態で保存されます。プロジェクトの依存関係に応じて、適切なベースイメージやサービスが選択されます。
ユースケース 26:エラーメッセージの多言語化
エラーメッセージを複数言語に翻訳します。
typescript// scripts/generate-i18n-errors.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
interface TranslatedErrors {
[locale: string]: {
[errorCode: string]: string;
};
}
多言語エラーメッセージの構造です。エラーコードをキーとすることで、言語間の対応が明確になります。
typescriptasync function generateErrorTranslations(
sourceLanguage: string,
targetLanguages: string[]
): Promise<void> {
const errors = readFileSync(`locales/${sourceLanguage}/errors.json`, 'utf-8');
const prompt = `
以下の${sourceLanguage}のエラーメッセージを、${targetLanguages.join(', ')}に翻訳してください。
翻訳要件:
1. エラーコードはそのまま維持
2. 各言語の自然な表現を使用
3. 技術用語は適切に翻訳
4. 丁寧な表現を使用
JSON形式で返してください:
{
"ja": { "ERROR_001": "日本語メッセージ", ... },
"en": { "ERROR_001": "English message", ... },
...
}
元のエラーメッセージ:
${errors}
`;
このプロンプトでは、単なる逐語訳ではなく、各言語の自然な表現を求めています。ユーザーにとって理解しやすいメッセージになります。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
const translations: TranslatedErrors = JSON.parse(result);
// 各言語のファイルを保存
Object.entries(translations).forEach(([locale, messages]) => {
const path = `locales/${locale}/errors.json`;
writeFileSync(path, JSON.stringify(messages, null, 2), 'utf-8');
console.log(`✅ 生成完了: ${path}`);
});
}
// 日本語から英語と中国語に翻訳
generateErrorTranslations('ja', ['en', 'zh']);
各言語のファイルが個別に生成されるため、言語ごとの管理が容易です。
ユースケース 27:OpenAPI 仕様の生成
Express や Next.js のルートハンドラーから OpenAPI 仕様を生成します。
typescript// scripts/generate-openapi.ts
import { execSync } from 'child_process';
import { readdirSync, readFileSync, writeFileSync } from 'fs';
import { join } from 'path';
async function generateOpenApiSpec(routesDir: string): Promise<void> {
// すべてのルートファイルを読み込み
const routes: string[] = [];
function readRoutes(dir: string): void {
const files = readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const fullPath = join(dir, file.name);
if (file.isDirectory()) {
readRoutes(fullPath);
} else if (file.name.match(/\.(ts|js)$/)) {
routes.push(readFileSync(fullPath, 'utf-8'));
}
}
}
readRoutes(routesDir);
すべてのルートファイルを再帰的に読み込みます。これにより、プロジェクト全体の API を網羅した仕様書が生成できます。
typescript const prompt = `
以下のExpressルートハンドラーからOpenAPI 3.0仕様を生成してください。
要件:
1. すべてのエンドポイントを含める
2. リクエスト/レスポンススキーマを定義
3. 認証要件を明示
4. エラーレスポンスも含める
5. 例を含める
ルートコード:
${routes.join('\n\n---\n\n')}
OpenAPI YAML形式で返してください。
`;
const spec = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
writeFileSync('openapi.yaml', spec, 'utf-8');
console.log('✅ OpenAPI仕様書を生成しました: openapi.yaml');
}
generateOpenApiSpec('src/routes');
コードから仕様書を生成することで、実装と仕様の乖離を防げます。CI/CD に組み込めば、常に最新の仕様書を維持できます。
ユースケース 28:CI/CD パイプラインの生成
プロジェクトの特性に合わせた GitHub Actions ワークフローを生成します。
typescript// scripts/generate-ci-pipeline.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync, existsSync } from 'fs';
async function generateCIPipeline(): Promise<void> {
const packageJson = readFileSync('package.json', 'utf-8');
const hasDocker = existsSync('Dockerfile');
const hasTests = existsSync('src/__tests__') || existsSync('tests');
const prompt = `
以下の情報をもとに、GitHub Actionsのワークフローを生成してください。
プロジェクト情報:
${packageJson}
環境情報:
- Dockerを使用: ${hasDocker}
- テストあり: ${hasTests}
生成するワークフロー:
1. CI(テスト、lint、ビルド)
2. CD(自動デプロイ)
3. 依存関係の自動更新(Dependabot設定)
各ファイルをJSON形式で返してください:
{
"ci": ".github/workflows/ci.ymlの内容",
"cd": ".github/workflows/cd.ymlの内容",
"dependabot": ".github/dependabot.ymlの内容"
}
`;
プロジェクトの実態を分析し、それに合わせたパイプラインを生成します。Docker の有無やテストの存在を考慮することで、実用的な設定になります。
typescript const result = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
const workflows = JSON.parse(result);
// ディレクトリ作成
execSync('mkdir -p .github/workflows');
// 各ファイルを保存
writeFileSync('.github/workflows/ci.yml', workflows.ci, 'utf-8');
writeFileSync('.github/workflows/cd.yml', workflows.cd, 'utf-8');
writeFileSync('.github/dependabot.yml', workflows.dependabot, 'utf-8');
console.log('✅ CI/CD設定を生成しました');
console.log(' - .github/workflows/ci.yml');
console.log(' - .github/workflows/cd.yml');
console.log(' - .github/dependabot.yml');
}
generateCIPipeline();
生成された設定ファイルは、即座に動作する状態で保存されます。プロジェクトの成長に応じて再生成することで、常に最適なパイプラインを維持できます。
ユースケース 29:サンプルデータの生成
開発・テスト用のリアルなサンプルデータを生成します。
typescript// scripts/generate-sample-data.ts
import { execSync } from 'child_process';
import { readFileSync, writeFileSync } from 'fs';
interface DataGenerationSpec {
entity: string;
count: number;
schema: any;
}
データ生成仕様の構造です。エンティティごとに件数とスキーマを指定できます。
typescriptasync function generateSampleData(specs: DataGenerationSpec[]): Promise<void> {
for (const spec of specs) {
const prompt = `
以下のスキーマに基づいて、リアルなサンプルデータを${spec.count}件生成してください。
要件:
1. 日本語の実在しそうなデータ
2. 関連性のあるデータ(例:メールアドレスと名前の整合性)
3. バリエーションを持たせる
4. テストに使える範囲でリアルに
スキーマ:
${JSON.stringify(spec.schema, null, 2)}
JSON配列で返してください。
`;
const data = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
このプロンプトでは、単なるランダムデータではなく、リアルで関連性のあるデータを求めています。これにより、実際の使用感に近いテストができます。
typescript const filename = `data/samples/${spec.entity}.json`;
writeFileSync(filename, data, 'utf-8');
console.log(`✅ サンプルデータ生成完了: ${filename}`);
}
}
// 使用例
generateSampleData([
{
entity: 'users',
count: 100,
schema: {
id: 'string (UUID)',
name: 'string',
email: 'string',
age: 'number',
registeredAt: 'ISO8601 timestamp'
}
},
{
entity: 'posts',
count: 500,
schema: {
id: 'string (UUID)',
userId: 'string (users.idを参照)',
title: 'string',
content: 'string',
createdAt: 'ISO8601 timestamp'
}
}
]);
複数のエンティティを関連付けたデータを生成できます。外部キー制約も考慮されるため、リレーショナルデータベースのテストに最適です。
ユースケース 30:コード変換スクリプトの生成
JavaScript から TypeScript への変換など、コードの一括変換スクリプトを生成します。
typescript// scripts/generate-converter.ts
import { execSync } from 'child_process';
import { writeFileSync } from 'fs';
async function generateConverter(
sourceLanguage: string,
targetLanguage: string
): Promise<void> {
const prompt = `
${sourceLanguage}から${targetLanguage}への変換スクリプトを生成してください。
変換スクリプトの要件:
1. Node.jsで実行可能
2. ディレクトリを再帰的に処理
3. 変換ログを出力
4. エラーハンドリング
5. ドライランモード対応
スクリプトは、@babel/parserと@babel/generatorを使って、
ASTレベルで変換を行ってください。
完全に動作するスクリプトを返してください。
`;
このプロンプトでは、単なるコード例ではなく、完全に動作するスクリプトを要求しています。具体的なライブラリ名を指定することで、実用的な出力が得られます。
typescript const script = execSync(`gemini "${prompt}"`, {
encoding: 'utf-8'
});
const filename = `scripts/convert-${sourceLanguage}-to-${targetLanguage}.js`;
writeFileSync(filename, script, 'utf-8');
console.log(`✅ 変換スクリプトを生成しました: ${filename}`);
console.log('\n使用方法:');
console.log(` node ${filename} <ソースディレクトリ> <出力ディレクトリ>`);
console.log(` node ${filename} --dry-run <ソースディレクトリ> # ドライラン`);
}
// JavaScript to TypeScript変換スクリプトを生成
generateConverter('JavaScript', 'TypeScript');
生成された変換スクリプトは、大規模なコードベースの移行に使えます。ドライランモードで事前確認できるため、安全に実行できます。
まとめ
Gemini CLI がもたらす開発体験の変化
Gemini CLI を活用することで、開発ワークフローは大きく変わります。ブラウザを開く必要がなくなり、ターミナル上ですべてが完結するため、集中力を維持したまま高品質な開発が可能になるのです。
本記事では、自動化・解析・生成という 3 つの軸で、合計 30 のユースケースをご紹介しました。これらはほんの一例に過ぎません。あなたのプロジェクト特有の課題に合わせて、独自の活用方法を見つけてください。
| # | カテゴリ | 代表的なユースケース | 期待効果 |
|---|---|---|---|
| 1 | 自動化 | PR の自動レビュー、コミット前チェック | 手動作業削減、品質向上 |
| 2 | 解析 | 技術的負債の可視化、API 使用分析 | 問題の早期発見、データ駆動の意思決定 |
| 3 | 生成 | テストコード生成、ドキュメント作成 | 開発速度向上、保守性向上 |
この表は、3 つのカテゴリとその期待効果を整理したものです。どのカテゴリも、開発者の生産性を大きく向上させる可能性を秘めています。
導入時の注意点
Gemini CLI を導入する際は、以下の点に注意してください。
まず、AI が生成した結果は必ず人間がレビューすることが重要です。AI は強力なアシスタントですが、完璧ではありません。特にセキュリティに関わる部分や、ビジネスロジックの核心部分は、慎重に確認しましょう。
次に、API の利用制限とコストを考慮する必要があります。大量のファイルを処理する場合は、バッチサイズを調整したり、並列度を制限したりすることで、制限に引っかからないよう工夫してください。
最後に、生成されたコードはあくまでスタート地点です。プロジェクトの規約やチームの方針に合わせて、適宜カスタマイズすることを忘れないでください。
次のステップ
本記事で紹介した 30 のユースケースを起点に、あなた独自の使いどころを探してみてください。開発フローの中で「この作業、自動化できないかな?」と感じたら、それが Gemini CLI の出番かもしれません。
小さな自動化から始めて、徐々に適用範囲を広げていくことをお勧めします。チーム全体で活用事例を共有することで、組織全体の生産性向上にもつながるはずです。
AI を活用した開発は、もはや未来の話ではなく、今日から始められる現実です。Gemini CLI という強力なツールを手に、新しい開発体験を楽しんでください。
関連リンク
- Google AI Studio - API キーの取得
- Gemini API 公式ドキュメント - API 仕様とサンプル
- @google/generative-ai-cli npm package - CLI ツールの詳細
- GitHub Actions 公式ドキュメント - CI/CD 構築の参考
- OpenAPI Specification - API 仕様書の標準
- WCAG 2.1 Guidelines - アクセシビリティ基準
articleGemini CLI 使いどころマップ:自動化・解析・生成を横断するユースケース 30
articleGemini CLI のコスト監視ダッシュボード:呼び出し数・トークン・失敗率の可視化
articleGemini CLI を中核にした“AI パイプライン”設計:前処理 → 推論 → 後処理の標準化
articleGemini CLI コマンド&フラグ早見表:入出力・温度・安全設定の定番セット
articleGemini CLI を macOS で最短導入:Homebrew・PATH・シェル補完のベストプラクティス
articleGemini CLI と curl + REST の生産性比較:開発速度・再現性・保守性を計測
articleWebLLM とは?ブラウザだけで動くローカル推論の全体像【2025 年版】
articleMistral とは? 軽量・高速・高品質を両立する次世代 LLM の全体像
articleOllama コマンドチートシート:`run`/`pull`/`list`/`ps`/`stop` の虎の巻
articletRPC とは?型安全なフルスタック通信を実現する仕組みとメリット【2025 年版】
articleJest の “Cannot use import statement outside a module” を根治する手順
articleObsidian プラグイン相性問題の切り分け:セーフモード/最小再現/ログの活用
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来