以前作ったRAG環境をより良くして、かつVibeCoding(AI駆動開発)で実装できるか検証してみました。
※以下の様なものを作ります。コード類はすべてGithubに公開しています。(記事最下部にリンクおいてます)
※ちょっと長いのでお気をつけください・・・
主な機能
この記事に倣えば同じものが作れますが、あくまで個人レベルの検証です。こちらを参考に頂く場合は自己責任でお願いいたします。
※環境は既にすべて削除済みです。
※VibeCodingで実装する場合、以下の記事で書いたセキュリティルールを読み込ませると結構セキュリティに気を付けて実装してくれますので、ご参照ください。
0. はじめに:インデックスと検証ステップ
本記事は、Gemini CLI(Vibe Coding)を用いて、API キーをバックエンドに隠蔽した「 RAG 環境」を構築するための手順です。
本資料の構成(Index)
- 検証の目的と背景: なぜこの検証を行うのか、設計の意図。
- 構成図とファイル・リソース対応: システムの全体図と中身の紐付け。
- 実行ロードマップ: 実際の検証ステップ(Phase 1〜9)。
- 最後に: 感想と成果物。
1. 検証の目的と背景 (Context & Why)
本検証は、Gemini CLI(Vibe Coding)を用いて、Azure 上に「文書検索(RAG)」を構築(検証)する一連のプロセスを記録したものです。
(これくらいできるようになっとけとプレッシャーを勝手に受けているからです)
なぜこの構成を選択したか
- 最高度のセキュリティ (Secure by Default): API キーをフロントエンド(ブラウザ)に一切持たせず、Azure の環境変数に隠蔽。さらにサイト全体に認証(ログイン)を強制し、部外者のアクセスを遮断する。
- 実用的な RAG 基盤: 擬似的な処理ではなく、Azure Storage 上に実際のコンテナを作成し、ファイルを保存可能な状態にする。
- 確実なデプロイ (Architecture Decision): クォータ制限を受けにくい Azure Static Web Apps (Free) をフロントエンドに採用し、確実な構築を実現する。
- 本音: 個人で作るからとにかく安く作れるものを選定しています。これが結構制約になって苦戦しましたが・・・
2. 構成図と作成するファイル・リソース
2.1 構成図 (Architecture & File Mapping)
この図は、ローカルにあるファイルが Azure 上のどのコンポーネントとして動作するかを示しています。
2.2 ファイル・リソース対応表
| ローカルファイル | Azure上のリソース / 役割 | 技術的役割の解説 |
|---|---|---|
infra/main.bicep |
Resource Group 全体 | Azure 全リソースの構成定義ファイル。Storage コンテナの作成、サービス間連携、API キーの自動注入ロジックを一括管理・実行する。 |
index.html |
Static Web Apps (Front) | ユーザーインターフェースの実装。ブラウザで動作し、API キーを持たずに自身のバックエンド(/api/chat)へ推論要求を送信する。 |
staticwebapp.config.json |
SWA 構成設定 | サイト全体の認証(ログイン)強制設定、およびバックエンドのランタイム(Python 3.10)を定義する。 |
api/function_app.py |
Static Web Apps (API) | バックエンド・ロジックの実装(プロキシ役)。Azure 側の環境変数から API キーを安全に読み取り、OpenAI API との通信を仲介・実行する。 |
api/host.json |
API サーバー構成 | Azure Functions の起動設定。これが欠落するとバックエンドが正常に初期化されず、404 エラーの原因となる。 |
main.bicepparam |
環境パラメータ |
main.bicep に渡す環境固有の変数値(リージョン、接頭辞等)を定義するファイル。機密情報を除いた環境設定を分離管理する。 |
※ファイルは最後にgithubのリンクを貼っています。
2.3 環境変数対応表 (Static Web Apps App Settings)
Bicep により SWA へ自動注入される環境変数の用途一覧です。これらはバックエンド API から安全に参照されます。
| 環境変数名 | 用途 |
|---|---|
OPENAI_API_KEY |
Azure OpenAI の認証に使用。Bicep が listKeys() で自動取得し注入する。 |
OPENAI_ENDPOINT |
Azure OpenAI の API エンドポイント URL。 |
OPENAI_DEPLOYMENT_NAME |
使用するモデルのデプロイ名(例: gpt-4o-mini)。 |
STORAGE_CONNECTION_STRING |
Blob Storage へのアクセス(SAS発行等)に使用。アカウント名とキーを含む完全な文字列。 |
SEARCH_ENDPOINT |
Azure AI Search のサービス URL。RAG の検索クエリ送信先。 |
SEARCH_API_KEY |
Azure AI Search の管理用キー。インデックスの自己構築や検索に使用。 |
3. 実行ロードマップ
Phase 1: Azure IAM & アカウント準備(手動:Azure Portal)
本フェーズでは、構築用と閲覧用の2つのアイデンティティを作成し、RBAC(ロールベースのアクセス制御)を構成します。
※ここも含めてVibeコーディングできますが、確実に権限を当てるために手動で割り当てます。
1.1 検証用ユーザーの作成
※これは構築用のアカウントがあれば飛ばしてもいいかもです。(自分は操作と閲覧で切り替える想定で用意しました。)無理にやる必要はないかもしれませんが、AIで操作する際も指定したアカウント・ロールに則って操作可否が決まるので、その理解のためにやってもいいかもです。
- Azure Portal に管理者としてサインイン。
- 上部検索バーで「ユーザー」と入力し、[ユーザー (Microsoft Entra ID)] を選択。
- [新しいユーザー] > [新しいユーザーの作成] をクリック。
- 以下の2つのユーザーを作成。
-
管理者 (
azure-admin-test)- ユーザー名:
azure-admin-test - 表示名:
Admin-Role - パスワード: 「パスワードの自動生成」をチェックし、メモしておく。
- ユーザー名:
-
閲覧者 (
azure-reader-test)- ユーザー名:
azure-reader-test - 表示名:
Reader-Role - パスワード: メモしておく。
※以下の赤枠を記載。パスワードは横の書類の様なアイコンでコピーできます。
- ユーザー名:
-
管理者 (
1.2 サブスクリプションへの権限付与
リソースを作成・参照できるよう、サブスクリプションレベルでロールを割り当てます。
- ポータルで「サブスクリプション」を検索して選択。
- 使用するサブスクリプション名をクリックし、左メニューの [アクセス制御 (IAM)] を選択。
- [追加] > [ロールの割り当ての追加] をクリックし、以下の通り設定。
以下から追加可能です。ロールの種類ごとに同じ操作を繰り返して必要なロールを割り当ててください。
| 対象ユーザー | 割り当てるロール | 理由(なぜ必要か) |
|---|---|---|
| Admin-Role | 1. 共同作成者 (Contributor)
|
リソースの作成・削除・設定変更を行うため。 |
2. ユーザーアクセス管理者
|
【重要】 Bicep 内でマネージド ID に権限を付与するために必須。付与時の「条件」は ②特権管理者ロールを除くすべてのロールを割り当てる... (おすすめ) を選択してください。 | |
3. ストレージ BLOB データ共同作成者
|
ストレージの中身(Blob)をCLIから操作するため。 | |
4. 検索インデックス データ共同作成者
|
AI Searchのインデックスを操作するため。 | |
| Reader-Role | 1. 閲覧者 (Reader)
|
リソースの設定情報を参照する権限。 |
2. ストレージ BLOB データ閲覧者
|
ストレージ内のファイルリストのみを参照するため。 |
Phase 2: ローカル環境セットアップ
本フェーズでは、Azure を操作するための CLI ツール群をインストールし、作成したユーザーでログイン確認を行います。
2.1 Azure CLI & Bicep のインストール
Windows 環境では winget を使用することで環境構築が可能です。
【実行するコマンド】 (PowerShell)
# Azure CLI のインストール
winget install --id Microsoft.AzureCLI -e --silent --accept-package-agreements --accept-source-agreements
# ターミナルの再起動後、Bicep のインストール
az bicep install
【Vibe Coding 再現用プロンプト】
Windows 環境です。Azure CLI (az) を winget でサイレントインストールしてください。
インストールが完了したら、続けて Bicep CLI (az bicep) もインストールしてください。
※もしazコマンドが認識されない場合は、ターミナルを再起動するか、フルパス (C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd) を使用してください。
2.1.1 インストール確認の手順
ツールが正しく導入されたか、以下のコマンドで確認してください。
【確認用コマンド】
# Azure CLI のバージョン確認
az version
# Bicep CLI のバージョン確認
az bicep version
【期待される結果】
-
az version:azure-cliのバージョン(例: 2.83.0)が JSON 形式で表示されること。 -
az bicep version:Bicep CLI version 0.xx.xと表示されること。
【Vibe Coding 検証用プロンプト】
インストールが成功したか確認してください。az コマンドと bicep コマンドのバージョンを表示し、正常に動作しているか判定してください。
2.2 ログイン確認とパスワード変更
作成したユーザーは初回ログイン時にパスワード変更が必須です。最新の Azure セキュリティ要件(MFA強制)に対応するため、ブラウザを使用した 対話型ログイン で行います。
※サインイン時は「職場または学校アカウント」でサインインしてください。

-
管理者 (
Admin-Role) の初回ログイン:# ユーザー名を指定せず実行(ブラウザが立ち上がります) az login- ブラウザで
Admin-Roleのアカウントを入力し、初期パスワードでサインインします。 - そのまま新しいパスワードへの変更を完了させてください。
- パスワード変更後「アカウントをセキュリティ保護しましょう」と出るので次を押してください
- Microsoft Authenticatorを入れていない方はインストールしてください。
- QRコードのスキャン画面が出たらMicrosoft Authenticatorを起動し、右下のQRコード読み取りアイコンから画面上のQRを読み込んでください。
- 読み込んだ後にPC側のQR画面の次へを押すと数字が出るので、それをAuthenticatorに登録して認証しましょう。
- ブラウザで
-
閲覧者 (
Reader-Role) の初回ログイン:az login- 同様にブラウザで
Reader-Roleのアカウントを選択し、パスワード変更を完了させます。
- 同様にブラウザで
【トラブルシューティング:MFAエラー】
az login -u <email>を使用すると、MFA(多要素認証)の影響でエラーが出ることがあります。その場合は上記のようにaz login単体で実行し、ブラウザ経由で認証を行ってください。
Phase 3: Bicep によるインフラ定義(Vibe Coding)
3.1 Bicep の作成と設計根拠
本検証の Bicep ファイルは、単なるリソース作成に留まらず、実務で求められる以下の設計思想に基づいて構成されています。
【設計の主要なポイントと根拠(Rationale)】
-
命名規則 (
uniqueString):- リソース名(Storage等)の重複を防ぐため、リソースグループIDに基づく一意な文字列を自動生成。
-
認証ベースのアクセス制御 (
Authentication):- Web サイト全体に対し、Microsoft アカウントによるログインを強制。IP アドレスの変動に依存せず、許可されたユーザーのみが OpenAI バックエンドを利用できる「プライベートな城」として機能させる。
-
機密情報の自動橋渡し (
listKeys):- OpenAI の API キーおよび Storage の接続文字列を、人間が介在することなく Bicep が取得し、Static Web Apps の設定へ直接注入。コピペミスやキーの露出リスクを物理的に排除する。
-
マルチリージョン戦略と制約回避:
-
Static Web Apps (Free): 日本リージョン(japaneast)未対応のため、アジア圏で利用可能な
eastasiaに固定。 -
OpenAI: コスパのよいモデル(gpt-4o-mini)の供給が安定している
eastus2を指定。
-
Static Web Apps (Free): 日本リージョン(japaneast)未対応のため、アジア圏で利用可能な
-
Storage コンテナの作成:
- 実際にファイルを保存するための
uploadsコンテナを定義し、実運用可能な RAG 基盤を構築する。
- 実際にファイルを保存するための
【Vibe Coding 再現用プロンプト】
Azure RAG 環境を構築するための Bicep ファイルを作成してください。
- リソース構成: Static Web Apps (Free), OpenAI (gpt-4o-mini), AI Search (Free), Storage (Standard_LRS)。
- ストレージ詳細:
blobServicesの下にuploadsという名前のコンテナを作成してください。- キーの自動連携:
listKeys()等を使い、以下の 6 つの情報を SWA のappsettingsへ自動注入するロジックを実装してください。
- OpenAI: API キー、エンドポイント、デプロイ名
- Storage: 接続文字列
- AI Search: エンドポイント、管理用 API キー
- リージョン: AI関連は eastus2、その他は japaneast としてください。
API Versionの確認等は[公式リファレンス]から
-
Azure Static Web Apps (SWA) の API リファレンス
- リソース名: Microsoft.Web staticSites
- API Version: 2023-12-01 (今回 Bicep で使用した安定版)
- リンク: Microsoft.Web staticSites - Bicep reference
(https://learn.microsoft.com/ja-jp/azure/templates/microsoft.web/staticsites?pivots=deployment-language-bicep)
-
OpenAI デプロイメント (Deployments) の API リファレンス
- リソース名: Microsoft.CognitiveServices accounts/deployments
- API Version: 2023-05-01 (今回 Bicep で使用したもの)
- リンク: Microsoft.CognitiveServices deployments - Bicep reference
(https://learn.microsoft.com/ja-jp/azure/templates/microsoft.cognitiveservices/accounts/deployments?pivots=deployment-language-bicep)
3.2 パラメータ定義 (main.bicepparam)
インフラの「設計図(本体)」から、環境ごとに変動する「設定値」を分離して定義します。
【主要なパラメータの役割】
-
prefix: リソース名の接頭辞。 -
location/aiLocation: 各リソースの配置リージョン。
【記述の手順】
-
main.bicepparamファイルに、使用する接頭辞やリージョンを記述して保存します。本構成では認証で保護するため、個別の IP 制限パラメータは不要です。
Phase 4: インフラのデプロイ実行
4.1 デプロイ前の最終確認 (Pre-flight Check)
az account show --query "{User:user.name, Subscription:name, Tenant:tenantId}" --output table
4.2 リソースグループの作成
az group create --name rg-VibeVerification --location japaneast
4.3 デプロイの実行
設定が完了したパラメータファイルを指定し、一括デプロイを実行します。
【実行コマンド】
az deployment group create --resource-group rg-VibeVerification --template-file infra/main.bicep --parameters infra/main.bicepparam
【成功の証跡:デプロイ結果】
-
Status:
Succeeded -
SWA URL:
https://****************.azurestaticapps.net -
OpenAI Endpoint:
https://***************.openai.azure.com/
※意味ないけどマスクしてます。
Phase 5: バックエンド API の作成(api フォルダ)
SWA の統合 API 機能(Managed Functions)を実装し、サーバー側で安全に OpenAI と通信します。
5.1 api フォルダの構成と各ファイルの役割
プロジェクトフォルダの直下に api/ フォルダを作成し、以下の 3 つ のファイルを配置します。これらが本アーキテクチャの「セキュリティの要」となります。
-
function_app.py(API 本体)- 役割: フロントエンド(ブラウザ)からの JSON リクエストを受け取り、Azure 側の環境変数に隠蔽された OpenAI 設定を使用して推論を実行するプロキシの役割を果たします。
-
host.json(構成定義ファイル)- 役割: Azure Functions のランタイム設定(拡張機能のバンドル等)を定義します。
- 必要性: これが欠落していると、Azure 側でバックエンドが「サーバー」として初期化されず、通信時に 404 エラーが発生します。
-
requirements.txt(依存ライブラリの定義)- 役割: 実行に必要なパッケージをリストアップします。
-
必要性: デプロイ時に Azure 側がこのファイルを読み取ります。環境依存によるビルド失敗を避けるため、今回は
azure-functionsの記述をします。
【再現用プロンプト】
SWA 統合 API (Azure Functions v2 Python) 用のコードを作成してください。
api/function_app.py:/api/chatというエンドポイントを作成。依存関係エラーを物理的に避けるため、外部ライブラリ(openai 等)は使わず、Python 標準のurllibで Azure OpenAI REST API を直接叩く堅牢な実装にしてください。api/host.json:Microsoft.Azure.Functions.ExtensionBundleバージョン [4.*, 5.0.0) を含めて作成してください。api/requirements.txt:azure-functionsを含めて作成してください。
Phase 6: フロントエンド UI とデプロイ設定の作成
6.1 フロントエンド UI の実装 (index.html)
セキュリティを最大化するため、ブラウザ側(フロントエンド)には API キーを記述せず、自身のバックエンド API (/api/chat) を呼び出す実装を行います。
【このファイルの役割と設計意図】
- 役割: ユーザーからの入力(質問やファイル)を受け付け、結果を画面に描画する「窓口」です。
- 必要性: ユーザーが直感的に RAG を利用するための UI を提供します。
-
設計ポイント:
- API キーを含まないため、ソースコードを誰に見られても(インターネットに公開しても)安全です。
- 通信先を相対パス
/api/chatに設定。
【Vibe Coding 再現用プロンプト】
Static Web Apps にデプロイする index.html を作成してください。セキュリティを考慮し、API キーは含めず、自身のバックエンド/api/chatに対して JSON 形式でプロンプトを送信し、回答を受け取ってチャット形式で表示するモダンな UI としてください。
6.1.1 デプロイ構成ファイルの作成 (staticwebapp.config.json)
Azure 側へバックエンドの言語環境を正確に伝え、かつサイト全体を保護するために必須です。
【このファイルの役割と設計意図】
-
ランタイム明示:
apiRuntimeをpython:3.10に設定することで、Azure 側でバックエンドが Python として正しく認識されます。 - サイト認証の強制: ログインしていないユーザーを Microsoft アカウントのログイン画面へ強制的にリダイレクトさせ、自分専用の環境を構築します。
【再現用プロンプト】
プロジェクトのルートにstaticwebapp.config.jsonを作成してください。
platform.apiRuntimeをpython:3.10に設定。routesを設定し、全ルート (/*) に対してauthenticatedロールを要求してください。- 401 エラー発生時の
responseOverridesを設定し、/.auth/login/aad(Microsoftログイン) へリダイレクトさせてください。
6.2 デプロイ実行(Azure Cloud Shell の利用)
ローカルの CLI 環境に依存せず確実にデプロイを行うため、Azure Portal 組み込みの Cloud Shell を使用します。
【手順】
-
ファイルの Zip 圧縮:
ローカルのプロジェクトフォルダにあるindex.html,staticwebapp.config.json, およびapi/フォルダを 同時に選択 し、右クリックして [Zip ファイルに圧縮する] を選択します。(例:app.zip)- ※ フォルダを包まず、中身を直接圧縮してください。
-
Cloud Shell の起動:
Azure Portal の画面上部にある>_(Cloud Shell) アイコンをクリックし、PowerShell 環境を起動します。


-
Zip のアップロード:
Cloud Shell 画面のメニューバーにある [ファイルのアップロード/ダウンロード] アイコンをクリックし、「アップロード」を選択してapp.zipを Cloud Shell 環境へ送信します。


-
デプロイ・コマンドの実行:
Cloud Shell のプロンプトで以下のコマンドを実行し、Zip ファイルを展開・公開します。
【期待されるフォルダ構成】
コマンド実行後、deploy_tmp フォルダ内が以下の構成になっていることを確認してください。この構造が崩れているとバックエンドが認識されません。
deploy_tmp/
├── index.html
├── staticwebapp.config.json
└── api/
├── function_app.py
├── host.json
└── requirements.txt
# 1. 環境の展開(deploy_tmpというフォルダを作り、その中にファイルを置きます)
mkdir deploy_tmp
Expand-Archive -Path app.zip -DestinationPath deploy_tmp -Force
# 2. デプロイトークンの取得
$token = (az staticwebapp secrets list --name <SWAリソース名> --resource-group rg-VibeVerification --query "properties.apiKey" -o tsv)
# 3. 【決定版】SWA CLI を使用したデプロイ
# API の場所 (--api-location)、言語 (--api-language)、バージョン (--api-version) をすべて明示することで、バックエンドを確実にビルド・認識させます。
npx @azure/static-web-apps-cli deploy ./deploy_tmp --api-location ./deploy_tmp/api --api-language python --api-version 3.10 --deployment-token $token --env production
Phase 7: 自動設定の確認
Bicep により OpenAI のキーが正しく SWA へ注入されていることを Portal で確認します。
- Azure Portal で SWA リソースを開く。
-
[設定] > [環境変数] 画面で
OPENAI_API_KEYやSTORAGE_CONNECTION_STRING等がセットされていることを確認。
Phase 8: RAG 動作検証(UAT)
構築した環境にアクセスし、実際にファイルが検索対象となるかを確認します。
8.1 公開 URL の確認
- Azure Portal で作成した Static Web Apps リソースを開きます。
-
[概要] 画面の右側にある 「URL」(例:
https://...azurestaticapps.net)をクリックします。
8.2 ログインと認証
- URL にアクセスすると、自動的に Microsoft アカウントのサインイン画面へリダイレクトされます。
- 検証用ユーザー、または自身の Microsoft アカウントでログインします。
- 初回のみ、アプリへのアクセス許可同意画面が出るので「承諾」をクリックします。
無事入れました!
8.3 アプリケーションの操作と検証
-
文書のアップロード:
- 画面左側の「ファイルをアップロード」セクションで、検証用のテキストファイルを選択します。
- [Storageへ保存] ボタンをクリックし、「✅ 成功: ... を保存しました」と表示されることを確認します。
今回は以前RAGを作ったときに使った架空のプロフィール(5人分)をアップロードしています。
Web UI経由でアップロードしていますがBLOB Storageにもアップされています。
-
AI との対話:
- 画面右側のチャット欄に、アップロードしたファイルの内容に基づいた質問を入力し、送信します。
うまく動いてます。
-
結果の判定:
- AI がアップロードしたファイルの内容を引用して回答を返せば、RAG システムは正常に稼働しています。
- ※アップロード直後は Azure AI Search のインデックス更新に数秒〜十数秒かかる場合があります。即座に回答されない場合は少し待ってから再度送信してください。
Phase 9: クリーンアップと一時停止
作業完了した際、あるいは作業を一時中断する際の後片付け手順です。
9.1 全リソースの一括削除(推奨)
課金や不正アクセスを確実に防ぐため、作業が終わったらリソースグループごと削除すると安全です。
az group delete --name rg-VibeVerification --yes --no-wait
※ 削除が完了するまで 5〜10 分程度かかります。これにより全ての課金が停止します。
9.2 作業の一時中断(再開予定がある場合)
リソースを消さずに、一時的に安全な状態にする方法です。
-
API 稼働の停止:
Azure Portal で Azure OpenAI を開き、[ネットワーク] 設定から [無効] に切り替えます。これで外部からの API 利用が完全に遮断されます。
-
Web アクセスの遮断:
staticwebapp.config.jsonのallowedRolesを一時的にnobodyなどに変更して再デプロイします。これで自分を含め誰もログインできなくなります。
9.3 データの管理
-
ローカルの成果物:
infra/フォルダやapp.zipは削除しないでください。これらがあれば、いつでも数分で同じ環境を再構築(再現)できます。 -
Blob のデータ: もしアップロードしたファイルのみを消去したい場合は、Portal のストレージアカウントから
uploadsコンテナの中身を削除してください。
4. 最後に
インフラの自動化(IaC)もバイブコーディング出来てしまいました。
フロントエンド、バックエンド、インフラすべてAIで実装できてしまう。というのは非常に大きなことだと実感しています。
勿論検証用なので、かなり簡素な感じですが、人間と壁打ちしながら伴走すればある程度のことは何でもできてしまいますね。素晴らしい。
※レビューは要所要所でしています。直接編集もすることありますが、出来る限りAIに実装させるよう指示だし中心で実装しました。
なお、個人開発でかつ検証なので細かいところは目をつぶってやっていますので、もし参考にされる場合はご自身の環境に合った適切なパラメータやプランをご選定ください。
一応、今回作ったファイル一式は以下に格納しておりますので、好きにご利用ください(自己責任でご利用ください)(何かあればコメント頂けますと幸いですm(__)m)
最後まで見ていただきありがとうございました。













