TECH PLAY

株式会社G-gen

株式会社G-gen の技術ブログ

744

G-gen の杉村です。当記事では、 BigQuery Data Transfer Service で提供される、 データセットコピー 機能を解説します。 BigQuery Data Transfer Service とは データセットコピー機能とは ユースケース 認証・認可 データ転送の挙動 注意点 ストレージ料金 複製の対象外のリソース BigQuery Data Transfer Service とは BigQuery Data Transfer Service は、外部から BigQuery へのデータ転送を自動化する Google Cloud(旧称 GCP)のフルマネージドサービスです。フルマネージドサービスであるため、基盤の準備やメンテナンスは必要ありません。 以下のようなデータソースから、BigQuery へのデータ転送を簡単に自動化できます(一部のみ抜粋)。 転送元 データ形式 Cloud Storage CSV, JSON, Avro, Parque 等 Amazon S3 CSV, JSON, Avro, Parque 等 Azure Blob Storage CSV, JSON, Avro, Parque 等 Google Ads Google 広告レポート YouTube 各種レポート Amazon Redshift テーブル BigQuery Data Transfer Service では 転送構成 (Transfer Config)という設定オブジェクトを作成して、データ転送元、転送先、繰り返しスケジュールを定義します。繰り返しスケジュールでは、日次実行、月次実行、オンデマンドなど、自動実行の頻度を設定できます。 参考 : BigQuery Data Transfer Service とは BigQuery Data Transfer Service は原則、無料で利用できます。ただし、Google Play など一部の転送元を利用する場合のみ料金が発生するほか、Amazon Web Services(AWS)側の外向きデータ転送料金などは発生しますので、ご注意ください。 参考 : Data Transfer Service pricing データセットコピー機能とは 当記事で紹介する データセットコピー (Dataset Copy)機能とは、BigQuery Data Transfer Service の機能の1つです。データの転送元として BigQuery データセットを指定し、転送先として他の BigQuery データセットとして転送構成を定義することができます。 データセットコピー機能では、異なる Google Cloud プロジェクト間や、異なるリージョン間でもデータを複製できます。 2025年4月現在、当機能は Beta 版です。SLA が適用されないことや、サポート対象外であること、また仕様変更の可能性があること等をご認識のうえ、ご利用ください。 参考 : Copy datasets なお、データセットコピー機能の利用自体には料金は発生しませんが、コピーがリージョンをまたぐ場合は、データ転送料金が発生します。詳細は以下の公式ドキュメントをご参照ください。 参考 : Data extraction pricing ユースケース データセットコピーは、以下のようなユースケースで用いられます。 リージョンをまたいだバックアップ リージョンをまたいだデータの複製 本番環境を複製した開発環境の作成 BigQuery では bq コマンドやコンソール画面の操作によって、簡単にテーブルの複製を行うことができますが、通常のテーブル複製は同一リージョン内でしか行うことができません。また、データの INSERT 〜 SELECT も、同一リージョン内のテーブル間に限られます。データセットコピー機能を使うことで、簡単に、ノーコードで、リージョンをまたいだデータ複製・同期が可能です。 また、開発用途などの目的で大量のテーブルがあるデータセットをまるごと複製したい場合も、当機能を使うことで、容易に複製環境を作成することができます。 認証・認可 転送構成を作成する際、デフォルトでは、転送構成を作成したユーザーの Google アカウントの認証情報が使われます。その Google アカウントが、転送元のデータセットに対する読み取り権限と、転送先のデータセットに対する書き込み権限を持っている必要があります。 オプションで、サービスアカウントの認証情報を使うように指定できます。 ユーザーの Google アカウントで認証していると、ユーザーの退職や異動に伴いその Google アカウントが削除されたり、権限を失った場合、転送ジョブが失敗することになります。可能な限り、 転送実行専用のサービスアカウントを作成して指定することが望ましい でしょう。 データ転送の挙動 当機能は、データセット単位でデータを複製します。 Overwrite destination table オプションを有効にするか無効にするかによって、挙動が異なります。 Overwrite destination table オプションが 有効 の場合 転送元データセットに存在するテーブルと同名のテーブルが転送先データセットに存在しない場合、テーブルを新規作成し、内容を複製する その際、作成されるテーブルは、パーティション設定、クラスタ設定、カラムの Description などは同等になる 同名のテーブルが既に存在する場合、転送元のテーブルで転送先のテーブルを上書きする 転送先テーブル内のすべてのレコードが削除されてから、転送元のデータが転送先に移送される 削除されたレコードは、タイムトラベルストレージやフェイルセーフストレージ( 参考 )に残る 最後の転送実行から転送元テーブルが変更されていない場合、そのテーブルの処理はスキップされる Overwrite destination table オプションが 無効 の場合 転送元データセットに存在するテーブルと同名のテーブルが転送先データセットに存在しない場合、テーブルを新規作成し、内容を複製する その際、作成されるテーブルは、パーティション設定、クラスタ設定、カラムの Description などは同等になる 同名のテーブルが既に存在する場合、転送は行われない なお転送先データセットに、転送元データセットには存在しない名称のテーブルが存在する場合、そのテーブルに対しては何も行いません(削除されてしまうようなことはありません)。 注意点 ストレージ料金 当機能を使う場合に特に留意すべきなのは、以下の仕様です。 Overwrite destination table オプションを有効にした場合、転送先テーブルのレコードがすべて削除され、転送元テーブルの内容で上書きされること(TRUNCATE => INSERT の挙動) このときのデータ削除に伴い、 タイムトラベル と フェイルセーフ のストレージが増加すること 前者(1.)については、転送元と転送先のデータの同期を目的としていれば、これ自体は問題ではありません。後者(2.)が問題です。 データは削除されると、論理バックアップを目的としてタイムトラベルストレージに移行されます。そのため、データ移送のたびにタイムトラベルストレージが増えることになります。タイムトラベルストレージの保持期間は2〜7日間から設定できます。保持期間が終了すると、データはフェイルセーフストレージに移行します。フェイルセーフストレージの保持期間は7日間で固定です。また、どちらのストレージ保持期間もゼロにすることはできません。 参考 : タイムトラベルとフェイルセーフによるデータの保持 データセットのストレージの課金モデルを Physical Storage(物理ストレージ。圧縮後の実データ容量に対する課金)にしている場合、「タイムトラベル」と「フェイルセーフ」のストレージは 課金対象 になります。データセットコピーを高い頻度で行い、またテーブルのデータサイズが大きいと、その分、毎回のデータ移送で削除されるデータの量が大きくなり、多額の課金が発生してしまうおそれがあります。 参考 : ストレージの課金モデル 同期したいデータセットのサイズが大きい場合は、データセットコピー機能ではなく、差分のみを転送する SQL を開発して Scheduled Query で定期実行するなど、代替案も検討しましょう。 なお、データセットの課金モデルが Logical Storage(論理ストレージ。圧縮前の額面データサイズに対する課金)であれば、タイムトラベルとフェイルセーフストレージに対しては課金されません。 複製の対象外のリソース 以下のリソースは、データセットコピー機能では複製されません。 外部テーブル ビュー ルーチン(ストアドプロシージャ、UDF、テーブル関数) (コピーがリージョンをまたぐ場合)CMEK で暗号化されたデータセット・テーブル その他の詳細は制限等は、公式ドキュメントをご参照ください。 参考 : 制限事項 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の荒井です。当記事ではプリンタ、スキャナ、アプリなどのシステムからメールを送信する方法をご紹介します。 はじめに ユースケース 前提知識 プリンタ、スキャナ、アプリからのメール送信 グループアドレス 構成 構成図 留意事項 別のアドレスからメールを送信する上限 アカウント管理 グループ管理 システムの設定項目 設定手順 概要 手順 1 : グループ作成 手順 2 : アカウント作成 手順 3 : グループアドレスでメールを送信する設定 手順 4 : 2段階認証設定 手順 5 : アプリパスワード作成 手順 6 : メール送信システム設定 はじめに Google Workspace はユーザーライセンスサービスのため、原則として1人の利用者につき、1ライセンスを購入する必要があります。 しかし業務で使用するプリンタ、スキャナ、アプリケーションなどは、人間の利用者に紐づかないメールアドレスを使用して、通知メールを送信することがあります。 今回は Google グループのメールアドレスを使用して、ユーザーに紐づかないメールアドレスからEメールを送信する方法をご紹介します。 ユースケース ユースケースとして、以下が挙げられます。 複合機でスキャンした後、スキャンデータをメールで送信 システムバックアップをした後、成否メールやアラートメールを送信 Web フォームで問い合わせを受け付けた後、受付完了メールを送信 前提知識 プリンタ、スキャナ、アプリからのメール送信 Google Workspace の公式ドキュメントに、今回ご紹介する内容に関するドキュメントがあります。 以下のドキュメントの「方法 2: Gmail SMTP サーバーを使用してメールを送信する」をご参照ください。 参考 : プリンタ、スキャナ、アプリからのメール送信 - Google Workspace 管理者 ヘルプ 上記の手順では、ユーザーアカウントのメインメールアドレスを使用する例となっておりシステムの数だけユーザーアカウントは必要となってしまいコストが増加してしまいます。また Google はセキュリティ強化のため、2024年9月30日以降はパスワードのみを使用して Google アカウントおよび Google Sync にアクセスするサードパーティアプリのサポートを終了することを明言しています。 参考 : Google Workspace Updates JA: 2024 年 9 月 30 日以降: パスワードのみを使用して Google アカウントおよび Google Sync にアクセスするサードパーティ アプリのサポートを終了 ※ 当初は2022年5月30日と発表されましたが、延期されました。 当記事ではグループアドレスを使用することでユーザーアカウントを最小限にするとともに、上記セキュリティの問題を回避し、2024年9月30日以降も継続して使用できる「アプリパスワード」を用いた方法をご紹介します。 グループアドレス グループアドレス とは、Google グループに設定されるメールアドレスです。グループアドレスに送信されたメールは Google グループの会話(受信ボックス)で受信し、グループメンバーが受信したメールを確認することが出来ます。またグループメンバーはグループアドレスに送信されたメールを自身の Gmail 受信ボックスで受信することができるため、従来のメーリングリストのようにも使用できます。 グループアドレスは、メールアドレスの @ より前の文字列をガイドラインに沿って自由に指定することが可能です。システムごとにわかりやすい名称でメールアドレスを設定しましょう。 今回は、このメールエイリアスをメールの送信元(From)として使います。 参考 : 組織内にグループを作成する - Google Workspace 管理者 ヘルプ 参考 : グループ アドレスで使用できない単語 - Google Workspace 管理者 ヘルプ 参考 : ユーザー名とグループ名のガイドライン - Google Workspace 管理者 ヘルプ 構成 構成図 今回実現する構成は、以下のとおりです。 システム専用のユーザーアカウント(以下 : システム専用アカウント)を1つ作成し、当該アカウントにグループのメールアドレスで送信できる設定を行います。 そのためメールを送信している実態は、システム専用のユーザーアカウントです。 留意事項 別のアドレスからメールを送信する上限 今回の設定ではシステム専用アカウントを1つ作成し、そのアカウントを使用してグループアドレスのメールアドレスでメールを送信する設定を行います。当機能では 1アカウントに設定できるグループアドレスの数(その他アカウント含む)は 99個までという制限があります。 99個を超えるグループアドレスを連携する場合、2つ目のシステム専用アカウントが必要です。 参考 : 別のアドレスやエイリアスからメールを送信する - Gmail ヘルプ アカウント管理 上記 別のアドレスからメールを送信する上限 で記載した通りシステム専用アカウントを作成し、このアカウントからグループアドレスでメールを送信する仕組みとなります。 そのためシステム専用アカウントに障害が発生した場合、連携されているシステムのメール送信が停止するリスクがあります。システム専用アカウントはシステム管理部署で保管し、ユーザーの通常業務では使用しないようにしてください。 ※ システム専用アカウントには、Gmail を使用できるライセンスの適用が必要です。 グループ管理 本記事の設定に沿ってシステム専用のグループアドレス(以下 : システム専用グループ)を作成すると、システムの数が多いお客様では多くのシステム専用グループが作成されることとなり管理工数の増加や運用リスクが発生するケースがあります。 具体例として、組織内で 「 グループ管理者 」 権限をユーザーに付与しグループ運用を情報システム部から切り出しているケースが挙げられます。システムの数に合わせて多くのシステム専用グループを作成すると、管理が煩雑化しオペレーションミスによるグループ削除のリスクが発生します。 グループのメールエイリアス を使用することでグループ数を集約することができますが、どのグループにどのグループのメールエイリアスが設定されているか管理をしていただく必要があります。 対策として、以下運用を推奨します。 システムから送信するメールアドレスは集約し、システム専用グループの数を少なくする グループを運用するユーザーには、当設定について周知する システムの設定項目 本記事の設定は、メールを送信するシステム側の設定項目で「送信元メールアドレスを指定する」ことができる場合にのみ、利用できます。前掲の構成図の赤い吹き出しを参照してください。 送信元メールアドレスが指定できず、SMTP サーバーへ認証したアカウントが送信元メールアドレスとなるシステムの場合、グループアドレスを使った方法では対応できないため、ユーザーアカウントのメインのメールアドレスでメール送信する必要があります。 設定手順 概要 作業手順の概要は以下の通りです。 グループ作成 アカウント作成 グループアドレスでメールを送信する設定 2段階認証設定 アプリパスワード作成 メール送信システム設定 手順 1 : グループ作成 システムで使用するためのメールアドレスを作成するため、システム専用グループ (scan@example.co.jp) を作成します。 参考 : 組織内にグループを作成する - Google Workspace 管理者 ヘルプ アクセス設定はデフォルトのままでも良いですが、セキュリティーポリシーに応じて設定変更をしてください。 グループメンバーの追加は不要です。システム専用アカウントもグループメンバーに含める必要はありません。 初回設定時にグループへ送信されたメールを確認する必要があるため、管理上オーナーは設定します。 手順 2 : アカウント作成 システム専用アカウント (system01@example.co.jp) を作成します。 参考 : 新規ユーザーのアカウントを追加する - Google Workspace 管理者 ヘルプ アカウントに対してライセンスを手動で適用する環境の場合、Gmail を利用できるライセンスを適用してください。 参考 : ライセンスの割り当て、削除、再割り当て - Google Workspace 管理者 ヘルプ 手順 3 : グループアドレスでメールを送信する設定 作成したアカウント (system01@example.co.jp) で、グループアドレス (scan@example.co.jp) からメール送信できるよう、Google Workspace 側で設定を行います。 システム専用アカウント (system01@example.co.jp) で Gmail にログインし、グループアドレス (scan@example.co.jp) から送信できるように設定します。 参考 : 別のアドレスやエイリアスからメールを送信する - Gmail ヘルプ リンク内「手順 2: アドレスを確認する」は、グループのオーナーアカウントで Google グループにアクセスし、システム専用グループの「会話 (受信ボックス)」を確認します。 手順 4 : 2段階認証設定 システム専用アカウント (system01@example.co.jp) に2段階認証の設定を行います。 参考 : 2 段階認証プロセスを有効にする - パソコン - Google アカウント ヘルプ 組織のポリシーとして2段階認証が許可されていない場合、システム管理者と相談のうえ、2段階認証の設定を有効化します。 参考 : 2 段階認証プロセスを導入する - Google Workspace 管理者 ヘルプ 手順 5 : アプリパスワード作成 2段階認証を有効にすると、アカウントに対するアプリパスワードを作成できるようになります。 システム専用アカウント (system01@example.co.jp) でアプリパスワードを発行します。 ※ アプリパスワードが表示されたら、必ずパスワードを控えてください。初回の表示以降は二度と確認できないため、再発行する必要があります。 参考 : アプリ パスワードでログインする - Google アカウント ヘルプ 手順 6 : メール送信システム設定 メールを送信するシステム側で、必要な設定を行います。 以下は一般的な設定例です。詳細な設定方法は、当該システムの管理者に確認してください。 設定項目 パラメータ 備考 SMTP サーバー smtp.gmail.com - 通信ポート 25 / 465 / 587 - SMTP 認証アカウント system01@example.co.jp パラメータは例です。実際に使用するアカウント情報を設定してください SMTP 認証パスワード 1234 abcd 5678 efgh パラメータは例です。実際に使用するアプリパスワードを設定してください From メールアドレス scan@example.co.jp パラメータは例です。実際に使用するメール エイリアスを設定してください Gmail の SMTP サーバーに関する留意事項は、以下をご参照ください。 参考 : プリンタ、スキャナ、アプリからのメール送信 - Google Workspace 管理者 ヘルプ 以上で設定は完了です。送信テストを実施して、本番運用を開始してください。 荒井 雄基 (記事一覧) クラウドソリューション部 オンプレ環境のネットワーク・サーバーシステムを主戦場としていたが、クラウド領域にシフト。 Google Cloud 認定資格 6冠 現在は Google Workspace を中心に企業の DX 推進をサポート。 最近頑張っていることは、子どもがハマっている戦隊モノの踊りを踊れるようになること。
アバター
G-gen の杉村です。2024年2月のイチオシ Google Cloud アップデートをまとめてご紹介します。記載は全て、記事公開当時のものですのでご留意ください。 はじめに Meet で参加者全員向けに画面のピン留めができるように Cloud Logging から Cloud Storage へのエクスポート Cloud Translation で Adaptive Translation が Preview => GA(Preview) Google Meet API が Preview => GA Google アカウントのログイン画面の UI が変更に Gemini Enterprise と Gemini Business Google が新しい生成 AI モデル「Gemma」を公開 Looker Studo リリースノートが Google Cloud リリースノートに統合 BigQuery Data Transfer Service が新しいデータソースに対応 Text-to-Speech で「Casual」Voice が Preview 公開 はじめに 月ごとの Google Cloud アップデートのうち、特にイチオシなものをまとめています。 ある程度の事前知識が必要な記載となっています。サービスごとの前提知識は、ぜひ以下の記事もご参照ください。 blog.g-gen.co.jp またリンク先の公式ガイドは英語版にしないと最新情報が反映されていない場合がありますためご注意ください。 Meet で参加者全員向けに画面のピン留めができるように Google Meet hosts can pin multiple tiles for all meeting participants (2024/02/05) Google Meet で、主催者であれば、特定の人のカメラ映像や画面共有を、全員向けにピン留めできるように。 メインの発表者のカメラやプレゼン画面をピン留めして、参加者がメインコンテンツに集中できるように設定できる 。 Cloud Logging から Cloud Storage へのエクスポート Copy log entries (2024/02/13) Cloud Logging のログが、Cloud Storage に簡単にエクスポート(コピー)できるように(GA)。 監査や分析目的に利用できる。2024年2月現在は、gcloud コマンドでの実行のみ可能。エクスポート自体に料金は発生しない 。 Cloud Translation で Adaptive Translation が Preview => GA(Preview) Adaptive translation (2024/02/14) Cloud Translation で Adaptive Translation(適応型翻訳。LLM を用いた翻訳の調整)が Preview => GA。 少量のサンプルを与えただけで翻訳を最適化。複数の言語に対応しており、日→英や英→日翻訳にも対応している。 Google Meet API が Preview => GA The Google Meet API is now generally available (2024/02/21) Developer Preview Program では Preview 公開されていた Google Meet API が GA(一般公開)に。 プログラマブルに Meet 会議を作成したり、出席者の取得、録画ファイルの取得などのタスクが行える。 Google アカウントのログイン画面の UI が変更に Updated user interface for signing in to or signing up for your Google Account (2024/02/21) Google アカウントのログイン画面のデザインが変わる。機能的な大きな変更は無し。 他の Google 製品と同等の「マテリアルデザイン」に統一される。 Gemini Enterprise と Gemini Business Introducing Gemini for Google Workspace, plus more AI offerings to better meet your business needs (2024/02/22) Duet AI for Google Workspace Enterprise add-on が Gemini Enterprise に改名。また、下位エディションである Gemini Business もリリース。 Google Workspace で、文章の自動生成やスライド画像の生成など、各種生成 AI 機能が使える。 さらに、Gemini Enterprise と Gemini Business から使えるチャットツール Gemini(旧 Bard)も利用可能に。チャットツール Gemini では、モデルとして Gemini Ultra 1.0 を使っており、エンタープライズレベルのデータ保護や管理機能が提供される。 Google が新しい生成 AI モデル「Gemma」を公開 Gemma is now available on Google Cloud (2024/02/22) Gemma: Introducing new state-of-the-art open models (2024/02/22) Google が新しい生成 AI モデル「Gemma」を公開。 軽量で低遅延と表現され、ノート PC などでも稼働するとされている。Vertex AI でカスタマイズし、その後 Google Kubernetes Engine(GKE) にデプロイして、スケーラブルな生成 AI アプリを構築することも想定。 オープンソースの概念に近い「オープンモデル」として位置づけ。従来よりある PaLM 2 や Gemini よりも、よりアプリケーション開発者がアクセスしやすいモデルである印象。 Gemma はラテン語で「宝石」の意 Looker Studo リリースノートが Google Cloud リリースノートに統合 Looker Studio release notes (2024/02/22) Looker Studo のリリースノートが、Google Cloud のリリースノートに統合。 これまでは別サイト・別ページで、RSS も非対応だったが、今後は Google Cloud 側のページで確認できるようになる。 Google Cloud のリリースノートは RSS や BigQuery での配信にも対応している。 BigQuery Data Transfer Service が新しいデータソースに対応 What is BigQuery Data Transfer Service? - Supported data sources (2024/02/26) BigQuery Data Transfer Service が新しいデータソースに対応(Preview)。 Facebook Ads Oracle Salesforce Salesforce Marketing Cloud Service Now BigQuery Data Transfer Service は、簡単に BigQuery へのデータ取り込み自動化ジョブが作成できるサービス。Amazon S3 や Cloud Storage にも対応。 Text-to-Speech で「Casual」Voice が Preview 公開 Casual voices (Preview) (2024/02/26) Text-to-Speech で「Casual」Voice が Preview 公開。 あえて oh, uh, um, mhm のようなフィラーが入ったり、間が入ったりして、自然に聞こえる音声。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の荒井です。当記事ではプリンタ、スキャナ、アプリなどのシステムからメールを送信する方法をご紹介します。 はじめに ユースケース 前提知識 プリンタ、スキャナ、アプリからのメール送信 メールエイリアス 構成 構成図 留意事項 エイリアス数上限 アカウント管理 システムの設定項目 設定手順 概要 手順 1 : アカウント作成 手順 2 : エイリアス設定 手順 3 : エイリアスでメールを送信する設定 手順 4 : 2段階認証設定 手順 5 : アプリパスワード作成 手順 6 : メール送信システム設定 はじめに Google Workspace はユーザーライセンスサービスのため、原則として1人の利用者につき、1ライセンスを購入する必要があります。 しかし業務で使用するプリンタ、スキャナ、アプリケーションなどは、人間の利用者に紐づかないメールアドレスを使用して、通知メールを送信することがあります。 今回はユーザーの予備メールアドレス(メールエイリアス)を使用して、ユーザーに紐づかないメールアドレスからEメールを送信する方法をご紹介します。 ユースケース ユースケースとして、以下が挙げられます。 複合機でスキャンした後、スキャンデータをメールで送信 システムバックアップをした後、成否メールやアラートメールを送信 Web フォームで問い合わせを受け付けた後、受付完了メールを送信 前提知識 プリンタ、スキャナ、アプリからのメール送信 Google Workspace の公式ドキュメントに、今回ご紹介する内容に関するドキュメントがあります。 以下のドキュメントの「方法 2: Gmail SMTP サーバーを使用してメールを送信する」をご参照ください。 参考 : プリンタ、スキャナ、アプリからのメール送信 - Google Workspace 管理者 ヘルプ しかし、上記の手順をそのまま実施してしまうと、2024年9月30日以降は、システムからメールが送信されなくなってしまいます。Google はセキュリティ強化のため、2024年9月30日以降はパスワードのみを使用して Google アカウントおよび Google Sync にアクセスするサードパーティアプリのサポートを終了することを明言しています。 参考 : Google Workspace Updates JA: 2024 年 9 月 30 日以降: パスワードのみを使用して Google アカウントおよび Google Sync にアクセスするサードパーティ アプリのサポートを終了 ※ 当初は2022年5月30日と発表されましたが、延期されました。 当記事では、この問題を回避し、2024年9月30日以降も継続して使用できる「アプリパスワード」を用いた方法をご紹介します。 メールエイリアス メールエイリアス (予備のメールアドレス)とは、Gmail において、ユーザーのメインのメールアドレスに加えて追加できるメールアドレスのことです。メールエイリアスに対して送信されたメールは、自動的にメインのメールアドレスの受信トレイに転送されます。今回は、このメールエイリアスをメールの送信元(From)として使います。 メールエイリアスは、メールアドレスの @ より前の文字列をガイドラインに沿って自由に指定することが可能です。システムごとにわかりやすい名称でメールアドレスを設定しましょう。 参考 : 予備のメールアドレス(メール エイリアス)を追加または削除する - Google Workspace 管理者 ヘルプ 参考 : ユーザー名とグループ名のガイドライン - Google Workspace 管理者 ヘルプ 構成 構成図 今回実現する構成は、以下のとおりです。 留意事項 エイリアス数上限 メールエイリアスは1アカウントに30個まで設定することが可能です。システムごとにメールアドレスが違う場合でも、30個までは1つのアカウントで束ねて運用できます。 メールエイリアスの代わりに「グループアドレス」を使用することも可能ですが、多数のグループを作成する必要があり、管理が煩雑になります。管理工数を削減するために、メールエイリアスを使用する当記事の方法を推奨します。 参考 : Google ワークスペースのメール エイリアスについて - Google Domains ヘルプ アカウント管理 当記事の方法では、ユーザーに紐づかないアカウントを1つ作成します。そのアカウントには、Gmail を使用できる Google Workspace ライセンスを適用する必要があります。 Google Workspace では、ユーザー(従業員)に紐づかないメールアカウントはアンチパターンです。しかしユーザーに紐づいたアカウントで設定を行ってしまうと、当該ユーザーが退職し、アカウントが削除された場合、すべてのシステムで設定を変更し、新しいアカウントを設定しなおす必要があります。 このような状況を回避するため、システム専用のアカウントを作成します。作成したアカウントはシステム管理部署で保管し、ユーザーの通常業務では使用しないようにしてください。 システムの設定項目 本記事の設定は、メールを送信するシステム側の設定項目で「送信元メールアドレスを指定する」ことができる場合にのみ、利用できます。前掲の構成図の赤い吹き出しを参照してください。 送信元メールアドレスが指定できず、SMTP サーバーへ認証したアカウントが送信元メールアドレスとなるシステムの場合、メールエイリアスを使った方法では対応できないため、ユーザーアカウントのメインのメールアドレスでメール送信する必要があります。 設定手順 概要 作業手順の概要は以下の通りです。 アカウント作成 エイリアス設定 エイリアスでメールを送信する設定 2段階認証設定 アプリパスワード作成 メール送信システム設定 手順 1 : アカウント作成 システムで使用する専用アカウント (system01@example.co.jp) を作成します。 参考 : 新規ユーザーのアカウントを追加する - Google Workspace 管理者 ヘルプ アカウントに対してライセンスを手動で適用する環境の場合、Gmail を利用できるライセンスを適用してください。 参考 : ライセンスの割り当て、削除、再割り当て - Google Workspace 管理者 ヘルプ 手順 2 : エイリアス設定 作成したアカウントに、メールエイリアス (scan@example.co.jp) を設定します。 参考 : 予備のメールアドレス(メール エイリアス)を追加または削除する - Google Workspace 管理者 ヘルプ 手順 3 : エイリアスでメールを送信する設定 専用アカウント (system01@example.co.jp) からメールエイリアス (scan@example.co.jp) を送信元としてメール送信できるよう、Google Workspace 側で設定を行います。 専用アカウント (system01@example.co.jp) で Gmail にログインし、メールエイリアス (scan@example.co.jp) から送信できるように設定します。 参考 : 別のアドレスやエイリアスからメールを送信する - Gmail ヘルプ 手順 4 : 2段階認証設定 専用アカウント (system01@example.co.jp) に2段階認証の設定を行います。 参考 : 2 段階認証プロセスを有効にする - パソコン - Google アカウント ヘルプ 組織のポリシーとして2段階認証が許可されていない場合、システム管理者と相談のうえ、2段階認証の設定を有効化します。 参考 : 2 段階認証プロセスを導入する - Google Workspace 管理者 ヘルプ 手順 5 : アプリパスワード作成 2段階認証を有効にすると、アカウントに対するアプリパスワードを作成できるようになります。 専用アカウント (system01@example.co.jp) でアプリパスワードを発行します。 ※ アプリパスワードが表示されたら、必ずパスワードを控えてください。初回の表示以降は二度と確認できないため、再発行する必要があります。 参考 : アプリ パスワードでログインする - Google アカウント ヘルプ 手順 6 : メール送信システム設定 メールを送信するシステム側で、必要な設定を行います。 以下は一般的な設定例です。詳細な設定方法は、当該システムの管理者に確認してください。 設定項目 パラメータ 備考 SMTP サーバー smtp.gmail.com - 通信ポート 25 / 465 / 587 - SMTP 認証アカウント system01@example.co.jp パラメータは例です。実際に使用するアカウント情報を設定してください SMTP 認証パスワード 1234 abcd 5678 efgh パラメータは例です。実際に使用するアプリパスワードを設定してください From メールアドレス scan@example.co.jp パラメータは例です。実際に使用するメール エイリアスを設定してください Gmail の SMTP サーバーに関する留意事項は、以下をご参照ください。 参考 : プリンタ、スキャナ、アプリからのメール送信 - Google Workspace 管理者 ヘルプ 以上で設定は完了です。送信テストを実施して、本番運用を開始してください。 荒井 雄基 (記事一覧) クラウドソリューション部 オンプレ環境のネットワーク・サーバーシステムを主戦場としていたが、クラウド領域にシフト。 Google Cloud 認定資格 6冠 現在は Google Workspace を中心に企業の DX 推進をサポート。 最近の楽しみは、FC24 の選手キャリアで分身を育てること。
アバター
G-gen の堂原です。 Gemini を搭載した Vertex AI Search を用いて、 Google Chat のチャットボット を作成してみましたので、紹介します。 はじめに 前提知識 Vertex AI Search Google Chat API 構成図 Vertex AI Search の設定 Cloud Run functions の設定 パラメータ ソースコード requirements.txt main.py 認証 基盤モデルの指定 Google Chat API の設定 添付 : ソースコード はじめに 当記事では、Google Cloud(旧称 GCP)の Vertex AI Search を用いて、 Google Chat のチャットボット を作成してみます。 Google Chat は Google Workspace に含まれるチャットツールです。REST API である Google Chat API を用いることで、Google Chat から利用するチャットボットを簡単に開発することが可能です。 Google Chat API と Vertex AI Search を組み合わせることで、データの検索や回答の要約をしてくれるチャットボットを開発できます。また、過去の質問と回答の履歴を取り込むことで、チャットボットの回答の精度を上げることができます。 チャットボットのサンプル 前提知識 Vertex AI Search Vertex AI Search は Google Cloud の生成 AI(Generative AI)関連サービスの1つで、Retrieval Augmented Generation(RAG)構成を簡単に構築できるサービスです。以下の記事をご参照ください。 blog.g-gen.co.jp Vertex AI Search では、2024年1月のアップデートで、要約文の生成に Gemini Pro が利用できる ようになりました。 参考 : Vertex AI Search and Conversation - Release notes - January 31, 2024 Google Chat API Google Chat API は、Google Chat に用意された REST API です。メッセージの投稿や、スペースの管理などをプログラムから行うことができます。Google Chat API を用いることで、Google Chat アプリ(チャットボット)を開発することができます。 Google Chat API を使うことで、対話型・非対話型のチャットボットが作成可能であり、メッセージ形式も柔軟にチューニングできます。 参考 : Google Chat - 概要 対話型のチャットボットを開発するには、Google Cloud コンソールで Google Chat API のセットアップを行う必要があります。その際、Google Chat から送られてきたメッセージを処理するためのプログラムを開発して、何らかのプラットフォームで稼働させる必要があります。Google Chat 自体には、プログラムを稼働させるプラットフォームは無いためです。以下は、実装方法の例です。 プログラムを Cloud Run functions (旧 Cloud Functions) にデプロイする。トリガー URL をGoogle Chat API から指定する プログラムを Google Apps Script で実装する。Apps Script プロジェクトのデプロイ ID を Google Chat API から指定する なお Google Chat API を利用するには、Google Cloud プロジェクトが必須です。 参考 : Chat アプリのインタラクション イベントを受信する 構成図 当記事では、以下のような構成でチャットボットを開発しました。 Cloud Storage バケット内の PDF ファイルを検索対象とする Vertex AI Search データストア及びアプリを作成 Google Chat からメッセージを受け取り、Vertex AI Search に検索をかける Cloud Run functions プログラムを開発 Cloud Run functions のトリガー URL を指定するよう Google Chat API を設定 Google Workspace の公式ドキュメントにも、Cloud Run functions を用いて Google Chat アプリを作成するチュートリアルがあり、上記の構成に似た設定を行っている箇所があるため、参考にしてください。 参考 : Cloud Run functions を用いて Google Chat アプリを作成するチュートリアル Vertex AI Search の設定 Vertex AI Search でデータストアとアプリ(App)を作成します。手順については、当記事では詳述しません、 今回のチャットボットでは、要約文を生成する必要があるため、アプリ(App)作成時に Advanced LLM features を有効化します。 Cloud Run functions の設定 パラメータ 以下のようにパラメータを設定します。記載のないパラメータは、デフォルト値とします。 設定項目 小項目 設定値 補足 環境 Cloud Run functions トリガー トリガーのタイプ HTTPS 認証 未承認の呼び出しを許可 他の Google Cloud プロジェクトで作成されたチャットボットからの呼び出しを防ぐため、ソースコード内でチェックを行います サービスアカウント 「ディスカバリー エンジン閲覧者」ロールを有しているものを指定 ランタイム環境変数 PROJECT_ID 今回使用している Google Cloud プロジェクトの ID PROJECT_NUMBER 今回使用している Google Cloud プロジェクトのプロジェクト番号 DATA_STORE Vertex AI Search データストアの ID CHAT_ISSUER リクエストが作成したチャットボットから来たものかを判別するために利用。値は「chat@system.gserviceaccount.com」で固定 PUBLIC_CERT_URL_PREFIX リクエストが作成したチャットボットから来たものかを判別するために利用。値は「 https://www.googleapis.com/service_accounts/v1/metadata/x509/ 」で固定 ランタイム Python 3.12 エントリポイント get_chat ソースコード requirements.txt functions-framework==3.* google-cloud-discoveryengine==0.12.3 oauth2client==4.1.3 main.py ソースコード本文は、本記事の末尾に掲載します。以下に、重要なポイントを解説します。 認証 当記事では、先述のパラメータの通り Cloud Run functions の認証タイプを「未承認の呼び出しを許可」としたうえで、Google Chat からのリクエストに含まれている Authorization ヘッダーの情報を用いて、アクセス元が特定の Google Cloud プロジェクトにてセットアップされたチャットボットであることを確認します。これにより、チャットボット以外からの呼び出しや、他の Google Cloud プロジェクトで作成されたチャットボットからの呼び出しは拒否されます。また、後述する Google Chat API のセットアップを行うためには、Google Cloud プロジェクトに対して IAM 権限 chat.bots.update が必要です。 つまり、Cloud Run functions からメッセージを受け取れるのは、開発者が意図したチャットボットに限定されます。そのチャットボットの設定変更も、IAM 権限を持っている者しかできません。 以上のことから、本構成は十分にセキュアであり、意図しない利用者からチャットボットが利用されることはない、ということができます。 公式ドキュメントでは、Cloud Run functions の認証機能を用いてリクエストの検証を行う方法も紹介されていますが、こちらの方法では他の Google Cloud プロジェクトで作成されたチャットボットからの呼び出しを拒否することが出来ません。 詳細については以下の参考リンクを確認ください。 参考 : Google Chat からのリクエストを確認する 以下が、ソースコードの該当部分です。 if req.method == "GET" : return flask.make_response(flask.jsonify({ "message" : "Bad Request" }), 400 ) auth_header = req.headers.get( "Authorization" ) # 「Authorization」ヘッダーが存在するか確認 if not auth_header: print ( "Missing Authorization header" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) # 「Authorization」ヘッダーが「Bearer」から始まるか確認 if auth_header.split()[ 0 ] != "Bearer" : print ( "Authorization header format is incorrect" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) bearer_token = auth_header.split()[ 1 ] try : token = client.verify_id_token( bearer_token, PROJECT_NUMBER, cert_uri=PUBLIC_CERT_URL_PREFIX + CHAT_ISSUER) if token[ 'iss' ] != CHAT_ISSUER: print ( "Invalid issuee" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) except : print ( "Invalid token" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) 基盤モデルの指定 Vertex AI Search においては、デフォルトでは基盤モデルとして Gemini 1.5 Flash を利用します。Vertex AI Search へのリクエスト時にクラス ModelSpec で明示的に指定することで他のモデルを使用することも可能です。 参考 : Class ModelSpec 参考 : Answer generation model versions and lifecycle # Vertex AI Searchの出力内容に関する設定 content_search_spec = SearchRequest.ContentSearchSpec( # スニペットを出力させない snippet_spec=SearchRequest.ContentSearchSpec().SnippetSpec( return_snippet= False ), # 要約文を出力させる summary_spec=SearchRequest.ContentSearchSpec().SummarySpec( summary_result_count= 3 , include_citations= False , # Gemini Proを用いるように指定 model_spec=SearchRequest.ContentSearchSpec().SummarySpec().ModelSpec( version= "gemini-1.5-flash-001/answer_gen/v1" ) ) ) # Vertex AI Searchにクエリを投げる response = discov_client.search( SearchRequest( serving_config=serving_config, query=text, page_size= 3 , content_search_spec=content_search_spec ) ) Google Chat API の設定 Google Cloud プロジェクトで、Google Chat API を有効にします。その後、Google Chat API の「構成」タブにて以下の設定を行います。 設定項目 小項目 設定値 補足 インタラクティブ機能 1:1 のメッセージを受信する チェックをつけるとダイレクトメッセージでチャットボットが使えます スペースとグループの会話に参加する チェックをつけるとスペースにチャットボットを導入できます 接続設定 「HTTP エンドポイント URL」を選択 HTTP エンドポイント URL Cloud Funcitons のトリガー URL を入力 認証オーディエンス プロジェクト番号 公開設定 「このチャットアプリを xxx (現在の Google アカウントの組織に依存) の特定のユーザーとグループが使用できるようにします」にチェックを付けて、チャットボットを使わせたいユーザまたはグループのメールアドレスを入力 より広い範囲で公開したい場合は Google Workspace Marketplace SDK を用いる必要があります Google Chat API 設定画面サンプル 添付 : ソースコード from typing import Any, Mapping from google.cloud.discoveryengine import SearchServiceClient, SearchRequest from google.protobuf.json_format import MessageToDict from oauth2client import client import functions_framework, flask, os, urllib.parse PROJECT_ID = os.environ.get( "PROJECT_ID" ) PROJECT_NUMBER = os.environ.get( "PROJECT_NUMBER" ) DATA_STORE = os.environ.get( "DATA_STORE" ) # Google Chatから送られてくるBearer Tokenの整合に使用 CHAT_ISSUER = os.environ.get( "CHAT_ISSUER" ) PUBLIC_CERT_URL_PREFIX = os.environ.get( "PUBLIC_CERT_URL_PREFIX" ) def search_document (text: str ) -> Mapping[ str , Any]: discov_client = SearchServiceClient() # Vertex AI Searchのアプリ等基本的な内容を設定 serving_config = discov_client.serving_config_path( project=PROJECT_ID, location= "global" , data_store=DATA_STORE, serving_config= "default_config" ) # Vertex AI Searchの出力内容に関する設定 content_search_spec = SearchRequest.ContentSearchSpec( # スニペットを出力させない snippet_spec=SearchRequest.ContentSearchSpec().SnippetSpec( return_snippet= False ), # 要約文を出力させる summary_spec=SearchRequest.ContentSearchSpec().SummarySpec( summary_result_count= 3 , include_citations= False , # Gemini Proを用いるように指定 model_spec=SearchRequest.ContentSearchSpec().SummarySpec().ModelSpec( version= "gemini-1.5-flash-001/answer_gen/v1" ) ) ) # Vertex AI Searchにクエリを投げる response = discov_client.search( SearchRequest( serving_config=serving_config, query=text, page_size= 3 , content_search_spec=content_search_spec ) ) # 要約文取得 summary = response.summary.summary_text.replace( "<b>" , "" ).replace( "</b>" , "" ) # 関連ファイル取得 references = [] for r in response.results: r_dct = MessageToDict(r._pb) link = r_dct[ "document" ][ "derivedStructData" ][ "link" ] file_name = link.split( "/" )[- 1 ] url = urllib.parse.quote(link.replace( "gs://" , "https://storage.cloud.google.com/" ), ":/" ) file_sentence = f "<a href={url}>{file_name}</a>" references.append(file_sentence) result = { "summary" : summary, "references" : references } return result # チャットボットが実際に出力するメッセージを作成する def create_message (text: str ) -> Mapping[ str , Any]: result = search_document(text=text) reference_sentence = "<br>・" .join(result[ "references" ]) # 返信文作成 cards = { "cardsV2" : [ { "cardId" : "searchResults" , "card" : { "sections" : [ { "collapsible" : False , "widgets" : [ { "textParagraph" : { "text" : "<b>回答文</b><br>" + result[ "summary" ] } }, { "divider" : {} }, { "textParagraph" : { "text" : "<b>関連ファイル</b><br>・" + reference_sentence } } ] } ] } } ] } return cards # チャットボットからメッセージを受信 # → create_message() で作成した JSON を返す @ functions_framework.http def get_chat (req: flask.Request): """ 正しいGoogle Chatから送られてきたリクエストかを確認 """ if req.method == "GET" : return flask.make_response(flask.jsonify({ "message" : "Bad Request" }), 400 ) auth_header = req.headers.get( "Authorization" ) # 「Authorization」ヘッダーが存在するか確認 if not auth_header: print ( "Missing Authorization header" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) # 「Authorization」ヘッダーが「Bearer」から始まるか確認 if auth_header.split()[ 0 ] != "Bearer" : print ( "Authorization header format is incorrect" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) bearer_token = auth_header.split()[ 1 ] try : token = client.verify_id_token( bearer_token, PROJECT_NUMBER, cert_uri=PUBLIC_CERT_URL_PREFIX + CHAT_ISSUER) if token[ 'iss' ] != CHAT_ISSUER: print ( "Invalid issuee" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) except : print ( "Invalid token" ) return flask.make_response(flask.jsonify({ "message" : "Unauthorized" }), 401 ) """ 受け取ったメッセージでVertex AI Searchに検索をかける 検索結果を整形し送信する """ request_json = req.get_json(silent= True ) text = request_json[ "message" ][ "text" ] response = create_message(text=text) return response 堂原 竜希 (記事一覧) クラウドソリューション部データアナリティクス課。2023年4月より、G-genにジョイン。 Google Cloud Partner Top Engineer 2023, 2024に選出 (2024年はRookie of the yearにも選出)。休みの日はだいたいゲームをしているか、時々自転車で遠出をしています。 Follow @ryu_dohara
アバター
G-gen の佐々木です。当記事では、生成 AI モデルである PaLM 2 のチャットボットを構築した際に、モデルからの回答文で同じ文章が何度も繰り返されてしまう事象の解決策を紹介します。 前提知識 事象 解決策 Frequency Penalty パラメータ サンプルコード Frequency Penalty の調整 前提知識 PaLM 2 は Google が開発した生成 AI モデルです。Google Cloud の機械学習サービスである Vertex AI で PaLM API として公開されており、生成 AI を使用したチャットボットの構築などに使用することができます。 PaLM 2 や PaLM 2 のモデルを使用したチャットボットについては以下の記事を参照してください。 blog.g-gen.co.jp また、以下の記事では Slack をフロントエンドとして PaLM 2 モデルを使用したチャットボットを実装しています。 blog.g-gen.co.jp 当記事では、これらの記事で紹介しているような PaLM 2 を使用したチャットボットの利用時に起こりうる事象と、その解決策を解説していきます。 事象 PaLM 2 の chat-bison や text-bison などのモデルを使用して作成したチャットボットに対して、以下のような質問を送信したとします。 # 質問文 クラウドエンジニアの採用面接を想定して、 1000 文字以内の自己PR文を生成してください。 PaLM 2 からは以下のような回答が返ってきます。1回の回答で同じ文章が何度も繰り返されており、自己 PR にはとても使用できない文章になっていることがわかります。 # PaLM 2 の回答 クラウドエンジニアとして、私はクラウドコンピューティングの深い知識と経験を持ち、クラウドインフラストラクチャの設計、構築、管理に精通しています。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 私は、クラウドコンピューティングの分野で 5 年以上の経験を持ち、大手企業のクラウドインフラストラクチャの設計、構築、管理に携わってきました。また、クラウドセキュリティのベストプラクティスにも精通しており、クラウド環境のセキュリティを確保することができます。 PaLM 2 だけではなく、Gemini(旧称:Bard)や ChatGPT などに代表される生成 AI チャットボットでは、このような同じ文章を繰り返す回答が生成される場合があります。 たとえ文章の内容が正しくても、壊れたように同じ文章を繰り返す様子は非常にインパクトがあります。 解決策 Frequency Penalty パラメータ PaLM 2 の回答精度をユーザー側で調整する手段として、Temperature や Top-K、Top-P などのパラメータが存在します。 PaLM 2 ではこれらの代表的なパラメータのほかに、 Frequency Penalty というパラメータを設定することで、同じ文章が繰り返し生成される可能性を低くすることができます。 以下は、 公式ドキュメント の Frequency Penalty に関する説明の抜粋です。 Parameter Description Acceptable values frequencyPenalty Positive values penalize tokens that repeatedly appear in the generated text, decreasing the probability of repeating content. Acceptable values are -2.0—2.0. Minimum value: -2.0 Maximum value: 2.0 サンプルコード PaLM 2 は Python 用の Vertex AI SDK から利用することができますが、2024年2月時点では Frequency Penalty パラメータを含めたリクエストを送信することができないようです。そこで、REST API 経由で Frequency Penalty パラメータを含むリクエストを送信します。 以下のコード例では Frequency Penalty の値を 0.0 に設定しており、この設定値で質問文「クラウドエンジニアの採用面接を想定して、1000文字以内の自己PR文を生成してください。」を送信すると、先ほど事例として紹介した同じ文章を何度も繰り返す回答文が返ってきます。 """ Python のバージョン: 3.12 外部ライブラリのバージョン: google-cloud-aiplatform==1.41.0 vertexai==0.0.1 """ import vertexai import google.auth from vertexai.language_models import ChatModel import json import requests # 環境変数の設定 PROJECT_ID = 'myproject' LOCATION = 'asia-northeast1' MAX_CHARACTER_COUNT = 4000 MAX_MULTI_TURN_COUNT = 50 CHAT_MODEL = 'chat-bison' TIMEZONE = 'Asia/Tokyo' LLM_PARAMETER_MAX_OUTPUT_TOKENS = 1024 # PaLM 2 の REST API エンドポイント URL = f 'https://{LOCATION}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/{CHAT_MODEL}:predict' # モデルに与えるパラメータ LLM_PARAMETER_TEMPERATURE = 0.2 LLM_PARAMETER_TOP_P = 0.95 LLM_PARAMETER_TOP_K = 40 # モデルの回答に同じ文章が繰り返し現れた場合、ペナルティを与えるかどうか (-2.0 ~ 2.0) # 数字が大きいほど同じ文章が繰り返される可能性が低くなる。 FREQUENCY_PENALTY = 0.0 # モデルに送信するメッセージ MESSAGE = 'クラウドエンジニアの採用面接を想定して、1000文字以内の自己PR文を生成してください。' vertexai.init(project=PROJECT_ID, location=LOCATION) chat_model = ChatModel.from_pretrained(CHAT_MODEL) # Google Cloud のアクセストークンを取得 def get_access_token () -> str : credentials, _ = google.auth.default(scopes=[ "https://www.googleapis.com/auth/cloud-platform" ]) auth_req = google.auth.transport.requests.Request() credentials.refresh(auth_req) return credentials.token # PaLM 2 の REST API にメッセージを送信 def send_message (token: str ) -> str : # リクエストのボディ body = { 'instances' : [ { 'messages' : [ { 'author' : 'user' , 'content' : MESSAGE } ] } ], 'parameters' : { 'maxOutputTokens' : LLM_PARAMETER_MAX_OUTPUT_TOKENS, 'temperature' : LLM_PARAMETER_TEMPERATURE, 'topP' : LLM_PARAMETER_TOP_P, 'topK' : LLM_PARAMETER_TOP_K, 'frequencyPenalty' : FREQUENCY_PENALTY } } # リクエストの送信 headers = { 'Authorization' : 'Bearer ' + token, 'Content-Type' : 'application/json' } response = requests.post(URL, headers=headers, json=body) if response.status_code != 200 : print ( 'ERROR: response status code is not 200.' ) print (f 'status code: {response.status_code}' ) return response_content = json.loads(response.content) return response_content[ 'predictions' ][ 0 ][ 'candidates' ][ 0 ][ 'content' ] if __name__ == '__main__' : response = send_message(get_access_token()) # PaLM 2 の回答を出力 print (response) Frequency Penalty の調整 Frequency Penalty の値を最大の 2.0 に変更し、同じ文章が繰り返される事象が解決されるか確認してみます。 サンプルコードの以下の行を修正してから実行してみます。 FREQUENCY_PENALTY = 2.0 # 0.0 → 2.0 に修正 Frequency Penalty を 2.0 に設定した場合の回答は以下のようになりました。同じ文章の繰り返しがなくなり、比較的整った文章になっていることがわかります。 # PaLM 2 の回答 クラウドエンジニアとして、私はクラウドコンピューティングの深い知識と経験を持ち、クラウドインフラストラクチャの設計、構築、管理に精通しています。また、DevOpsやCI/CDパイプラインなどの最新の開発手法にも精通しており、効率的で信頼性の高いシステムを構築することができます。 私はチームプレイヤーでありながら独立して働くこともでき、常に新しいことを学び成長することを目指しています。またコミュニケーション能力が高く複雑な技術的コンセプトを明確かつ簡潔に説明することができます. さらに英語も堪能でグローバルなチームとのコミュニケーションにも問題ありません. 私のスキルと経験は貴社のクラウドエンジニアリングチームにとって貴重な資産になると確信しておりますのでご検討いただければ幸いです 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の杉村です。 Pub/Sub の BigQuery サブスクリプション を使うと、Pub/Sub に対して発行したメッセージを簡単に BigQuery テーブルに書き込むことができます。 前提知識 BigQuery サブスクリプションとは スキーマ テーブルの作成 Pub/Sub トピックの作成 Pub/Sub サブスクリプションの作成 メッセージ送信のテスト BigQuery テーブルの確認 前提知識 BigQuery サブスクリプションとは Pub/Sub は、Google Cloud(旧称 GCP)のフルマネージドなメッセージングサービスです。Pub/Sub の意義や、実現できるアーキテクチャは以下の記事もご参照ください。 blog.g-gen.co.jp Pub/Sub の BigQuery サブスクリプション を使うと、Pub/Sub に発行(パブリッシュ)されたメッセージを、直接 BigQuery に書き込むことができます。 BigQuery サブスクリプションを使わない場合は、Pub/Sub から取得したメッセージを BigQuery に書き込むためのサブスクライバー(メッセージを受け取る主体)を、Cloud Functions や Dataflow で実装する必要があります。一方で BigQuery サブスクリプションを使えば、サブスクライバーの実装は必要なく、Pub/Sub に発行された メッセージがそのまま BigQuery に書き込まれます。 参考 : BigQuery subscriptions スキーマ BigQuery サブスクリプションには、設定方法が3つあります。 トピックスキーマ 、 テーブルスキーマ 、そして スキーマなし です。 前者のトピックスキーマは、あらかじめ Pub/Sub トピックにスキーマ(メッセージの形式)を定義しておきます。トピックスキーマは、Apache Avro と Protocol Buffer の2つの形式に対応しています。 後者のテーブルスキーマは、Pub/Sub に投入された JSON メッセージのキー名と対応する列に、データが書き込まれます。あらかじめ Pub/Sub 側にスキーマを設定しておく必要はありません。 テーブルスキーマの使用例を示します。以下のような JSON メッセージであれば、BigQuery テーブルの「key1」列に「value1」が書き込まれ、「key2」列に「value2」が書き込まれ...というように、JSON キーに対応する列に値が書き込まれます。 { " key1 " : " value1 ", " key2 " : " value2 ", " key3 " : " value3 " } 3つ目のスキーマなしを選択すると、データは対象 BigQuery テーブルの data という名称の列にメッセージを書き込みます。 当記事の検証では、2つ目のテーブルスキーマを使用しました。その流れと結果をご紹介します。 参考 : BigQuery properties サブスクリプション作成画面 テーブルの作成 以下のように、任意のプロジェクトの任意のデータセットに、2つのカラムを持つシンプルなテーブルを作成しました。 Pub/Sub トピックの作成 Pub/Sub のトピックとサブスクリプションを作成します。 まず、 bq-test という名前のトピックを作成しました。トピックの詳細画面から以下のボタンを押すと、そのトピックに紐づくサブスクリプションを作成できます(次のステップ)。 Pub/Sub サブスクリプションの作成 サブスクリプションの作成画面では、配信タイプとして BigQuery への書き込み を選択します。 書き込み先の BigQuery テーブルのプロジェクト、データセット名、テーブル名を指定します。 また、Schema Option には テーブルスキーマを使用する を選択します。 なお、テーブル名を指定した際に、サービスアカウント( service-(プロジェクト番号)@gcp-sa-pubsub.iam.gserviceaccount.com )に権限が不足している旨のエラーメッセージが表示されることがあります。その場合、該当の BigQuery データセットまたはテーブル、あるいはプロジェクトレベルで、同サービスアカウントに BigQuery データ編集者 (roles/bigquery.dataEditor) のロールを付与してください。 サービス アカウント service-(プロジェクト番号)@gcp-sa-pubsub.iam.gserviceaccount.com に、次の BigQuery テーブルへの書き込みに必要な権限がありません: bigquery.tables.get、bigquery.tables.updateData。 メッセージ送信のテスト ここまでで、事前準備が完了しました。動作確認をしてみます。 作成した Pub/Sub トピック bq-test に、テストメッセージを送信(公開またはパブリッシュともいいます)してみます。 トピックの詳細画面から、「メッセージ」タブを開き、「メッセージをパブリッシュ」ボタンを押します。 表示された画面に、JSON メッセージを書き込みます。今回は以下のような JSON を書き込んでみます。 { " id " : " 10001 ", " data " : " Hello. This is a test message. " } 最下部の「公開」ボタンを押下すると、メッセージがパブリッシュされます。 BigQuery テーブルの確認 書き込み対象のテーブルに SELECT 文を実行してみます。以下のように、テーブルにデータが書き込まれていました。 なお、メッセージをパブリッシュしてから SELECT 文を実行するまでには30秒ほどしか経っていませんでしたが、既に反映されていました。 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の荒井です。Google Workspace では、初期設定の際にいくつかの DNS レコードの登録が必要です。本記事では Google Workspace で使用する DNS レコードについて解説します。 前提知識 DNS ドメイン ゾーン レコード 名前解決 TTL Google Workspace で使用するレコード 概要 TXT レコード CNAME レコード MXレコード A レコード DNS の詳細 メールセキュリティに関するレコード 概要 SPF レコード DKIM レコード DMARC レコード 前提知識 DNS DNS はドメインネームシステム(Domain Name System)の略称であり、組織(企業や官公庁、個人など)が保有するドメイン(後述)に関する電話帳のようなものです。 ドメインがどのサーバーで運用されているかを判別し、ユーザーからのリクエストを正しいサーバーに誘導する仕組みです。 DNS は通常、組織ごとに保有されています。また多くの組織が、お名前ドットコムなどのドメイン登録事業者や、Google などのインターネット関連事業者から貸し出される DNS を利用しています。 ドメイン ドメイン とは、インターネット上の住所のようなものです。 インターネットには無数のサーバーが接続されており、Web サーバーやメールサーバーが運用されています。ネットワークに接続されたサーバーは IP アドレス(例 : 172.217.26.227)という正規の住所を保有します。しかしこうした数字の羅列は人間が理解したり、覚えたりしづらいため、IP アドレスに文字列(名前)を付与して管理しています。この名称がドメイン(ドメイン名)です。 ドメインは、Web サイトの URL やメールアドレスの一部として使用されます。例えば、 g-gen.co.jp や google.com はドメイン名です。 ゾーン ゾーン とは、DNS が持つ、ドメインと IP アドレスの対応表です。 1つのドメインごとに少なくとも1つのゾーンが用意されます。ゾーンにレコード(後述)を記載することで、DNS を管理します。 レコード レコード とは、ゾーンに記載された1行1行の設定を指します。 レコードには タイプ (種類)があり、用途や目的が異なります。タイプには以下のようなものがあります。 タイプ名 説明 A レコード ドメイン名(ホスト名)と IP アドレスの対応を記述するためのレコードタイプ TXT レコード テキスト情報を持たせるためのレコードタイプ MX レコード メールサーバーを示すためのレコードタイプ 名前解決 名前解決 とは、ドメイン名から IP アドレスに変換する作業を指します。 例えば、Web ブラウザで www.google.co.jp という URL にアクセスすると、ブラウザは www.google.co.jp に対応する A レコードを DNS に問い合わせます。DNS は対応する A レコードから IP アドレスを返答します。これにより、ブラウザは Google の Web サイトにアクセスすることができます。 この「ドメイン名を DNS に問い合わせて、IP アドレスを得る」というプロセスが、名前解決です。 TTL TTL とは、DNS に問い合わせる側が、そのレコードの返答を何秒間キャッシュに保持してよいかを示す値です。レコードごとに設定します。TTL は「Time To Live」の略称です。 レコードを変更したとしても、TTL の秒数が経過するまでは、DNS 利用者は新たに名前解決を行わず、キャッシュに保存されたレコードを使用するため、設定変更が反映されません。 TTL の単位は 秒 ですので、「TTL=3600」は1時間を示します。 Google Workspace で使用するレコード 概要 ここからは、Google Workspace の初期設定時や運用時によく利用される DNS レコードを紹介します。 TXT レコード TXT レコード とは、ドメインに関する文字列情報が記載されたレコードです。 Google Workspace では初期セットアップの際にドメインの所有権確認として使用します。 またメールの信頼性を高めるため、SPF、DKIM、DMARK(後述)などの設定を行う際も TXT レコードを使用します。 TXT レコードに関する詳細な説明や記述方法については、以下のリンクを参照してください。 参考 : TXT レコード - Google Workspace 管理者 ヘルプ 参考 : TXT レコードの値 - Google Workspace 管理者 ヘルプ CNAME レコード CNAME レコード とは、ドメイン名の正規の名称と、エイリアス名(別名)を紐づけるためのレコードです。Web サーバーなどにはエイリアス名(別名)を付与することができますが、CNAME レコードは、その別名への問い合わせを、正規名に紐づけるためのレコードです。 Google Workspace では、初期セットアップ時のドメイン所有権確認の際に TXT レコードが利用できない場合に使用したり、Google サイトの URL をカスタマイズする際に使用します。 また特殊な使い方として、管理コンソールにアクセスするパスワードを忘れてしまった場合にも、CNAMEレコードを使用することで再設定を行うことが可能です。 CNAME レコードに関する詳細な説明や記述方法については、以下のリンクを参照してください。 参考 : CNAME レコード - Google Workspace 管理者 ヘルプ MXレコード MX レコード とは、ドメインに送られたメールを、指定したメールサーバーへ転送する役割を担うレコードです。MX は、「Mail Exchanger」の略です。 Google Workspace を使わない場合でも、新しいドメイン名でメールを送受信するためには必ず設定します。運用中の MX レコードを変更すると、メールが受信できなくなってしまう可能性もあるため、設定変更の際には注意が必要です。 Google Workspace では、Gmail でメールを送受信できるようにするために、必ず設定が必要です。 MX レコードに関する詳細な説明や記述方法については、以下のリンクを参照してください。 参考 : MX レコード - Google Workspace 管理者 ヘルプ 参考 : Google Workspace の MX レコードの値 - Google Workspace 管理者 ヘルプ A レコード A レコード とは、ドメイン名やホスト名と、IP アドレスを対応させるためのレコードです。 「名前解決」の項でも記載した例を再掲します。例えば、Web ブラウザで www.google.co.jp という URL にアクセスすると、ブラウザは www.google.co.jp に対応する A レコードを DNS に問い合わせます。DNS は対応する A レコードから IP アドレスを返答します。これにより、ブラウザは Google の Web サイトにアクセスすることができます。 Google Workspace では、Google サイトで作成したサイトの URL を、カスタムドメインに変更する際に使用します。 A レコードに関する詳細な説明や記述方法については、以下のリンクを参照してください。 参考 : A レコード - Google Workspace 管理者 ヘルプ DNS の詳細 ここまで、DNS に関する基礎知識を解説しました。より詳細な説明は、以下のリンクを参照してください。 参考 : ドメインとは何か教えてください。 - Google Workspace 管理者 ヘルプ 参考 : DNS に関する基本ガイド - Google Workspace 管理者 ヘルプ 参考 : ドメイン名に関する基本ガイド - Google Workspace 管理者 ヘルプ メールセキュリティに関するレコード 概要 組織がメールを使用する際は、受信者のメールボックスに確実にメールが配信されるよう、メールセキュリティに関する DNS レコードを適切に設定する必要があります。 Google Workspace では適切に DNS レコードを設定することで、以下の効果が期待できます。 自組織から送信されたメールが、受信者の迷惑メールボックスに分類されることを防ぐ 第三者が自組織のドメインを偽装して「なりすましメール」や「フィッシングメール」を送信した場合に、受信者が偽装に気がつくようになる(迷惑メールに分類されたり、ブロックされるようになる) これから記載するメールセキュリティに関する DNS レコードは、Gmail の利用開始にあたっては必須ではありません。しかし、相手方にメールが確実に配信されるよう、適切に設定することが強く推奨されます。 参考 : 認証方法について - Google Workspace 管理者 ヘルプ 参考 : なりすまし、フィッシング、迷惑メールの防止を支援する - Google Workspace 管理者 ヘルプ SPF レコード SPF とは、送信メールのドメイン(メールアドレス)が詐称されていないことを確認するための技術です。 SPF に対応したメールサーバーでは、メール受信時に SPF レコード(実体は、メール送信者のドメインに設定された TXT レコード)の内容を確認し、正規のサーバーからメールが送信されているかどうかを確認します。正規サーバーからの送信ではない場合、受信メールサーバーの仕様に従い、迷惑メールに分類したり、受信拒否するなどの処理を行います。 Google Workspace では、確実にメールが送信できるよう、SPF を設定することを強く推奨しています。 SPF レコードに関する詳細な説明や記述方法については、以下のリンクを参照してください。 参考 : SPF を設定する - Google Workspace 管理者 ヘルプ DKIM レコード DKIM とは、送信メールのドメイン認証技術です。DKIM が送信者側で適切に設定されていると、メール送信時に送信メールサーバーが電子署名を行い、受信者がそれを検証することでメールの改ざん(なりすまし等)を検知することができます。送信者側の DNS に DKIM レコード(実体は TXT レコード)を追加することで設定できます。 Google Workspace では、SPF と同様に、DKIM も設定することが強く推奨されています。 DKIM に関する詳細な説明や記述方法については、以下のリンクを参照してください。 参考 : DKIM を設定する - Google Workspace 管理者 ヘルプ DMARC レコード DMARC とは、SPF や DKIM と同じく、送信メールのドメイン認証技術です。DMARC レコード(実体は TXT レコード)を設定することで、SPF と DKIM の認証が失敗した際の当該メールの処理方法を、送信者側から受信メールサーバーに指示することが出来ます。 SPF と DKIM では、受信メールの正当性検証に失敗したメールをどのように処理するか(廃棄するのか、迷惑メールに分類するのか、あるいはそのまま受信するか)は、受信メールサーバー側の設定に従います。そのため、メール送信者は、そのようなメールの処理方法を指示することもできませんし、処理の結果を把握することも、そのように処理された理由も把握できません。 それに対して DMARC では、認証失敗時に受信メールサーバーが当該メールに対してどういった処理を行わせるかを、送信者側の DNS にポリシー定義することが可能です。また DMARC では、受信メールサーバーからレポートを取得することが可能なため、メール配信が失敗する原因を把握することも可能です。 DMARC レコードに関する詳細な説明や記述方法については、以下のリンクを参照してください。 blog.g-gen.co.jp 参考 : DMARC を設定する - Google Workspace 管理者 ヘルプ 荒井 雄基 (記事一覧) クラウドソリューション部 オンプレ環境のネットワーク・サーバーシステムを主戦場としていたが、クラウド領域にシフト。 Google Cloud 認定資格 7冠 現在は Google Workspace を中心に企業の DX 推進をサポート。 最近頑張っていることは、子どもがハマっている戦隊モノの踊りを踊れるようになること。
アバター
G-gen の藤岡です。当記事では、Google Cloud のログ管理サービス Cloud Logging の Tips を紹介します。 Cloud Logging とは ログカテゴリと保存先 全体像 カテゴリ 保存先 保持期間 ログ料金の節約 2 つの料金軸 Cloud Logging 料金の節約 Gemini Cloud Assist データアクセス監査ログ 有効は継承される 閲覧には追加権限が必要 参考記事 Cloud Logging とは Cloud Logging (旧称 Stackdriver Logging)は、Google Cloud 上のシステム等が生成したログを収集、保管、管理するサービスです。似た名前のサービスで Cloud Audit Logs もありますが、これは監査ログを記録するサービスであり、ログの出力先が Cloud Logging です。 Cloud Logging および Cloud Audit Logs については以下の記事で解説されているので、当記事と併せてお読みください。 blog.g-gen.co.jp blog.g-gen.co.jp ログカテゴリと保存先 全体像 Cloud Logging には大きく分けて ログルーター 、 ログバケット (別名ログストレージ)の 2 つのコンポーネントがあります。 全体像 ログエクスプローラで閲覧できるログは、Cloud Logging ログバケットに保存されているログのみです。そのため、Cloud Storage や BigQuery 等へシンクされたログは、ログエクスプローラで閲覧できません。 カテゴリ Cloud Logging が扱うログカテゴリは 5 つあります。 参考 : Cloud Loggingの概念と仕組みをしっかり解説 参考 : Cloud Logging の概要 - ログのカテゴリ 種別名 説明 プラットフォームログ BigQuery や Cloud Run 等、ほとんどの Google Cloud サービスのログ コンポーネントログ Google が提供するソフトウェア コンポーネントが生成するログ。Google Kubernetes Engine(GKE)の管理機構が出力するログなど 監査ログ Cloud Audit Logs やアクセスの透明性ログ(Google サポート等がユーザのコンテンツにアクセスした際に出るログ) ユーザー作成のログ ユーザーのアプリケーションなどによって出力したログ。エージェントや API 経由で収集 マルチクラウドとハイブリッド クラウドのログ Microsoft Azure や Amazon Web Services(AWS)から取り込んだログやオンプレミスから取り込んだログ このうち、セキュリティログのうちの 1 つである Cloud Audit Logs はさらに以下の 4 つに分類されます。 参考 : Cloud Audit Logs の概要 - 監査ログの種類 No. カテゴリ ログ名 説明 1 管理アクティビティ監査ログ activity リソースに対する更新系の API コールが記録される 2 データアクセス監査ログ data_access リソースに対する読取系の API コールやデータの作成・変更・読取の API コールが記録される (有効化するとログ量が大きくなる可能性があるため注意が必要) 3 システムイベント監査ログ system_event ユーザーではなく Google Cloud サービスによって行われたリソースの構成変更が記録される 4 ポリシー拒否監査ログ policy VPC Service Controls 機能で拒否された API コールが記録される 保存先 Cloud Logging のログはデフォルトで _Required または _Default というログバケットに保存されます。ログバケットは Cloud Storage のバケットとは別物です。 ログカテゴリと保存先 各ログバケットに保存されるログは、ログルーターの詳細画面の包含フィルタで確認できます。 参考 : 転送とストレージの概要 - 包含フィルタ ログルーター画面 _Required ログバケットへシンクされるログルーターの包含フィルタは以下の通りです。 externalaudit から始まるログは Google Workspace のログです。 # 管理アクティビティ監査ログ (セキュリティログ) LOG_ID("cloudaudit.googleapis.com/activity") OR # システムイベント監査ログ (セキュリティログ) LOG_ID("cloudaudit.googleapis.com/system_event") OR # アクセスの透明性ログ (セキュリティログ) LOG_ID("cloudaudit.googleapis.com/access_transparency") OR LOG_ID("externalaudit.googleapis.com/activity") OR LOG_ID("externalaudit.googleapis.com/system_event") OR LOG_ID("externalaudit.googleapis.com/access_transparency") _Default ログバケットへシンクされるログルーターの包含フィルタは以下の通りです。 _Required ログバケットの包含フィルタに NOT が付いているため、 _Required ログバケットにルーティングされないすべてのログは _Default ログバケットへシンクされることが分かります。 NOT LOG_ID("cloudaudit.googleapis.com/activity") AND NOT LOG_ID("externalaudit.googleapis.com/activity") AND NOT LOG_ID("cloudaudit.googleapis.com/system_event") AND NOT LOG_ID("externalaudit.googleapis.com/system_event") AND NOT LOG_ID("cloudaudit.googleapis.com/access_transparency") AND NOT LOG_ID("externalaudit.googleapis.com/access_transparency") つまり、セキュリティログと Google Workspace のログの一部以外は全て _Default のログバケットへシンクされます。ただし、 _Default ログバケットへのシンクは設定変更ができるため、環境によっては上記の包含フィルタと異なる場合もあります。 参考 : 転送とストレージの概要 - ログバケット 参考 : Google Workspace の監査ログ - 監査ログを Google Cloud に転送する Google Workspace サービス 保持期間 _Required ログバケットにシンクされたログは、 400 日間 保持されます。この 保持期間は変更できません 。 _Default ログバケットにシンクされたログは、 30 日間 保持されます。この 保持期間は変更できます が、変更した場合は後述のストレージ料金が発生します。 保持期間 ログ料金の節約 2 つの料金軸 Cloud Logging の料金を節約するには、まず課金の仕組みを正確に理解する必要があります。 Cloud Logging の料金は 取り込み処理量 (公式ドキュメントでは「Logging ストレージ」と記載)と 保管料金 (公式ドキュメントでは「ロギング保持」と記載)の2軸で計算されます。前者の取り込み処理量は、公式の料金ページに「Logging ストレージ」と記載されていますが、これはログの取り込み時に発生する処理量に対する課金であり、ログを保管したサイズに対するものではありません。 参考 : Google Cloud Observability の料金 料金図 Cloud Logging 料金の節約 Cloud Logging の料金を節約する方法の 1 つに、 除外フィルタ で特定のログを除外することが挙げられます。具体的にどのリソースタイプのログが多いかは、Cloud Monitoring の Metrics Explorer で確認できます。ログストレージの画面から遷移すると自動で指標が設定されるため、当記事ではその確認方法を紹介します。 コンソールのログストレージ画面から対象のログバケットの [ このバケットの使用状況データを表示 ] を押下 ログ確認方法① 指標に Log bucket monthly bytes ingested が設定された Metrics Explorer が開く ログ確認方法② Log bucket monthly bytes ingested は 1800 秒ごとのサンプリングのため、ログの合計を 1440 倍 (30 日/月 計算) すると取り込まれているログ量がわかります。どのリソースタイプのログが多いか確認し、ログエクスプローラ等で詳細を確認します。 ただし、ログを除外することによって調査時や Google サポートへ問い合わせ時に必要な情報が不足する場合もあるため注意が必要です。 参考 : 転送とストレージの概要 - 除外フィルタ なお、Log bucket monthly bytes ingested の指標は 2025 年 4 月時点ではベータ版のため、サンプリング間隔等は変更になる場合があります。 もう1つの節約方法は、Cloud Storage や BigQuery にログを逃がすことです。詳細は以下の記事を参照してください。 参考 : Cloud Loggingの概念と仕組みをしっかり解説 - 取り込み料金の節約 Gemini Cloud Assist Gemini Cloud Assist を使うことで、ログエクスプローラのログを要約して表示できます。ログエクスプローラで対象のログを開き、[ Explain this log entry ] を押下すると、要約されたログが表示されます。 Gemini Cloud Assist は、2025 年 4 月現在、プレビューです。 この機能を使用するには、Gemini Cloud Assist が プロジェクトで有効になっており、ユーザーが利用権限を持っている必要があります。さらに、2025 年 4 月現在、Google Cloud コンソールの言語設定が 英語 になっている必要があります。 参考 : Gemini アシスト機能を使用してログエントリを要約する データアクセス監査ログ 有効は継承される データアクセス監査ログ はデフォルトで BigQuery のみ有効になっています。それ以外のサービスは明示的に有効化する必要があります。前述の通り、データアクセス監査ログを有効にすると大量のログが発生する場合があるため注意が必要です。 データアクセス監査ログは組織、フォルダ、プロジェクトレベルで有効化でき、上位階層の設定が継承され、上書きはできません。 例えば、組織で有効化している場合、配下のフォルダやプロジェクトでも有効になり、フォルダやプロジェクトで無効化はできません。 設定は継承される そのため、プロジェクト作成者が明示的に有効化せずとも、上位階層の設定が引き継がれ、データアクセス監査ログがログエクスプローラで閲覧できる場合もあります。 参考 : データアクセス監査ログを有効にする - 構成の概要 閲覧には追加権限が必要 ログエクスプローラで _Required と _Default ログバケット内のログを閲覧するには、ログ閲覧者( roles/logging.viewer )ロールが必要です。 しかしこのロールではデータアクセス監査ログの閲覧はできません。データアクセス監査ログも含めたログを閲覧するには、 プライベート ログ閲覧者 ( roles/logging.privateLogViewer )ロールが必要です。 参考 : IAM によるアクセス制御 - Logging のロール 参考記事 以下の記事では、データの保存先や暗号化など、エンタープライズ企業でよくある制約下における Cloud Audit Logs の運用方法について詳細に記載していますので、ご参照ください。 blog.g-gen.co.jp 藤岡 里美 (記事一覧) クラウドソリューション部 数年前までチキン売ったりドレスショップで働いてました!2022年9月 G-gen にジョイン。ハイキューの映画を4回は見に行きたい。 Google Cloud All Certifications Engineer / Google Cloud Partner Top Engineer 2024 Follow @fujioka57621469
アバター
G-gen の片岩です。当記事では文書のデジタル化と解析を自動化するサービスである Document AI について解説します。 概要 Document AI とは ユースケース 利用方法 対応フォーマット プロセッサ プロセッサとは 汎用プロセッサ OCR プロセッサ Form パーサー 専用プロセッサ カスタムプロセッサ カスタムドキュメントエクストラクタ カスタムドキュメント分類器 カスタムドキュメントスプリッター サマライザ トレーニング Document AI におけるトレーニング カスタムドキュメントエクストラクタにおけるトレーニング 従来型トレーニングを利用したトレーニング 生成 AI を用いたトレーニング トレーニングの流れ 人間参加型 人間参加型とは ラベリングマネージャー ラベラー BigQuery との統合 日本語対応状況 料金 概要 Document AI とは Google Cloud の Document AI は、文書のデジタル化と解析を自動化するクラウドサービスです。手書きのテキストや印刷文書、PDF、スキャンされた画像などのさまざまな形式の文書から名前、住所、電話番号、日付、金額、メールアドレスといった任意の情報を JSON 形式で抽出することができます。 参考 : Document AI 以下の公式サイトでは、ファイルをアップロードして Document AI を簡易的に試すことができます。 参考 : Try Document AI 領収書の解析結果 ユースケース 企業内には多種多様な文書があるため Document AI のユースケースは多岐に及びますが、たとえば以下のようなユースケースが考えられます。 請求書や領収書の自動処理 :金融や会計業務で、請求書や領収書からデータを自動的に抽出し、データベースに入力するプロセスを自動化します。 契約書や法的文書の解析 :法的文書や契約書から重要な情報を抽出し、リスク分析やコンプライアンスチェックを支援します。 カスタマーサービスの最適化 :カスタマーサポートで顧客からの書類を迅速に処理し、応答時間を短縮します。 利用方法 Document AI は、Web ブラウザで操作する Web コンソール (Google Cloud コンソール)、Python など各言語用の クライアントライブラリ 、HTTPS でコールする Rest API などのインターフェイスを介して利用します。 また、Document AI は BigQuery と統合されているため、Document AI による処理を SQL で呼び出すこともできます。詳細は後述します。 Document AI のコンソール画面 参考 : Quickstart: Set up the Document AI API 参考 : Process documents by using client libraries 参考 : APIs and reference 対応フォーマット Document AI は、以下のようなファイルタイプ(フォーマット)に対応しています。 PDF GIF TIFF JPEG PNG BMP WebP 詳細は、以下の公式ドキュメントを参照してください。 参考 : Supported Files プロセッサ プロセッサとは Document AI において、テキストの抽出やドキュメントの分類、解析を実行する主体を プロセッサ と呼びます。プロセッサは大きく以下の 3 つに分類できます。 さまざまな用途に利用できる 汎用プロセッサ 請求書や本人確認書類、契約書など個別の用途に特化した 専用プロセッサ カスタマイズ可能な カスタムプロセッサ 以下ではそれぞれのプロセッサについて詳しく見ていきます。 汎用プロセッサ OCR プロセッサ 最もシンプルな機能を備えたプロセッサが OCR プロセッサ です。 画像や PDF 内のテキストを抽出します。 ここでは一例として領収書の解析結果を示します。 領収書 OCR プロセッサによる解析結果 参考 : Enterprise Document OCR Form パーサー Form パーサー はキーとバリューのペアとして情報を抽出します。 単なる文字列の羅列と異なり、後続処理に連携しやすい形式になっています。 Form パーサーによる解析結果 参考 : Form Parser 専用プロセッサ 専用プロセッサ は、領収書や請求書、契約書のように頻繁に使われるドキュメントの解析に特化したプロセッサです。たとえば領収書であれば、領収書に存在すべき項目を収集します。 先程同様に領収書の解析結果を以下に示します。 専門プロセッサによる解析結果 参考 : Specialized processors 後述しますが、一部の専用プロセッサでは アップトレーニング を実施することにより独自にカスタマイズできます。 参考 : Uptrain a specialized processor カスタムプロセッサ カスタムドキュメントエクストラクタ カスタムドキュメントエクストラクタ は、利用者が事前に設定した内容に沿ってドキュメントから任意の項目を抽出します。専用プロセッサをベースとしたアップトレーニングと異なり、ゼロから新しくプロセッサを作成します。詳細については後述します。 参考 : Custom Extractor 参考 : Create a Custom Document Extractor in the Google Cloud console カスタムドキュメント分類器 カスタムドキュメント分類器 は、利用者が事前にトレーニングした内容に沿ってドキュメントをカテゴリに分類します。たとえば領収書や請求書などを自動で判別するといったことができます。 参考 : Custom Classifier 参考 : Create a Custom Document Classifier in the Google Cloud console カスタムドキュメントスプリッター カスタムドキュメントスプリッター は、利用者が事前にトレーニングした内容に沿ってサイズの大きいドキュメントの境界を特定します。その境界でドキュメントを分割することにより、 1 つのドキュメントを複数のドキュメントに分割することができます。 参考 : Custom Splitter 参考 : Create a Custom Document Splitter in the Google Cloud console サマライザ サマライザ はドキュメントの要約を生成します。生成する文章の長さや、箇条書きといった形式を選択することが可能です。先程の領収書の処理結果を以下に示します。 This document is a receipt issued by Japan Airlines (JAL) on November 22, 2023, at 19:04. It acknowledges the payment of 34,180 yen (including tax) for airfare and fees. The receipt includes the following details: - Date of Issue: October 20, 2023 - Issuing Office: Japan Airlines - Payment Method: Cash, credit card, or other means Please note that this summary is based solely on the provided document and may not include all relevant information. 参考 : Summarizer 参考 : Build a document summarizer in the Google Cloud console トレーニング Document AI におけるトレーニング 一部の専用プロセッサやカスタムプロセッサでは トレーニング によって独自にカスタマイズすることができます。以下のとおりプロセッサに応じて学習内容が異なります。 プロセッサ トレーニングによる学習内容 専用プロセッサ カスタムドキュメントエクストラクタ 抽出対象 カスタムドキュメント分類器 ドキュメントのカテゴリ カスタムドキュメントスプリッター ドキュメントの境界 トレーニングがサポートされている専用プロセッサは以下のとおりです。 給与明細パーサー W2 パーサー 経費パーサー 請求書パーサー 発注書パーサー 参考 : Processor training and evaluation overview カスタムドキュメントエクストラクタにおけるトレーニング 従来型トレーニングを利用したトレーニング カスタムドキュメントエクストラクタでは、専用プロセッサのアップトレーニングと同じようにデータを読み込んで抽出対象を学習することができます。具体的には以下 2 種類のトレーニングが提供されています。 カスタムモデル (テンプレート) を利用する方法 :固定レイアウトの文書に適しています。トレーニングに要するドキュメント数は 3 文書で構いません。 カスタムモデル (モデル) を利用する方法 :年度ごとにフォーマットが変わる文書や、取引先によりフォーマットが変わる文書に適しています。フォーマットごとにサンプルデータを用意してトレーニングします。 生成 AI を用いたトレーニング 生成 AI に抽出対象を検索させる方法もあります。従来型と比較して生成 AI は文脈を読み取ることができるため、契約書のような自由記述型の文書の場合は生成 AI の利用が適しています。こちらも 2 通りの方法でプロセッサを作成できます。 Google が提供する基盤モデルをそのまま呼び出す方法 :サンプルデータが数少ない場合でも有効な方法です。いわゆるワンショットのようなイメージで、生成 AI が文章の意味を把握して対象の項目を抽出します。 ファインチューニングを利用する方法 :Google が提供する基盤モデルのままだと精度不足の場合に有効な方法です。ファインチューニングをすることにより生成 AI のモデル自体を追加学習させ、抽出精度を向上させることができます。 参考 : Which training method should I use? 参考 : Document AI Custom Extractor, powered by gen AI, is now Generally Available 参考 : Document AI Workbench is now powered by generative AI to structure document data faster トレーニングの流れ Document AI におけるトレーニングの流れを以下に示します。 Vertex AI AutoML におけるトレーニングの流れとほぼ同じです。 データセットの作成 ドキュメントのラベル付け トレーニングの実施 評価指標の確認 トレーニングを手早く実行できるように、 これら一連の機能が Document AI ワークベンチ としてまとめられています。 人間参加型 人間参加型とは 実業務では Document AI による処理結果を人間がチェックする運用が必要です。 たとえばサービス導入直後の段階では、Document AI によって処理した全ての結果を人間の担当者がレビューすることが望ましいですし、Document AI の処理精度を十分検証できた後であれば、人間の担当者は項目を読み取れなかった場合だけレビューすれば十分です。Document AI には人間の担当者がレビューできる機構が備わっており、その機構を 人間参加型 と呼びます。 また、レビュー結果をトレーニングサンプルとしてフィードバックすることで、バリエーションが多い場合にも Document AI のプロセッサが徐々に学習し、高精度の処理をできるようになります。 なお、2024年1月16日に 当機能は非推奨 となりました。2025年1月16日に機能が廃止されることが決定しています。 参考 : Human-in-the-Loop Overview ラベリングマネージャー 人間参加型ではラベリング全体のタスクを管理する ラベリングマネージャー と個々の Document AI のラベリング結果を確認する ラベラー によって運用されるイメージです。 ラベリングマネージャーは以下のような画面を利用してタスクを管理し、ラベラーにタスクをアサインします。 ラベリングマネージャによるタスク管理画面 参考 : Labeling Manager UI and Labeler Workbench ラベラー ラベラーは以下のような画面でラベリング結果を確認・修正を実施します。 ラベラーによる確認画面 参考 : Labeling Manager UI and Labeler Workbench BigQuery との統合 Document AI は BigQuery と統合されています。すなわち BigQuery のクエリを発行することにより Document AI による処理を実行することができます。 参考 : BigQuery integrates with Document AI to help build document analytics and generative AI use cases 以下ではおおまかな流れを紹介します。 1. まず Cloud Storage バケットに解析対象の文書を保存します。 2. 次に BigQuery に Cloud Storage を参照する オブジェクトテーブル を作成します。 Cloud Storage を参照する BigQuery のオブジェクトテーブル 3. 適用したい Document AI プロセッサを BigQuery のモデルに登録します。 4. 最後にクエリを発行して文書を処理します。 BigQuery における Document AI プロセッサの呼び出し結果 この方法を用いれば BigQuery のクエリを発行するだけで Document AI による処理を実行することができます。 日本語対応状況 2024年1月時点の日本語対応状況を以下に示します。詳細については こちら をご参照ください。 プロセッサ 日本語対応 GA / Preview OCR プロセッサ 一般提供 (GA) あり Form パーサー 一般提供 (GA) あり 専用プロセッサ (領収書用) 一般提供 (GA) あり 専用プロセッサ (請求書用) 一般提供 (GA) なし カスタムドキュメントエクストラクタ (生成 AI 利用なし) 一般提供 (GA) あり カスタムドキュメントエクストラクタ (生成 AI 利用あり) ※1 あり カスタムドキュメント分類器 一般提供 (GA) なし カスタムドキュメントスプリッター 一般提供 (GA) なし サマライザ プレビュー提供 なし ※1:英語のみ一般提供 (GA) 。ただし日本語はプレビュー提供。ファインチューニングもプレビュー提供。 料金 Document AI の料金は、処理したドキュメントのページ数に応じた従量課金で、プロセッサに応じて単価が変わります。2024年1月時点の料金例を以下に示します。 参考 : Document AI pricing プロセッサ 料金 OCR プロセッサ 1,000 ページあたり $1.5 Form パーサー 1,000 ページあたり $30 専用プロセッサ (Expense parser) 10 ページあたり $0.1 以下の機能を利用する場合は追加の費用が掛かります。 人間参加型を利用する場合、1 ページあたり $0.02 デプロイしたカスタムプロセッサをホスティングする場合、1 時間あたり $0.05 片岩 裕貴 (記事一覧) データアナリティクス準備室 2022年5月にG-gen にジョイン。 AI/ML系に関心が強く、ディープラーニングE資格とProfessional Machine Learningを取得。最近話題のGenerative AIにも興味がある。毎日の日課は三人乗りの電動自転車で子供を幼稚園に送り迎えすること。和歌山県在住。
アバター
G-gen の三木です。Slack 投稿をもとに、気楽に Google Tasks の ToDo リストへタスクを追加したいと思ったので、Zapier を使って自動化してみました。 作ったもの 課題感 Google カレンダーの ToDo リスト機能 登録が面倒 ソリューション アーキテクチャ 手順 1. Slack emojiを作成 2. emoji を追加 3. Zapier と Slack を連携 4. Zap の作成 5. Zap の設定 (Trigger) 6. Zapの設定(Action) 7. テスト 今後の課題 誰が emoji をつけてもタスクが増える [解決済] タスクに自動で期限をつけたい 完了タスクを自動削除 作ったもの Slack で特定リアクションをすると、以下のように Google ToDo リストにタスクが追加されます。 Slackメッセージに特定のリアクションをつけると 自動でGoogleカレンダーのToDoリストに連携されます 日時設定を追加すれば、カレンダーにも連携されます 課題感 Google カレンダーの ToDo リスト機能 当社ではプロジェクトのタスク割当の際、Google Docs のタスク割り当て機能を利用しています。 参考 : Google ドキュメント上からタスクを割り当てる - パソコン - Google ドキュメント エディタ ヘルプ 利用されていない方にはイメージしにくいかと思うので、画面を用意しました。こんな感じで管理しています。 Google Document 上でチェックリストを作り、「割り当て」を押して... 日時と対応者を入れれば... ToDo リストに表示される 日付設定すればGoogleカレンダー上に表示されます。便利。 登録が面倒 G-gen ではコミュニケーションツールとして Slack を利用しています。なので、作業のほとんどは Slack 経由で発生します。 日常のタスクも含めて Google ToDo リストで管理したいと思っていましたが、Slack から転記するのが手間でした。そんなわけで、ソリューションを考えてみました。 ソリューション アーキテクチャ Slack だけで完結させたかったのですが、上手くイベント発生を検知できなかったので、サードパーティのサービスである Zapier を使っています。 手順 1. Slack emojiを作成 Slack で使用する emoji を作成します。 MEGAMOJIで作りました 参考 : MEGAMOJI - カスタム絵文字メーカー 2. emoji を追加 作成した emoji を Slack に追加します。 3. Zapier と Slack を連携 Zapier を連携します。 4. Zap の作成 Zapier にログインして、Zap を作成します。 参考 : Login | Zapier "Create Zap"を選択 5. Zap の設定 (Trigger) 以下のパラメータで設定しました。 ParamName Value App Slack Event New Reaction Added Account 組織のSlackアカウント Trigger - Reaction mikitask ※emoji名を指定します Trigger - Channel 空白 Trigger - User 自分のユーザーID (2024-05-07追記) TriggerのUserを指定することで、「自分がEmojiリアクションをした場合のみタスクが追加される」という制約をかけられます。 これにより、「想定外の場所で登録したEmojiを利用されてタスクが無限に増える...」という不具合を解消することが出来ます。 6. Zapの設定(Action) 以下のパラメータで設定しました。 ParamName Value App Google Tasks Event Create Task Account 組織のGoogleアカウント Acition - Task List マイリスト Action - Title 1. Message Text: ※フィールドを選択 Action - Note 1. Message Parmalink: ※フィールドを選択 Title と Notes は、添付のようにフィールドを選択することで変数化されます 7. テスト Zapをテストします。エラーが発生したら、左ペインの "Zap Runs" からエラーを見てトラブルシュートします。 今後の課題 誰が emoji をつけてもタスクが増える [解決済] 同僚からも emoji を付けてもらえるように、あえて制御していません。 そのため、悪意を持って emoji を連打されると、無限にタスクが増えます。 (2024-05-07追記 社内でアドバイスを貰ったので追記します。 New Reaction Added in Slack のパラメータの「Trigger - User」を設定することで、「特定のユーザーがEmojiを押した場合にのみタスクを追加する」ということが可能です。 タスクに自動で期限をつけたい 最初に Inbox に入る時点でその日時点の日付が入るといいな、と思ってます(私はすべてのタスクをとりあえずInboxに入れて仕分けをする派ですが、ある方が仕分け忘れが減りそうです)。 完了タスクを自動削除 「完了タスクは2週間後に削除」のようにライフサイクルルールを設定したいと考えています。 三木宏昭 (記事一覧) クラウドソリューション部 HROne→ServerWorks→WealthNavi→G-gen。AWS 11資格、Google Cloud認定全冠。Google Cloud Partner Top Engineer 2024。最近の悩みは中年太り。Twitter では クラウド関連のことや副業、その他雑多に呟いています。(頻度少なめ) Follow @cloudeep_miki
アバター
G-gen の佐々木です。当記事では AlloyDB for PostgreSQL でパブリック IP アドレスを有効化して、Cloud Run からの接続を試してみます。 前提知識 AlloyDB と Cloud Run パブリック IP アドレスを使用した AlloyDB への接続 Cloud Run から AlloyDB への接続 VPC の作成 AlloyDB の作成 AlloyDB クラスターの作成 AlloyDB インスタンスの作成 サービスアカウントの作成 データベースの作成 踏み台 Compute Engine VM の作成 踏み台 VM からデータベース、テーブルを作成する 事前準備 AlloyDB に接続する Cloud Run の作成 使用するコード(Go) コンテナイメージのビルド YAML ファイルの作成 Cloud Run サービスの作成 動作確認 前提知識 AlloyDB と Cloud Run AlloyDB for PostgreSQL (以下、AlloyDB)と Cloud Run については、それぞれ以下の記事をご参照ください。 blog.g-gen.co.jp blog.g-gen.co.jp blog.g-gen.co.jp パブリック IP アドレスを使用した AlloyDB への接続 AlloyDB では、プライベート IP アドレスもしくはパブリック IP アドレスを使用した接続がサポートされています。 Cloud SQL 同様、DB インスタンスでパブリック IP アドレスを有効化する場合、 承認されたネットワーク として DB インスタンスにアクセスできるアクセス元 IP アドレス範囲を制限することができます。 AlloyDB ではプロキシソフトウェアである AlloyDB Auth Proxy を使用することで、TLS によって暗号化されたデータベース接続を構成することができるため、パブリック IP アドレスを使用する場合は Auth Proxy 経由で接続することを推奨します。また、Auth Proxy を使用する場合、承認されたネットワークの設定は必要ありません。 参考: Connect using Public IP Cloud Run から AlloyDB への接続 Cloud Run などのサーバーレスサービスから Cloud SQL や AlloyDB などの VPC リソースに接続する場合、プライベート IP アドレスを使用した接続ではサーバーレス VPC アクセスを構成し、コネクタインスタンスを経由して接続を行う必要がありました。 Cloud Run からプライベート IP アドレスで AlloyDB に接続する(Auth Proxy は省略可能) サーバーレス VPC アクセスのコネクタインスタンスは常時起動のリソースであり「起動時間ぶんのコストがかかってしまう」「一度スケールアウトするとスケールインできない」といった仕様があります。そのため Cloud SQL の場合は、Cloud SQL インスタンスでパブリック IP アドレスを有効化し、Cloud SQL Auth Proxy を使用して Cloud Run から接続するケースも少なくありません。 AlloyDB クラスタでパブリック IP アドレスを有効化することで、Cloud SQL 同様、Cloud Run から Auth Proxy を経由したパブリック IP アドレスによる接続を実現することができます。Cloud Run で AlloyDB Auth Proxy を使用する場合、Cloud Run のマルチコンテナ(サイドカー)機能を使用します。 Cloud Run から パブリック IP アドレスで AlloyDB に接続する Cloud Run のマルチコンテナ機能、およびプライベート IP アドレスを使用した AlloyDB への接続に関しては以下の記事で解説しています。 blog.g-gen.co.jp なお、2024年4月に Direct VPC Egress が GA となったことで、サーバーレス VPC アクセスを使用することなく、VPC リソースにプライベート IP で接続することができるようになりました。 Direct VPC Egress 機能の詳細については以下の記事で解説しています。 blog.g-gen.co.jp VPC の作成 AlloyDB に紐付ける VPC を作成します。 プライベートサービスアクセス を使用して、この VPC を AlloyDB が実際に作成されるサービスプロデューサー VPC にピアリング接続します。 # VPC の作成 $ gcloud compute networks create my-vpc --subnet-mode = custom # サービスプロデューサー VPC が使用する IP アドレス範囲を作成 gcloud compute addresses create my-iprange \ --global \ --purpose = VPC_PEERING \ --addresses = 192 . 168 . 200 . 0 \ --prefix-length = 24 \ --network = my-vpc # プライベートサービスアクセスの構成 $ gcloud services vpc-peerings connect \ --service = servicenetworking.googleapis.com \ --ranges = my-iprange \ --network = my-vpc AlloyDB の作成 AlloyDB クラスターの作成 AlloyDB を作成するには、まず大枠となるクラスターを作成します。 以下のコマンドを使用して AlloyDB クラスターを作成します。 # AlloyDB クラスターの作成 $ gcloud alloydb clusters create my-alloycluster \ --password = mypassword \ --region = asia-northeast1 \ --network = my-vpc AlloyDB インスタンスの作成 クラスターを作成したら、その中に パブリック IP アドレスを有効化した DB インスタンスを作成していきます。 --assign-inbound-public-ip フラグで ASSIGN_IPV4 を指定することで、パブリック IP アドレスを有効化できます。 # AlloyDB インスタンスの作成 $ gcloud alloydb instances create my-alloyinstance \ --cluster = my-alloycluster \ --cpu-count = 2 \ --instance-type = PRIMARY \ --region = asia-northeast1 \ --availability-type = ZONAL \ --require-connectors \ --assign-inbound-public-ip = ASSIGN_IPV4 \ --database-flags = password. enforce_complexity =on パブリック IP アドレスを有効化したインスタンスを作成する際、データベースフラグである 「 password.enforce_complexity 」を ON にしないとエラーが発生してしまいます。 # エラー抜粋 ERROR: ( gcloud.alloydb.instances.create ) INVALID_ARGUMENT: The request was invalid: password complexity flag password.enforce_complexity is required when public IP is enabled また、 --require-connectors フラグを指定することで、AlloyDB インスタンスの接続元に Auth Proxy の使用を強制することができます。パブリック IP アドレスを有効化する場合は指定したほうがよいでしょう。 # 使用できるオプションの確認 $ gcloud alloydb instances create --help --- 出力抜粋 --- -- [ no- ] require-connectors Enable or disable enforcing connectors only ( ex: AuthProxy ) connections to the database. Use --require-connectors to enable and --no-require-connectors to disable. 作成された AlloyDB インスタンスを確認すると、 publicIpAddress の項目にパブリック IP アドレスの値が入っていることがわかります。 # AlloyDB インスタンスのパブリック IP アドレスを確認 $ gcloud alloydb instances describe my-alloyinstance \ --cluster = my-alloycluster \ --region = asia-northeast1 \ --format =' value(publicIpAddress) ' サービスアカウントの作成 AlloyDB インスタンスに接続するための権限を付与したサービスアカウントを作成します。このサービスアカウントは後ほど作成する踏み台 VM と Cloud Run で使用します。 # サービスアカウントを作成する $ gcloud iam service-accounts create my-serviceaccount --project = { プロジェクト名 } AlloyDB に接続するために、 roles/alloydb.client および roles/serviceusage.serviceUsageConsumer ロールをサービスアカウントに付与します。 # alloydb.client ロールを付与 $ gcloud projects add-iam-policy-binding { プロジェクト名 } \ --role =" roles/alloydb.client " \ --member = serviceAccount:my-serviceaccount@ { プロジェクト名 } .iam.gserviceaccount.com # serviceusage.serviceUsageConsumer ロールを付与 $ gcloud projects add-iam-policy-binding { プロジェクト名 } \ --role =" roles/serviceusage.serviceUsageConsumer " \ --member = serviceAccount:my-serviceaccount@ { プロジェクト名 } .iam.gserviceaccount.com データベースの作成 踏み台 Compute Engine VM の作成 踏み台 VM から psql クライアントを使用して AlloyDB にデータベースを作成していきます。 AlloyDB にはパブリック IP アドレスを使用して接続するため、VM を作成する VPC は任意のもので構いませんが、ここでは AlloyDB に紐づけた VPC を使用していきます。 踏み台 VM には AlloyDB クライアントのロールを付与したサービスアカウントを紐付けます。 # VM 用のサブネットの作成 $ gcloud compute networks subnets create my-subnet \ --network = my-vpc \ --range = 192 . 168 . 100 . 0 / 28 \ --region = asia-northeast1 # 踏み台 VM の作成 $ gcloud compute instances create my-bastion \ --machine-type = e2-micro \ --subnet = my-subnet \ --zone = asia-northeast1-b \ --image-family = debian-12 \ --image-project = debian-cloud \ --service-account = my-serviceaccount@ { プロジェクト名 } .iam.gserviceaccount.com \ --scopes = cloud-platform ファイアウォールルールを設定し、踏み台 VM への SSH 接続を許可します。 # SSH 接続を許可するファイアウォールルールを作成 $ gcloud compute firewall-rules create my-firewall-rule \ --network = my-vpc \ --allow = tcp:22 \ --direction = INGRESS \ --target-service-accounts = my-serviceaccount@ { プロジェクト名 } .iam.gserviceaccount.com 踏み台 VM からデータベース、テーブルを作成する 踏み台 VM に SSH 接続して作業を進めていきます。 事前準備 AlloyDB に接続するためのクライアントをインストールし、また AlloyDB Auth Proxy をダウンロードします。 # psql クライアントのインストール $ sudo apt-get update && sudo apt-get install -y postgresql-client AlloyDB への接続に Auth Proxy の使用を強制する設定にしたため、AlloyDB Auth Proxy クライアントをダウンロードします(最新バージョンのダウンロードは ドキュメント を参考)。 # Auth Proxy クライアントのダウンロード $ wget https://storage.googleapis.com/alloydb-auth-proxy/v1. 10 . 2 /alloydb-auth-proxy.linux.amd64 -O alloydb-auth-proxy # クライアントを実行可能にする $ chmod +x alloydb-auth-proxy AlloyDB に接続する AlloyDB Auth Proxy を起動して psql クライアントが AlloyDB に接続できるようにします。 Auth Proxy クライアントをそのまま実行した場合、Auth Proxy はプライベート IP アドレスを使用して AlloyDB に接続しようとします。 今回作成した踏み台 VM がある VPC からはプライベートサービスアクセス経由で AlloyDB に接続できるため、プライベート IP アドレスを使用してもよいのですが、ここではあえてパブリック IP アドレスを使用して接続してみます。 以下のコマンドを使用して、バックグラウンドで Auth Proxy を実行します。 # バックグラウンドで AlloyDB Auth Proxy を実行する(実行後 ctrl + C) $ ./alloydb-auth-proxy projects/ { プロジェクト名 } /locations/asia-northeast1/clusters/my-alloycluster/instances/my-alloyinstance \ --public-ip & psql クライアントで Auth Proxy を経由して AlloyDB に接続します。 # psql クライアントを起動する $ psql -h 127 . 0 . 0 . 1 -U postgres -W Password: # パスワードを入力(この記事では mypassword) AlloyDB に接続したら、データベースとテーブルを作成します。 # データベースを作成 > CREATE DATABASE mydb; # データベースの切り替え > \c mydb # users テーブルを作成 > CREATE TABLE users ( id varchar ( 128 ) , name varchar ( 128 )) ; # 適当なデータを挿入 > INSERT INTO users VALUES ( ' 3 ' , ' sasashun ' ) ; # ログアウト > \q ここまで完了したら、踏み台 VM からログアウトします。 以降は VM を使用しないため、消し忘れ防止のためここで削除してしまっても構いません。 Cloud Run の作成 使用するコード(Go) PostgreSQL ドライバを使用して AlloyDB の mydb データベースに接続し、 users テーブルのデータを取得する Web アプリケーションを実装します。 取得したデータはブラウザ上にそのまま表示します。 // main.go package main import ( "database/sql" "fmt" "log" "net/http" "os" _ "github.com/jackc/pgx/v4/stdlib" // PostgreSQLドライバ ) type User struct { ID string NAME string } // AlloyDB Auth Proxy に接続する関数 func connectTCPSocket() (*sql.DB, error ) { mustGetenv := func (k string ) string { v := os.Getenv(k) if v == "" { log.Fatalf( "Warning: %s environment variable not set." , k) } return v } // Cloud Run の環境変数に設定するデータベース接続情報 var ( dbUser = mustGetenv( "DB_USER" ) // データベースユーザ dbPwd = mustGetenv( "DB_PASS" ) // データベースユーザのパスワード dbTCPHost = mustGetenv( "INSTANCE_HOST" ) // 127.0.0.1 (Auth Proxy コンテナ) dbPort = mustGetenv( "DB_PORT" ) // Port 5432 dbName = mustGetenv( "DB_NAME" ) // データベース名 ) // データベース接続情報 dbURI := fmt.Sprintf( "host=%s user=%s password=%s port=%s database=%s" , dbTCPHost, dbUser, dbPwd, dbPort, dbName) // Auth Proxy 経由で AlloyDB に接続 dbPool, err := sql.Open( "pgx" , dbURI) if err != nil { return nil , fmt.Errorf( "sql.Open: %v" , err) } return dbPool, nil } // SELECT * を実行する関数 func selectAll() ([]User, error ) { db, err := connectTCPSocket() if err != nil { return nil , fmt.Errorf( "connectTCPSocket: %v" , err) } defer db.Close() rows, err := db.Query( "SELECT * FROM users" ) if err != nil { return nil , fmt.Errorf( "db.Query: %v" , err) } var users []User for rows.Next() { var u User rows.Scan(&u.ID, &u.NAME) users = append (users, u) } return users, nil } // SELECT オペレーションを実行するハンドラ func selectHandler(w http.ResponseWriter, r *http.Request) { users, err := selectAll() if err != nil { log.Fatal(err) } fmt.Fprintf(w, "Select Users: %v \n " , users) } // Cloud Runで Webサーバを実行する func main() { log.Print( "starting server..." ) http.HandleFunc( "/" , selectHandler) port := os.Getenv( "PORT" ) if port == "" { port = "8080" log.Printf( "defaulting to port %s" , port) } log.Printf( "listening on port %s" , port) if err := http.ListenAndServe( ":" +port, nil ); err != nil { log.Fatal(err) } } コンテナイメージのビルド 当記事では Dockerfile を使用せず、Buildpack を使用してコンテナイメージをビルドします。Buildpack を使用することで、ソースコードを自動でパッケージ化し、デプロイ可能なコンテナイメージを生成することができます。 コンテナイメージは Artifact Registry のリポジトリにプッシュします(リポジトリがない場合は作成してください)。 # Buildpack を使用してコンテナイメージをビルド $ gcloud builds submit --pack image =asia-northeast1-docker.pkg.dev/ { プロジェクト名 } / { リポジトリ名 } /run-alloydb 参考: Buildpack を使用してアプリケーションをビルドする YAML ファイルの作成 当記事では YAML ファイルを使用して Cloud Run サービスをデプロイしていきます。 サイドカーコンテナのコンテナイメージに AlloyDB Auth Proxy のコンテナイメージを指定したファイル service.yaml を作成します。 踏み台 VM で Auth Proxy を使用したときと同様、サイドカーコンテナのエントリポイントの引数( args )で --public-ip=true を指定することで、パブリック IP アドレスを使用した AlloyDB への接続が可能です。 また、プライベート IP アドレスで AlloyDB に接続する場合( 参考 )と比べると、サーバーレス VPC アクセスに関する設定が無くなっています。 # service.yaml apiVersion : serving.knative.dev/v1 kind : Service metadata : name : service-alloyrun spec : template : metadata : annotations : run.googleapis.com/execution-environment : gen1 run.googleapis.com/container-dependencies : '{"alloydb-app":["alloydb-proxy"]}' autoscaling.knative.dev/maxScale : '10' spec : # AlloyDB に接続できるサービスアカウント serviceAccountName : my-serviceaccount@{プロジェクト名}.iam.gserviceaccount.com containers : # Ingress Container - name : alloydb-app # アプリケーションのコンテナイメージを指定する image : asia-northeast1-docker.pkg.dev/{プロジェクト名}/{リポジトリ名}/run-alloydb:latest ports : - containerPort : 8080 # 環境変数にデータベース接続情報を設定する env : - name : DB_USER value : postgres # AlloyDB のデフォルトのユーザ - name : DB_PASS value : mypassword # AlloyDB 作成時に設定したパスワード # サイドカーコンテナの Auth Proxy に接続するため 127.0.0.1(localhost)を指定する - name : INSTANCE_HOST value : 127.0.0.1 - name : DB_PORT value : '5432' - name : DB_NAME value : mydb # Sidecar Container - name : alloydb-proxy # AlloyDB Auth Proxy のコンテナイメージを指定する image : gcr.io/alloydb-connectors/alloydb-auth-proxy:latest args : # AlloyDB インスタンスの接続文字列を設定する - "projects/{プロジェクト名}/locations/asia-northeast1/clusters/my-alloycluster/instances/my-alloyinstance" - --address=0.0.0.0 - --port=5432 - --public-ip= true # パブリックIPを使用して接続する # Startup Probe の設定 startupProbe : tcpSocket : port : 5432 initialDelaySeconds : 5 timeoutSeconds : 1 failureThreshold : 10 periodSeconds : 3 Cloud Run サービスの作成 YAML ファイルからサービスを作成する場合、新規作成であっても gcloud run services replace コマンドを使用します。 出力の URL 欄に Cloud Run のエンドポイントが表示されるので、これをメモしておきます(コンソールからも確認可能)。 # 新しいサービスのデプロイ $ gcloud run services replace service.yaml --region = asia-northeast1 --- 出力例 --- Applying new configuration to Cloud Run service [ service-alloyrun ] in project [ myproject ] region [ asia-northeast1 ] ✓ Deploying new service... Done. ✓ Creating Revision... Creating Service. ✓ Routing traffic... Done. New configuration has been applied to service [ service-alloyrun ] . URL: https://service-alloyrun-xxxxxxxxxx-an.a.run.app YAML ファイルからのデプロイでは metadata.annotations.run.googleapis.com/ingress に all を設定しても「 未認証の呼び出しを許可 」の設定ができないようなので、別途 allUsers に対して Cloud Run 起動元 のロールを付与します。 # 未認証で Cloud Run サービスを呼び出せるようにする $ gcloud run services add-iam-policy-binding service-alloyrun \ --role =" roles/run.invoker " \ --member =" allUsers " \ --region = asia-northeast1 動作確認 ブラウザから Cloud Run のエンドポイントにアクセスします。 サーバーレス VPC アクセスが設定されていなくても、Cloud Run 上のアプリケーションからパブリック IP アドレスで AlloyDB に接続され、 SELECT * クエリの結果が画面に表示されます。 AlloyDB から取得したデータがブラウザに表示される 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の杉村です。 Personalized Service Health は、Google Cloud の障害を特定、通知するサービスです。このサービスについて、徹底解説します。 Personalized Service Health とは 対応プロダクト インシデント インシデントとは Relevance(影響度) 有効化 アラート通知 アラートポリシーの利用 メール通知の例 設定手順 ポリシーを作成 テンプレートを選択 アラートポリシーの編集 参考ドキュメント Personalized Service Health とは Personalized Service Health とは、Google Cloud(旧称 GCP)の障害を特定したり、通知したりするためのサービスです。このサービスの利用に、料金は発生しません。 ここでいう「Google Cloud の障害」とは、Google Cloud のグローバル単位、リージョン単位、ゾーン単位、サービス単位で、機能停止やパフォーマンス低下などが起きることを指します。一方で、Compute Engine VM や Cloud Run で稼働するアプリケーションの障害など、ユーザー側の実装における障害は、このサービスの対象ではありません。 Personalized Service Health が検知した障害は、以下の3つの方法で確認することができます。 Service Health Dashboard(Web 画面) Service Health API Cloud Logging また、障害情報は以下のような方法でメールや Slack に通知することができます。 Cloud Logging にアラートポリシー(ログアラート)を設定し、通知チャンネル(メール、Slack 等)に通知する Service Health API からプログラムで定期的に情報を Pull して、任意の通知先に通知する 概要図 参考 : Personalized Service Health overview 対応プロダクト Personalized Service Health は、多くの Google Cloud プロダクトの障害情報に対応しています。 Compute Engine、Cloud SQL、AlloyDB for PostgreSQL、Firestore、BigQuery、App Engine、Cloud Run などほとんどの代表的なプロダクトに対応しています。詳細なリストは、以下のドキュメントをご参照ください。 参考 : Supported Google products インシデント インシデントとは Personalized Service Health からは、 インシデント という単位で Google Cloud の障害情報を取得できます。インシデントは以下の情報を含んでいます。 名称 説明 Event State イベントの状況。Active または Closed Incident impact イベントの影響箇所。Google Cloud プロダクト名やロケーションなど Personalized relevance インシデントが自分の Google Cloud プロジェクトに影響があるかどうか Description 何が起きているかの説明 Updates from Google Cloud Google Cloud からの追加情報。定期的に追加される Symptoms このイベントが引き起こす実害に関する説明 Workarounds 回避策 インシデントの一覧 インシデントの詳細 Relevance(影響度) イベントが持っている「Personalized relevance」という情報から、そのイベントが利用者の Google Cloud プロジェクトに影響があるかどうかを確認することができます。 影響度には以下の種類があります。 名称 訳語 (※1) 説明 Impacted 影響あり 影響があることが確定 (※2) Related 関連あり プロジェクトに関連があり、プロジェクトで使っているロケーションに影響している Partially Related 部分的に関連 プロジェクトで使っているプロダクトに関連あり。影響が出る可能性がある Not Impacted 影響なし プロジェクトに影響がない Unknown 不明 影響の有無が不明である (※1) 訳語は筆者独自のものです (※2) Compute Engine、Cloud SQL、Firestore、Cloud Bigtable など一部のプロダクトのみ判別可能 イベントが自分のプロジェクトに影響があることが明確であれば、影響度は「Impacted」になりますが、注釈でも示したとおり、この関連度が表示されるのは一部の対応プロダクトのみです。対応プロダクトは、以下の公式ドキュメントで十字のマークがついています。 参考 : Supported Google products 有効化 Personalized Service Health はデフォルトではオフになっており、プロジェクトごとに有効化することができます。繰り返しになりますが、このサービスの利用に料金は発生しません。 有効化するには、Google Cloud コンソールの検索ボックスで「Service Health(日本語の場合は「サービスの状態」)」と検索し、遷移した先の画面で Service Health API を有効化するだけです。 組織配下のすべてのプロジェクトで有効化したい場合、コンソールは提供されていませんが、以下の公式ドキュメントで公開されているシェルスクリプトを使うことができます。 参考 : Enable Personalized Service Health for all projects in an organization or folder アラート通知 アラートポリシーの利用 障害発生時に E メールや Slack などに通知を発報したい場合、Cloud Monitoring のアラートポリシーを使うことができます。 イベントが発生すると、Personalized Service Health はログを Cloud Logging に出力するため、このログをアラートポリシーで検出することで、通知を発報することができます。アラートポリシーの通知先(通知チャンネル)は、E メールや Slack、Pub/Sub などのほか、PagerDuty などのサードパーティ、Webhook(HTTP エンドポイントを呼び出す)などに対応しています。 インシデントの通知 メール通知の例 以下は、メール通知の例です。 メール通知の例 設定手順 ポリシーを作成 Google Cloud コンソールの Personalized Service Health の画面から、ボタン「アラート ポリシーを作成」を押下します。 「アラート ポリシーを作成」を押下 テンプレートを選択 アラートポリシーのテンプレートが複数表示されますので、作成したいアラートに一番近いものを選択します。 なおアラートポリシーとは、Cloud Monitoring の設定オブジェクトであり、特定条件を満たすと E メールや Slack に通知を発報する仕組みのことです。 テンプレートを選択 今回は「利用中のロケーション(リージョン)の障害」「利用中の Google Cloud サービスの障害」を検知したいため、最も近いであろうテンプレートを選択しました。 テンプレートと通知チャンネルを選択 実際に通知したいのが、例えば「東京(asia-northeast1)リージョン」の「BigQuery 障害」だとすると、表示されているテンプレートの内容と異なっていますが、あとから編集可能です。また、テンプレートを2つ選択しているので、2つのアラートポリシーが作成されてしまいますが、ログのフィルタの構文だけを参考にして、片方がのちほど削除します。 また、 通知チャンネル (E メールアドレスや Slack など、通知先設定)を選択します。以前に作成したことがなければ、このプルダウンをクリックすると表示されるメニューの中から「MANAGE NOTIFICATION CHANNELS」を押下することで、通知チャンネルを新規作成することができます。 アラートポリシーの編集 画面下部に、以下のような表示が現れます。「すべてのアラート ポリシーを表示」を押下すると、アラートポリシーの一覧画面へ遷移できます。 表示が消えてしまった場合は、「Cloud Monitoring > アラート > Policies」の部分にある、See all policies をクリックしてください。 以下のように、アラートポリシーが一覧表示されます。 アラートポリシー一覧 Location alerts (us-central1) という方をクリックして選択してみます。ポリシーの詳細が表示されます。ログクエリ構文を見ると、このアラートが、Cloud Logging のクエリ構文を使ってログをフィルタし、引っかかるログがあれば通知を発報する仕組みであることが分かります。 アラートポリシーの詳細 EDIT を押下すると、ポリシーの設定を編集できます。 Choose logs to include in the alert の項までスクロールすると、ログクエリを編集できます。 ログクエリの編集 今回は、対象のロケーションを「東京(asia-northeast1)リージョン」に書き換えてみます。また、テンプレートから作成されたもう1つのアラートポリシー Product alerts (Google Compute Engine) のクエリ構文を一部、コピー&ペーストして、 BigQuery と Cloud Storage に関する障害だけ をフィルタするよう書き換えました。なお、サービス名は 公式ドキュメント の Value for productName or impactedProducts 列の表記に従います。 東京リージョンの BigQuery / Cloud Storage 障害を検知するクエリ resource . type = " servicehealth.googleapis.com/Event " AND labels. " servicehealth.googleapis.com/new_event " = true AND jsonPayload.state = " ACTIVE " AND jsonPayload.@ type = " type.googleapis.com/google.cloud.servicehealth.logging.v1.EventLog " AND jsonPayload.category = " INCIDENT " AND jsonPayload.impactedLocations =~ " asia-northeast1 " AND ( jsonPayload.impactedProducts =~ " Google BigQuery " OR jsonPayload.impactedProducts =~ " Google Cloud Storage " ) PREVIEW LOGS をクリックすると、構文をテストすることができます。過去にこのフィルタに該当するログが出力されたことがある場合に、そのログが表示されます。 またこの画面から、クエリ構文の他にも、件名、通知先、メール本文の体裁などをカスタマイズすることができます。 設定を保存したら、もう1つのアラートポリシー Product alerts (Google Compute Engine) は不要なので、削除しましょう。 参考ドキュメント メール通知の設定手順は、以下の公式ドキュメントをご参照ください。 参考 : Quickstart: Set up an alert また、Cloud Logging のクエリ構文は、以下の公式ドキュメントをご参照ください。 参考 : Logging のクエリ言語 Cloud Monitoring や Cloud Logging の詳細は、以下の記事をご参照ください。 blog.g-gen.co.jp blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の杉村です。2024年1月のイチオシ Google Cloud アップデートをまとめてご紹介します。記載は全て、記事公開当時のものですのでご留意ください。 はじめに GmailへのDMARC設定方法 BigQuery に Document AI が統合 Google Cloud、解約時のデータの外部転送料金を無料に textembedding-gecko でチューニングが Preview => GA Vertex AI Workbench で User Managed Notebook と Managed Notebook が廃止 Cloud Build のサービスアカウントの挙動が変更に Database Migration Service で Oracle to AlloyDB (Preview) Google Meet のカメラ映像でスタジオ光源を AI で再現 プロキシ環境下での ChromeOS デバイスへのログイン要件が変更 AlloyDB for PostgreSQL の PostgreSQL 15 互換バージョンが GA Cloud Run で Cloud Storage をマウントできるように(Preview) Pub/SubのBigQueryサブスクリプションでテーブルスキーマが使用可能に 新サービス「Personalized Service Health」がリリース(GA) はじめに 月ごとの Google Cloud アップデートのうち、特にイチオシなものをまとめています。 ある程度の事前知識が必要な記載となっています。サービスごとの前提知識は、ぜひ以下の記事もご参照ください。 blog.g-gen.co.jp またリンク先の公式ガイドは英語版にしないと最新情報が反映されていない場合がありますためご注意ください。 GmailへのDMARC設定方法 機能アップデートではないが、2024年2月1日以降、個人用の Gmail アカウントに対してメールを配信する送信者に対し、新しいメール送信者ガイドラインを適用することが発表された。その要件の1つである DMARC を Gmail へ設定する方法については、以下の記事で紹介されている。 blog.g-gen.co.jp BigQuery に Document AI が統合 BigQuery integrates with Document AI to help build document analytics and generative AI use cases (2024/01/05) BigQuery に Document AI が統合。生成 AI で PDF や画像を読み取り、テキストとして抽出する。そのテキストを BigQuery から SQL でクエリが可能になる。以下のような手順が実現できる。 Cloud Storage に請求書のスキャン画像を保存 これらのファイルに対し BigQuery オブジェクトテーブルを作成 関数 ML.PROCESS_DOCUMENT を使い、推論を実行 請求書情報を取得 Google Cloud、解約時のデータの外部転送料金を無料に Cloud switching just got easier: Removing data transfer fees when moving off Google Cloud (2024/01/12) Google Cloud の利用をやめることを決定した場合、データの外部転送が無料に(要申請)。万一 Google Cloud の利用をやめても、他クラウドにデータを無料で持ち出せる。Google Cloud を安心して利用開始できることをアピール。 textembedding-gecko でチューニングが Preview => GA Tune text embeddings (2024/01/12) 生成 AI 基盤モデル PaLM 2 のエンべディング用モデルである textembedding-gecko と textembedding-gecko-multilingual で、ファインチューニング機能が Preview => GA。 質問(クエリ)と回答(コーパス)のセットを用意することでエンべディング用モデルをチューニングし、ベクトル検索を最適化。なお、カスタムモデルを利用するにはエンドポイントのデプロイが必要(別料金)。 Vertex AI Workbench で User Managed Notebook と Managed Notebook が廃止 Vertex AI Workbench (2024/01/17) Vertex AI Workbench で、User Managed Notebook と Managed Notebook が廃止になる。廃止期日は約1年後の2025/01/30。 フルマネージドの Jupyter notebook である Vertex AI Workbench は従来、以下の3タイプから選択できたが、残るのは Workbench Instance のみ。2つは廃止になるため、今後は移行が必要。 User Managed Notebook Managed Notebook Workbench Instance Cloud Build のサービスアカウントの挙動が変更に Cloud Build Service Account Change (2024/01/17) 2024/04/29以降に Cloud Build API を有効化したプロジェクトで、Cloud Build が Cloud Build service account ではなく Compute Engine service account を使うようになる。Compute Engine service account への編集者ロール付与を抑止する組織ポリシーを使っている環境下などで影響がある。詳細は以下の記事を参照。 blog.g-gen.co.jp Database Migration Service で Oracle to AlloyDB (Preview) Supported source and destination databases (2024/01/17) Database Migration Service で、Oracle Database から AlloyDB for PostgreSQL への移行がサポートされた(Preview 公開)。Oracle 11g〜21c に対応。Google Cloud の高性能 RDB である AlloyDB へ自動かつオンラインでの移行を実現。 Google Meet のカメラ映像でスタジオ光源を AI で再現 Combine multiple video effects, improve lighting and audio in Google Meet (2024/01/17) Google Meet のカメラ映像でスタジオのような光源(位置や明るさ)を再現したり、AI で通話音声の品質を改善できるように。Duet AI for Google Workspace ライセンス利用者のみ、利用可能。 プロキシ環境下での ChromeOS デバイスへのログイン要件が変更 Set up a hostname allowlist (2024/01/18) インターネット通信がプロキシ等で制限された環境で ChromeOS デバイスを使う場合、指定のホスト名を許可する必要がある。2024/02/16に Google 側でシステム改修があり、これらのホスト名が許可されていないと、ChromeOS デバイスにログインできなくなる可能性がある。 特に www.gstatic.com と ssl.gstatic.com を確認するように通知されている。ホスト名リストはタイトルのリンクから。 AlloyDB for PostgreSQL の PostgreSQL 15 互換バージョンが GA AlloyDB for PostgreSQL release notes - January 19, 2024 (2024/01/19) AlloyDB for PostgreSQL の PostgreSQL 15 互換バージョンが GA(Preview 公開は2023年9月)。選択肢は PostgreSQL 14 互換 or 15 互換の2つに。クラスタ構築時に 14 か 15 を選択。既存クラスタを14から15にアップグレードする場合、新規クラスタ作成とデータ移送が必要。 Cloud Run で Cloud Storage をマウントできるように(Preview) Cloud Storage volume mounts for services (2024/01/19) Cloud Run (service/job) で、Cloud Storage をマウントできるように(Preview)。既存ツールである Cloud Storage FUSE を利用し、読み書きを Cloud Storage API に変換。ファイルシステムとの違いや、クセは FUSE のドキュメントを参照。 なお Cloud Storage FUSE は、Cloud Storage バケットをローカル ファイル システムとしてマウントしてアクセスできるようにする FUSE (file system in user space) アダプタ。Linux から、Cloud Storage バケットをファイルシステムのように扱えるツール。 Pub/SubのBigQueryサブスクリプションでテーブルスキーマが使用可能に Use table schema (2024/01/22) Pub/Sub の BigQuery サブスクリプションで「テーブルスキーマ」が使えるように。従来は Pub/Sub トピック側でトピックスキーマの定義が必要だった。「テーブルスキーマ」では Pub/Sub に JSON でメッセージを入れると、対応する列にデータが入るようになる。 BigQuery サブスクリプション 新サービス「Personalized Service Health」がリリース(GA) Personalized Service Health overview (2024/01/24) 新サービス「Personalized Service Health」がリリース(今回、GA。Preview 公開は 2023/08/03)。Google Cloud 障害を「ダッシュボード閲覧」「API 経由取得」「Cloud Logging へ出力」できる。Cloud Logging にアラートポリシーを設定してメール、Slack、Webhook 等へ通知が可能。 以下の記事も参照のこと。 blog.g-gen.co.jp 杉村 勇馬 (記事一覧) 執行役員 CTO / クラウドソリューション部 部長 元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。 Follow @y_sugi_it
アバター
G-gen の武井です。当記事では Google Cloud SDK の2つの認証コマンドの違いについて解説します。 はじめに 2つの認証用コマンド gcloud auth login gcloud auth application-default login 違い 検証 シナリオ 検証パターン 実行環境 プログラムのソースコード 検証結果 パターン #1 パターン #2 パターン #3 パターン #4 まとめ 検証結果 補足1 (認証情報の格納場所) 補足2 (認証コマンドの実行方法) API スコープ 関連記事 はじめに 2つの認証用コマンド gcloud auth login と gcloud auth application-default login はどちらも Google Cloud SDK の認証 に使用されるコマンドですが、その違いと適切な使い分けが混同されがちです。 そこで当記事では、これらコマンドの基本的な機能や使い分けを、実際の検証を交えて解説します。 参考 : Google Cloud SDK gcloud auth login gcloud auth login を実行すると、個人の Google アカウントを使って認証し、gcloud コマンドラインツールから Google Cloud の各サービスにアクセスできるようになります。 認証に成功すると、例えば Compute Engine のインスタンスや Cloud Storage のバケットといった各サービスを gcloud コマンドで管理できます 。 参考 : gcloud 参考 : gcloud auth login gcloud auth application-default login gcloud auth application-default login を実行すると、個人の Google アカウントもしくはサービスアカウントを使って認証し、任意のアプリケーションが Google Cloud API にアクセスできるようになります。 認証に成功すると、Go や Python といった言語で記述したプログラムや IaC ツールに代表される Terraform など、様々なアプリケーションが Google Cloud の API を呼び出せます。 参考 : gcloud auth application-default login 違い これら2つのコマンドの違いは、 gcloud auth login が gcloud コマンドラインツールのための認証を行うコマンドであるのに対し、 gcloud auth application-default login は Google Cloud SDK を使ったアプリケーションのための認証を行うコマンドである、という点です。 検証 シナリオ 検証パターン このセクションでは gcloud auth login と gcloud auth application-default login の違いを理解するため、4パターンで検証を行います。 gcloud auth login を認証1、 gcloud auth application-default login を認証2として、以下のパターンで検証を行いました。 # 実行するツール 認証1 認証2 1 コマンド ( gcloud storage buckets list ) なし - 2 コマンド ( gcloud storage buckets list ) あり - 3 プログラム ( Cloud Storage API をコール) - なし 4 プログラム ( Cloud Storage API をコール) - あり 実行環境 上記検証を筆者のローカル環境で実施するにあたり、gcloud を以下のように構成しました。 $ gcloud config configurations list NAME IS_ACTIVE ACCOUNT PROJECT COMPUTE_DEFAULT_ZONE COMPUTE_DEFAULT_REGION test-prj-20240109 True test-user01@g-gen.co.jp test-prj-20240109 $ gcloud config list [core] account = test-user01@g-gen.co.jp disable_usage_reporting = True project = test-prj-20240109 Your active configuration is: [test-prj-20240109] 参考 : gcloud CLI の構成の管理 プログラムのソースコード Cloud Storage API を呼び出すプログラムは Go で記述しています。 package main import ( "context" "fmt" "log" "cloud.google.com/go/storage" "google.golang.org/api/iterator" ) func main() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { log.Fatalf( "Failed to create client: %v" , err) } defer client.Close() it := client.Buckets(ctx, "test-prj-20240109" ) // プロジェクトIDをここに設定 for { bucketAttrs, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatalf( "Failed to list buckets: %v" , err) } fmt.Println(bucketAttrs.Name) fmt.Printf( "Location: %s \n " , bucketAttrs.Location) fmt.Printf( "Creation Time: %v \n " , bucketAttrs.Created) fmt.Printf( "Storage Class: %s \n\n " , bucketAttrs.StorageClass) } } 検証結果 パターン #1 認証1 ( gcloud auth login ) を行わずに gcloud storage buckets list を実行した際の結果です。 エラーメッセージに記されている通り、有効な認証情報がないため gcloud auth login を実行して認証情報を取得するよう促されていることがわかります。 $ gcloud storage buckets list ERROR: (gcloud.storage.buckets.list) Your current active account [test-user01@g-gen.co.jp] does not have any valid credentials Please run: $ gcloud auth login to obtain new credentials. For service account, please activate it first: $ gcloud auth activate-service-account ACCOUNT 参考 : gcloud storage buckets list パターン #2 認証1 ( gcloud auth login ) を行ったあとに gcloud storage buckets list を実行した際の結果です。 認証エラーがなくなり、接続先プロジェクトにある Cloud Storage バケットの情報が表示されたことがわかります。 $ gcloud storage buckets list --- creation_time: 2024-01-09T12:38:33+0000 default_storage_class: STANDARD location: ASIA-NORTHEAST1 location_type: region metageneration: 1 name: test-prj-20240109-bucket public_access_prevention: enforced storage_url: gs://test-prj-20240109-bucket/ uniform_bucket_level_access: true update_time: 2024-01-09T12:38:33+0000 パターン #3 認証2 ( gcloud auth application-default login ) を行わずにプログラムを実行した際の結果です。 エラーメッセージに記されている通り、プログラムに有効な認証情報がないため文中の リンク先 に従い認証情報を取得するように促されていることがわかります。 $ go run main.go 2024/01/09 22:45:33 Failed to create client: dialing: google: could not find default credentials. See https://cloud.google.com/docs/authentication/external/set-up-adc for more information exit status 1 パターン #4 認証2 ( gcloud auth application-default login ) を行ったあとにプログラムを実行した際の結果です。 認証エラーがなくなり、接続先プロジェクトにある Cloud Storage バケットの情報が表示されたことがわかります。 $ go run main.go test-prj-20240109-bucket Location: ASIA-NORTHEAST1 Creation Time: 2024-01-09 12:38:33.981 +0000 UTC Storage Class: STANDARD まとめ 検証結果 検証の結果、 ユーザーによる gcloud コマンド実行と、プログラムによる API アクセスでは異なる認証が必要 とわかりました。 # 実行するツール 認証1 認証2 実行結果 1 コマンド ( gcloud storage buckets list ) なし - 失敗 2 コマンド ( gcloud storage buckets list ) あり - 成功 3 プログラム ( Cloud Storage API をコール) - なし 失敗 4 プログラム ( Cloud Storage API をコール) - あり 成功 ※ 認証1: gcloud auth login ※ 認証2: gcloud auth application-default login 補足1 (認証情報の格納場所) 今回の検証で gcloud auth login と gcloud auth application-default login による認証を行いましたが、取得した認証情報は以下のパスに格納されます。 # ホームディレクトリ直下の隠しディレクトリ .config/gcloud に格納 $ pwd && ls -l | grep credentials. /home/test-user01/.config/gcloud -rw------- 1 test-user01 test-user01 346 Jan 9 23:10 application_default_credentials.json -rw------- 1 test-user01 test-user01 12288 Jan 9 23:05 credentials.db # 認証情報 説明 1 application_default_credentials.json gcloud auth application-default login により取得 2 credentials.db gcloud auth login により取得 補足2 (認証コマンドの実行方法) gcloud auth login と gcloud auth application-default login のどちらにおいても、コマンドを実行するだけで認証が行えます。 # gcloud auth login の場合 $ gcloud auth login Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=vfnYU3SJwjYhB5bf4Pvt0tVqda3FHn&access_type=offline&code_challenge=VYMPz-UcrhOnonDiCzim2wBV-LvOdsjFpQ1imxyc8Wo&code_challenge_method=S256 # gcloud auth application-default login の場合 $ gcloud auth application-default login Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login&state=db7JI5mCJGVNnUONd7CQjKNMut9sXL&access_type=offline&code_challenge=5DznJO_rgOO_WP_dHHpwfAbrPYW1p-m7ndU5xvpXydU&code_challenge_method=S256 認証コマンドを実行すると別途 Web ブラウザが起動して認証に使用するアカウントを選択する画面が表示されます。 左が gcloud auth login、右が gcloud auth application-default login 実行時の画面 許可 をクリックすると認証が成功し、ブラウザ上に認証が完了した旨が表示されます。 左が gcloud auth login、右が gcloud auth application-default login 実行時の画面 認証完了画面 API スコープ Google ドライブ上の Google スプレッドシートを参照するような Python スクリプトを開発する例を考えます。このスクリプトでは、BigQuery に定義した外部テーブルを経由して、Google スプレッドシートから情報を取得していました。この記事で紹介したように gcloud auth application-default login を用いて認証したのにも関わらず、ローカル PC でテストした際に、以下のようなエラーメッセージが表示されました。 google.api_core.exceptions.Forbidden: 403 Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.; reason: accessDenied, location: (英数字), message: Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials. 事前に gcloud auth コマンドを実行した Google アカウントには、間違いなく Google ドライブへの権限も、対象のシートへの権限も、もちろん BigQuery への権限も付与されています。どうしてこのエラーが起こったのでしょうか。 これは、 gcloud auth コマンドを実行する際の API スコープ が関係しています。 gcloud auth application-default login を実行すると、デフォルトでは Google ドライブへのアクセス権限はスコープに含まれません。以下のように明示的に指定して、コマンドを実行します。 gcloud auth application-default login --scopes \ " https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/drive.readonly " これにより、Google ドライブへの読み取り権限が認証情報にスコープとして含まれ、正しくスクリプトを実行することができました。API スコープの名称やそこに含まれる権限は、公式ドキュメントに記載されています。以下は、Google Drive API のドキュメントです。 参考 : Drive API スコープ 同様に、gcloud コマンドの認証時に Google ドライブへのアクセスを許可するには、以下のコマンドを実行します。 gcloud auth login --enable-gdrive-access 関連記事 ローカル環境で Terraform を実行する際の認証については以下の記事で解説していますのでこちらもあわせてご確認いただけると幸いです。 blog.g-gen.co.jp 武井 祐介 (記事一覧) クラウドソリューション部所属。G-gen唯一の山梨県在住エンジニア Google Cloud Partner Top Engineer 2025 選出。IaC や CI/CD 周りのサービスやプロダクトが興味分野です。 趣味はロードバイク、ロードレースやサッカー観戦です。 Follow @ggenyutakei
アバター
G-gen の佐々木です。当記事では Cloud Run で Cloud Storage バケットをボリュームマウントする方法を解説します。 前提知識 Cloud Run とは Cloud Storage(GCS)とは ネイティブ機能によるマウント Cloud Storage バケットの作成 バケットにテキストファイルをアップロード Artifact Registry リポジトリの作成 コンテナイメージの作成 使用するコード コンテナイメージのビルド Cloud Run サービスの作成 コンソールから Cloud Run サービスを作成する場合 CLI で Cloud Run サービスを作成する場合 YAML ファイルから Cloud Run サービスを作成する場合 動作確認 前提知識 Cloud Run とは Cloud Run は Google Cloud のマネージドなコンテナ実行基盤を使用してアプリケーションを実行することができるサーバーレス コンテナコンピューティング サービスです。 HTTP リクエストをトリガーとする Cloud Run services と、手動もしくはスケジュール、ワークフローをトリガーとする Cloud Run jobs の 2種類が提供されています。当記事で紹介する機能は、いずれの Cloud Run でも使用することができます。 それぞれ、以下の記事でサービスの詳細を解説しています。 blog.g-gen.co.jp blog.g-gen.co.jp Cloud Storage(GCS)とは Cloud Storage は Google Cloud が提供する容量無制限のオブジェクトストレージサービスであり、99.999999999% (イレブンナイン) の堅牢性を持つオブジェクトストレージを安価に利用することができます。 Cloud Storage の詳細は以下の記事で解説しています。 blog.g-gen.co.jp ネイティブ機能によるマウント Cloud Run では Cloud Storage FUSE を利用することで、Cloud Storage バケットをローカルファイルシステムとしてマウントし、コンテナからバケット内のオブジェクトにアクセスすることができます。従来の方法では、コンテナに Cloud Storage FUSE を明示的にインストールして実行する必要がありました。 2024年1月のアップデートにて、明示的に Cloud Storage FUSE をインストールしなくても、Cloud Run の ネイティブ機能として Cloud Storage バケットをマウントすることができるようになりました。 ネイティブ機能では、従来の方法同様、Cloud Storage FUSE を使用してマウントする点は変わりませんが、FUSE に関する処理はサービスの裏側で行われるため、ユーザー側で FUSE の設定を行う必要がなくなります。Cloud Storage FUSE の制限事項や、従来の利用方法については、以下の記事で解説しています。 blog.g-gen.co.jp 当記事ではこれ以降、Cloud Run サービスを使用して、ネイティブ機能によるバケットのマウントを試してみます。 Cloud Storage バケットの作成 Cloud Run からファイルシステムとして使用する Cloud Storage バケットを作成します。 ここではバケット名を mybucket としていますが、実際のバケット名はグローバルに一意の名前を設定する必要があります。 # Cloud Storage バケットを作成する $ gcloud storage buckets create gs://mybucket --location = asia-northeast1 バケットにテキストファイルをアップロード 作成したバケットにテキストファイル test.txt を配置しておきます。 # テキストファイルの作成 $ echo ' Hello, GCS!! ' > test .txt # テキストファイルをバケットにアップロード $ gcloud storage cp test .txt gs://mybucket Artifact Registry リポジトリの作成 Cloud Run にデプロイするコンテナイメージを格納するための Artifact Registory リポジトリを作成します。 # Artifact Registry リポジトリを作成する $ gcloud artifacts repositories create myrepo \ --repository-format = docker \ --location = asia-northeast1 コンテナイメージの作成 使用するコード 当記事では、マウントした Cloud Storage バケットからテキストファイルの中身を読み取り、ブラウザ上に表示するだけの簡単な Web アプリケーションを作成します。 // main.go package main import ( "fmt" "log" "net/http" "os" ) func readGCS() ( string , error ) { // マウントした Cloud Storage バケットからテキストファイルを読み込む f, err := os.Open( "/mnt/gcs/" + "test.txt" ) if err != nil { return "" , err } defer f.Close() text := make ([] byte , 1024 ) count, err := f.Read(text) if err != nil { return "" , err } return string (text[:count]), nil } func readGCSHandler(w http.ResponseWriter, r *http.Request) { text, err := readGCS() if err != nil { log.Printf( "failed to read GCS: %v" , err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // text の内容をブラウザに表示する fmt.Fprintf(w, "%s" , text) } func main() { log.Print( "Starting server..." ) http.HandleFunc( "/" , readGCSHandler) port := os.Getenv( "PORT" ) if port == "" { port = "8080" } log.Printf( "Listening on port %s" , port) if err := http.ListenAndServe( ":" +port, nil ); err != nil { log.Fatal(err) } } コンテナイメージのビルド Cloud Build を使用してコンテナイメージをビルドし、Artifact Registry リポジトリにプッシュします。 当記事では Dockerfile を使用せず、Buildpack を使用してコンテナイメージをビルドします。Buildpack を使用することで、ソースコードを自動でパッケージ化し、デプロイ可能なコンテナイメージを生成することができます。 # Buildpack を使用してコンテナイメージをビルド $ gcloud builds submit --pack image =asia-northeast1-docker.pkg.dev/myproject/myrepo/run-gcs 参考: Buildpack を使用してアプリケーションをビルドする Cloud Run サービスの作成 コンソールから Cloud Run サービスを作成する場合 作成画面の「コンテナ、ボリューム、ネットワーキング、セキュリティ」項目でボリュームマウントの設定を行います。 まず、「ボリューム」タブでマウントするバケットを選択します。 マウント対象の Cloud Storage バケットを選択 そして「コンテナ」タブで、コンテナにマウントするボリュームとマウントパスの設定を行います。 コンテナにマウントするボリュームとマウントパスの設定 CLI で Cloud Run サービスを作成する場合 公式ドキュメントでは gcloud run service update コマンドを使用した方法が紹介されていますが、当記事では gcloud run deploy コマンドを使用してサービスを作成します。 いずれのコマンドでもサービスを新規作成することができますが、 deploy コマンドでは --allow-unauthenticated オプションを使用して、未認証のサービス呼び出しを許可した状態でサービスを作成することができます。 # Cloud Run サービスの作成 $ gcloud run deploy run-gcs \ --image = asia-northeast1-docker.pkg.dev/myproject/myrepo/run-gcs \ --region = asia-northeast1 \ --execution-environment = gen2 \ --allow-unauthenticated \ --add-volume = name =gcs, type= cloud-storage, bucket =mybucket \ --add-volume-mount = volume =gcs,mount-path = /mnt/gcs 使用するオプションは以下のようになります。 オプション 説明 --image Artifact Registory リポジトリにプッシュしたコンテナイメージを指定します。 --region Cloud Run サービスを作成するリージョンを指定します。 --execution-environment Cloud Storage FUSE の使用には第2世代の Cloud Run を使用する必要があるため gen2 を指定します。 --allow-unauthenticated 未認証の Cloud Run サービスの呼び出しを許可します。 --add-volume マウントする Cloud Storage バケットの情報を指定します。 name には任意のボリューム名、 type には cloud-storage を指定し、 bucket で Cloud Storage バケットの名前を指定します。 --add-volume-mount volume には --add-volume の name で指定した任意のボリューム名と同じものを指定します。 mount-path にはコンテナからバケットにアクセスするための任意のパスを設定します。当記事で使用するコードでは /mnt/gcs からバケットにアクセスします。 YAML ファイルから Cloud Run サービスを作成する場合 YAML ファイルから Cloud Run サービスを作成する場合は、以下のような YAML ファイルを用意します。 apiVersion : serving.knative.dev/v1 kind : Service metadata : name : run-gcs labels : cloud.googleapis.com/location : asia-northeast1 spec : template : metadata : annotations : run.googleapis.com/execution-environment : GEN2 # Cloud Storage FUSE を使用する場合、第2世代の Cloud Run を使用する spec : containers : - image : asia-northeast1-docker.pkg.dev/myproject/myrepo/run-gcs # Cloud Run で実行するコンテナイメージ ports : - name : http1 containerPort : 8080 resources : limits : cpu : 1000m memory : 512Mi volumeMounts : - name : gcs mountPath : /mnt/gcs # コンテナからバケットにアクセスするためのパスを設定する volumes : - name : gcs # 任意のボリューム名 csi : driver : gcsfuse.run.googleapis.com volumeAttributes : bucketName : mybucket # マウントするバケットの名前を指定する YAML ファイルを使用した Cloud Run サービスの作成には、 gcloud run services replace コマンドを使用します。 # Cloud Run サービスを作成する $ gcloud run services replace service.yaml YAML ファイルからのデプロイでは metadata.annotations.run.googleapis.com/ingress の値として all を設定しても 未認証の呼び出しを許可 の設定ができないようなので、以下の gcloud コマンド使用して未認証のサービス呼び出しを許可します。 # 未認証のサービス呼び出しを許可する $ gcloud run services add-iam-policy-binding run-gcs \ --role =" roles/run.invoker " \ --member =" allUsers " \ --region = asia-northeast1 参考: Cloud Run YAML Reference 動作確認 Cloud Run サービスのデプロイ後、サービスにアクセスするためのエンドポイントが生成されます(以下の出力例では Service URL の値)。 # コマンド出力例 Deploying container to Cloud Run service [ run-gcs ] in project [ myproject ] region [ asia-northeast1 ] ✓ Deploying new service... Done. ✓ Creating Revision... ✓ Routing traffic... ✓ Setting IAM Policy... Done. Service [ run-gcs ] revision [ run-gcs-00001-f7c ] has been deployed and is serving 100 percent of traffic. Service URL: https://run-gcs-ai4xxxxxxx-an.a.run.app ブラウザでエンドポイントにアクセスすると、Cloud Storage バケットにアップロードしたテキストファイルの中身が表示されます。 バケットにアップロードしたテキストファイルの中身が表示される 佐々木 駿太 (記事一覧) G-gen最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
アバター
G-gen の藤岡です。当記事では、Google Cloud (旧称 GCP) の VPC Service Controls を設定する際に登場する、 アクセスポリシー や アクセスレベル について解説します。 前提知識 全体像 サービス境界 アクセスポリシー アクセスレベル 前提知識 VPC Service Controls は Access Context Manager サービスを基盤としたセキュリティ機能の 1 つであり、Access Context Manager API 経由でリソースが管理されます。VPC Service Controls の解説については以下の記事をご参照ください。 blog.g-gen.co.jp Access Context Manager は、送信元 IP アドレスやプリンシパル等、クライアント属性 (アクセスレベル) に基づいてリクエストを分類するサービスです。Access Context Manager によって、VPC Service Controls のサービス境界へアクセスできるクライアント属性を設定することができます。 Access Context Manager 全体像 以下の図は、VPC Service Controls と Access Context Manager を構成するリソースの全体像を示しています。 構成要素 VPC Service Controls を設定する際、 アクセスポリシー や アクセスレベル という用語が登場しますが、リソース構造がわかりづらく、混乱を呼びやすい要素です。これらは Access Context Manager のリソースであり、VPC Service Controls を適切に利用するうえでは、構造を正しく理解する必要があります。 サービス境界 VPC Service Controls では、 サービス境界 (Perimeter) と呼ばれる論理的な囲いを作り、その囲いの中のリソースへのアクセス元制限 (IP アドレスやサービスアカウント等) や、どのような操作ができるかを細かく制御します。 VPC Service Controls 参考 : API とリファレンス アクセスポリシー アクセスポリシー は、アクセスレベル (後述) や VPC Service Controls のサービス境界等のリソースをグルーピングするためのリソースです。 アクセスポリシーは 組織レベルでのみ作成できます 。Google Cloud コンソールでアクセスレベルを作成すると、自動的に default policy というアクセスポリシーが作成されます。 自動で作られるポリシー アクセスポリシーには スコープ の概念があります。スコープによって、そのアクセスポリシーをどの階層 (組織、フォルダ、プロジェクト) で管理するかを定義できます。 スコープを設定することにより、アクセスポリシーの管理を各フォルダ、プロジェクトの管理者に委任できます。 スコープの概念 最小権限の原則に従い、上図のように IAM ロールを各階層ごとに付与している場合、組織をスコープとするアクセスポリシーの設定を誰でも編集できる状態は、管理上好ましくありません。そのため、スコープを用いることで影響範囲を限定できます。 スコープ設定時のコンソール表示 前述のアクセスポリシー default policy のスコープは組織であり、 組織をスコープとするアクセスポリシーは1つしか作成できません 。また作成方法 (自動、手動) を問わず、組織をスコープとするアクセスポリシーはコンソールで「範囲」が 組織レベルのポリシーの範囲外 と表示されます。 参考 : アクセス ポリシー 参考 : スコープ指定されたポリシー 参考 : アクセス ポリシーを作成する アクセスレベル アクセスレベル は、次のようなアクセス条件を定義できます。 誰が : ユーザーやサービスアカウントのプリンシパル どこから : IP アドレスや地域 (日本、US 等) どのようなデバイスで : モバイルデバイスやパソコン等 アクセスレベルはあくまで、アクセス条件の定義情報でしかありません。単体で使うものではなく、サービス境界や IAM Conditions と紐づけることで効果が適用されます。 参考 : アクセスレベル 参考 : アクセスレベルの属性 藤岡 里美 (記事一覧) クラウドソリューション部 数年前までチキン売ったりドレスショップで働いてました!2022年9月 G-gen にジョイン。今期は「おっさんずラブ」がイチオシです :) Google Cloud All Certifications Engineer / Google Cloud Partner Top Engineer 2024 Follow @fujioka57621469
アバター
G-genの三木です。突然ですが、技術サポートへのお問合せを送ったことはありますか?今回は、私の経験といくつかの公式資料を基に、技術サポートから素早く回答を貰える質問文(サポートケース)を書くコツをお伝えします。 書き方 1ケースにつき1質問 迷ったら箇条書き ローコンテクストな記述を意識する 状況を正確に共有する 内容 解決したい課題を明確にする 最終的なゴールを共有する すでに試した対応策を連携する 添付資料 ログや画面キャプチャを共有する 機密情報以外はマスキング/トリミングしない 参考資料 書き方 1ケースにつき1質問 多くのサービス・製品では1つのサポートケースに、1人のエンジニアが対応します。そのため、1つのケースには複数の質問を記載すると、1人のエンジニアが複数の調査を行ったうえで回答することとなります。 これを避けるため、1つのケースには1つの質問を記載するようにしましょう。複数の質問がある場合は、ケースを分けることで回答スピードが上がります。 迷ったら箇条書き 文章を書くのが苦手な方!朗報です!箇条書きで構いません。 事実を書き並べるだけで大丈夫です。高度なレトリックはいりません。相手に必要な情報が不足なく伝わるように、記述しましょう。 ローコンテクストな記述を意識する 基本的にサポートエンジニアはユーザ側の環境を知らない(知ることが出来ない)ことがほとんどです。そのため、システム名やコード名をはじめとする組織内用語などは使わないようにしましょう。 また、過去のサポートケースでやりとりした内容であっても、新規のケース起票であれば改めて説明する方が結果的に早くレスポンスが来る場合が多いです。 (これは私の体感になりますが、こちらから明示せずとも過去のサポートケースを見た上で返信してもらえることは極僅かです。) もしどうしても過去のサポートケースを見てほしい場合は、過去のサポートケースIDを直接伝える方が良いでしょう。 状況を正確に共有する ぜひ、以下の内容を記載するようにしてください。 これがあると、回答する側としてはグッと答えやすくなります。 項目 内容 時刻 問題が発生した具体的なタイムスタンプおよび、タイムゾーン プロダクト名 問題に関連するプロダクト名や、バージョン 設定値 問題が発生しているプロダクトの設定値やリージョンなどの、詳細情報 継続の有無 問題が断続的なものか、一時的なものか。再現性があるか、ないか。 内容 解決したい課題を明確にする 「何を解消したいのか」を明確にしましょう。 それは疑問かもしれませんし、エラーかもしれません。不具合かもしれません。とにかく、あなたが期待する解消したいことを記述してください。 意外に感じるかもしれませんが、これが抜けているサポートケースは少なくありません。 最終的なゴールを共有する 「何を解消したいのか」と並んで大切なことは、「何を実現したいのか」を正確に伝えることです。相手と目的を共有することで、最速でゴールにたどりつくことができます。 場合によっては、「解消したいこと」を無視してゴールに辿り着く方法を案内してもらえる...かもしれません。 すでに試した対応策を連携する すでに実施済みの対応策があれば、それも連携しましょう。「xxではうまくいかなかった」という情報は、強力な手がかりの一つです。 この際は手順とその結果を正しく伝えてください。 特に結果については自分たちで判断せず、画面ショットやログを添付しましょう。 (質問者側が「失敗だ!」と思っていても、精通しているプロフェッショナルから見るとまた違った意味を持つことがあります。) 添付資料 ログや画面キャプチャを共有する サポート側はあらゆる可能性を検討してくれます。それこそコマンドのタイプミスから実行権限、サービス側の基盤障害、アップデートの影響...と幅広く調査します。しかし、手がかりが少なければ調査に時間もかかりますし、精度も落ちてしまいます。 そこで、ログや画面キャプチャを率先して提供するようにしましょう。何の変哲もない画面やログに見えても、サポートにとっては大きなヒントが眠っている可能性があります。ただし、ログやエラーメッセージは画面キャプチャでなく、テキスト情報で記載してください。テキストをコピー&ペーストして調査に利用するためです。 (昔の話ですが、画面キャプチャを送ったところ「あなたのコンソールは昔のバージョンだ。新しいバージョンにしたら直る」と爆速で解決したことがあります。) 機密情報以外はマスキング/トリミングしない ログ等を送る際は、出来るだけマスキングやトリミングをせずにそのまま送るようにしましょう。 (機密情報はもちろんマスキングする必要がありますが、必要以上にマスキングやトリミングをしないように注意してください。 私の経験則からいって、関連する可能性のあるログはそのまま送るほうが早期解決に役立ちます。なお、ログのフォーマットを変更している場合は、その情報も添付しましょう。 参考資料 cloud.google.com aws.amazon.com 三木宏昭 (記事一覧) クラウドソリューション部 HROne→ServerWorks→WealthNavi→G-gen。AWS 11資格、Google Cloud認定全冠。Google Cloud Partner Top Engineer 2024。最近の悩みは中年太り。Twitter では クラウド関連のことや副業、その他雑多に呟いています。(頻度少なめ) Follow @cloudeep_miki
アバター
G-gen の藤岡です。これまでデフォルトの Cloud Build サービスアカウントとして使われていた <PROJECT_NUMBER>@cloudbuild.gserviceaccount.com の仕様が2024年4月29日から変更されます。当記事では、変更点とその影響について詳しく解説します。 注意点 前提知識 Cloud Build とは デフォルトの Cloud Build サービスアカウントとは デフォルトの Compute Engine サービスアカウントとは 変更点 適用条件 内容 影響範囲の例 Terraform など IaC ツールのテンプレート更新が必要 特定の組織ポリシー適用下でビルドが失敗する Disable Automatic IAM Grants for Default Service Accounts VPC Service Controls 境界で API コールが拒否される 対処法 組織のポリシーによる対策 適切な設定変更を行う 注意点 本変更は、2024年5月〜6月にかけて順次展開されます。 最新の仕様は、必ず以下の Google Cloud の公式ドキュメントをご確認ください。 またリンク先の公式ドキュメントは英語版にしないと最新情報が反映されていない場合がありますのでご注意ください。 参考 : Cloud Build Service Account Change 前提知識 Cloud Build とは Cloud Build とは、ソースコードのコンパイル、テストの実行、アプリケーションのデプロイなどを行う CI/CD サービスです。また、コードの変更をトリガーにビルドを起動することもできます。 Cloud Run や Google Kubernetes Engine(GKE)など、Google Cloud の他のサービスへのデプロイでも Cloud Build が使われます。Cloud Build の履歴画面から過去のビルド履歴を確認できます。利用者側で Cloud Build を使っていると思っていなくても、別のサービスの裏側で使われている場合もあります。 Cloud Build の履歴画面 デフォルトの Cloud Build サービスアカウントとは デフォルトの Cloud Build サービスアカウントは <PROJECT_NUMBER>@cloudbuild.gserviceaccount.com です。これは Cloud Build API を有効にすると自動で作られます。 デフォルトの Cloud Build サービスアカウント このデフォルトの Cloud Build サービスアカウントには、「Cloud Build サービス アカウント ( roles/cloudbuild.builds.builder )」ロールが自動で付与されます。このロールには、Artifact Registry へのイメージのプッシュや Cloud Logging へのログ書き込みなど、ビルドで必要な権限が包含されています。明示的にサービスアカウントを指定しない場合、このデフォルトの Cloud Build サービスアカウントが裏側で動いています。 Cloud Build API を有効化すると、サービスアカウントのうちの 1 つであるサービスエージェント ( service-<PROJECT_NUMBER>@gcp-sa-cloudbuild.iam.gserviceaccount.com ) も自動作成されますが、今回の仕様変更にサービスエージェントは含まれないため、当記事では説明を割愛します。 サービスエージェントについては以下の記事をご参照ください。 blog.g-gen.co.jp 参考: Cloud Build サービス アカウント デフォルトの Compute Engine サービスアカウントとは デフォルトの Compute Engine サービスアカウントは <PROJECT_NUMBER>-compute@developer.gserviceaccount.com です。これは Compute Engine API を有効にすると自動で作られます。 デフォルトの Compute Engine サービスアカウント このデフォルトの Compute Engine サービスアカウントには「編集者 ( roles/editor )」 ロールが自動で付与されます。この編集者ロールは広範囲な権限を持っているため、実運用での利用は非推奨です。 参考: Compute Engine のデフォルトのサービス アカウント 参考: デフォルトのサービス アカウントへの自動的なロール付与を使用しない 変更点 適用条件 デフォルトの Cloud Build サービスアカウントの仕様変更は、 2024年4月29日以降に Cloud Build API を有効にしたプロジェクト に対して適用されます。これは プロジェクトの作成日ではなく 、API を有効にした日に基づきます。 つまり、 2024年4月28日までに Cloud Build API を有効化しているプロジェクトではこれまでの仕様と変わらず利用できる ため、対応は不要です。 参考: Cloud Build Service Account Change 内容 変更点は以下の 3 つです。 No. 概要 変更前 変更後 ワークアラウンド (対処法) 1 サービスアカウントの名称が変更される Cloud Build サービスアカウント 従来の Cloud Build サービスアカウント(Legacy Cloud Build Service Account) - 2 デフォルトでビルド時に使われるサービスアカウントが変更される Cloud Build サービスアカウント Compute Engine サービスアカウント Cloud Build 用にサービスアカウントを作成し、適切な権限を付与する 3 ビルドトリガー作成時にサービスアカウント指定が必須になる 指定しない場合は、Cloud Build サービスアカウントが自動選択されていた サービスアカウントの明示的な指定が必須 ビルドトリガー作成時にサービスアカウントを明示的に指定する 影響範囲の例 Terraform など IaC ツールのテンプレート更新が必要 Terraform などの IaC ツールを使ってクラウド環境の払い出し(プロジェクトの新規作成)をする運用をしている場合、今回の仕様変更により、同じテンプレートが使えなくなる場合があります。 IaC ツールにより、定期的に「プロジェクトの新規作成」「Cloud Build API の有効化」を自動的に行い、その後 Cloud Build でのビルド(Cloud Functions 関数のデプロイを含む)を行う環境の場合、2024年4月29日以降に同じテンプレートでビルドを実行すると、前述の変更点 No. 2と No. 3に該当するため、権限不足などのエラーが発生する可能性があります。 特定の組織ポリシー適用下でビルドが失敗する Disable Automatic IAM Grants for Default Service Accounts Disable Automatic IAM Grants for Default Service Accounts ( constraints/iam.automaticIamGrantsForDefaultServiceAccounts ) は、Compute Engine API を有効にすると自動で作られるデフォルトの Compute Engine サービスアカウントへの編集者( roles/editor )ロール付与を無効にする制約です。 この制約下では、前述の変更点 No. 2の影響を受けます。Cloud Build で使われるサービスアカウントを指定しない場合、これまではデフォルトの Cloud Build サービスアカウントが使われ、必要な権限はユーザー側で意識する必要はありませんでした。しかしこの制約下では、デフォルトの Compute Engine サービスアカウントは何の権限も持たないため、ビルドが失敗するようになります。 組織ポリシーに関する詳細は以下の記事をご参照ください。 blog.g-gen.co.jp 参考: デフォルトのサービス アカウントへの自動的なロール付与を無効にする また、この制約を使っていないとしても、デフォルト Compute Engine サービスアカウントのプロジェクトレベルでの編集者( roles/editor )ロールを削除している場合で、かつビルドに必要な権限が不足している場合は、ビルドが権限不足エラーになります。 VPC Service Controls 境界で API コールが拒否される VPC Service Controls の内向きポリシー (Ingress rules) や外向きポリシー (Egress rules) でデフォルトの Cloud Build サービスアカウントを FROM 属性に指定している場合、前述の変更点 No. 2の影響を受けます。 ビルド時に明示的にサービスアカウントを指定しない場合、デフォルトの Compute Engine サービスアカウントが使われるようになるため、既存のルールではアクセスレベル違反になります。 VPC Service Controls に関する詳細は以下の記事をご参照ください。 blog.g-gen.co.jp 対処法 組織のポリシーによる対策 本仕様変更後に Cloud Build API を有効化するプロジェクトで、現在の仕様を変更したくない場合は、組織ポリシー「 Disable Create Default Service Account (Cloud Build) ( constraints/cloudbuild.disableCreateDefaultServiceAccount )」の制約を オフ にします。 この制約をオンにすると、Cloud Build API を有効化してもデフォルトの Cloud Build サービスアカウント ( <PROJECT_NUMBER>@cloudbuild.gserviceaccount.com ) は作られません。 This boolean constraint, when enforced, disallows the Cloud Build service account from being created on demand. (日本語訳)このブール型制約を適用すると、従来の Cloud Build サービス アカウントを作成できなくなります。 デフォルトで「適用済み」つまり、オンの状態になっています。編集画面からオフにすると以下のように未適用となります。 Disable Create Default Service Account (Cloud Build) 制約の画面 ドキュメントの記述によると、「Disable Create Default Service Account (Cloud Build)」の制約を明示的に オフ にした場合、2024年4月29日以降も、これまでどおり Cloud Build API を有効にした際にデフォルトの Cloud Build サービスアカウント ( <PROJECT_NUMBER>@cloudbuild.gserviceaccount.com ) が自動作成され、従来の動作が継続されます。 適切な設定変更を行う 根本対処としては、以下のように、影響範囲に応じた対処を行います。以下の記載は例であり、実際には影響範囲を適切に考慮して対策を行ってください。 影響範囲 ワークアラウンド (対処法) A Terraform など IaC ツールのテンプレート更新が必要 Compute Engine サービスアカウントへの権限付与、VPC Service Controls 境界の設定変更など、テンプレートを更新する B 特定の組織ポリシー適用下でビルドが失敗する Cloud Build によるビルド時に明示的にサービスアカウントを指定する。または、Compute Engine サービスアカウントに適切な権限を付与する C VPC Service Controls で弾かれる VPC Service Controls 境界の設定を変更する Bについては、ユーザーが明示的に Cloud Build を使ってビルドを行う場合に加えて、以下のような場合における影響が考えられます。 Cloud Functions のデプロイ(デプロイ時に Cloud Build が使われる) Cloud Composer の環境作成(環境作成時に Cloud Build が使われる) 前者の Cloud Functions のデプロイにおいては、デフォルト Compute Engine サービスアカウントが使用されるようになります。デフォルト Compute Engine サービスアカウントに適切な権限を付与するか、以下のドキュメントを参考にして、デプロイ時にビルド用サービスアカウントを明示的に指定します。 参考 : Custom Service Account for Cloud Build 後者の Cloud Composer の環境作成においては、環境(environment)にアタッチするサービスアカウントがビルド時にも使用されるようになります(明示的に指定しない場合、デフォルト Compute Engine サービスアカウント)。環境用のサービスアカウントに明示的にカスタムサービスアカウントを指定している場合、そのサービスアカウントは自分自身に対して「サービス アカウント ユーザー ( roles/iam.serviceAccountUser )」を付与する必要があります。 参考 : Grant roles to an environment's service account 藤岡 里美 (記事一覧) クラウドソリューション部 数年前までチキン売ったりドレスショップで働いてました!2022年9月 G-gen にジョイン。ハイキューの映画を4回は見に行きたい。 Google Cloud All Certifications Engineer / Google Cloud Partner Top Engineer 2024 Follow @fujioka57621469
アバター
G-gen 又吉です。Google の提供する最新の生成 AI モデルである Gemini を用いて、マルチモーダルな生成 AI チャットアプリを簡単に開発できましたので、ご紹介します。 概要 当記事の内容 デモ動画 前提知識 Gemini とは 使用するモデル Gradio Cloud Runサービスへのアクセス制御 準備 ディレクトリ構成 app.py requirements.txt Dockerfile デプロイ 動作検証 認証 テキストのみ 画像① 画像② 動画 利用状況の可視化 概要 当記事の内容 Google の提供する最新の生成 AI モデルである Gemini を用いて、テキスト、画像、動画の入力に対応したマルチモーダルな生成 AI チャットアプリを作ってみたので、当記事ではその開発の経緯をご紹介します。 実行環境として Google Cloud(旧称 GCP)の Cloud Run を利用しています。また、Cloud Run サービスの前段に Identity-Aware Proxy (IAP) 認証を用いることで、社内ユーザーのみがアクセスできる状態を構成しました。 Vertex AI 経由で提供される Gemini API を用いていますので、生成 AI モデルへの入出力データは Google によって利用されることがなく、データガバナンスを維持することができます。この点が、コンシューマ向け生成 AI サービスである Bard との大きな違いです。 デモ動画 以下は、当記事で開発したマルチモーダル生成 AI チャットアプリのデモ動画です。 youtu.be 前提知識 Gemini とは Gemini とは、Google が2023年12月初旬に発表した、最新の生成 AI モデルです。テキスト、画像、動画など、複数の形式のデータを扱えるマルチモーダル生成 AI モデルであり、テキスト生成、動画や画像の説明など、さまざまなタスクで高いパフォーマンスを出すとされています。 Gemini には Ultra、Pro、Nano という3つのサイズが用意されておりますが、2024年1月現在では Pro のみが Vertex AI 上で Public Preview(一般利用者も試用できる状態)となっています。 気軽に Vertex AI 上の Gemini Pro を触ってみたい方は、以下のブログで紹介しているように Google Cloud の Vertex AI Studio という Web UI を通して試すことができます。 blog.g-gen.co.jp 使用するモデル 2024年1月現在、Vertex AI 上の Gemini API では Gemini Pro と Gemini Pro Vision の2つの基盤モデルが利用可能です。 モデル名 説明 Gemini Pro (gemini-pro) 自然言語タスク、マルチターン(会話)、コード生成を処理するように設計されており、プロンプトにテキストのみを含む場合は Gemini Pro を推奨 Gemini Pro Vision (gemini-pro-vision) マルチモーダルなタスクを処理するように設計されており、プロンプトに画像や動画が含まれる場合は Gemini Pro Vision を推奨 今回の Web アプリ上では、ユーザーの入力 (プロンプト) がテキストのみの場合は Gemini Pro を、画像や動画も含まれる場合は Gemini Pro Vision を利用します。 参考: Gemini API models Gradio Gradio とは、Python で機械学習 Web アプリを容易に構築できるフレームワークです。 今回は、テキスト以外にも画像と動画の入力に対応できる Web アプリを構築するために以下のコンポーネントを使用しました。 Webアプリの画面構成 No コンポーネント 説明 1 Chatbot 会話履歴を表示する部分 2 Image 画像をアップロードする部分 3 Video 動画をアップロードする部分 4 Textbox テキストを入力する部分 5 Slider Gemini API のプロンプトパラメータを調整する部分 6 Button Refresh ボタンは画面をリロードする処理を、Submin ボタンはユーザーの入力を送信する処理を実装 Cloud Runサービスへのアクセス制御 Cloud Run サービスへのアクセス制御は、 Identity-Aware Proxy (IAP) を用いることで IAP を利用できる IAM ロール がアタッチされた組織内 Google アカウント / グループ に制限することができます。 また、IAP を用いることで、ユーザーのメールアドレスが HTTP リクエストヘッダーに格納されます。 社内ユーザーしかアクセスできない仕様であれども、誰がどのくらい利用しているのか管理者側で把握したい場合に、IAP からユーザーのメールアドレスを取得してユーザーの識別ができることで実装可能になります。 全体の構成図は以下のとおりです。 構成図 参考: Enabling IAP for Cloud Run 参考: Getting the user's identity 準備 ディレクトリ構成 開発環境は Cloud Shell を用いて行います。ディレクトリ構成は以下のとおりです。 multimodal_app ディレクトリ配下は、以下のとおりです。 multimodal_app |-- app | |-- app.py | `-- requirements.txt `-- Dockerfile app.py app.py には、以下の Python コードを記述します。 import base64 from datetime import datetime import json import logging import math from typing import Optional import os import pytz import sys import time import google.cloud.logging from google.cloud import storage import gradio as gr import PIL.Image from proto.marshal.collections import RepeatedComposite import vertexai from vertexai.preview.generative_models import GenerativeModel, Part, GenerationConfig, GenerationResponse from moviepy.editor import VideoFileClip PROJECT_ID = os.environ.get( "PROJECT_ID" ) if not PROJECT_ID: raise ValueError ( "PROJECT_ID environment variable is not set." ) LOCATION = os.environ.get( "LOCATION" ) if not LOCATION: raise ValueError ( "LOCATION environment variable is not set." ) FILE_BUCKET_NAME = os.environ.get( "FILE_BUCKET_NAME" ) if not FILE_BUCKET_NAME: raise ValueError ( "FILE_BUCKET_NAME environment variable is not set." ) LOG_BUCKET_NAME = os.environ.get( "LOG_BUCKET_NAME" ) if not LOG_BUCKET_NAME: raise ValueError ( "LOG_BUCKET_NAME environment variable is not set." ) SUPPORTED_IMAGE_EXTENSIONS = [ "png" , "jpeg" , "jpg" , ] SUPPORTED_VIDEO_EXTENSIONS = [ "mp4" , "mov" , "mpeg" , "mpg" , "avi" , "wmv" , "mpegps" , "flv" , ] ALL_SUPPORTED_EXTENSIONS = set (SUPPORTED_IMAGE_EXTENSIONS + SUPPORTED_VIDEO_EXTENSIONS) MAX_PROMPT_SIZE_MB = 4.0 # Cloud Logging ハンドラを logger に接続 logger = logging.getLogger() try : logging_client = google.cloud.logging.Client(project=PROJECT_ID) logging_client.setup_logging() except Exception as e: logger.error(f "An error occurred during Cloud Logging initialization: {e}" ) # Vertex AI インスタンスの初期化 try : vertexai.init(project=PROJECT_ID, location=LOCATION) except Exception as e: logger.error(f "An error occurred during Vertex AI initialization: {e}" ) # Cloud Storage インスタンスの初期化 try : storage_client = storage.Client(project=PROJECT_ID) except Exception as e: logger.error(f "An error occurred during Cloud Storage initialization: {e}" ) # Gemini モデルの初期化 try : txt_model = GenerativeModel( "gemini-pro" ) multimodal_model = GenerativeModel( "gemini-pro-vision" ) except Exception as e: logger.error(f "An error occurred during GenerativeModel initialization: {e}" ) # ファイルを Base64 にエンコード def file_to_base64 (file_path: str ) -> str : try : with open (file_path, "rb" ) as file : return base64.b64encode( file .read()).decode( "utf-8" ) except Exception as e: logger.error(f "An error occurred during file_to_base64 func.: {e}" ) # ファイルの拡張子を取得 def get_extension (file_path: str ) -> str : if "." not in file_path: logger.error(f "Invalid file path. : {file_path}" ) extension = file_path.split( "." )[- 1 ].lower() if not extension: logger.error(f "File has no extension. : {file_path}" ) return extension # 画像/動画ファイルを Cloud Storage にアップロード def file_upload_gsc (file_bucket_name: str , source_file_path: str ) -> str : try : bucket = storage_client.bucket(file_bucket_name) # ファイルの名前を取得 destination_blob_name = os.path.basename(source_file_path) # ファイルをアップロード blob = bucket.blob(destination_blob_name) blob.upload_from_filename(source_file_path) return f "gs://{file_bucket_name}/{destination_blob_name}" except Exception as e: logger.error(f "Error uploading to Cloud Storage: {e}" ) # extension がサポートされているか判定 def is_extension (extension: str ) -> bool : return extension in ALL_SUPPORTED_EXTENSIONS # mime_type を取得 def create_mime_type (extension: str ) -> str : # サポートされた画像形式の場合 if extension in SUPPORTED_IMAGE_EXTENSIONS: return "image/jpeg" if extension in [ "jpg" , "jpeg" ] else f "image/{extension}" # サポートされた動画形式の場合 elif extension in SUPPORTED_VIDEO_EXTENSIONS: return f "video/{extension}" # サポートされていない拡張子の場合 else : logger.error(f "Not supported mime_type for extension: {extension}" ) # プロンプトサイズの計算 def calculate_prompt_size_mb (text: str , file_path: str ) -> float : try : # テキストサイズをバイト単位で取得 text_size_bytes = sys.getsizeof(text) # ファイルサイズをバイト単位で取得 file_size_bytes = os.path.getsize(file_path) # バイトからメガバイトに単位変換 prompt_size_mb = (text_size_bytes + file_size_bytes) / 1048576 except Exception as e: logger.error(f "Error calculating prompt size: {e}" ) return prompt_size_mb # safety_ratingsオブジェクトをリストに変換する def repeated_safety_ratings_to_list (safety_ratings: RepeatedComposite) -> list : safety_rating_li = [] for safety_rating in safety_ratings: safety_rating_dict = {} safety_rating_dict[ "blocked" ] = safety_rating.blocked safety_rating_dict[ "category" ] = safety_rating.category.name safety_rating_dict[ "probability" ] = safety_rating.probability.name safety_rating_li.append(safety_rating_dict) return safety_rating_li # citation_metadataオブジェクトをリストに変換する def repeated_citations_to_list (citations: RepeatedComposite) -> list : citation_li = [] for citation in citations: citation_dict = {} citation_dict[ "startIndex" ] = citation.startIndex citation_dict[ "endIndex" ] = citation.endIndex citation_dict[ "uri" ] = citation.uri citation_dict[ "title" ] = citation.title citation_dict[ "license" ] = citation.license citation_dict[ "publicationDate" ] = citation.publicationDate citation_li.append(citation_dict) return citation_li # Gemini 利用ログの作成 def create_gemini_usage_log ( current_time_str: str , user_name: str , temperature: float , max_output_tokens: int , top_k: int , top_p: float , text: str , response: GenerationResponse, gcs_file_path: Optional[ str ] = None , local_file_path: Optional[ str ] = None ) -> json: # 初期値を設定 image_path, video_path, video_duration = None , None , 0 # gcs_file_pathが提供された場合の処理 if gcs_file_path: # ファイルの拡張子を取得 file_extension = get_extension(gcs_file_path) # 画像ファイルの場合 if file_extension in SUPPORTED_IMAGE_EXTENSIONS: image_path = gcs_file_path # 動画ファイルの場合 elif file_extension in SUPPORTED_VIDEO_EXTENSIONS: video_path = gcs_file_path # 動画ファイルの場合は動画時間を取得 try : with VideoFileClip(local_file_path) as video: video_duration = math.ceil(video.duration) except Exception as e: logger.error(f "An error occurred while calculating the video duration: {e}" ) video_duration = 0 gemini_usage_log = { "current_time_str" : current_time_str, "user" : user_name, "prompt" : { "text" : text, "image_path" : image_path, "video_path" : video_path, "video_duration" :video_duration, "config" : { "temperature" : temperature, "top_p" : top_p, "top_k" : top_k, "max_output_tokens" : max_output_tokens }, }, "response" : { "text" : response.candidates[ 0 ].text, "finish_reason" : response.candidates[ 0 ].finish_reason.name, "finish_message" : response.candidates[ 0 ].finish_message, "safety_ratings" : repeated_safety_ratings_to_list(response.candidates[ 0 ].safety_ratings), "citation_metadata" : repeated_citations_to_list(response.candidates[ 0 ].citation_metadata.citations) }, "usage_metadata" : { "prompt_token_count" : response._raw_response.usage_metadata.prompt_token_count, "candidates_token_count" : response._raw_response.usage_metadata.candidates_token_count, "total_token_count" : response._raw_response.usage_metadata.total_token_count } } gemini_usage_log_json = json.dumps(gemini_usage_log) return gemini_usage_log_json # ログデータを Cloud Storage にアップロード def log_upload_gcs ( log_bucket_name: str , current_time_str: str , user_name: str , log_data_json: json ): try : bucket = storage_client.get_bucket(log_bucket_name) blob = bucket.blob(f "output/{current_time_str}-{user_name}.json" ) blob.upload_from_string(log_data_json) except Exception as e: logger.error(f "Error uploading to Cloud Storage: {e}" ) # ユーザーのクエリメッセージを作成 def query_message (history: str , txt: str , image: str , video: str ) -> str : try : # ユーザーのクエリがテキストのみの場合 if not (image or video): history += [(txt, None )] # ユーザーのクエリに画像が含まれる場合 if image: prompt_size_mb = calculate_prompt_size_mb(text= None , file_path=image) # 画像サイズが上限を超えた場合 if prompt_size_mb > MAX_PROMPT_SIZE_MB: history += [(f "[This Image is not display] {txt}" , None )] else : image_extension = get_extension(image) base64 = file_to_base64(image) data_url = f "data:image/{image_extension};base64,{base64}" image_html = f '<img src="{data_url}" alt="Uploaded image">' history += [(f "{image_html} {txt}" , None )] # ユーザーのクエリに動画が含まれる場合 if video: prompt_size_mb = calculate_prompt_size_mb(text= None , file_path=video) # 動画サイズが上限を超えた場合 if prompt_size_mb > MAX_PROMPT_SIZE_MB: history += [(f "[This video is not display] {txt}" , None )] else : video_extension = get_extension(video) base64 = file_to_base64(video) data_url = f "data:video/{video_extension};base64,{base64}" video_html = f '<video controls><source src="{data_url}" type="video/{video_extension}"></video>' history += [(f "{video_html} {txt}" , None )] except Exception as e: logger.error(f "Error processing query message: {e}" ) return history # Gemini からの出力を取得 def gemini_response ( history: str , text: str , image: str , video: str , temperature: float , max_output_tokens: int , top_k: int , top_p: float , request: gr.Request ) -> str : try : # ログインしたユーザー情報を取得 user_email = request.headers.get( 'X-Goog-Authenticated-User-Email' , 'Unknown' ) user_name = user_email.split( ':' )[ 1 ].split( '@' )[ 0 ] # 現在時刻を取得 jst = pytz.timezone( 'Asia/Tokyo' ) current_time_str = datetime.now(jst).strftime( "%Y%m%d-%H%M%S" ) # テキストが未入力の場合 if not text: response = "テキストを入力して下さい。" history += [( None ,response)] # テキストのみの場合 elif not (image or video): # Gemini Pro にリクエストを送信 response = txt_model.generate_content( contents=text, generation_config=GenerationConfig( temperature=temperature, top_p=top_p, top_k=top_k, max_output_tokens=max_output_tokens ) ) # Gemini Pro 使用ログを作成 gemini_usage_log_json = create_gemini_usage_log( current_time_str=current_time_str, user_name=user_name, temperature=temperature, max_output_tokens=max_output_tokens, top_k=top_k, top_p=top_p, text=text, response=response, ) # データを Cloud Storage にアップロード log_upload_gcs( log_bucket_name=LOG_BUCKET_NAME, current_time_str=current_time_str, user_name=user_name, log_data_json=gemini_usage_log_json ) history += [( None ,response.text)] # 画像と動画の両方が入力された場合 elif image and video: response = "1度に画像と動画を含めることはサポートされていません。" history += [( None ,response)] else : # ファイルパスを取得 file_path = image or video # プロンプトサイズを取得 prompt_size_mb = calculate_prompt_size_mb(text=text, file_path=file_path) # プロンプトサイズが上限を超えた時 if prompt_size_mb > MAX_PROMPT_SIZE_MB: response = f "画像/動画とテキストを含むプロンプトサイズは{MAX_PROMPT_SIZE_MB}MB未満として下さい。現在のプロンプトサイズは{round(prompt_size_mb, 1)}MBです。" history += [( None ,response)] else : # ファイルの拡張子を取得 extension = get_extension(file_path=file_path) # サポートされている extension の場合 if is_extension(extension): # 画像/動画ファイルを Cloud Storage にアップロード gcs_url = file_upload_gsc(file_bucket_name=FILE_BUCKET_NAME, source_file_path=file_path) # mime_type を取得 mime_type = create_mime_type(extension) # Gemini Pro Vision にリクエストを送信 file = Part.from_uri(uri=gcs_url, mime_type=mime_type) response = multimodal_model.generate_content( contents=[ file , text], generation_config=GenerationConfig( temperature=temperature, top_p=top_p, top_k=top_k, max_output_tokens=max_output_tokens ) ) # Gemini Pro Vision 使用ログを作成 gemini_usage_log_json = create_gemini_usage_log( current_time_str=current_time_str, user_name=user_name, temperature=temperature, max_output_tokens=max_output_tokens, top_k=top_k, top_p=top_p, text=text, response=response, gcs_file_path=gcs_url, local_file_path=file_path ) # データを Cloud Storage にアップロード log_upload_gcs( log_bucket_name=LOG_BUCKET_NAME, current_time_str=current_time_str, user_name=user_name, log_data_json=gemini_usage_log_json ) history += [( None ,response.text)] else : support_image_extensions_str = ", " .join(SUPPORTED_IMAGE_EXTENSIONS) support_video_extensions_str = ", " .join(SUPPORTED_VIDEO_EXTENSIONS) response = f "サポートされている形式について、画像の場合は {support_image_extensions_str} で、動画の場合は {support_video_extensions_str} です。" history += [( None ,response)] except Exception as e: logger.error(f "Error during Gemini response generation: {e}" ) return history # Gradio インターフェース with gr.Blocks() as app: # 画面の各コンポーネント with gr.Row(): with gr.Column(): chatbot = gr.Chatbot(scale = 2 ) with gr.Column(): image_box = gr.Image( type = "filepath" , sources=[ "upload" ], scale = 1 ) video_box = gr.Video(sources=[ "upload" ], scale = 1 ) with gr.Row(): with gr.Column(): text_box = gr.Textbox( placeholder= "テキストを入力して下さい。" , container= False , scale = 2 ) with gr.Column(): with gr.Row(): temperature = gr.Slider(label= "Temperature" , minimum= 0 , maximum= 1 , step= 0.1 , value= 0.4 , interactive= True ) max_output_tokens = gr.Slider(label= "Max Output Token" , minimum= 1 , maximum= 2048 , step= 1 , value= 1024 , interactive= True ) with gr.Row(): top_k = gr.Slider(label= "Top-K" , minimum= 1 , maximum= 40 , step= 1 , value= 32 , interactive= True ) top_p = gr.Slider(label= "Top-P" , minimum= 0.1 , maximum= 1 , step= 0.1 , value= 1 , interactive= True ) with gr.Row(): btn_refresh = gr.Button(value= "Refresh" ) btn_submit = gr.Button(value= "Submit" ) # Submitボタンが押下されたときの処理 btn_submit.click( query_message, [chatbot, text_box, image_box, video_box], chatbot ).then( gemini_response, [chatbot, text_box, image_box, video_box, temperature, max_output_tokens, top_k, top_p], chatbot ) # Refreshボタンが押下されたときの処理 btn_refresh.click( None , js= "window.location.reload()" ) app.launch(server_name= "0.0.0.0" , server_port= 7860 ) 本 Web アプリでは、以下の点に考慮して作成しています。 ユーザーのプロンプトがテキストのみの場合は gemini-pro に、画像もしくは動画を含む場合は gemini-pro-vision にリクエストを送信します。 画像や動画を含むプロンプト全体で 4MB 以上になった際は gemini-pro-vision へリクエストを実行しません。 画像や動画はサポートされてる拡張子のみを受け付けます。 画像と動画を一回のプロンプトで同時に送信しないようにしています。 一方で、以下の点は考慮しておりません。 gemini-pro はマルチターン(会話)をサポートしていますが、本 Web アプリではマルチターンを考慮しておりません。 gemini-pro-vision では画像ファイルを 1 回のプロンプトで最大 16 枚送信できますが、本 Web アプリは UI の設計上、1 回のプロンプトに 1 枚しか送信できません。 参考: Image requirements for prompts 参考: Video limits and requirements for prompts requirements.txt google-cloud-logging==3.9.0 google-cloud-storage==2.14.0 gradio==4.12.0 Pillow==10.1.0 google-cloud-aiplatform==1.38.1 moviepy==1.0.3 Dockerfile FROM python:3.10-slim COPY ./app /app WORKDIR /app RUN pip install --no-cache-dir -r requirements.txt EXPOSE 7860 CMD [ "python" , "app.py" ] デプロイ Cloud Shell にて、現在のディレクトリが multimodal_app ディレクトリであることを確認し、以下 gcloud コマンドを順次実行します。 # 環境変数の設定 PROJECT_ID = { プロジェクト ID } BILLING_ACCOUNT_ID = { 請求先アカウント ID } REGION =asia-northeast1 FILE_BUCKET_NAME = { FILE_BUCKET_NAME } LOG_BUCKET_NAME = { LOG_BUCKET_NAME } AR_REPO = { Artifact Repogitory のレポジトリ名 } SERVICE_NAME = { Cloud Run サービス名 } SA_NAME = { サービスアカウント名 } # プロジェクト作成 gcloud projects create ${PROJECT_ID} --name= ${PROJECT_NAME} # プロジェクト設定の変更 gcloud config set project ${PROJECT_ID} # 請求先アカウントの紐づけ gcloud beta billing projects link ${PROJECT_ID} \ --billing-account = ${BILLING_ACCOUNT_ID} # API の有効化 gcloud services enable --project= $PROJECT_ID run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ compute.googleapis.com \ aiplatform.googleapis.com \ iap.googleapis.com # サービスアカウント作成 gcloud iam service-accounts create $SA_NAME # Cloud Storage バケットの作成 gcloud storage buckets create gs:// $FILE_BUCKET_NAME gs:// $LOG_BUCKET_NAME \ --location= $REGION \ --uniform-bucket-level-access \ --public-access-prevention # サービスアカウントへ権限付与 gcloud projects add-iam-policy-binding $PROJECT_ID \ --member= " serviceAccount: $SA_NAME @ $PROJECT_ID .iam.gserviceaccount.com " \ --role= " roles/aiplatform.user " gcloud projects add-iam-policy-binding $PROJECT_ID \ --member= " serviceAccount: $SA_NAME @ $PROJECT_ID .iam.gserviceaccount.com " \ --role= " roles/storage.admin " # Artifacts repositories 作成 gcloud artifacts repositories create $AR_REPO \ --location= $REGION \ --repository-format=Docker \ --project= $PROJECT_ID # イメージの作成&更新 gcloud builds submit --tag $REGION -docker.pkg.dev/ $PROJECT_ID / $AR_REPO / $SERVICE_NAME \ --project= $PROJECT_ID # Cloud Run デプロイ gcloud run deploy $SERVICE_NAME --port 7860 \ --image $REGION -docker.pkg.dev/ $PROJECT_ID / $AR_REPO / $SERVICE_NAME \ --no-allow-unauthenticated \ --service-account= $SA_NAME @ $PROJECT_ID .iam.gserviceaccount.com \ --ingress=internal-and-cloud-load-balancing \ --region= $REGION \ --set-env-vars=PROJECT_ID= $PROJECT_ID , LOCATION = $REGION , FILE_BUCKET_NAME = $FILE_BUCKET_NAME , LOG_BUCKET_NAME = $LOG_BUCKET_NAME \ --memory=8Gi \ --cpu=2 \ --project= $PROJECT_ID Cloud Run サービスと IAP の連携は、以下ブログの手順をご参照下さい。 blog.g-gen.co.jp 動作検証 認証 マルチモーダル Web アプリの URL にアクセスすると、まず最初に IAP による認証画面が現れます。 IAP による認証画面 許可された Google アカウントでログインするとマルチモーダル Web アプリの画面に遷移します。 テキストのみ まずはテキストのみの入力を検証します。テキストのみの場合は、Gemini Pro モデルが利用されます。 入力するプロンプトは以下のとおりです。 BigQuery の特徴について箇条書きで3つにまとめて教えてください。 Gemini Pro からの出力は以下の通りでした。 Geminiからの出力(テキストのみ) 画像① 画像と動画の入力には、Gemini Pro Vision モデルが利用されます。まずは、食べ物が写っている画像から 食べ物の情報を取得できるか 試してみます。 食べ物の画像 画像とともに入力するテキストは以下のとおりです。 画像から、料理名、特徴、1人前あたりのカロリー、アレルギー物質をjson形式で出力してください。 Gemini Pro Vision からの出力は以下の通りでした。 { " 料理名 ": " 沖縄そば ", " 特徴 ": " 沖縄そばは、沖縄県で古くから食べられている郷土料理です。鰹節と昆布で出汁をとったスープに、小麦粉を原料とした麺と三枚肉、かまぼこ、紅ショウガなどが乗っています。 ", " 1人前あたりのカロリー ": " 約500kcal ", " アレルギー物質 ": " 小麦、卵、豚肉 " } Genimiからの出力(画像①) 画像② 画像内の表を読み取れるか 試してみます。 栄養成分表示の画像 画像とともに入力するテキストは以下のとおりです。 栄養成分表示をテーブル形式で出力して下さい。 Gemini Pro Vision からの出力は以下の通りでした。 栄養成分表示 1食(180g)当たり エネルギー 273kcal たんぱく質 6.8g 脂質 10.2g 炭水化物 38.5g 食塩相当量 1.2g Geminiからの出力(画像②) 動画 愛犬とカフェに行った際の動画から 動画内に写るオブジェクトを抽出 させてみます。 youtube.com 動画とともに入力するテキストは以下のとおりです。 この動画内に映っている全てのオブジェクトにラベルを付けて、検索しやすい形で情報を提供してください。各オブジェクトの名称、種類、色をjson形式で出力してください。 Gemini Pro Vision からの出力は以下の通りでした。 { " objects ": [ { " name ": " dog ", " type ": " animal ", " color ": " brown and white " } , { " name ": " chair ", " type ": " furniture ", " color ": " black " } , { " name ": " table ", " type ": " furniture ", " color ": " brown " } , { " name ": " floor ", " type ": " surface ", " color ": " gray " } , { " name ": " wall ", " type ": " surface ", " color ": " white " } , { " name ": " ceiling ", " type ": " surface ", " color ": " white " } , { " name ": " window ", " type ": " opening ", " color ": " transparent " } , { " name ": " door ", " type ": " opening ", " color ": " brown " } , { " name ": " tree ", " type ": " plant ", " color ": " green " } , { " name ": " sky ", " type ": " natural ", " color ": " blue " } , { " name ": " sea ", " type ": " natural ", " color ": " blue " } , { " name ": " cloud ", " type ": " natural ", " color ": " white " } , { " name ": " sun ", " type ": " natural ", " color ": " yellow " } , { " name ": " ghost ", " type ": " decoration ", " color ": " white " } ] } Genimiからの出力(動画) 利用状況の可視化 Gemini API の料金は、入力した画像、動画、テキストの量と、出力されたテキストの量に応じた従量課金となります。マルチモーダルなチャットボットの導入に伴い、Gemini API の課金状況は気になるところです。 本 Web アプリでは、Gemini API への入出力情報をログとして Cloud Storage に出力しているため、そのログデータを解析することで利用状況を可視化することもできます。 以下は、組織全体またはユーザーごとに今どれだけ利用しているのか一目で把握できるように Looker Studio で可視化しています。 Gemini API の利用状況ダッシュボード もし自社内で生成 AI を利用した社内アプリの実装を検討中なら、当社の Generative AI 活用支援ソリューションをご検討ください。 g-gen.co.jp 又吉 佑樹 (記事一覧) クラウドソリューション部 はいさい、沖縄出身のクラウドエンジニア! セールスからエンジニアへ転身。Google Cloud 全 11 資格保有。Google Cloud Champion Innovator (AI/ML)。Google Cloud Partner Top Engineer 2024。Google Cloud 公式ユーザー会 Jagu'e'r でエバンジェリストとして活動中。好きな分野は AI/ML。 Follow @matayuuuu
アバター