TECH PLAY

NTT西日本

NTT西日本 の技術ブログ

78

はじめに NTTビジネスソリューションズの山本です。 本記事では、Google Gemini 2.5 ProやGoogle Gemini 2.5 Flash Image(別名Nano Banana)におけるトークンと課金の考え方について学んだ内容を紹介します。 本記事は2025年10月時点の情報に基づきます。 対象読者 本記事が想定する対象読者は以下の通りです。 生成AIに興味を持っている人 生成AIにおけるトークンについて知りたい人 Google Gemini CLIとNano Bananaを使っている人 背景・目的 Google for Developersのブログで「最先端の画像処理モデル Gemini 2.5 Flash Image のご紹介」の記事が公開されており、興味を持ちました。 最先端の画像処理モデル Gemini 2.5 Flash Image のご紹介 - Google Developers Blog ちょうど、Google for Developersのコミュニティイベントが開催される直前で申し込みをし、PoC環境を構築しました。 その後無料試用期間が終了し、有料に替わるタイミングで、課金の概念(トークン)の理解を深めたいと考えました。 Google Gemini CLIの使用方法 前提条件・動作環境 Node.jsがインストールされていること。 今回はWindows環境上でWSL+VS Codeを使用します。筆者の環境は次の通りです。 ホストOS: Windows 11 Pro 25H2 使用したディストリビューション: Ubuntu 24.04.3 LTS VS Codeのバージョン: 1.105.1 Googleアカウントは個人名義で問題ありません。ただし、今回の検証を実施すると料金が発生します。その点ご留意下さい。 Node.jsがインストールされたら以下のコマンドでGemini CLIをインストールします。  # npm install -g @google/gemini-cli 以下のコマンドを利用し、Gemini CLIを起動します。  # gemini 認証 認証方法は、下記の3パターンあります。 Googleで認証 Gemini API Keyで認証 Vertex AIで認証 今回はGEMINI_API_KEYで認証しました。APIキーの取得方法は、 Gemini API キーを使用する  |  Google AI for Developers を参照してください。 Gemini CLIの使用 プロンプトを打ってみる:今日の大阪の天気は?->Google検索を利用します。 図1:Gemini CLIにプロンプトを入力 Geminiからの回答が表示される。 図2:Geminiからの回答を表示 終了する際は、Ctrl+Cキーを2回押してください。 トークンの確認 ここからトークンについて学んでいきます。詳細はこちらをご確認ください。 トークンを理解してカウントする  |  Gemini API  |  Google AI for Developers Gemini や他の生成 AI モデルは、トークンと呼ばれる粒度で入力と出力を処理します。 Gemini モデルの場合、1 個のトークンは約 4 文字に相当します。100 個のトークンは、約 60 ~ 80 ワード(英語)に相当します。 トークンは、z などの単一の文字、cat などの単語全体にすることができます。長い単語は複数のトークンに分割されます。モデルで使用されるすべてのトークンのセットを語彙と呼び、テキストをトークンに分割するプロセスをトークン化と呼びます。 課金が有効になっている場合、Gemini API の呼び出し費用は、入力トークンと出力トークンの数によって決まります。そのため、トークンのカウント方法を知っておくと便利です。 トークンについては、Colabの環境で対話型で学習することができます。 Google Colab 図3:トークン数を確認 プロンプトのトークン数は、7つと確認することができました。あとは Gemini 側で処理をし、結果を出力するだけです。 ここまで来て気になることを思い出しました! Geminiは質問を受け取ったあと、Google検索を使用して内容を調査し、確認してから回答していました。 ひょっとすると、この思考の過程もトークンとしてカウントしているのでは?と考えました。 Gemini モデルのトークン数をカウントする  |  Firebase AI Logic をもとに、Gemini モデルのトークン数をカウントする python スクリプトを作成します。 import google.generativeai as genai # APIキーを設定 genai.configure(api_key="YOUR_API_KEY") def count_tokens(prompt_text, model_name="gemini-2.5-pro"): """トークン数をカウントして詳細を出力""" model = genai.GenerativeModel(model_name) # トークン数をカウント token_count = model.count_tokens(prompt_text) # 結果を出力 print(f"prompt_token_counts: {token_count.total_tokens}") # レスポンス生成してトークン数を取得 response = model.generate_content(prompt_text) print(f"candidates_token_count: {response.usage_metadata.candidates_token_count}") print(f"prompt_token_count: {response.usage_metadata.prompt_token_count}") print(f"total_token_count: {response.usage_metadata.total_token_count}") return response # 使用例 if __name__ == "__main__": prompt = "今日の大阪の天気を教えて?" count_tokens(prompt) 図4:実行結果 トークンをカウントするオプション Gemini API の入力と出力はすべてトークン化されます。トークンのカウント方法には次のオプションがあります。 prompt_token_count: 入力のみのトークン数 candidates_token_count: 出力のトークン数(思考トークンは含まれません) total_token_count: 入力と出力の両方のトークンの合計数(思考トークンを含む) 上記のオプションについては、次の点に注意してください。 入力トークン数には、プロンプト(テキストと入力ファイル)だけでなく、システム指示とツールも含まれます。 出力トークン数には思考トークンは含まれません。思考トークンは別のフィールドで提供されます。 トークンの考え方について詳細調査 Google AI Studio では確認できなかったのですが、Vertex AI Studio でトークンの考え方イメージを視覚的に確認することができました。 プロンプト入力時のトークン数、処理後のトークン数がわかります。 図5:Vertex AI Studio 返答完了後、 381個のトークン と表示されています。Vertex AIも料金が発生します。検証される場合は、ご留意下さい。 まとめ トークンの考え方やカウント方法について理解を深めることができました。トークンの扱いはモデルによって異なり、特に料金に直結する要素であるため、継続的に情報をアップデートしながら学習する必要があると感じています。 今回のPoCでは従量課金でAPIを利用しましたが、実際のシステム導入時には、利用状況や予算に応じたコスト制御の仕組みを検討することが重要であると再認識しました。 以下は、チャットでのPoC実施時の請求結果です。 SKU サービス 使用料 使用費用 Generate content output token count Gemini 2.5 Pro short output text Gemini API 7,398 count ¥11 Generate content input token count Gemini 2.5 Pro short input text Gemini API 18,943 count ¥4 Generate content cached input token count gemini 2.5 pro short input Gemini API 32,442 count ¥1 執筆者 山本 寛(NTTビジネスソリューションズ エンタープライズビジネス営業部所属) 現在はMicrosoft 365やGoogle Workspaceを活用した設計、構築案件に携わっています。 技術士(情報工学部門)、PMI認定PMPなど取得。 参考資料・出典 最先端の画像処理モデル Gemini 2.5 Flash Image のご紹介 - Google Developers Blog Gemini API キーを使用する  |  Google AI for Developers トークンを理解してカウントする  |  Gemini API  |  Google AI for Developers Google Colab Gemini モデルのトークン数をカウントする  |  Firebase AI Logic 商標  「Google」「Gemini」「Vertex AI」「Google Workspace」は、Google LLCまたはその関連会社の商標もしくは登録商標です。 「Windows」「VS Code」「Microsoft 365」は、米国Microsoft Corporationの米国およびその他の国における商標もしくは登録商標です。 「PMI」「PMP」は 、米国Project Management Instituteの商標もしくは登録商標です。 「Node.js」は 、Joyent, Inc.の商標もしくは登録商標です。 「Python」は、Python Software Foundationの商標もしくは登録商標です。
はじめに NTT西日本エンタープライズビジネス営業部の吉田泰隆です。 本記事ではユーザ認証に用いられるRADIUSサーバ・クライアントをAWS上に構築し、CloudWatchによるアクセスログの可視化について紹介します。 本記事は2025年9月時点の情報に基づきます。 対象読者 本記事が想定する対象読者は以下の通りです。 AWSやネットワーク認証システムに興味を持っている人 AWS環境でサーバー構築経験を積みたい人 RADIUSサーバーの導入・設定方法を学びたい人 CloudWatchを使ったログ監視・可視化を実装したい人 背景・目的 担当案件でRADIUSサーバーを構築することになりました。その際、ドキュメントや資料を読んだだけでは、認証の仕組みや各設定のつながりが腑に落ちず、深く理解するためには実際に手を動かすしかないと感じました。 本記事は、RADIUSサーバーの構築手順を丁寧に解説するハンズオンです。私が構築中につまずいたポイントや、理解を深めるための補足情報も盛り込んでいます。この記事を通して、読者の皆さんがRADIUSの仕組みを実践的に学び、今後の業務に役立てていただければ幸いです。 全体構成図 同じ VPC 内に RADIUS サーバーとクライアントを配置し、クライアントからサーバーへ認証リクエストを送信するシンプルな構成です。 構築手順 ステップ1: AWS環境の準備 まず、サーバーとクライアントとして利用する2台のEC2インスタンスを準備します。 以下の設定で2台のEC2インスタンスを作成します。 設定項目 値 補足 名前 RADIUS-Server と RADIUS-Client それぞれの役割が分かるように命名します。 AMI Amazon Linux 2023 - インスタンスタイプ t2.micro デモ用途には十分なスペックです。 ネットワーク 同じVPC、同じパブリックサブネット 2台のインスタンスが相互に通信できるようにします。 パブリックIPの自動割り当て 有効化 SSH接続用 次にRADIUS-SG という名前で新しいセキュリティグループを作成し、2台のインスタンスにアタッチします。以下のインバウンドルールを設定してください。 タイプ プロトコル ポート範囲 ソース 説明 SSH TCP 22 マイIP(コンソールにアクセスしているユーザーのパブリックIPアドレス) ユーザからのSSH接続 カスタムUDP UDP 1812 RADIUS-SG のID RADIUS認証通信 カスタムUDP UDP 1813 RADIUS-SG のID RADIUSアカウンティング通信 プライベートIPアドレスの確認 後ほどの設定で利用するため、作成した2台のインスタンスのプライベートIPアドレスを控えておきます。 ステップ2: RADIUSサーバーの構築 1. RADIUS-ServerインスタンスへのSSH接続 以下2種類の方法でRADIUS-Serverへ接続します。 ・EC2 Instance Connect ・SSH クライアント ※手順はコマンドともにコンソールに記載されておりますので、そちら(下記画像)をご参照ください。 2. FreeRADIUSのインストール FreeRADIUS をインストール・設定します。 sudo dnf update -y sudo dnf install -y freeradius freeradius-utils タイムゾーンを日本時間 (Asia/Tokyo) に設定します。 sudo timedatectl set-timezone Asia/Tokyo 3. クライアント情報の登録 (clients.conf) RADIUS サーバーがどのクライアントからのリクエストを受け付けるかを設定します。 sudo vi /etc/raddb/clients.conf を開き、ファイルの末尾に RADIUS-Client の情報を追記します。 <RADIUS-ClientのプライベートIP> は控えておいたIPアドレスに置き換えてください。 # /etc/raddb/clients.conf # (...ファイルのもともとの内容...) # 自前のRADIUSクライアントを追加 client radius_client { ipaddr = <RADIUS-ClientのプライベートIP> secret = hands-on # サーバーとクライアント間の合い言葉 } この secret (共有シークレット) は非常に重要です。 !注意!本記事では構成を理解する目的で簡単化のため平文でパスワードを使用しています。実運用では絶対に使わないでください。 4. ユーザー情報の登録 ( users ) 認証に利用するユーザーを登録します。 sudo vi /etc/raddb/users を開き、ファイルの先頭にテストユーザーの情報を追記します。 # /etc/raddb/users # テストユーザーを追加 (ユーザー名: testuser, パスワード: testpassword) testuser Cleartext-Password := "testpassword" # 複数人登録する場合は同様に追記する hanako.yamada Cleartext-Password := "P@ssword_Yamada123" taro.suzuki Cleartext-Password := "P@ssword_Suzuki456" # (...ファイルのもともとの内容...) ステップ3: EAP無効化 FreeRADIUS は、インストール直後の状態では高度な認証方式 (EAP) が有効になっています。しかし、これらの機能はSSL/TLS証明書などを必要とするため、シンプルなID/パスワード認証を行う際には、これが原因で起動エラーが発生します。 今回のデモでは、より簡単にするためにあらかじめEAP(Extensible Authentication Protocol, 拡張認証プロトコル)を無効化しておきます。 ※EAP:IEEE 802.1X認証フレームワークの1つ。ユーザーID/パスワードや電子証明書を用いた多様な認証方式(EAP-TLS、EAP-PEAPなど)を柔軟に利用できるようにする仕組み。 !注意!本記事では構成を理解する目的で簡単化のためEAPを無効化しています。盗聴・中間者攻撃のリスク増大のため、実運用では絶対に使わないでください。 1. eap モジュールを無効化 EAP はセキュアな認証方式ですが、証明書がないと起動に失敗します。以下のコマンドで無効化します。 sudo rm /etc/raddb/mods-enabled/eap 2 inner-tunnel サイトを無効化 inner-tunnel は EAP のトンネル処理で使われる設定ですが、今回は不要なので無効化します。 sudo rm /etc/raddb/sites-enabled/inner-tunnel 3. default サイトの修正 モジュールを無効化しても、メインの設定ファイル ( `default` ) からの呼び出しが残っているため、それらもコメントアウトします。まず、下記コマンドで設定ファイルを開きます。 sudo vi /etc/raddb/sites-enabled/default その後、2箇所修正します。 authorize セクションの修正(419行目) ※eapだけでなく、{ }の部分もコメントアウトすることを忘れないでください。起動時に構文エラーとなります。 # 編集前 authorize { ... eap { ok = return # updated = return } } # 編集後 authorize { ... #eap { # ok = return # updated = return #} } authenticate セクションの修正(603行目) # 編集前 authenticate { ... eap ... } # 編集後 authenticate { ... # eap ... } Tips:編集する行を409, 603行目と記載しましたが、見つからない場合は以下のコマンドをお試しください。編集すべき行数を知ることができます。 sudo grep -n '^\s*eap' /etc/raddb/sites-enabled/default これで、シンプルなPAP認証(ID/パスワード認証)に必要な設定だけが残った状態になりました。 ステップ4: サーバーの起動とクライアントの準備 1. FreeRADIUSサービスの起動 RADIUS-Server で以下のコマンドを実行し、サービスを起動・自動起動設定します。 sudo systemctl start radiusd sudo systemctl enable radiusd 以下のコマンドで active (running) となっていれば成功です。 [ec2-user@ip-10-0-14-102 ~]# sudo systemctl status radiusd ● radiusd.service - FreeRADIUS high performance RADIUS server. Loaded: loaded (/usr/lib/systemd/system/radiusd.service; enabled; preset: disabled) Active: active (running) since Sun 2025-06-22 11:29:19 UTC; 12s ago Main PID: 31373 (radiusd) Tasks: 6 (limit: 1111) Memory: 40.5M CPU: 80ms CGroup: /system.slice/radiusd.service └─31373 /usr/sbin/radiusd -d /etc/raddb 2. クライアントツールのインストール RADIUS-Client インスタンスに SSH で接続し、テストツールをインストールします。 sudo dnf update -y sudo dnf install -y freeradius-utils ステップ5: 認証テスト RADIUS-Client から radtest コマンドを使い、認証テストを実行します。 1. 認証成功テスト 正しい共有シークレット ( hands-on ) を使ってテストします。 radtest testuser testpassword <RADIUS-ServerのプライベートIP>:1812 0 hands-on 以下のように Received Access-Accept と返ってくれば認証成功です! Sent Access-Request Id 95 from 0.0.0.0:55186 to 10.0.14.102:1812 length 78 User-Name = "testuser" User-Password = "testpassword" NAS-IP-Address = 10.0.8.100 NAS-Port = 0 Message-Authenticator = 0x00 Cleartext-Password = "testpassword" Received Access-Accept Id 95 from 10.0.14.102:1812 to 10.0.8.100:55186 length 38 Message-Authenticator = 0xf224b42683d891fa7fcf3193349935ad 2. 認証失敗テスト (共有シークレット不一致) わざと間違った共有シークレット ( hands-off ) を使ってみましょう。 radtest testuser testpassword <RADIUS-ServerのプライベートIP>:1812 0 hands-off 今度はサーバーから何の応答もなく、最終的にタイムアウトエラーになります。 Sent Access-Request Id 27 from 0.0.0.0:56334 to 10.0.14.102:1812 length 78 User-Name = "testuser" User-Password = "testpassword" NAS-IP-Address = 10.0.8.100 NAS-Port = 0 Message-Authenticator = 0x00 Cleartext-Password = "testpassword" Sent Access-Request Id 27 from 0.0.0.0:56334 to 10.0.14.102:1812 length 78 User-Name = "testuser" User-Password = "testpassword" NAS-IP-Address = 10.0.8.100 NAS-Port = 0 Message-Authenticator = 0x00 Cleartext-Password = "testpassword" Sent Access-Request Id 27 from 0.0.0.0:56334 to 10.0.14.102:1812 length 78 User-Name = "testuser" User-Password = "testpassword" NAS-IP-Address = 10.0.8.100 NAS-Port = 0 Message-Authenticator = 0x00 Cleartext-Password = "testpassword" (0) No reply from server for ID 27 socket 3. 登録されたクライアントからでも共有シークレットが違う場合、サーバーは不正なリクエストとみなし、パケットを破棄します。 【発展】AWSサービスのワンポイント:認証ログの可視化 ステップ6: FreeRADIUSの設定ファイル radiusd.conf を編集 設定ファイルをテキストエディタで開きます。 sudo vi /etc/raddb/radiusd.conf log セクション内の auth の設定(348行目)をnoからyesへ変更します。 #編集前 # Log all (accept and reject) authentication results to the log file. # # This is the same as setting "auth_accept = yes" and # "auth_reject = yes" # # allowed values: {no, yes} # auth = no #編集後 # Log all (accept and reject) authentication results to the log file. # # This is the same as setting "auth_accept = yes" and # "auth_reject = yes" # # allowed values: {no, yes} # auth = yes デフォルトの設定では取得できなかった成功時のログも吐き出し可能となりました。 変更を反映させるために、RADIUSサーバを再起動させてください。 sudo systemctl restart radiusd 再起動後、サービスが正常に稼働しているか確認します。 active (running) と表示されていれば、正常に再起動されています。 sudo systemctl status radiusd ステップ7: CloudWatch Agentのインストールと設定 1. IAMロールのアタッチ RADIUS-Server のEC2インスタンスに、CloudWatch Agentがログを送信するための権限が必要です。   1-1. IAMコンソールで新しいロールを作成します。   1-2. 信頼されたエンティティタイプ: AWSのサービス   1-3. ユースケース: EC2   1-4. 許可ポリシーとして CloudWatchAgentServerPolicy をアタッチします。   1-5. ロール名(例: EC2-CloudWatchAgent-Role )を付けて作成します。   1-6. EC2ダッシュボードに戻り、 RADIUS-Server インスタンスにこのIAMロールをアタッチします。 2. CloudWatch Agentのインストール RADIUS-Server にSSHで接続し、以下のコマンドでAgentをインストールします。 sudo dnf install -y amazon-cloudwatch-agent 3. Agent設定ファイルの作成 どのログファイルをCloudWatchに送信するかを定義する設定ファイルを作成します。FreeRADIUSは認証結果を /var/log/radius/radius.log に出力するので、これを対象とします。 sudo vi /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json を実行し、以下の内容を貼り付けます。 { "agent": { "metrics_collection_interval": 60, "run_as_user": "root", "debug": true }, "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "/var/log/radius/radius.log", "log_group_class": "STANDARD", "log_group_name": "/aws/ec2/freeradius-logs", "log_stream_name": "{instance_id}", "retention_in_days": 7, "timestamp_format": "%a %b %d %H:%M:%S %Y", "timezone": "LOCAL" } ] } } }, "metrics": { "aggregation_dimensions": [ [ "InstanceId" ] ], "append_dimensions": { "AutoScalingGroupName": "${aws:AutoScalingGroupName}", "ImageId": "${aws:ImageId}", "InstanceId": "${aws:InstanceId}", "InstanceType": "${aws:InstanceType}" }, "metrics_collected": { "disk": { "measurement": [ "used_percent" ], "metrics_collection_interval": 60, "resources": [ "*" ] }, "mem": { "measurement": [ "mem_used_percent" ], "metrics_collection_interval": 60 }, "statsd": { "metrics_aggregation_interval": 60, "metrics_collection_interval": 10, "service_address": ":8125" } } } } log_group_name : CloudWatch Logs内でログを格納するグループ名です。分かりやすい名前をつけましょう。 参考までに上記jsonは以下の内容となっています。変更したいパラメータ等あれば、自由に調整してください。 CloudWatch Agent パラメータ設定 エージェント共通 (agent) パラメータ 設定値 説明 run_as_user root エージェントを実行するユーザー。rootで実行することでファイルアクセス権限の問題を回避します。 metrics_collection_interval 60 (デフォルト値) メトリクスを収集する基本間隔(秒)。 debug TRUE デバッグモードを有効化。詳細な動作ログが出力され、トラブルシューティングに役立ちます。本番環境では false を推奨します。 ログ収集 (logs) パラメータ 設定値 説明 file_path /var/log/radius/radius.log 収集対象のログファイルへのフルパス。 log_group_name /aws/ec2/freeradius-logs ログを格納するCloudWatch Logsのロググループ名。 log_stream_name {instance_id} ロググループ内のログストリーム名。 {instance_id} とすることで、実行したEC2インスタンスのIDが自動的に設定されます。 retention_in_days 7 CloudWatch Logsでのログ保持期間(日数)。7日経過後に自動で削除されます。 timestamp_format %a %b %d %H:%M:%S %Y ログファイル内のタイムスタンプを解釈するための書式。 timezone LOCAL ログのタイムスタンプに使用するタイムゾーン。LOCALはEC2インスタンスのOS設定に従います。 log_group_class STANDARD ロググループのストレージクラス。標準のアクセス頻度に適しています。 メトリクス共通 (metrics) パラメータ 設定値 説明 aggregation_dimensions InstanceId 収集したメトリクスをInstanceId単位で集約します。 append_dimensions.AutoScalingGroupName ${aws:AutoScalingGroupName} 全てのメトリクスにAuto Scalingグループ名のディメンション(タグ)を付与します。 append_dimensions.ImageId ${aws:ImageId} 全てのメトリクスにAMIのIDのディメンション(タグ)を付与します。 append_dimensions.InstanceId ${aws:InstanceId} 全てのメトリクスにインスタンスIDのディメンション(タグ)を付与します。 append_dimensions.InstanceType ${aws:InstanceType} 全てのメトリクスにインスタンスタイプのディメンション(タグ)を付与します。 収集メトリクス (ディスク・メモリ) パラメータ 設定値 説明 measurement used_percent 収集するディスクの指標。ディスク使用率(%)を収集します。 resources * 収集対象のリソース。 * は全てのマウント済みディスクパーティションを意味します。 metrics_collection_interval 60 このメトリクスの収集間隔(秒)。 measurement mem_used_percent 収集するメモリの指標。メモリ使用率(%)を収集します。 metrics_collection_interval 60 このメトリクスの収集間隔(秒)。 収集メトリクス (StatsD) パラメータ 設定値 説明 service_address :8125 アプリケーションからカスタムメトリクスを受け付けるStatsDリスナーのアドレスとポート。 metrics_collection_interval 10 StatsDプロトコルでデータを受け付ける間隔(秒)。 metrics_aggregation_interval 60 受け付けたデータを集約し、CloudWatchへ送信する間隔(秒)。 4. CloudWatch Agentの起動 以下のコマンドで設定ファイルを読み込み、Agentを起動します。 sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s これで、 RADIUS-Server で認証が発生するたびに、そのログが自動でCloudWatch Logsに送信されるようになります。 左がCloudWatchエージェントが取得した情報で、右側がRADIUSサーバ内の radius.log  です。少し見にくいですが、きちんとログを収集できることがわかります。 ステップ8: CloudWatch Logs Insightsでのログ分析 radtest コマンドで何度か認証を成功・失敗させてログを生成した後、AWSコンソールのCloudWatch画面を開きます。 左側のメニューから「ログ」>「Logs Insights」を選択します。 「ロググループを選択」で、先ほど設定した RadiusServer/radius.log を選びます。 クエリエディタに、SQLライクなクエリを入力してログを分析できます。 クエリ 最新の認証ログ取得 fields @timestamp, @message | sort by @timestamp desc | limit 10 認証成功(Access-Accept)と失敗(Access-Reject)の件数を集計 fields @timestamp, @message | filter @message like /Login OK/ or @message like /error/ | stats count(*) as event_count by if(@message like /Login OK/, 'Login OK', 'Error') as event_type | sort by event_type asc 認証数の推移 fields @timestamp, @message | filter @message like /Login OK/ or @message like /error/ | stats sum(if(@message like /Login OK/, 1, 0)) as LoginOK_Count, sum(if(@message like /error/, 1, 0)) as Error_Count by bin(1m) as interval | sort by interval asc ステップ9: CloudWatch Dashboardでの可視化 Logs Insightsのクエリ結果は、そのままダッシュボードのウィジェットとして追加できます。 Logs Insightsで上記のクエリを実行した後、「アクション」>「ダッシュボードに追加」をクリックします。 「新しいダッシュボードを作成」を選び、ダッシュボード名(例: RADIUS-Monitoring )を入力します。 ウィジェットの種類(折れ線グラフ、円グラフ、数値など)を選択し、「ダッシュボードに追加」をクリックします。 これを繰り返すことで、以下のようなウィジェットを持つダッシュボードを作成できます。 みなさんもお好きなメトリクスを収集して、オリジナルを作ってみてください。 まとめ 今回は AWS 環境で RADIUS サーバーを構築し、認証テストを行うまでの一連の流れを解説しました。 ぜひ、みなさんもトライしてみてください。 執筆者 吉田 泰隆(NTT西日本 エンタープライズビジネス営業部所属) 好きなAWSサービス:Route53 所有資格:AWS Certified Solutions Architect – Professional 参考資料・出典 本記事を執筆するにあたり、以下のサイトを参考にしました。 qiita.com qiita.com https://www.hcnet.co.jp/column/detail23.html https://www.infraexpert.com/study/wireless14.html 商標 「AWS」は、Amazon Web Services,Inc.またはその関連会社の商標もしくは登録商標です。
1. はじめに 2. 対象読者 3. 背景・目的 4. 用語の解説 ◆ MCPとは? ◆ AWS Documentation MCP Serverとは? 5. 動作環境・前提条件 6. Windows環境での設定手順 ◆ Step 1: 必要なツールのインストール ◆ Step 2: Claude Desktop設定ファイルへのアクセス ◆ Step 3: Claude Desktopの設定 ◆ Step 4: Claude Desktopの再起動 ◆ Step 5: AWS Documentation MCP Serverの起動確認 7. 動作確認 ◆ ①AWS Documentation MCP Serverを無効にして質問 ◆ ②AWS Documentation MCP Serverを有効にして質問 8. まとめ 執筆者 商標 免責事項 1. はじめに こんにちは。NTT西日本の三浦です。 皆さまは、「特定のAWSサービスの情報を調べたいけど、適したAWS公式ドキュメントがすぐに見つからない...!」といったお悩みはありませんでしょうか? AWS公式ドキュメントの数は膨大な量になるので、その中からピンポイントに必要な情報を見つけることは大変です。 さらに、見つけた情報が最新かどうかの確認や、複数のドキュメントを横断した調査には多くの時間がかかってしまいます。 本記事では、そういった悩みを解決するアプローチとして、AWS Documentation MCP Serverをご紹介します。 生成AIとAWS Documentation MCP Serverを連携させることで、AWS公式ドキュメントの検索・参照が自動化され、従来の問い合わせ対応が劇的に効率化されます。 2. 対象読者 本記事が想定する対象読者は以下の通りです。 AWS公式ドキュメントへの効率的なアクセス方法を求めている人 MCPについて知りたい人 CCoE担当者や、または日常的にAWSなどの技術的な問合せを受けている人 3. 背景・目的 私は担当の業務として、日々多くのAWSの技術的な問い合わせを受けています。 「技術検証を行っているが、IAM権限エラーが出て困っている」「こんなイメージでネットワーク接続を実現したいが、設定方法がわからない」といった質問に対して、迅速かつ正確な回答を提供する必要があります。 従来はブラウザでAWS公式ドキュメント等を検索しながら回答していましたが、この方法では次の課題がありました。 膨大な情報の中から、ピンポイントに適した情報(特に、信頼性のある公式ドキュメントの情報)を見つけることが大変 見つけた情報を一つ一つ確認して、それが回答として適した情報かの解釈に30分~1時間程度の時間がかかる 質問者への回答作成に時間がかかる そこで、Model Context Protocol(MCP)を活用したClaude DesktopとAWS Documentation MCP Serverの連携を試したところ、問い合わせ対応の効率が改善されました。 この経験を共有し、同じような課題を抱える方々の参考になればと思い記事にしました。 4. 用語の解説 そもそも「MCPって何?」という方へ向けて、本記事で登場する重要な用語について解説します。 ◆ MCPとは? Model Context Protocol (MCP) とは、Anthropic社が2024年11月にオープンソース化した、生成AIが外部のデータやツールと連携するための新しい標準規格のことです。 www.anthropic.com 従来はAIアプリケーションから外部のデータやツールにアクセスするには、個別にカスタマイズする必要がありました。 これらの連携方法をMCPによって標準化することで、AIアプリケーションから様々なデータやツールと簡単に接続できるようになります。 ◆ AWS Documentation MCP Serverとは? AWS Documentation MCP Server とは、生成AIがAWSの公式ドキュメントにアクセスするためのMCPに対応したツールのことです。 github.com AWS Documentation MCP Serverは、主に次の機能を提供します。 ドキュメント読み取り:AWS公式ドキュメントをMarkdown形式で取得 ドキュメント検索:公式検索APIを使用したAWS公式ドキュメントの検索 関連ページ推奨:AWS公式ドキュメントに関連する推奨のページを取得 AWS Documentation MCP Serverの実態は、公式検索APIやドキュメント取得用のAPI等に対して問い合わせを行うラッパーサーバーです。 生成AIからドキュメント検索用に用意されたAPIを利用する際の橋渡しのような役割を担っています。 5. 動作環境・前提条件 AWS Documentation MCP Serverを利用するには、MCPクライアントとなる生成AIが必要です。 本記事では、例としてWindows版のClaude Desktopを利用して、AWS Documentation MCP Serverを利用するための設定手順を紹介します。 動作環境は次の通りです。 システム要件 OS:Windows 11 Claude Desktop バージョン:Windows版の最新バージョン(推奨) インストールがまだの方は、 公式サイト からダウンロードおよびインストール、ログインまで実施してください なお、本記事の構成は無償版のClaude Desktopでも動作します。 6. Windows環境での設定手順 実際にWindows環境で検証した結果を基に、手順を説明します。 手順はAWS Documentation MCP Serverの ドキュメント をベースに記載しておりますが、皆さまの環境によっては一部の手順が異なる場合があることにご注意ください。 ◆ Step 1: 必要なツールのインストール AWS Documentation MCP Serverの利用に必要な環境をインストールします。 コマンドプロンプトを開いて以下のコマンドを実行します。 実行後しばらく待つとインストールが完了します。 powershell -c "irm https://astral.sh/uv/install.ps1 | iex" インストールができたら、uv が適切にインストールされているか確認します。 uv --version 次に、Python 3.10以降がインストールされているか確認します。 python --version もしもPythonがインストールされていなければ、以下コマンドを実行してPython 3.10(またはより新しいバージョン)をインストールします。 uv python install 3.10 ◆ Step 2: Claude Desktop設定ファイルへのアクセス Windows環境でのClaude Desktopの設定ファイルを開きます。 設定ファイルへのアクセス方法: メニューもしくは画面左下のアイコンから、「設定」をクリックして設定メニューを表示する 設定メニューにて「開発者」、「設定を編集」の順にクリック 表示された「claude_desktop_config.json」を任意のエディタで開く ◆ Step 3: Claude Desktopの設定 claude_desktop_config.jsonファイルに以下のテキストを貼り付けて保存します。 { " mcpServers ": { " awslabs.aws-documentation-mcp-server ": { " disabled ": false , " timeout ": 60 , " type ": " stdio ", " command ": " uv ", " args ": [ " tool ", " run ", " --from ", " awslabs.aws-documentation-mcp-server@latest ", " awslabs.aws-documentation-mcp-server " ] , " env ": { " FASTMCP_LOG_LEVEL ": " ERROR ", " AWS_DOCUMENTATION_PARTITION ": " aws " } } } } 注意: JSONファイルの構文エラーがあるとClaude Desktopが正常に起動しません 編集前に設定ファイルのバックアップを取ることをお勧めします 他のMCPサーバーを既に設定している場合は、インデントやカンマの位置にご注意ください ◆ Step 4: Claude Desktopの再起動 設定ファイル保存後、Claude Desktopを再起動します。 Claude Desktopの左上のメニューから、[ファイル] > [終了] をクリックして終了します。 その後、改めてClaude Desktopを起動してください。 Claude Desktopの「✕ボタン」を押して閉じるだけでは再起動されないのでご注意ください。 ◆ Step 5: AWS Documentation MCP Serverの起動確認 Claude Desktop起動後エラーが表示されないことを確認します。 Claude Desktop画面左下の自身のアイコンから、[設定] > [開発者]の順に選択して、AWS Documentation MCP Serverのステータスが「running」になっていることを確認します。 新規チャットにてAWS Documentation MCP Serverが表示されていれば、設定は終わりです。 7. 動作確認 以下の質問で機能確認を行います。 精度の比較として、①AWS Documentation MCP Serverを無効にして質問した場合と、②AWS Documentation MCP Serverを有効にして質問した場合で対照実験を行います。 AWS Lambda SnapStartの対応ランタイムについて教えてください。 回答は対応ランタイムだけリストして答えてください。 なお、期待する回答は以下になります。 AWS Lambda SnapStartのPythonや.NETへの対応は2024年11月18日にリリースされた機能になるので、Claude Desktopの回答の精度に違いがでるかを検証します。 Java 11以降 Python 3.12以降 .NET 8以降 docs.aws.amazon.com ◆ ①AWS Documentation MCP Serverを無効にして質問 まずは、AWS Documentation MCP Serverを 無効にして 質問した結果を示します。 Claude Desktopが記憶している古い情報を元にした回答になっており、回答に誤りがあることがわかります。 AWS Lambda SnapStartの対応ランタイムとして、Javaしかリストされておらず、Pythonや.NETに関する記載はありません。 なお、回答内容はお手元の環境で実行した場合では異なる場合があります。 ◆ ②AWS Documentation MCP Serverを有効にして質問 次に、AWS Documentation MCP Serverを 有効にして 質問してみます。 実行時、「Claudeがこのツールを使用したいと思っています」とポップアップが表示された場合は、「一度だけ許可」もしくは「常に許可する」を選択してください。 ツール利用毎にClaudeからの確認が必要ないなら、「常に許可する」を選択してください。 AWS Documentation MCP Serverを利用して、公式ドキュメントを検索・参照します。 回答内容を確認すると、期待する回答と一致しており、最新の情報が取得できていることがわかります。 また、AWS Documentation MCP Serverのツールアクションの内容を確認すると、今回の質問に該当する公式ドキュメントを参照していることがわかります。 8. まとめ 今回の記事では、MCPの概要とAWS Documentation MCP Serverについて紹介いたしました。 CCoE担当者、テクニカルサポート、ソリューションアーキテクトなど、日常的にAWSドキュメントを参照する業務に従事する方に特に有効だと思います。 従来のブラウザ検索では、複数のAWSドキュメントページを手動で確認し、情報を横断的に確認する必要がありました。今回の動作確認は簡単なデモでしたが、実際の問い合わせ対応や技術調査では、AWS Documentation MCP Serverを活用することで以下の具体的な改善が実現できます。 検索精度の向上 曖昧な技術用語でも関連ドキュメントを包括的に抽出することができる 複数サービス間の依存関係も含めた情報収集が可能 作業時間の短縮 これまで30分程度かかっていたドキュメント調査が2~3分程度に短縮 情報品質の担保 AWS公式ドキュメントのみを参照するため、信頼性が高い AWS Documentation MCP Serverの他にも、AWS Labs では、 AWS MCP Collection としてAWS Knowledge MCP Server、AWS Pricing MCP Serverなどの様々な便利なMCPが提供されています。こちらに関しても今後ブログ記事を執筆していきたいと思います。 執筆者 三浦大輝 (NTT西日本 ビジネス営業本部 エンタープライズビジネス営業部所属) クラウドエンジニアとして、主にAWS導入プロジェクトや社内のクラウド人材育成を担当しています。 2024 Japan AWS Top Engineers 商標 Amazon Web Services、AWS、AWS Lambda、および本記事で言及されるその他のAWSサービス名は、Amazon.com, Inc.またはその関連会社の商標です。 Claude、Claude Desktop、およびAnthropic関連の名称は、Anthropic PBC の商標です。 Microsoft、Windows、Windows 11は、Microsoft Corporationの米国およびその他の国における登録商標または商標です。 Python は、Python Software Foundation の登録商標です。 その他、記載されている会社名、製品名は、各社の登録商標または商標です。 免責事項 本記事の内容は執筆時点(2025年9月)の情報に基づいており、サービスの仕様変更等により内容が変更される可能性があります。 本記事で紹介する設定手順や使用方法は、特定の環境での動作確認に基づくものであり、すべての環境での動作を保証するものではありません。 AWS Documentation MCP Server は AWS Labs によって提供されるオープンソースプロジェクトであり、AWSの公式サポート対象外です。 本記事では生成AIを活用した内容が含まれており、AIによる情報の生成過程でハルシネーション(事実に基づかない情報の生成)が発生する可能性があります。記載内容の正確性については、必ず公式ドキュメントや信頼できる情報源で検証してください。
はじめに NTT西日本の服部です。本記事はNTT WEST Engineers' Blog 開設にむけて投稿記事レビューのワークフローを爆速で構築した話の第6回の記事となります。 前回までの記事も読んでいただけるとありがたいです。 最終回の第6回となる本記事ではPower Automateによるレビューフロー後編として差戻による修正依頼と記事公開後の通知フローについてご紹介します。 本記事は2025年9月時点の情報に基づきます。 ①~概要編~ ②~Microsoft Forms/Microsoft Lists編~ ③~Power AutomateによるMicrosoft Listsへの自動登録編~ ④~Power Automateによるレビューフロー前編~ ⑤~Power Automateによるレビューフロー中編~ ⑥~Power Automateによるレビューフロー後編~ (本記事) 第1回の記事でご紹介したワークフローの全体像のうち、以下の図にあたる内容となります。 修正依頼フロー 投稿完了通知フロー 対象読者 本記事が想定する対象読者は以下の通りです。 自動化に興味がある人 繰り返しの定常的な作業に困っている人 Microsoft Forms/Microsoft Lists/Power Automateを使ってみたい人 背景 NTT WEST Engineers' Blog に向けて、ブログ記事のレビュープロセスを効率化したいという要望を受けて執筆者が検討・構築しました。 SaaSの新規サービスを導入する予算はありませんでしたが、幸い全社的にMicrosoft Forms、Microsoft Lists、Power Automateが利用できる環境だったため、これらを用いてブログ記事レビューのワークフローを構築しました。 本記事ではPower Automateを用いた1.差戻による修正依頼フローと2.記事公開後の通知フローについてご紹介します。 アダプティブカードについて 本記事でご紹介するフローにはアダプティブカードを使った処理が含まれています。 アダプティブカードの詳細については前回の記事で紹介しておりますのでぜひそちらの記事も読んでみてください。 1.修正依頼フロー 修正依頼フローの全体像は以下の通りです。 ここで冒頭でご紹介したフローのイメージ図ではレビュー結果通知および修正依頼から始まっているにも関わらず上記のフローでは アイテムが作成または変更されたとき から始まっている点が気になる方がいらっしゃるかもしれません。 元々構築したフローでは前回ご紹介したレビューフローと今回の修正依頼フローは一つのフローにまとめていたためイメージ図通りの処理内容でした。しかしブログ執筆にあたり分割したほうが読みやすい記事にできると判断しフローを二つに分けた結果、ここでは差分が発生しています。 以下で各ステップの詳細についてご紹介します。 1-1. アイテムが作成または変更されたとき このフローが実行されるトリガーです。 前回/前々回の記事でも紹介しましたがMicrosoft Listsにおける一行ごとのデータ(レコード)のことをアイテムといい、本記事においては1アイテム=1件分のレビュー依頼に相当します。 トリガーの条件として以下を指定しました。 @equals(triggerBody()['OData__x30b9__x30c6__x30fc__x30bf__x30/Value'],'差し戻し(修正待ち)') 上記は作成または更新されたアイテムのステータスが差し戻し(修正待ち)のときにこのフローが実行されることを意味しています。 前回ご紹介したレビューフローで差し戻しとなったときの処理としてステータスが 差し戻し(修正待ち) に更新されたことをトリガーとして本フローが実行されます。 トリガーの条件の書き方については第3回の記事で詳しく解説しているため、そちらを参照ください。 1-2. 変数を初期化する レビュアーコメントの一部を置換した内容をcommentという文字列変数に代入しています。 値の部分には以下の評価式が入っています。 replace(replace(triggerOutputs()?['body/OData__x30ec__x30d3__x30e5__x30fc__x30'],'"','”'),'\','¥') ここではレビュアーコメントの列の値について、半角のバックスラッシュ \ を全角の円マーク ¥ に置換するという処理と半角のダブルクォート " を全角のダブルクォート ” に置換するという処理を実行しています。 半角のダブルクォートやバックスラッシュが残っていると次のアダプティブカードの投稿処理でJSON形式が崩れることでエラーが発生してしまうため、それを回避するためにこのような処理を挟んでいます。 1-3. アダプティブ カードを投稿して応答を待機する(修正依頼) 投稿者宛に修正依頼のためのアダプティブカードを送る処理です。 省略されているメッセージ部分には以下のJSONが記載されています。 { " type ": " AdaptiveCard ", " body ": [ { " type ": " TextBlock ", " size ": " Medium ", " weight ": " Bolder ", " text ": " ブログ記事の修正依頼 " } , { " type ": " TextBlock ", " text ": " タイトル:@{triggerOutputs()?['body/Title']}の記事についてレビューの結果、差し戻しとなりました。 \n レビューコメントを参照して記事を修正してください。 \n\n レビューコメント: \n\n @{variables('comment')} ", " wrap ": true } , { " type ": " ActionSet ", " actions ": [ { " type ": " Action.OpenUrl ", " title ": " 下書きプレビューURL ", " url ": " @{triggerOutputs()?['body/OData__x4e0b__x66f8__x304d__x30d7__x30']} " } ] } , { " type ": " ActionSet ", " actions ": [ { " type ": " Action.Submit ", " title ": " 完了 ", " id ": " complete " } , { " type ": " Action.Submit ", " title ": " キャンセル ", " id ": " cancel " } ] , " horizontalAlignment ": " Center ", " spacing ": " Medium " } , { " type ": " TextBlock ", " text ": " ・完了:再度レビュー依頼をあげます。 \n ・キャンセル:投稿依頼を取り下げます。 ", " wrap ": true } ] , " $schema ": " http://adaptivecards.io/schemas/adaptive-card.json ", " version ": " 1.5 " } 上記のアダプティブカードが送信されるとMicrosoft TeamsでWorkflowsという対象から以下のようなメッセージがレビュアーの個人チャット宛に届きます。 このアダプティブカードの内容を参照して投稿者は記事の修正対応を実施し、再度レビュー依頼をあげるために完了をクリックするか、投稿依頼を取り下げるとしてキャンセルをクリックすることで次の処理に進めることができます。 こちらのアダプティブカードの処理はタイムアウトを7日間(P7D)に設定しています。 タイムアウト設定については前回の記事を参照ください。 1-4. スイッチ(修正対応の結果) アダプティブカードの結果によって処理が分岐します。 分岐処理の判定には以下の値を使用しています。 outputs('アダプティブ カードを投稿して応答を待機する(修正依頼)')?['body/submitActionId'] ここには直前に処理されたアダプティブカードでクリックされたボタンのIDが入ります。 つまりアダプティブカードのメッセージで定義された以下のボタンに割り当てられたIDである complete , cancel のいずれかが入ります。 " type ": " ActionSet ", " actions ": [ { " type ": " Action.Submit ", " title ": " 完了 ", " id ": " complete " } , { " type ": " Action.Submit ", " title ": " キャンセル ", " id ": " cancel " } ] , 1-4-1. ケース1(完了) アダプティブカードで完了がクリックされたときの処理です。 完了の場合はステータスをレビュー完了に変更する処理が実行されます。 ここの処理ではレビュアーの値は特に指定していないため、これまでに設定されたレビュアーの値が残ったままになっています。 これによって前回と同じレビュアー宛に再度レビュー依頼を送るフローが実行されます。 レビュー依頼のフローについては前回の記事を参照ください。 1-4-2. ケース2(キャンセル) アダプティブカードでキャンセルがクリックされたときの処理です。 キャンセルの場合はステータスを却下/消滅に変更する処理が実行されます。 ステータスが却下/消滅に変更された場合は他のフローは実行されないため、ここで処理が終了となります。 投稿者都合で修正対応をする時間が取れない場合等を想定しています。 1-5.項目の更新(タイムアウトに伴う消滅) アダプティブカードがタイムアウトしたときの処理です。 ここではレビュー依頼をクローズするためにステータスを 却下/消滅 に更新しています。 タイムアウト時の並列分岐の追加方法については前回の記事を参照ください。 2.記事公開後の通知フロー 事務局によって記事が公開された後、事務局の担当者はリストのステータスを投稿完了に手動で変更します。 ステータスが投稿完了になったことをトリガーとして投稿者に通知を送るためのフローの全体像は以下の通りです。 以下で各ステップの詳細についてご紹介します。 2-1. アイテムが作成または変更されたとき このフローが実行されるトリガーです。 トリガーの条件として以下を指定しました。 @equals(triggerBody()['OData__x30b9__x30c6__x30fc__x30bf__x30/Value'],'投稿完了') 上記は作成または更新されたアイテムのステータスが 投稿完了 のときにこのフローが実行されることを意味しています。 トリガーの条件の書き方については第3回の記事で詳しく解説しているため、そちらを参照ください。 2-2. チャットまたはチャネルでメッセージを投稿する 投稿者宛に記事が公開されたことを通知します。 上記の処理によってMicrosoft TeamsでWorkflowsという対象から投稿者の個人チャット宛にメッセージが投稿されます。 注意事項 今回ご紹介したPower Automateのフローは意図的にフローの実行結果から別のフローを呼び出すという設計にしていますが、設定値を誤ると無限ループが発生する可能性があります。 本記事の内容を流用される場合には無限ループが発生しないように十分に注意して設計/構築してください。 無限ループへの対処法については以下の日本マイクロソフトのブログ記事も参照ください。 Power Automate のフローで無限トリガーループが起きる際の対処法 | Japan Dynamics CRM & Power Platform Support Blog 最後に NTT WEST Engineers' Blog 開設にむけて投稿記事レビューのワークフローを爆速で構築した話と題して第6回までお送りしました。 本記事で紹介した内容の各要素は他のブログ等でも紹介されており、特別難しいことをしているわけではありません。 ただ私自身がこのフローを作る中で調べものをしているときに各要素を紹介したものはあるがこれらを組み合わせて構築してみたといった内容の記事は数が多くないように感じました。 なければ自分で作ればいいじゃないということで今回執筆してみましたがいかがでしたでしょうか。 需要がないから誰も書いていない可能性はあるかも・・・と思いつつ執筆しましたが少しでも参考になる部分があれば幸いです。 ここでご紹介したフロー自体は3,4日程度で執筆者自身が単独で構成検討/構築したもので運用も始まったばかりでこれから様々なブラッシュアップが入ることが想定されます。 ブラッシュアップしていく中で参考になりそうな内容が出てきた際には本ブログにて改めてご紹介できればと思います。 ここまで読んでいただきありがとうございます。 執筆者 服部 真智(NTT西日本 ビジネス営業本部所属) 普段はAWS案件の提案、設計、構築等の支援を行っています。 自業務の効率化のためにPython,Power Automate,生成AI等を使って日々試行錯誤しています。 2025 Japan AWS Top Engineers (Services) 商標 Microsoft (Microsoft Entra 、 Microsoft Teams 、 Power Automate 、 Microsoft Lists 、 Microsoft Forms)及び関連する名称並びにそれぞれのロゴは、米国 Microsoft Corporation の米国およびその他の国における商標または登録商標です。
はじめに NTT西日本の服部です。本記事はNTT WEST Engineers' Blog 開設にむけて投稿記事レビューのワークフローを爆速で構築した話の第5回の記事となります。 前回までの記事も読んでいただけるとありがたいです。 第5回となる本記事ではPower Automateによるレビューフロー中編としてレビュアーアサイン後のレビューフローについてご紹介します。 本記事は2025年9月時点の情報に基づきます。 ①~概要編~ ②~Microsoft Forms/Microsoft Lists編~ ③~Power AutomateによるMicrosoft Listsへの自動登録編~ ④~Power Automateによるレビューフロー前編~ ⑤~Power Automateによるレビューフロー中編~ (本記事) ⑥~Power Automateによるレビューフロー後編~ 第1回でご紹介したワークフローの全体像のうち、以下の図にあたる内容となります。 対象読者 本記事が想定する対象読者は以下の通りです。 自動化に興味がある人 繰り返しの定常的な作業に困っている人 Microsoft Forms/Microsoft Lists/Power Automateを使ってみたい人 背景 NTT WEST Engineers' Blog に向けて、ブログ記事のレビュープロセスを効率化したいという要望を受けて執筆者が検討・構築しました。 SaaSの新規サービスを導入する予算はありませんでしたが、幸い全社的にMicrosoft Forms、Microsoft Lists、Power Automateが利用できる環境だったため、これらを用いてブログ記事レビューのワークフローを構築しました。 本記事ではレビュアーアサイン後のレビューフローとして構築したPower Automateのフローについて紹介します。 補足:アダプティブカードについて 今回紹介するフローの中で利用されているアダプティブカードについて事前にご紹介します。 アダプティブカードとは、テキストや画像、ボタンなどを組み合わせたインタラクティブなメッセージカードです。 Microsoft Teamsで利用するアダプティブカードについての詳細は以下の公式ドキュメントを参照ください。 Teams 向けアダプティブ カードの概要 - Power Automate | Microsoft Learn アダプティブカードを設計する際には以下のデザイナーを利用することができます。 Designer | Adaptive Cards 上記のデザイナーを使ってMicrosoft Teamsに投稿するアダプティブカードをデザインする際には下図赤枠の Select host app で Microsoft Teams を選択するようにしてください。 引用元: https://adaptivecards.io/designer デフォルトで選択されている Bot Framework WebChat の場合、画面右上の Target Version が 1.6 となっておりこちらのバージョンはMicrosoft Teamsに対応していません。 非対応のバージョンで作成されたアダプティブカードをMicrosoft Teamsに投稿すると以下のメッセージが表示されます。 レビュアーアサイン後のレビューフロー アダプティブカードについてご紹介したところで本題のPower Automateのフローについてご紹介します。 今回レビューの処理用に構築したフローの全体像は以下の通りです。 以下で各ステップの詳細についてご紹介します。 1.アイテムが作成または変更されたとき このPower Automate のフローが実行される条件(トリガー)になります。 前回の記事でも紹介しましたがMicrosoft Listsにおける一行ごとのデータ(レコード)のことをアイテムといい、本記事においては1アイテム=1件分のレビュー依頼に相当します。 アイテムが新規に作成されたもしくは既存のアイテムの値が変更されたときにこのフローが実行されます。 トリガーの条件として以下を指定しました。 @equals(triggerBody()['OData__x30b9__x30c6__x30fc__x30bf__x30/Value'],'レビュアーアサイン待ち') @not(equals(triggerBody()['OData__x30ec__x30d3__x30e5__x30a2__x30/Value'],'未設定')) 上記は作成または更新されたアイテムのステータスが レビュアーアサイン待ち かつレビュアーが 未設定ではない (=誰かしらレビュアーがアサインされている)ときにこのフローが実行されることを意味しています。 トリガーの条件式の書き方については前回の記事で詳しく解説しているため、そちらを参照ください。 2.項目の更新(レビュー待ち) 実際のレビュー依頼をあげるまえにステータスをレビュー待ちに更新します。 ステータスをレビュー待ちに更新したとしても他のフローのトリガー条件にあてはまることはないため、他のフローは実行されません。 3.アダプティブ カードを投稿して応答を待機する(レビュー依頼) レビュアーとしてアサインされた担当者にアダプティブカードを送る処理です。 省略されているメッセージ部分には以下のJSONが記載されています。 { " type ": " AdaptiveCard ", " body ": [ { " type ": " TextBlock ", " size ": " Medium ", " weight ": " Bolder ", " text ": " ブログ記事のレビュー依頼 " } , { " type ": " TextBlock ", " text ": " タイトル:@{outputs('項目の更新(レビュー待ち)')?['body/Title']}の記事のレビュアーとして設定されました。 \n 以下の下書き記事を見てレビューコメントを入力してください。 \n コメントを入力後レビュー結果に相当するボタンをクリックしてください。 ", " wrap ": true } , { " type ": " ActionSet ", " actions ": [ { " type ": " Action.OpenUrl ", " title ": " 下書きプレビューURL ", " url ": " @{outputs('項目の更新(レビュー待ち)')?['body/OData__x4e0b__x66f8__x304d__x30d7__x30']} " } ] } , { " type ": " Input.Text ", " placeholder ": " Placeholder text ", " id ": " comment ", " isRequired ": true , " errorMessage ": " レビューコメントは必須項目です。 ", " label ": " レビューコメント ", " isMultiline ": true } , { " type ": " ActionSet ", " actions ": [ { " type ": " Action.Submit ", " title ": " 承認 ", " id ": " approval " } , { " type ": " Action.Submit ", " title ": " 差戻 ", " id ": " remand " } , { " type ": " Action.Submit ", " title ": " キャンセル ", " id ": " cancel " } , { " type ": " Action.Submit ", " title ": " 却下 ", " id ": " reject " } ] , " horizontalAlignment ": " Left " } , { " type ": " TextBlock ", " text ": " ・承認:レビューを完了します。 \n ・差戻:投稿者に修正を依頼します。 \n ・キャンセル:レビュアーの変更を依頼します。 \n ・却下:規定違反などを理由に却下します。 ", " wrap ": true } ] , " $schema ": " http://adaptivecards.io/schemas/adaptive-card.json ", " version ": " 1.5 " } 上記のアダプティブカードが送信されるとMicrosoft TeamsでWorkflowsという対象から以下のようなメッセージがレビュアーの個人チャット宛に届きます。 下書きプレビューURLのボタンはリンクとなっており、ブログ記事の下書きページを確認することができ、その内容についてレビューした結果をレビューコメントの枠に入力します。 レビューコメントを入力したらレビュー結果に相当するボタンをクリックすることで次の処理に進めることができます。   また、レビューコメントの属性として "isRequired": true, を指定することで必須の入力項目となり、空欄のままでは次の処理に進められないようにしています。 補足:アダプティブカードのタイムアウト設定について アダプティブカードは規定では30日でタイムアウトとなりますがこの期間は変更することが可能です。 変更する場合はアダプティブカードのステップの右側にある ・・・ から 設定 をクリックします。 設定をクリックすると以下の画面が表示されるため、タイムアウトを設定することが出来ます。 ここでは14日間経過するとタイムアウトするように設定しています。 タイムアウトの期間はISO 8601 形式で期間を指定します。 ISO 8601 形式の詳細については以下を参照ください。 ISO 8601 - Wikipedia ISO 8601-1:2019(en) 4.スイッチ(レビュー結果) アダプティブカードに対してレビュアーが操作した結果によって処理が分岐します。 分岐処理の判定には以下の値を使用しています。 outputs('アダプティブ カードを投稿して応答を待機する(レビュー依頼)')?['body/submitActionId'] ここには直前に処理されたアダプティブカードでクリックされたボタンのIDが入ります。 つまりアダプティブカードのメッセージで定義された以下のボタンに割り当てられたIDである approval , remand , cancel , reject のいずれかが入ります。 " type ": " ActionSet ", " actions ": [ { " type ": " Action.Submit ", " title ": " 承認 ", " id ": " approval " } , { " type ": " Action.Submit ", " title ": " 差戻 ", " id ": " remand " } , { " type ": " Action.Submit ", " title ": " キャンセル ", " id ": " cancel " } , { " type ": " Action.Submit ", " title ": " 却下 ", " id ": " reject " } ] , 4-1.ケース1(承認) アダプティブカードで 承認 がクリックされたときの処理です。 承認された場合には投稿者へのレビュー完了の通知処理とステータスをレビュー完了に変更する処理と事務局への記事公開依頼処理が含まれています。 本来は以下のステップの前に タグの @mention トークンを取得する のステップを追加するべきですが、ここでは割愛しています。 上記の処理によってMicrosoft Teamsで指定されたチャネルにメッセージが投稿されます。 上記の処理によってMicrosoft TeamsでWorkflowsという対象から投稿者の個人チャット宛にメッセージが投稿されます。 4-2.ケース2(差戻) アダプティブカードで 差戻 がクリックされたときの処理です。 ここではステータスを差し戻しに更新する処理のみを定義しています。 修正依頼のフローはここでは定義しておらず、別のフローとして定義されています。 修正依頼のフローの詳細については次回ご紹介します。 4-3.ケース3(キャンセル) アダプティブカードで キャンセル がクリックされたときの処理です。 レビュアーが業務都合などの理由から担当者を変更して欲しい場合に使うことを想定しています。 ここではステータスをレビュアーアサイン待ちに、レビュアーを未設定に更新する処理を実行します。 この処理によって前回ご紹介したレビュアーアサイン依頼のフローのトリガー条件を満たすことになり、レビュアーのアサインからやり直すことができます。 4-4.ケース4(却下) アダプティブカードで 却下 がクリックされたときの処理です。 記事の内容が規定に反する等の理由から投稿できないと判断されたときに使うことを想定しています。 ここではステータスを 却下/消滅 に更新する処理と投稿者へのレビュー結果通知の処理を定義しています。 上記の処理によってMicrosoft TeamsでWorkflowsという対象から投稿者の個人チャット宛にメッセージが投稿されます。 5.項目の更新(レビュータイムアウトに伴うレビュアーリセット) 本記事でアダプティブカードのタイムアウトについて解説しましたが、アダプティブカードがタイムアウトするとフローの処理としては失敗となりそこで処理が終了してしまいます。 そこで万が一タイムアウトが発生した場合の処理の定義が以下の内容になります。 ここではケース3(キャンセル)と同じでステータスを レビュアーアサイン待ち に、レビュアーを 未設定 に更新することでレビュアーのアサイン依頼のフローを呼び出せるようにしています。 タイムアウト用の処理を定義したい場合は分岐したいステップの直後(今回はアダプティブカードのステップの直後)で⊕ボタンをクリックして並列分岐の追加をクリックします。 分岐先で追加したステップ(今回は項目の更新)の右側の ・・・ から実行条件の構成をクリックします。 実行条件の構成をクリックすると以下の画面が表示され、直前のステップ(ここではアダプティブカードのステップ)の処理結果がどうなったときにこのステップを実行するかを選択することができます。ここではタイムアウトした場合に実行すると定義しています。 成功しました以外が選択された状態で完了をクリックすると該当のステップに繋がる矢印が赤の破線に変更されます。 注意事項 今回ご紹介したPower Automateのフローは意図的にフローの実行結果から別のフローを呼び出すという設計にしていますが、設定内容を誤ると無限ループが発生する可能性があります。 本記事の内容を流用される場合には無限ループが発生しないように十分に注意して設計/構築してください。 無限ループへの対処法については以下の日本マイクロソフトのブログ記事も参照ください。 Power Automate のフローで無限トリガーループが起きる際の対処法 | Japan Dynamics CRM & Power Platform Support Blog まとめ 今回は本シリーズの最も重要なレビューフローについてご紹介しました。 多くの処理が含まれるため非常に長い記事となりましたがここまで読んでいただきありがとうございます。 次回は本シリーズの最終回で修正依頼と投稿完了通知のフローのご紹介となります。 もしよろしければ最後までお付き合いください。 執筆者 服部 真智(NTT西日本 ビジネス営業本部所属) 普段はAWS案件の提案、設計、構築等の支援を行っています。 自業務の効率化のためにPython,Power Automate,生成AI等を使って日々試行錯誤しています。 2025 Japan AWS Top Engineers (Services) 商標 Microsoft (Microsoft Entra 、 Microsoft Teams 、 Power Automate 、 Microsoft Lists 、 Microsoft Forms)及び関連する名称並びにそれぞれのロゴは、米国 Microsoft Corporation の米国およびその他の国における商標または登録商標です。
はじめに NTT西日本の桂川です。 本記事では、クラウド運用自動化の実践として、「AWS Step Functions(以降、Step Functions)」を活用したワークフロー自動化について紹介します。 「Step Functions」は、AWS SDKサービス統合により、各種AWSサービスのAPIアクションを呼び出すことが可能であり、複数のAWSサービスを組み合わせたワークフローを構築することができます。 本記事では、運用自動化の一例として、IAMユーザーの自動作成に取り組んだ事例を解説します。 なお、本記事の内容は2025年9月時点の情報に基づいています。 対象読者 本記事の対象読者は、以下のような方々を想定しています。 AWS や 運用自動化に関心のある方 Step Functions の活用方法を知りたい方 IAMユーザー作成の自動化を検討している方 背景・目的 AWSアカウントに多数のIAMユーザーを作成する必要がある場面に直面し、手作業による対応では効率が悪いため、作業の自動化について検討を始めました。 IAMユーザー作成の自動化にあたり、以下の要件を満たす必要がありました。 前提条件 AWSアカウントは、管理アカウントとメンバーアカウントで構成されている 管理アカウントがメンバーアカウントのセキュリティ統制やコスト管理を行う 要件 メンバーアカウント利用開始時に初期セットアップとしてIAMユーザーを作成する IAMユーザの初期パスワードは、ランダムなパスワードを自動作成する 初回サインイン時にパスワードのリセットを要求する 制限事項 他のIAMユーザーのパスワードは閲覧不可とする メンバーアカウントのIAMユーザーは、IAM関連操作を禁止する これらの要件を満たすため「AWS Cloud Formation(以降、Cloud Formation)」で実現する方法と「Step Functions」で実現する方法の2つの方法を検討しました。 ■ 各サービスの比較結果 要件 Cloud Formation Step Functions IAMユーザ作成 〇 〇 パスワード自動作成 △ 〇 パスワードリセット 〇 〇 パスワード閲覧不可 △ 〇 IAM関連操作禁止 △ 〇 各サービスの実現方法を比較した結果、パスワードの自動作成などの要件を容易に満たせること、またアクセス権限に関する考慮が比較的少なくて済むことから、「Step Functions」を採用しました。 表について、要件の達成は可能だが、実装が複雑になる項目を「△」としています。「Cloud Formation」の採用を見送った主な理由は、以下の通りです。 パスワード自動作成 パスワードを自動作成する際、「AWS Secrets Manager(以降、Secrets Manager)」を使用してパスワードをシークレットとして保存し、IAMユーザー作成時にそのシークレットを参照する必要がありました。 パスワード閲覧不可 メンバーアカウント内の他のIAMユーザーがパスワードを閲覧ができないよう「Secrets Manager」に保存されたパスワードのアクセス権限を適切に設定する必要がありました。 IAM関連操作禁止 メンバーアカウントのIAMユーザーが展開済みの「Cloud Formation」を使用して、IAM関連の操作を実行できないよう考慮する必要がありました。 「Step Functions」は、AWS SDKサービス統合により、さまざまなAWSサービスのAPIアクションを呼び出すことが可能となっており、 複数のサービスを組み合わせたワークフローを容易に作成できます。 さらに、ノーコードで開発できるデザインツールも備えており、Cloud Formationのようにコードを書くことが苦手な方でも取り組みやすいという特長があります。 「Step Functions」は、各サービスとの柔軟な統合が可能で、幅広いユースケースに対応できるため、運用自動化を推進するうえで、皆様にとっても非常に有用なツールになると考えています。 本記事では、IAMユーザーの自動作成に取り組んだ事例を通じて、その活用方法についてご紹介したいと思います。 ソリューションの概要 このソリューションでは、AWSアカウントへIAMユーザーを自動作成するStep Functions ワークフローについて紹介します。 本事例では、管理アカウントからメンバーアカウントへIAMユーザを自動作成する構成について解説します。 管理アカウントがない場合は、対象アカウント上にStep Functionsワークフローを直接構築することも可能です。 ■ 構成図 前提条件 以下のIAMリソースを事前に作成してください。 アカウント IAMリソース 概要 管理アカウント Step Functions実行用IAMロール クロスアカウントアクセス用IAMロールに対するAssumeRole権限を許可 メンバーアカウント クロスアカウントアクセス用IAMロール IAMユーザー作成に必要な権限を許可 メンバーアカウント IAMグループ IAMユーザーが所属するIAMグループ 例)StepFunctions実行用IAMロール { " Version ": " 2012-10-17 ", " Statement ": [ { " Action ": [ " sts:assumeRole " ] , " Resource ": [ " arn:aws:iam::<メンバーアカウントID>:role/<クロスアカウントアクセス用IAMロール> " ] , " Effect ": " Allow " } ] } 例)クロスアカウントアクセス用IAMロール { " Version ": " 2012-10-17 ", " Statement ": [ { " Action ": [ " iam:CreateLoginProfile ", " iam:AddUserToGroup ", " iam:AttachUserPolicy ", " iam:ListAccountAliases ", " iam:CreateUser " ] , " Resource ": [ " * " ] , " Effect ": " Allow " } , { " Action ": [ " secretsmanager:GetRandomPassword " ] , " Resource ": [ " * " ] , " Effect ": " Allow " } ] } アカウントエイリアスを事前に設定してください。 今回は、サインインURLを自動作成する際にアカウントエイリアスを使用します。 以下の場合は、設定不要です。 サインインURLにアカウントIDを使用する場合 サインインURLを自動作成しない場合 考慮事項 クロスアカウントアクセス用IAMロールの信頼関係でAssumeRoleを許可するPrincipalは必要最小限としてください。 適切な信頼関係が設定されていない場合、メンバーアカウントのIAMユーザーがクロスアカウントアクセス用IAMロールにSwitchRoleすることで、意図せずアクセス権限が付与されてしまう可能性があります。 例)クロスアカウントアクセス用IAMロールの信頼関係 { " Version ": " 2008-10-17 ", " Statement ": [ { " Effect ": " Allow ", " Principal ": { " AWS ": " arn:aws:iam::<管理アカウントID>:<Step Functions実行用IAMロール> " } , " Action ": " sts:AssumeRole " } ] } 管理アカウントがなく対象アカウント上にStep Functionsワークフローを直接構築する場合、Step Functionsを実行することで、意図せずアクセス権限が付与されないよう注意してください。 例えば、対象アカウント上のIAMユーザーにおいてIAM関連操作を禁止している場合、IAMユーザがStep Functionsワークフローを実行することで、意図せずIAMユーザー作成が可能となってしまう可能性があります。 例)管理アカウントがなく対象アカウント上にStep Functionsワークフローを直接構築する場合 IAMユーザー自動作成ワークフローの作成 ■ 概要 メンバーアカウントにIAMユーザーを自動作成するStep Functions ワークフローを作成します。 AWSマネジメントコンソール上からIAMユーザーを作成する場合と同様に「ユーザー名」、「サインインURL」、「パスワード」を出力するワークフローを作成します。 「パスワード」は、ワークフローで自動作成し、次回のサインイン時に新しいパスワードを設定するよう要求します。 ■ Step Functions ワークフロー 「メンバーアカウントID」と「ユーザー名」をパラメータとして入力し、「ユーザー名」、「サインインURL」、「パスワード」を出力するワークフローを作成します。 ワークフロー 入力パラメータ { " AccountId ": " <メンバーアカウントID> ", " UserNames ": [ " <ユーザー名> ", " <ユーザー名> " ] } 出力パラメータ { " Users ": [ { " UserName ": " <ユーザー名> ", " LoginURL ": " <サインインURL> ", " Password ": " <パスワード> " } , { " UserName ": " <ユーザー名> ", " LoginURL ": " <サインインURL> ", " Password ": " <パスワード> " } ] } ■ 作成手順 1. Step Functions の [ステートマシンの作成] から ワークフローを作成します。 2. Step Functions Workflow Studio で ワークフローを編集します。 「デザイン」モード は、状態をキャンバスにドラッグアンドドロップすることでワークフローを作成することが可能です。 「コード」モード は、 Amazon States Language(ASL)を使用してワークフローを作成します。 デザインモード コードモード 実行したいアクションを選択し、[APIパラメータ] 、[次の状態] 、[入力] 、[出力] 、[エラー処理] などのパラメータを設定します。 クロスアカウントアクセスを行う場合、[クロスアカウントアクセスを有効にする] をチェックし、[ターゲットロール ARN] を設定します。 IAMユーザー自動作成ワークフローのASL定義を参考として記載します。エラー処理などは割愛しています。 IAMユーザー自動作成ワークフロー(ASL定義) { " Comment ": " Create multiple IAM users with random passwords ", " StartAt ": " ListAccountAliases ", " States ": { " ListAccountAliases ": { " Type ": " Task ", " Resource ": " arn:aws:states:::aws-sdk:iam:listAccountAliases ", " Parameters ": {} , " ResultPath ": " $.AccountAliasResult ", " Next ": " CreateUsersMap ", " Credentials ": { " RoleArn.$ ": " States.Format('arn:aws:iam::{}:role/<クロスアカウントアクセス用IAMロール>', $.AccountId) " } } , " CreateUsersMap ": { " Type ": " Map ", " ItemsPath ": " $.UserNames ", " Parameters ": { " AccountId.$ ": " $.AccountId ", " UserName.$ ": " $$.Map.Item.Value ", " AccountAlias.$ ": " $.AccountAliasResult.AccountAliases[0] " } , " ResultPath ": " $.UserResults ", " Iterator ": { " StartAt ": " GenerateRandomPassword ", " States ": { " GenerateRandomPassword ": { " Type ": " Task ", " Resource ": " arn:aws:states:::aws-sdk:secretsmanager:getRandomPassword ", " Parameters ": { " PasswordLength ": 13 , " RequireEachIncludedType ": true , " ExcludeCharacters ": " \"\\ ,./:;<>?`~. " } , " ResultPath ": " $.RandomPasswordResult ", " Next ": " CreateIAMUser ", " Credentials ": { " RoleArn.$ ": " States.Format('arn:aws:iam::{}:role/<クロスアカウントアクセス用IAMロール>', $.AccountId) " } } , " CreateIAMUser ": { " Type ": " Task ", " Resource ": " arn:aws:states:::aws-sdk:iam:createUser ", " Parameters ": { " UserName.$ ": " $.UserName " } , " ResultPath ": " $.TaskResult ", " Next ": " CreateLoginProfile ", " Credentials ": { " RoleArn.$ ": " States.Format('arn:aws:iam::{}:role/<クロスアカウントアクセス用IAMロール>', $.AccountId) " } } , " CreateLoginProfile ": { " Type ": " Task ", " Resource ": " arn:aws:states:::aws-sdk:iam:createLoginProfile ", " Parameters ": { " UserName.$ ": " $.UserName ", " Password.$ ": " $.RandomPasswordResult.RandomPassword ", " PasswordResetRequired ": true } , " ResultPath ": " $.TaskResult ", " Next ": " AttachUserPolicy ", " Credentials ": { " RoleArn.$ ": " States.Format('arn:aws:iam::{}:role/<クロスアカウントアクセス用IAMロール>', $.AccountId) " } } , " AttachUserPolicy ": { " Type ": " Task ", " Resource ": " arn:aws:states:::aws-sdk:iam:attachUserPolicy ", " Parameters ": { " UserName.$ ": " $.UserName ", " PolicyArn ": " arn:aws:iam::aws:policy/IAMUserChangePassword " } , " ResultPath ": " $.TaskResult ", " Next ": " AddUserToGroup ", " Credentials ": { " RoleArn.$ ": " States.Format('arn:aws:iam::{}:role/<クロスアカウントアクセス用IAMロール>', $.AccountId) " } } , " AddUserToGroup ": { " Type ": " Task ", " Resource ": " arn:aws:states:::aws-sdk:iam:addUserToGroup ", " Parameters ": { " UserName.$ ": " $.UserName ", " GroupName ": " <IAMグループ> " } , " ResultPath ": " $.TaskResult ", " Next ": " ReturnLoginInfo ", " Credentials ": { " RoleArn.$ ": " States.Format('arn:aws:iam::{}:role/<クロスアカウントアクセス用IAMロール>', $.AccountId) " } } , " ReturnLoginInfo ": { " Type ": " Pass ", " Parameters ": { " LoginURL.$ ": " States.Format('https://{}.signin.aws.amazon.com/console', $.AccountAlias) ", " UserName.$ ": " $.UserName ", " Password.$ ": " $.RandomPasswordResult.RandomPassword " } , " End ": true } } } , " Next ": " ReturnAllLoginInfo " } , " ReturnAllLoginInfo ": { " Type ": " Pass ", " Parameters ": { " Users.$ ": " $.UserResults " } , " End ": true } } } 3. Step Functions の 実行ロールを設定します。 Step Functions の 実行ロールを設定します。必要に応じて、ログ記録設定などを行い、[作成] をクリックします。 4. Step Functions の [実行を開始] から ワークフローを実行します。 Step Functions の 実行ステータス が [成功] となり、実行が完了していることを確認します。 5. メンバーアカウントにIAMユーザーが作成されていることを確認します。 メンバーアカウントにサインインして、IAMユーザーが作成されていることを確認します。 まとめ 本記事では、クラウド運用自動化の一例として、AWSの「Step Functions」を活用したIAMユーザーの自動作成に取り組んだ事例をご紹介しました。 「Step Functions」は、AWS SDKサービス統合により、各種AWSサービスのAPIアクションを呼び出すことが可能で、幅広いユースケースに対応することができます。 また、Workflow Studioを使用することでノーコード開発も可能となり、Cloud Formationのようにコードを書くことが苦手な方でも取り組みやすくなっています。 さらに、「AWS Lambda」を使用しない構成であれば、ランタイムバージョンのアップグレードなどの定期保守が不要となり、運用負荷の軽減にもつながります。 運用における定型作業や繰り返し作業を自動化することで、「作業時間の削減」や「手動操作によるヒューマンエラーの防止」、「作業の一貫性確保」といった多くのメリットが得られます。 まずは、運用自動化の第一歩として、身近な業務から取り組んでみてはいかがでしょうか。 本記事が、皆様の業務改善の一助となれば幸いです。 執筆者 桂川 裕幸(NTT西日本 ビジネス営業本部 エンタープライズビジネス営業部所属) AWSを活用したクラウドシステムの設計・構築に携わっています。 サーバーレスアーキテクチャが好きです。 2025 Japan AWS All Certifications Engineers に選出。 参考資料・出典 本記事を執筆するにあたり、以下のサイトを参考にさせていただきました。 docs.aws.amazon.com docs.aws.amazon.com docs.aws.amazon.com 商標  「AWS」「AWS Step Functions」「AWS Lambda」「AWS Secrets Manager」「AWS Cloud Formation」は、Amazon Web Services,Inc.またはその関連会社の商標もしくは登録商標です。 免責事項 本記事の内容には、IAMアクセス権限管理 や クロスアカウントアクセスなどのセキュリティに関する考慮事項があります。 本記事を参照する際は、ご自身の環境をよくご確認の上、適切な権限管理をお願いします。 なお、本記事の内容を実施した結果発生する損失・損害については一切の責任を負いかねます。
はじめに NTT西日本の服部です。本記事はNTT WEST Engineers' Blog 開設にむけて投稿記事レビューのワークフローを爆速で構築した話の第4回の記事となります。 前回までの記事も読んでいただけるとありがたいです。 第4回となる本記事ではPower Automateによるレビューフロー前編としてレビュアーのアサイン依頼のフローについてご紹介します。 本記事は2025年9月時点の情報に基づきます。 ①~概要編~ ②~Microsoft Forms/Microsoft Lists編~ ③~Power AutomateによるMicrosoft Listsへの自動登録編~ ④~Power Automateによるレビューフロー前編~ (本記事) ⑤~Power Automateによるレビューフロー中編~ ⑥~Power Automateによるレビューフロー後編~ 第1回でご紹介したワークフローの全体像のうち、以下の図にあたる内容となります。 対象読者 本記事が想定する対象読者は以下の通りです。 自動化に興味がある人 繰り返しの定常的な作業に困っている人 Microsoft Forms/Microsoft Lists/Power Automateを使ってみたい人 背景 NTT WEST Engineers' Blog に向けて、ブログ記事のレビュープロセスを効率化したいという要望を受けて執筆者が検討・構築しました。 SaaSの新規サービスを導入する予算はありませんでしたが、幸い全社的にMicrosoft Forms、Microsoft Lists、Power Automateが利用できる環境だったため、これらを用いてブログ記事レビューのワークフローを構築しました。 本記事ではPower Automateによるレビュアーのアサイン依頼フローについてご紹介します。 レビュアーのアサイン依頼フロー レビュアーのアサイン依頼フローとして構築したPower Automateのフローは以下の通りです。 各ステップの内容についてご紹介します。 1.アイテムが作成または変更されたとき 上記の設定はこのPower Automate のフローが実行される条件(トリガー)になります。 ここでアイテムというワードが唐突に登場しましたが、Microsoft Listsにおける一行ごとのデータ(レコード)のことをアイテムといいます。本記事においては1件分のレビュー依頼に相当します。 特定のSharepointサイトのリスト名を指定して、対象のリストでアイテムが作成または変更されたときにこのフローが実行されます。 初期設定のままではアイテムが新しく作成されたときにもこのフローが実行されてしまいますし、既存のアイテムについては何か一つでも列の値が変更されたときでもこのフローが実行されてしまいます。 そのため、このフローが実行される条件を限定する必要があります。 ステップの右上の ・・・ から設定をクリックします。 設定をクリックすると下図の画面が表示されます。 トリガーの条件の部分にこのフローが実行されるために満たすべき条件を指定します。 このフローのトリガーの条件は以下の内容が設定されています。 これはリストでアイテムが作成もしくは値が更新されたときに該当のアイテムについて ステータスがレビュアーアサイン待ち かつ レビュアーが未設定 であればフローが実行されることを意味します。 @equals(triggerBody()['OData__x30b9__x30c6__x30fc__x30bf__x30/Value'],'レビュアーアサイン待ち') @equals(triggerBody()['OData__x30ec__x30d3__x30e5__x30a2__x30/Value'],'未設定')` OData__x30b9__x30c6__x30fc__x30bf__x30 や OData__x30ec__x30d3__x30e5__x30a2__x30 は列の名前を指しています。 列の名前に ステータス や レビュアー というように全角文字を使用した場合、この値はMicrosoft Listsの設定画面から指定すべき文字列を確認する必要があります。 Sharepointサイトでリストを開き右上の歯車のマークから リストの設定 をクリックします。 以下の画面に遷移し、条件として使いたい列をクリックします。 今回はステータスとします。 遷移後の画面のURLを確認し Field= に続く値をコピーします。 OData_ とコピーした値を結合した文字列が特定の列を指す値となります。 条件として指定する列の種類が選択肢の場合は /Value を末尾に追加する必要があります。 今回の例では OData__x30b9__x30c6__x30fc__x30bf__x30/Value という文字列がステータスという列で選択されている選択肢を指すことになります。 条件式の書き方については以下の公式ドキュメントも参照ください。 Power Automate で条件式を使用する - Power Automate | Microsoft Learn 2.チャネルでメッセージを投稿する(レビュアーアサイン依頼) 今回作成したワークフローではレビュアーを設定する操作自体は運営担当者にて手動で設定するという設計にしているため、運営向けにMicrosoft Teamsで通知するという処理を設けています。 メッセージの編集画面の右上の </> をクリックするとhtmlのタグを使ってメッセージの内容を設定することが出来ます。 注意事項 今回ご紹介するPower Automateのフローは意図的にフローの実行結果から別のフローを呼び出すという設計にしていますが、設定値を誤ると無限ループが発生する可能性があります。 本記事の内容を流用される場合には無限ループが発生しないように十分に注意して設計/構築してください。 無限ループへの対処法については以下の日本マイクロソフトのブログ記事も参照ください。 Power Automate のフローで無限トリガーループが起きる際の対処法 | Japan Dynamics CRM & Power Platform Support Blog まとめ 今回はレビュアーのアサイン依頼フローとして構築したPower Automateついてご紹介しました。 次回はレビュアーアサイン後のレビューフローについてご紹介します。 執筆者 服部 真智(NTT西日本 ビジネス営業本部所属) 普段はAWS案件の提案、設計、構築等の支援を行っています。 自業務の効率化のためにPython,Power Automate,生成AI等を使って日々試行錯誤しています。 2025 Japan AWS Top Engineers (Services) 商標 Microsoft (Microsoft Entra 、 Microsoft Teams 、 Power Automate 、 Microsoft Lists 、 Microsoft Forms)及び関連する名称並びにそれぞれのロゴは、米国 Microsoft Corporation の米国およびその他の国における商標または登録商標です。
はじめに NTT西日本の坂下です。 本記事では、セキュリティに関心のある学生の皆さんに向けて、セキュリティ分野に特化したワークショップをご案内します。 ※2027年度卒業予定の学生の皆様を対象とした、NTT西日本インターンシップの1つとして開催いたします。 このワークショップは実践形式でセキュリティの業務内容を広く体感できる内容になっています。 「セキュリティ」というキーワードに少しでも興味を持った方は、ぜひ気軽にチェックしてみてください! 本記事は2025年10月時点の情報に基づきます。 対象読者 本記事が想定する対象読者は以下の通りです。 セキュリティ分野に興味がある2027年卒業予定の学生 背景・目的 「セキュリティに興味はあるけど、実際にどんな業務があるのかわからない」という声を学生の方々から多くいただいています。 実はセキュリティは"単に攻撃を防ぐ"だけではありません。どのように戦略を立て、情報資産を管理し、調査・対応をするか、そして、如何に攻撃を防御し、検知、対応復旧させるか。技術力に加え、思考力やチーム力もいかされる、とても奥深く面白い分野です。 当社では、社内にSOCを設置しており、近年注目されているオフェンシブセキュリティの視点から検証するREDチームを編成しています。単なる “守り” にとどまらない、まさに攻撃と防御の両輪で思考力やチーム力をいかした、幅広くも奥深い業務を展開しています。 この面白さを皆さんに知ってもらいたい。 その想いで今回、実際の現場に近い体験を通して “セキュリティのリアル” を体感してもらえる二日間のワークショップを企画し、本投稿を執筆しています。 セキュリティワークショップとは 今回企画しているセキュリティワークショップの内容を以下に記載します。 ワークショップ概要 開催日:2025年11月6日(木)〜11月7日(金)※ 第4回 応募締切:2025年10月30日(木)17:00 開催形式:オンライン 【応募方法】 以下①②の手順で応募を受け付けています。 ① NTT西日本 採用マイページ に登録 ② 応募フォーム に必要事項を入力して回答 ※必ずこのリンクからマイページへの登録、フォームへの回答をお願いします。 ※参加の可否については11/3までにマイページ上でご連絡させていただきます。 ※第1回から第3回までの開催分につきましては、すでに受付を終了しております。 今回の第4回が、「INTERNSHIP 2027 セキュリティワークショップ」へのご参加の最後の機会となります。 ワークショップ詳細 幅広く弊社のセキュリティ業務の現場感を、ワークを通して体感することができます。 内容の一部をご紹介すると システムに対する調査内容を考えるワーク 攻撃者視点に立って考えるワーク インシデントに対する対応判断ワーク などを予定しています。 また、実際にセキュリティ業務に携わっている社員との座談会も予定しており、「どんなキャリアを描いているのか」「どんな働き方をしているのか」といったリアルな話も聞くことができます。 セキュリティの考え方 さて、もしかしたらご存じの方もいるかもしれません。先ほどお伝えしたセキュリティの面白さの内容につながる、現代におけるセキュリティ対策を考えるためのフレームワークが存在します。 それが、米国国立標準技術研究所(NIST)の提供する「サイバーセキュリティフレームワーク2.0(NIST CSF 2.0)」です。 NIST CSF 2.0とは、統治(Govern)、識別(Identify)、防御(Protect)、検知(Detect)、対応(Respond)、復旧(Recover)の6つの機能を軸に、サイバーセキュリティ対策を改善する、世界的にも広く使われている枠組みです。 私たちもこういったフレームワークを取り入れながら、日々の業務でサイバーセキュリティを考え、実践しています。 今回のワークショップでは、このようなフレームワークの考え方も踏まえ、全方位的なセキュリティ対策を体験することで、実際の業務でいかされている幅広いスキルやその業務分野を肌で感じていただけるはずです。 まとめ 「セキュリティに興味はあるけど、どんな仕事かわからない」 そんなあなたにこそ、このワークショップがぴったりです。 もちろん、既にサイバーセキュリティに精通している方も大歓迎! 2日間という短い期間ですが、セキュリティのリアルを体感することで、新しい学びや気づきが得られるはずです。 迷っている方もぜひ気軽にエントリーしてみてください! 用語解説 SOC(Security Operation Center) システムやサービスを監視し、サイバー攻撃や情報漏洩などのセキュリティインシデントをいち早く発見・対応する専門チームです。「セキュリティの最前線」とも言える重要な役割を担っています。 オフェンシブセキュリティ(Offensive Security) 攻撃者視点でシステムの弱点を探し、攻撃される前に対策を立てるセキュリティ手法です。「守るために攻める」考え方で、実践的なスキルが身につく分野です。 REDチーム(Red Team) オフェンシブセキュリティを実践するために、模擬的な攻撃を仕掛け、脆弱性やセキュリティ上の問題点を洗い出す専門チームです。 フレームワーク(Framework) 複雑な物事を整理して捉えるための「考え方の枠組み」です。 執筆者 坂下 晴哉(NTT西日本 セキュリティ&トラスト部所属) NTT西日本Gのセキュリティ戦略、および人材育成業務に従事し、セキュリティ人材育成計画や育成方針を日々考えています。 参考資料・出典 本記事を執筆するにあたり、以下のサイトを参考にしました。 【Web】 IPA 独立行政法人 情報処理推進機構: The NIST Cybersecurity Framework (CSF) 2.0 https://www.ipa.go.jp/security/reports/oversea/nist/ug65p90000019cp4-att/begoj9000000d400.pdf 【Web】 NIST 米国国立標準技術研究所: Cybersecurity Framework | NIST https://www.nist.gov/cyberframework 商標  記載の会社名・製品名・団体名はそれぞれの会社の商標もしくは登録商標です。
はじめに NTT西日本 ミライ事業共創室の西村です。 今回は業務とは関係なく、 趣味として取り組んだ技術チャレンジ についてご紹介します。 私はプログラミングが得意ではなく、コードを見ると「暗号かな??」と思ってしまうほどでした(´;ω;`) そんな自分でも、生成AIに助けてもらいながら 2024年6月ごろ、わずか3日でリアルタイム翻訳ツールを完成させることができました 。 なお、 今回の取組みは業務とは切り離した個人プロジェクト です。 この記事では、その誕生からOSS公開・デモ公開までの歩みをまとめ、さらに読んだ方が持ち帰れる「開発プロセスの工夫」や「現時点でのベストプラクティス」を共有させていただきたいと思います。 開発したツールをイベント利用した際の写真。翻訳がスムーズに表示され、会場の参加者にも安心して楽しんでいただけました。@ QUINTBRIDGE 対象読者 この記事はこんな方に向けています: プログラミングが苦手でも、AIと一緒にモノづくりをしてみたい人 業務外で技術チャレンジをしてみたい社会人・学生 AIを活用して最小構成のプロトタイプ開発に挑戦したいエンジニア まず動くものを作るスタイル(Vibecoding)に共感する人 背景:通訳がいない!? きっかけは、あるイベントでの課題でした。 日本語を話せないゲストが登壇する予定でしたが、同時通訳ができるメンバーはおらず、予算的にも通訳を依頼することは難しい状況でした。 「ゲストの話が伝わらないのは困る。でも通訳なしでどうすればいいの?」 悩んでいたときに思いついたのが、 生成AIを使ったリアルタイム翻訳 でした。 開発プロセスと工夫 アイデアの共有と仕様の壁打ち まずは自分のやりたいこと・必須要件を明確にしてAIに伝えました。 私の場合は: 大画面スクリーンに投影したい PCで動かしたい 翻訳はリアルタイムで表示したい これをChatGPTに壁打ちすると、 Python + Whisper + GPT-4o + OBS Studio という構成に落ち着きました。 この「仕様を固める工程」が一番大事だと実感しました。 下記のような構成で実装しました。 構成 コード生成 ChatGPTにコードを書いてもらい、そのままコピーペースト。 翻訳の品質が安定しないときは、 「録音時間を少し延ばしたい」「表示を短く区切りたい」 と自然言語で指示してチューニングしました。 ※補足 当時はGPT-4oがリリースされたばかりで、長いコードを生成させると出力が途中で切れ、省略されることもしばしばありました。 そのため、動くように調整するのに時間がかかったのも事実です。 今では CursorやClaudeCode等 があり、長いコードも安定して出力できるので、これから試す方にはこちらをおすすめします。 エラー対応 エラーが出たときは「ここが動きません」と伝えるだけで修正コードを提示してくれるので、ひたすらトライ! 改善 操作方法やレスポンスを調整し、イベント本番で使えるレベルにブラッシュアップしました。 成果と反響 2024年6月、わずか3日で初期版が完成。(業務後に徹夜💪) イベント本番では、ゲストのスピーチをリアルタイムで翻訳しスクリーンに表示。参加者は言語の壁を感じることなく楽しむことができました。 ゲスト様:「スピーチが伝わって嬉しい!」 参加者:「翻訳が自然でわかりやすい!」 社内:「こんなツールを作った社員がいる」と紹介され話題に 自分としても 「AIがあればプログラムができなくても本当に使えるものが作れるんだ」 という大きな自信になりました。 なお、初期版では英語→日本語の翻訳にのみ対応していました。 完成後、このツールはパッケージ化して他のイベントでも使える形に進化させました。 手順書を整備して社内に共有し、これまでに3回以上の大きなイベントで活用されています。 (ちなみにパッケージ化の方法もChatGPTに相談して学びました) さらに 2025年7月には双方向対応(日⇄英)を実現させました 。 当時最新だったClaude Codeを活用することにチャレンジし、そちらで修正を実施。 結果、 わずか1時間程度でアップデートに対応できた のは大きな学びでした。  ちなみに  ClaudeCodeはProプラン(現時点で月17ドル)でも十分に動作し、この規模の改善は簡単にできてしまいました。 200ドルの上位プランも試しましたが、日⇄英対応などはProで十分でしたので、参考にしていただければと思います。 ClaudeCodeでの開発風景です。個人環境(WSL)で実施しており、社内情報・個人情報は一切含まれていません。 OSS公開への挑戦 最終的にはこの翻訳ツールを OSSとして公開しました 。 GitHubを本格的に使ったのは初めてでしたが、ClaudeCodeに教えてもらいながらPushまで実装。 ユーザ名の記載や不要ファイル削除といった細かい点は社外の有識者様からアドバイスいただきましたが、 基本的な部分はClaudeCodeに任せて問題なく進められ、 初心者でもAIを頼れば一人でOSS公開できる ことを実感しました。  #ご協力いただいた有識者様に感謝🙏 ClaudeCodeはMCPでGitHub操作までやってくれるので非常に便利でしたが、 Windowsユーザの場合はWSLの設定が少しハードルでした。 ここはGPTに壁打ちしながら調整し、無事に環境を整えることができました。 「最初は動かなくてもAIに聞けば解決できる」という安心感 を強く感じました。 また、OSS版ではバッチファイルを整備し、コマンド操作に慣れていない人でも簡単に起動できるよう工夫しています。 実際に触っていただいて、環境構築から起動まで短時間で体験していただけたら嬉しいなと思います。 github.com さらに、このOSSをベースに 翻訳UIをClaudeCodeのみで実装したデモ も公開しています。 精度はOSSをそのまま動かすより低いのが課題ですが、イメージは掴んでいただけると思います。 利用にはOpenAIのAPIキーが必要です。 デモページ: https://translate.mintan.org/   使い方イメージ動画: youtu.be  ⚠️ 注意事項   デモページはあくまで個人で試験的に公開しているものです。 精度や安定性はOSSそのままの利用よりも低く、動作保証はしていません。 ご利用は自己責任でお願いします。 私自身も、英語話者とミーティングをするときにこのツールを個人で動かして、 英語を日本語にリアルタイム翻訳しながら理解を深めるのによく活用しています。 イベントだけでなく日常の学びやコミュニケーションにも役立つので、ぜひ試してみてください✨ 動かす→課題→改善:Vibecoding的な実践知 まず動かして課題を明確化する 実際に作ってみて初めて「翻訳の区切り方」や「表示のしやすさ」が課題になることが分かりました。 さらにイベント利用や他者からのフィードバックを通じて、 日⇄英対応 や 専門用語への対応 、 他PCでの導入のしやすさ といった具体的な改善ニーズが見えてきました。 このサイクルが改善を重ねる大きな原動力になっていて、振り返ると デザイン思考やアジャイルの実践に近い進め方 そのものだったなと感じています。 Vibecodingと組み合わせると相性が良く、とても気に入っているやり方です。 誰でも触れるようにする工夫 改善の過程で、コマンド操作に慣れていない人でも使えるように バッチファイルを整備 したり、 OSSとして公開 したり、 ブラウザから試せるデモUI を用意するなど、「触りやすさ」を意識して工夫を重ねました。 現時点の課題と今後の挑戦 現状は openai==0.28.1 に依存しており、最新バージョンだとうまく動作しないという制約があります。 また、 Mac対応が未完了 のため、今後はここを重点的に改善していきたいと考えています。 現時点での個人的ベストプラクティス 今回の開発を通じて、自分なりに見えてきた「AI開発の進め方」を整理しました。 課題から入ること 何かをAIで作ろうとすると、あれもこれもと機能を盛り込みすぎてしまい、結果的に使いにくいものになることが多い。 まず「解決したい課題」を起点にし、 必要最小限の機能に絞って実装する(MVP的に) ことが大切だと感じました。 仕様検討はGPTで壁打ちする 要件を伝えると、構成・技術選定を精度高く返してくれる。 ClaudeやGeminiも試しましたが、仕様整理はGPTが最も的確に感じました。 実装・テストはClaude Codeで進める 仕様を伝えて実装する際は現時点ではClaude Codeが使いやすく、特に改善やデバッグのやりとりがスムーズでした。 改善 → 他者に見せる → (できれば)OSS化 最小構成で作り、改善しながら他の人に使ってもらう。 フィードバックを取り入れ、必要に応じてOSSとして公開できるとより広がりやすいかと思います。 まとめ 今回の経験を通じて、私は 「プログラミングができなくても、AIを頼れば作れる」 ことを強く実感しました。 そして、作ったものをOSSとして公開することで、自分の課題解決が他の誰かの役にも立つ可能性が広がることも学びました。 今までは分厚い技術書を読んで「何をしているか分からないけどとりあえず進める」学習スタイルでした。 しかし今は分からないところをAIに聞きながら、周辺知識も自然に身につけられるようになり、学習が格段にやりやすくなりました。 これは特に初学者やノンプログラマにとって大きな助けになると感じています。 小さな不便を起点にしたチャレンジが、思いがけず大きな広がりにつながる。 この記事が、誰かの 「やってみよう!」 の一歩につながれば嬉しいです。 もしこの記事を読んで「自分も試してみたい」と思った方は、ぜひ感想をシェアしていただけると励みになります 🙌 最後まで読んでいただき、ありがとうございました! 商標 「GPT™」「ChatGPT™」「Whisper™」は、OpenAI社の商標または登録商標です。 「Claude™」は、Anthropic社の商標または登録商標です。 「Cursor™」は、Cursor社の商標または登録商標です。 「OBS Studio™」は、OBS Projectの商標または登録商標です。 「Python®」は、Python Software Foundationの登録商標です。 「Linux®」は、Linus Torvalds氏の米国およびその他の国における登録商標です。 「Windows®」は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。 「Mac®」および「macOS®」は、Apple Inc. の米国およびその他の国における登録商標です。 「GitHub®」は、GitHub, Inc. の米国およびその他の国における登録商標です。 「YouTube™」は、Google LLC の商標または登録商標です。 執筆者 西村奈々(NTT西日本 経営企画部 ミライ事業共創室) R&D組織での経験を活かしつつ、技術起点での事業開発に取り組んでいます。 現在はブロックチェーンとVerifiable Credentialsを活用したデジタルコンテンツの真正性強化と、そのビジネス適用に挑戦中です。 QUINTBRIDGE
はじめに NTT西日本の服部です。本記事はNTT WEST Engineers' Blog 開設にむけて投稿記事レビューのワークフローを爆速で構築した話の第3回の記事となります。 第1回、第2回の記事も読んでいただけるとありがたいです。 第3回となる本記事ではMicrosoft Formsの回答送信を検知してMicrosoft Listsに登録するためのPower Automateついてご紹介します。 本記事は2025年9月時点の情報に基づきます。 ①~概要編~ ②~Microsoft Lists/Microsoft Forms~ ③~Power AutomateによるMicrosoft Listsへの自動登録編~ (本記事) ④~Power Automateによるレビューフロー前編~ ⑤~Power Automateによるレビューフロー中編~ ⑥~Power Automateによるレビューフロー後編~ 第1回でご紹介したワークフローの全体像のうち、以下の図にあたる内容となります。 対象読者 本記事が想定する対象読者は以下の通りです。 自動化に興味がある人 繰り返しの定常的な作業に困っている人 Microsoft Forms/Microsoft Lists/Power Automateを使ってみたい人 背景 NTT WEST Engineers' Blog に向けて、ブログ記事のレビュープロセスを効率化したいという要望を受けて執筆者が検討・構築しました。 SaaSの新規サービスを導入する予算はありませんでしたが、幸い全社的にMicrosoft Forms、Microsoft Lists、Power Automateが利用できる環境だったため、これらを用いてブログ記事レビューのワークフローを構築しました。 前回の記事では投稿者がレビュー依頼をするための以下のフォームについてご紹介しました。 今回はこのフォームの回答内容をMicrosoft Listsに自動登録するためのPower Automateについてご紹介します。 Microsoft Listsに自動登録するためのPower Automate Microsoft Formsの回答内容をMicrosoft Listsに自動登録するためにPower Automateで作成したフローは以下の通りです。 各ステップの内容についてご紹介します。 1.新しい応答が送信されるとき トリガー(フローが実行される条件)として、特定のフォームに新しい応答が送信されるときを指定しています。 ドロップダウンで対象となるフォームを選択することができますが、出てこない場合はForm Idを直接指定することも可能です。 Form IdはフォームのURLから確認することが可能です。 フォームの編集画面から確認する場合は 回答を収集 をクリックするとURLを確認することが可能です。 URLを短縮のオプションを有効にしているとForm Idは記載されないため注意してください。 URLは以下のような形式で <Form Id> にあたる箇所にForm Idが記載されています。 https://forms.office.com/Pages/ResponsePage.aspx?id=<Form Id> 2.応答の詳細を取得する 具体的な回答内容を取得するために必要な処理です。 Form Idの指定方法は新しい応答が送信されるときと同じです。 Response Idは具体的にどの応答内容を取得するか指定します。 コンソールで候補が表示されるため、新しい応答が送信されるときの Response Id を選択すると新しい応答の回答内容を取得することができます。 万が一候補が出てこない場合は以下の評価式を使うことで取得することも可能です。 triggerOutputs()?['body/resourceData/responseId'] 3.項目の作成 ステップ2で回答内容を取得することができたため、その内容を基にMicrosoft Listsに新しいアイテムを追加します。 3-1.サイトのアドレス/リスト名 サイトのアドレス はアイテムを追加したいリストが作成されているSharepointサイトを選択します。 リスト名 は上記で指定したサイトに作成されているリストが表示されます。 3-2.フォームの回答内容を利用する項目 以下のように入力候補としてトリガーに指定したフォームの質問文が出てくるため、対応する質問文が表示されている項目を選択することでその質問に対する回答内容を利用することが出来ます。 3-3.投稿者 Claims 投稿者 Claimsには Responders' Email ( 投稿者 Email と表示されることもあります。)を指定します。 これはフォームの設定で 名前を記録 というオプションを有効にしていると利用でき、Entra IDに紐づいたメールアドレスを取得することが可能です。 Microsoft Formsの設定についての詳細は 前回の記事 を参照ください。 3-4.ステータスValue/レビュアーValue 列の種類が選択肢の場合は <列名>Value と表示されます。 他のPower Automateで処理するために初期値としてステータスは レビュアーアサイン待ち 、レビュアーは 未設定 としています。 詳細は次回ご紹介します。 4.チャットでメッセージを投稿する この処理は必須ではありませんが、回答を受け付けて処理待ちであることを投稿者にMicrosoft Teamsのチャットで通知します。 投稿者: フローボット 、投稿先: フローボットとチャットをする とすると、下図のように Workflows という対象からMicrosoft Teamsのチャットが投稿者宛に届きます。 Recipient は宛先指定で今回はMicrosoft Formsの回答者(投稿者)とするため、 Responders' Email ( 投稿者 Email )としています。 まとめ 今回はMicrosoft Formsの回答送信を検知してMicrosoft Listsに登録するためのPower Automateついてご紹介しました。 次回はレビュアーのアサイン依頼フローについてご紹介します。 執筆者 服部 真智(NTT西日本 ビジネス営業本部所属) 普段はAWS案件の提案、設計、構築等の支援を行っています。 自業務の効率化のためにPython,Power Automate,生成AI等を使って日々試行錯誤しています。 2025 Japan AWS Top Engineers (Services) 商標 Microsoft (Microsoft Entra 、 Microsoft Teams 、 Power Automate 、 Microsoft Lists 、 Microsoft Forms)及び関連する名称並びにそれぞれのロゴは、米国 Microsoft Corporation の米国およびその他の国における商標または登録商標です。
はじめに  NTTビジネスソリューションズの平田です。  API開発の現場では、多数、迅速かつ正確な試験が求められます。しかし、手作業による試験は時間がかかり、ヒューマンエラーのリスクも伴います。本記事では、API試験の自動化ツールであるrunn(らんえぬ)を活用した、API試験の効率化の一例を紹介します。runnは、YAMLを用いた直感的なテストシナリオの記述と、柔軟な自動化機能を持つオープンソースのツールです。  本記事は2025年8月時点の情報に基づきます。 対象読者  本記事が想定する対象読者は以下の通りです。 API開発に携われる方 CI/CDを実装される方 ソフトウェアの試験を実施される方 Amazon Cognitoを利用した開発に携われる方 背景・課題  私が所属するバリューデザイン部システム開発部門で、あるサービスで利用するAPI群の開発・試験を実施しています。このAPI群はAmazon Cognitoから取得したトークンで認可制御を行う機能を持ち、リソース毎(API毎)に利用可能メソッドを設定できるという機能を持ちます。例えば、AというAPIに対し、ユーザXはGETのみ許可、ユーザYはGET/POST/PUT/PATCH/DELETEを許可、といった認可制御を行います。  そのため、認証認可機能は試験の網羅性を高めて品質を担保する必要があり、多くの試験項目が必要です。具体的には、APIが呼び出された時の認可が想定通り(200 OK、403 forbiddenなど)であることを確認しますが、APIが多数あり権限パターンも複数あることから試験の数は膨大になります。  開発当初はPythonのrequestsライブラリを利用したテストコードを作成したり、curlコマンドを使った手作業で試験を実施していました。ただ、テストコードの作成にPythonのスキルが必要だったり、試験にかかる工数が大きいなどの課題を抱えていました。そこで、API試験を効率化するために、runnの評価・導入を行いました。 ツール(runn)の簡単な紹介  runnは、オープンソースで提供されているAPI試験ツールです。シナリオ試験に強みがあります。基本的な利用方法を開発者の方が提供してくださっています。 runnチュートリアル runnクックブック  さくらインターネット株式会社やフリー株式会社のような大手のサービスプロバイダでも活用されています。 さくらのクラウドのAPIにrunnを導入してみた runnを用いたバックエンドテストの試行錯誤の変遷とこれから yamlでテストシナリオを書いてそのまま実行までできるAPIテストツールの新星 “runn” を試してみた  runnの特徴や基本的な使い方は他の記事や本家の記事におまかせすることとし、本記事では具体的な適用例を紹介します。 適用例① Amazon CognitoからIDtokenを取得する  本サービスでAPI経由でにデータを登録する際の基本的なフローは以下です。 Amazon CognitoからIDtokenを取得する APIを呼び出す際に、リクエストヘッダにIDtokenを付与する  このフローをrunnで試験できるよう実装してみました。以下の3ファイルを準備し、コマンドラインから実行します。 runn run .\scenario.yml --verbose  ファイルを3つに分割したのは、再利用のためです。cognito.ymlはAmazon CognitoからIDtokenを取得する関数的なYAML、call_api.ymlはAPIを呼び出すための関数的なYAML、scenario.ymlに実際のシナリオを記述します。 scenario.yml secrets : # --debugオプション指定時に、以下の項目の出力を抑制する - PASSWORD - IdToken vars : # 試験で利用する各種情報 # インラインでパラメータ設定しましたが、実際には外部ファイルに切り出し、 # または環境変数での引き渡しを推奨します COGNITO_URL : "https://cognito-idp.ap-northeast-1.amazonaws.com" COGNITO_CLIENTID : "<CognitoのClientID>" USERNAME : "<CognitoのユーザID>" PASSWORD : "<Cognitoのパスワード>" API_URL : "<試験対象のAPIのBaseURL>" API_KEY : "<試験対象のAPI呼び出しに必要なAPIキー>" steps : # シナリオ get_Cognito_IdToken : desc : Amazon CognitoからIDtokenを取得する include : # 外部ファイルの呼び出し path : cognito.yml bind : IdToken : current.IdToken # Cognitoから取得したIdTokenの参照方法: # - このyamlファイル内で参照:IdToken # - include先のYAMLから参照:parents.IdToken scenario1 : desc : 試験シナリオ1 include : # 外部ファイルの呼び出し path : call_api.yml vars : # 外部ファイル(call_api.yml)に引き渡すパラメータ(引数相当) # 利用するMethod method : "GET" # 試験対象のAPI Path ApiPath : "/v2/entities?type=testdata" # 期待するステータスコード expectedReturnStatuscode : 200 cognito.yml desc : CognitoからIdToken取得 if : included runners : req : '{{ parent.vars.COGNITO_URL }}' steps : GetToken : desc : CognitoからIDトークンを取得する req : / : post : headers : # リクエストヘッダを設定 X-Amz-Target : 'AWSCognitoIdentityProviderService.InitiateAuth' Content-Type : 'application/x-amz-json-1.1' body : # Cognitoの認証に必要なパラメータは、呼び出し元であるscenario.ymlの変数を # parent.vars.変数名 として参照しています。 application/json : { 'ClientId' : '{{parent.vars.COGNITO_CLIENTID}}' , 'AuthFlow' : 'USER_PASSWORD_AUTH' , 'AuthParameters' : { 'USERNAME' : '{{parent.vars.USERNAME}}' , 'PASSWORD' : '{{parent.vars.PASSWORD}}' } } test : current.res.status == 200 bind : IdToken : current.res.body.AuthenticationResult.IdToken call_api.yml desc : APIを呼び出すYAML if : included runners : req : '{{ parent.vars.API_URL }}' steps : call_api_with_Idtoken : req : '{{ vars.ApiPath }}' : '{{ vars.method }}' : headers : # リクエストヘッダを設定 Accept : 'application/json' x-api-key : '{{ parent.vars.API_KEY }}' # Cognitoから取得したTokenを送信 TOKEN : '{{ parent.IdToken }}' User-Agent : 'runn' # 期待するステータスコードと比較 test : current.res.status == vars.expectedReturnStatuscode 実行結果は以下のようになりました。 === [No Description] (.\scenario.yml) --- Amazon CognitoからIDtokenを取得する (get_Cognito_IdToken) ... ok === CognitoからIdToken取得 (cognito.yml) --- CognitoからIDトークンを取得する (GetToken) ... ok --- 試験シナリオ1 (scenario1) ... ok === APIを呼び出すYAML (call_api.yml) --- (call_api_with_Idtoken) ... ok 1 scenario, 0 skipped, 0 failures 適用例② データの加工  シナリオの中で、あるAPIで取得したデータを後続のAPIに引数として渡したいケースがあります。このとき、取得したデータを加工して後続のAPIに渡せると便利です。このようなニーズに対して、runnは expr lang によるデータの加工が可能です。  例えば、あるAPIの応答に含まれるLocationヘッダの一部を切り出してSubscriprionId変数に代入したい場合、以下のように記述します。 SubscriptionId: 'trimPrefix(current.res.headers["Location"][0],"/v2/subscriptions/")'   具体的には、Locationヘッダが以下のような結果の場合、 /v2/subscriptions/ を削除して(trimして)、 ABCD だけをSubscriptionId変数に代入できます。 Location: /v2/subscriptions/ABCD デメリット  大変便利なrunnですが、実際に利用してみて気になる点もあります。(もしかしたら私たちがまだrunnを使いこなせてないだけかもしれません) 条件分岐機能がない  例えば、ある条件を満たしたらリクエストに特定のヘッダを追加する、といった条件分岐の機能が見つかりませんでした。goからの利用であれば条件分岐を利用できるようですが、YAMLのみでは難しいようです。 YAMLの書き方がシビア、構文エラーの原因が特定しづらい  YAMLにインデントずれや必須項目の漏れがあるとエラーになりますが、どこで間違ったのか、何が足りないのかを特定がしにくい点があります。また、予約語(steps:、req:などの命令)なのか識別子(例:ステップの名前)がわかりづらい点もあります。慣れるまでに時間がかかるかもしれません。 まとめ  本記事では、runnを利用したAPI試験の実装例を紹介しました。  当初は構文エラーと原因調査に悩まされ、シンプルな試験が動くようになるまで時間を要しました。しかし、その後は出来上がったYAMLを型紙にして、コピペ+修正で試験項目をどんどん増やせます。  最終的には約500項目の試験を実装し、シナリオ試験を約20分で一周できるようになり、試験効率が向上しました。また、リリース作業時の動作確認にも活用しており、リリース作業に伴う影響発生の早期検知にも役立っています。  runnにはそのほかにもあらかじめ準備されたJSONテンプレート内の値を変更してPOSTしたり、CI(継続的インテグレーション)に組み込んだりと便利な機能があります。まだまだ機能を使いこなせていませんが、もっと使い込んでみたいと思います。 執筆者  平田賀一(NTTビジネスソリューションズ(株) バリューデザイン部 システム開発部門) PaaS/SaaSの開発・運用、社内案件のコンサル、エンジニア育成、NTT西日本Engineers' Blogの運営などに携わっています。 技術士(情報工学部門)/2025 Japan All AWS Certifications Engineers 参考資料・出典 本記事を執筆するにあたり、以下のサイトを参考にしました。 runnチュートリアル runnクックブック さくらのクラウドのAPIにrunnを導入してみた runnを用いたバックエンドテストの試行錯誤の変遷とこれから yamlでテストシナリオを書いてそのまま実行までできるAPIテストツールの新星 “runn” を試してみた expr-langリファレンス 商標 「AWS」「Amazon Cognito」は、Amazon Web Services,Inc.またはその関連会社の商標です。 記載の会社名・製品名はそれぞれの会社の商標もしくは登録商標です。
はじめに NTT西日本の服部です。本記事はNTT WEST Engineers' Blog開設にむけて投稿記事レビューのワークフローを爆速で構築した話の第2回の記事となります。 概要は 第1回の記事 を読んでいただけるとありがたいです。 第2回となる本記事ではレビュー依頼をあげるためのMicrosoft Formsとレビューの進捗管理をするためのMicrosoft Listsについてご紹介します。 本記事は2025年9月時点の情報に基づきます。 ①~概要編~ ②~Microsoft Lists/Microsoft Forms~ (本記事) ③~Power AutomateによるMicrosoft Listsへの自動登録編~ ④~Power Automateによるレビューフロー前編~ ⑤~Power Automateによるレビューフロー中編~ ⑥~Power Automateによるレビューフロー後編~ 第1回でご紹介したワークフローの全体像のうち、以下の図にあたる内容となります。 対象読者 本記事が想定する対象読者は以下の通りです。 自動化に興味がある人 繰り返しの定常的な作業に困っている人 Microsoft Forms/Microsoft Lists/Power Automateを使ってみたい人 背景 NTT WEST Engineers' Blog に向けて、ブログ記事のレビュープロセスを効率化したいという要望を受けて執筆者が検討・構築しました。 SaaSの新規サービスを導入する予算はありませんでしたが、幸い全社的にMicrosoft Forms、Microsoft Lists、Power Automateが利用できる環境だったため、これらを用いてブログ記事レビューのワークフローを構築しました。 本記事では1.レビュー依頼をあげるためのMicrosoft Formsと2.レビューの進捗管理をするためのMicrosoft Listsについてご紹介します。 1.レビュー依頼をあげるためのMicrosoft Forms 投稿者がレビューを申し込む用に以下のフォームを作成しました。 特別変わったことをしているわけではありませんが、フォーム作成の上で工夫したポイントをご紹介します。 1-1.回答者の情報を自動で収集する 今回のフォームは社内向けに公開されるフォームになるため、回答できるユーザーをEntraIDのテナントに参加しているユーザーに限定します。 また、後の処理でメールアドレス等を利用したいので回答者の情報も自動的に収集します。 作成しているFormsの 設定 から <テナント名>内のユーザーのみが回答できます。 と 名前を記録 のオプションを有効化することで実装できます。 1-2.規約への同意などを求める 規約への同意などの意思確認をするための質問を実装したい場合は、質問の種類を 選択肢 にした上で 複数回答 と 必須 のオプションを有効にした上で選択肢を同意するなど1つにすることで簡単に実装出来ます。 1-3.お礼のメッセージをカスタマイズ Formsの回答が送信された後に表示される画面で案内したいことがあるなどの場合には下図における赤枠部分のテキストを編集することが可能です。 設定 → お礼のメッセージをカスタマイズ を有効にすると回答後に表示されるテキストを編集できるようになります。 2.レビューの進捗管理をするためのMicrosoft Lists レビューの進捗管理をするために以下のようなリストをSharepoint上に作成しました。 各列の詳細は以下の通りです。 列の名前 列の種類 概要 ID 数値 デフォルトで作成されている列 タイトル 1 行テキスト 記事のタイトル/デフォルトで作成されている列 概要 複数行テキスト 記事の概要 投稿者 ユーザーまたはグループ 投稿者のメールアドレス 下書きプレビューURL 複数行テキスト ブログ記事の下書きを共有するためのURL 自由記述 複数行テキスト 備考欄 レビュアー 選択肢 レビュー担当者のメールアドレス ・未設定 ・レビュアー1のメールアドレス ・レビュアー2のメールアドレス 以下略 ステータス 選択肢 レビューの進捗状況 ・レビュアーアサイン待ち ・レビュー待ち ・差し戻し(修正待ち) ・レビュー完了 ・投稿完了 ・却下/消滅 更新日時 日付と時刻 デフォルトで作成されている列 登録日時 日付と時刻 デフォルトで作成されている列 リストについても作成の上で工夫したポイントをご紹介します。 2-1.投稿者 / レビュアー 投稿者についてはMicrosoft Formsで回答者の情報を自動で収集するようにしており、この項目ではUPN(メールアドレス)を登録しています。 次回解説予定のため、そうなんだくらいの認識で大丈夫です。 レビュアーについてもワークフローの中でメールアドレスを利用するため、列の種類をユーザーまたはグループとしても問題ありません。 しかし今回構築したワークフローではレビュアーの指定は運営者が手動で設定する設計としており、入力ミスで関係がないユーザーがレビュアーに設定されてしまう可能性があったため、レビュアーについては選択肢としました。 2-2.下書きプレビューURL Microsoft ListsにはURLという列の種類が元々存在していますが、URLには255文字の文字数制限があります。 万が一256文字以上になったとしてもエラーを回避できるように複数行テキストとしています。 通常の複数行テキストの場合はリンクとして機能しませんが、列の書式設定を以下のようにすることでリンクとして機能させることができるようになります。 { " $schema ": " https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json ", " elmType ": " a ", " txtContent ": " @currentField ", " attributes ": { " target ": " _blank ", " href ": " = @currentField " } } 列の書式設定の変更は設定したい列をクリックし、 列の設定 → この列の書式設定 → 詳細モード を選択することでJSON形式で書式設定をすることができるようになります。 設定欄に上記のJSONをコピー&ペーストして保存をクリックすることで該当列の文字列はURLリンクとして機能するようになります。 2-3.ステータスでグループ化 レビュー依頼リストを見やすくするためにステータスでグループ化することで表示方法を変更しています。 下図はステータスの値でグループ化されている状態です。 2-4.ID/更新日時/登録日時 これらの列はデフォルトで作成されている列ですが、初期設定では表示されていない列です。 列の表示/非表示や順番を変更したい場合は、 すべてのアイテム → 現在のビューの編集 をクリックします。 以下の画面の 列 の項目で表示/非表示や順番を変更することが可能です。 まとめ 今回は本ブログ開設にむけて構築した投稿記事レビューのワークフローのうち、レビュー依頼用のMicrosoft Formsと進捗管理のMicrosoft Listsをご紹介しました。 次回はFormsの回答内容をListsに自動登録するためのPower Automateについてご紹介します。 執筆者 服部 真智(NTT西日本 ビジネス営業本部所属) 普段はAWS案件の提案、設計、構築等の支援を行っています。 自業務の効率化のためにPython,Power Automate,生成AI等を使って日々試行錯誤しています。 2025 Japan AWS Top Engineers (Services) 商標 Microsoft (Microsoft Entra 、 Microsoft Teams 、 Power Automate 、 Microsoft Lists 、 Microsoft Forms)及び関連する名称並びにそれぞれのロゴは、米国 Microsoft Corporation の米国およびその他の国における商標または登録商標です。
はじめに 2025年現在、AI駆動によるアプリケーション開発のパラダイムシフトが進行しています。 今後、エンタープライズ組織においてAIを活用したアプリの内製化が一層進むと考えられます。 本記事では、チーム開発を行う際に必要性の高い「Dev Containers」を解説し、AIコーディング環境も含めた開発環境のセットアップ手順をご紹介します。 また、1台のローカルPC内で、ローカルOSと「Dev Container」がどのように連携して動作するのかも解説します。 用語補足 Dev Containers は、Visual Studio Code の拡張機能名を指します Dev Container は、その拡張機能で利用する開発用のコンテナ単体を指します 対象読者 本記事の対象読者として下記の方々を想定します。 アプリケーション開発、チーム開発を行う AIエージェントによるコーディングでDev Containerを使ってみたい Dev Containerのセットアップ手順や仕組みを知りたい 背景・課題 アプリケーションの開発環境には、開発ツールや依存ソフトウェアの複雑なバージョンの組み合わせが存在し、プロジェクト固有の構成で環境構築することが求められます。同じプロジェクトのメンバー間ではバージョン構成を統一する必要があり、異なるプロジェクトであれば環境の分離が必要です。 チーム開発の場合、複数メンバーで開発環境を統一しておかないと、動作差異や不具合発生につながります。 仮に1人で複数プロジェクトの開発を行う場合でも、1台のPC環境の中でプロジェクトごとの環境分離が必要です。   それから、AI駆動開発で用いられるClaude CodeやGemini CLIなどのAIエージェントは便利な一方で、rmコマンドの自動実行により重要ファイルが削除されてしまう危険性があります。 また、AIエージェントがソフトウェアやライブラリを自動インストール・自動バージョンアップすることもあり、意図せず環境を破壊してしまう危険性があります。このため、隔離された環境の中でAIエージェントを動作させることが求められます。   チーム開発やAI駆動開発の際に求められる開発環境の分離は、Dev Containersで実現できます。 Dev Containersとは Dev Containersは、Visual Studio Codeで利用できる拡張機能で、Dockerコンテナを活用して開発環境を分離できます。開発に必要な環境(Node.js、Python、データベースなど)を設定ファイルに記述することで自動構築できます。 Dev Containersにより、同じ環境が自動構築されるため、環境差異によるトラブルを防げます。開発環境はコンテナ内にインストールされるためローカルOSを汚さず、プロジェクトごとにDev Containerを分けられます。これにより、異なるバージョン構成の環境を手元に複数保持できます。 現場でよくある問題 アプリケーション開発の現場で、こんな経験はありませんか? 1. 「私の環境では動くのに...」問題 # 開発者A: Node.js 16.x + npm 7 # 開発者B: Node.js 18.x + npm 9 # 本番環境: Node.js 14.x + npm 6 2. ローカル環境の汚染問題 # プロジェクトAのために npm install -g create-react-app@4.0.0 # プロジェクトBは古いバージョンが必要... npm install -g create-react-app@3.0.0 # 衝突! 3. 新メンバーの環境構築地獄 「環境構築の手順書通りやったけど動きません」 「あ、それPostgreSQLのバージョンが...」 「Redisも入れないと...」 「環境変数の設定が...」 → 丸2日かかる 実践的なメリット 1. 開発効率の向上 環境構築 : 2日 → 10分 (私の経験によるケース。状況により時間は変化) トラブルシューティング : 環境起因の問題がほぼゼロに 実験的な変更 : 壊れてもDev Containerのリビルドで即復旧 2. チーム開発の改善 # 新メンバー参加時 git clone [repository] code . # VS Code起動 # 「コンテナで開きますか?」→ Yes # 10分後には開発開始! 3. 本番環境との一致 # Dockerfile(本番用)とdevcontainer.json(開発用)で # 同じベースイメージを使用 FROM node:22-alpine Dev Containersを使うべきシーン AI駆動開発 AIエージェントの試行錯誤を隔離し、ローカル環境の破壊を防ぐ チーム開発 同一環境を即時再現し、動作差異と初期構築時間を削減 複数プロジェクトの並行開発 依存関係とバージョンをプロジェクト単位で分離 特定バージョンの言語/DBが必要 任意のバージョンを固定し、安全に切替可能 技術検証・試行錯誤 互換性を無視した変更を行ってもリビルドで元に戻せる Dev Containerの構築手順 解説用にシンプルな環境を例に、以下をセットアップします。 Node.js TypeScript React Vite Claude Code 1. 事前準備 以下をローカルPCにインストールしてください Docker Desktop または Rancher Desktop などのDocker動作環境 Visual Studio Code(VS Code) VS Codeでプロジェクトフォルダを開いておく 2. Dev Container構成ファイルを作成 プロジェクトフォルダに .devcontainer フォルダを作成 .devcontainer フォルダ内に devcontainer.json ファイルを作成 以下、devcontainer.json { "name": "Node.js & TypeScript & React & Vite with Claude Code", "image": "mcr.microsoft.com/devcontainers/typescript-node:22", "features": { "ghcr.io/anthropics/devcontainer-features/claude-code:1": {} }, "postCreateCommand": "npm create vite@7.1 . -- --template react-ts && npm install" }   devcontainer.jsonの設定解説 項目 値 解説 name "Node.js & TypeScript & React & Vite with Claude Code" Dev Containerの名前を記載 image "mcr.microsoft.com/devcontainers/typescript-node:22" 使用するDockerイメージを指定しています。Microsoft Container Registry(mcr)から提供される公式のTypeScript/Node.js開発用イメージで、Node.js 22系がプリインストールされています。TypeScriptの開発に必要なツールが含まれた環境です。 features "ghcr.io/anthropics/devcontainer-features/claude-code:1": {} Dev Container Featuresを使って追加機能をインストールしています。ここではGitHub Container Registry(ghcr)からAnthropic社のClaude Code バージョン1を追加します。 postCreateCommand "npm create vite@7.1 . -- --template react-ts && npm install" コンテナ作成後に自動実行されるコマンドです。Vite 7.1を使ってReact+TypeScriptテンプレートのプロジェクトを現在のディレクトリ( . )に作成し、その後 npm install で依存関係をインストールします。 3. Dev Container の起動 開発コンテナー: コンテナーでリビルドして再度開く F1 または Ctrl+Shift+P (Mac: Cmd+Shift+P ) 「Dev Containers: Rebuild and Reopen in Container」を選択 コンテナのビルドと起動を待つ 以下の処理が自動実行されます: Dockerイメージがダウンロードされます コンテナが起動します Claude Codeがインストールされます Viteプロジェクトの作成( postCreateCommand の実行) 以下が表示されたら y を入力してください 以下が表示されたら、.devcontainerを保持するため「Ignore files and continue」を選択してください npm依存関係がインストールされます 以下が表示されたら任意のキーを押してください   4. 開発ツール:Viteの起動 VS Code内でターミナルを開く 開発ツール:Viteの起動 npm run dev -- --host 3. 起動メッセージの確認 5. ブラウザで接続 アプリケーションへのアクセス ポートフォワーディングの確認 VS Codeが自動的にポート5173をフォワーディングします 「ポート」タブで確認可能(VS Codeの下部パネル) ブラウザでアクセス 方法1: ターミナルのURLをCtrl+クリック(Cmd+クリック) 方法2: ブラウザで直接 http://localhost:5173 を開く 方法3: VS Codeの「ポート」タブから ポート5173の行を右クリック 「Open in Browser」を選択 React + Viteアプリの確認 Vite + Reactのデフォルトページが表示されます   トラブルシューティング よくある問題と解決方法 問題 解決方法 コンテナが起動しない Docker Desktopなど、コンテナエンジンが起動しているか確認 ポート5173にアクセスできない VS Codeの「ポート」タブでポートが開いているか確認 ブラウザが自動で開かない 手動で http://localhost:5173 にアクセス 6. AIコーディングエージェント:Claude Codeを起動 VS Code内でターミナルを開く Claude Codeの起動 claude 好みのテキストスタイルを選ぶ Claude Codeが起動しました Dev Container環境の動作フロー 本記事のDev Containerについて、動作の流れを説明します ① git clone GitHubリポジトリからソースコードと .devcontainer/devcontainer.json をローカルPCにクローンします。(git cloneの解説は割愛) 統一されたリモートリポジトリをチームメンバーがクローンすることで、メンバー全員が同じ開発環境に統一されます。 ② Dev Container起動時の自動マウント ①でクローンしたプロジェクトフォルダ(マウント元)が、Dev Container環境内に自動マウントされます。 ③ コンテナ自動構築 ②のマウント先の .devcontainer/devcontainer.json に基づき、コンテナレジストリからコンテナイメージがダウンロードされ、Dev Container環境が自動構築されます。 また、Node.jsやVite、Claude Codeなど、開発に必要なツール・依存関係が自動インストールされます。 ④ 開発ツール起動 Dev Containerに接続されたターミナルで、 npm run dev -- --host コマンドを実行し、開発サーバー(Vite)を起動します。 ⑤ ポートフォワーディング コンテナ内でViteのデフォルトポート5173が自動検出され、ローカルPCのポート5173に自動的にフォワーディングされます。 ⑥ アプリ動作確認 ローカルPCのWebブラウザ から、ポートフォワーディング経由でアプリ動作確認ができます。   おわりに 本記事では、Dev Containersによる開発環境の分離と再現性の確保、AIエージェントを安全に活用するためのシンプルな構成と構築手順を紹介しました。また、ローカルPC内でDev Containerがどのように動作するか図解で解説しました。ぜひ、記事のdevcontainer.jsonをコピーして動かし、Viteを起動するところまで試してみてください。チームで共有し、必要な機能を小さく追加しながら、運用しやすいプロジェクト標準へと整備していきましょう。 執筆者 三島 映人 NTT西日本グループのサービス開発におけるテックリードやプロジェクトマネジメント、アプリケーション開発組織の技術統括、エンジニア育成を行っています。 PMP、MBA等を保有。趣味は自作キーボードの設計。 参考資料・出典 本記事を執筆するにあたり、以下のサイトを参考にしました。 code.visualstudio.com github.com 商標 Windows / Visual Studio Code は、Microsoft Corporationの商標もしくは登録商標です Mac は、Apple Inc.の商標もしくは登録商標です GitHub は、GitHub Inc.の商標もしくは登録商標です Docker / Docker Desktop は、Docker Inc.の商標もしくは登録商標です Rancher は、SUSE LLCの商標もしくは登録商標です Claude / Claude Code は、Anthropic PBCの商標もしくは登録商標です Gemini は、Google LLCの商標もしくは登録商標です Node.js は、OpenJS Foundationの商標もしくは登録商標です React は、Meta Platforms, Inc.の商標もしくは登録商標です PostgreSQL は、PostgreSQL の商標もしくは登録商標です Redis は、Redis Ltd.の商標もしくは登録商標です Python は、Python Software Foundationの商標もしくは登録商標です MySQL はOracle Corporationの商標もしくは登録商標です MongoDB はMongoDB Inc.の商標もしくは登録商標です PMP は、Project Management Institute, Inc. の商標もしくは登録商標です
はじめに NTT西日本の服部です。本記事ではMicrosoft Forms、Microsoft Lists、Power Automateを使って、ブログ記事のレビュー効率化を実現したのでご紹介します。 以下6回のシリーズで第1回となる今回は概要編としてワークフローの検討内容や構築したリソースの概要についてご紹介します。 本記事は2025年9月時点の情報に基づきます。 ①~概要編~ (本記事) ②~Microsoft Lists/Microsoft Forms~ ③~Power AutomateによるMicrosoft Listsへの自動登録編~ ④~Power Automateによるレビューフロー前編~ ⑤~Power Automateによるレビューフロー中編~ ⑥~Power Automateによるレビューフロー後編~ 対象読者 本記事が想定する対象読者は以下の通りです。 自動化に興味がある人 繰り返しの定常的な作業に困っている人 Microsoft Forms/Microsoft Lists/Power Automateを使ってみたい人 背景 NTT WEST Engineers' Blog に向けて、ブログ記事のレビュープロセスを効率化したいという要望を受けて執筆者が検討・構築しました。 SaaSの新規サービスを導入する予算はありませんでしたが、幸い全社的にMicrosoft Forms、Microsoft Lists、Power Automateが利用できる環境だったため、これらを用いてブログ記事レビューのワークフローを構築しました。 使用するツールの紹介 レビューフロー構築にあたり使用したツールを簡単にご紹介します。 Microsoft Forms Microsoft 提供するアンケート、クイズ、投票フォームを簡単に作成・共有できるWebツールです。 今回は投稿者がレビュー依頼を申し込むためのフォームとして利用します。 Microsoft Forms とは - Microsoft サポート Microsoft Lists Microsoft が提供する情報追跡アプリで、チームで情報を整理、共同作業、共有するのに役立つツールです。 今回はSharepoint上に構築し記事の提出状況やレビュー進捗をトラッキングするために使用します。 Microsoft 365 のリストとは何ですか? - Microsoft サポート Power Automate Microsoftが提供するクラウドベースのRPAツールで、プログラミング知識がなくても、日常の繰り返し作業や部門間の連携などを自動化する「ワークフロー(フロー)」をノーコードで作成できます。 Microsoft Forms の回答を検知してMicrosoft Listsに自動で登録したり、投稿者やレビュアーへ通知したりといった処理を自動化するために使用します。 Microsoft Power Automate – Process Automation プラットフォーム | Microsoft レビューフローの全体像 はじめにレビューフロー構築のためにどういった処理が必要か整理しました。 大まかな流れは以下の通りです。 ①. 投稿者がMicrosoft Formsでレビュー依頼をあげる。 ②. Formsの回答内容をListsに自動登録する。 ③. 運営担当者にレビュアーのアサインを依頼する。 ④. レビュアーにレビュー依頼を通知し、レビューを対応する。 ⑤. 必要に応じて記事の修正を依頼する。 ⑥. レビューが完了したら記事を公開し、投稿者に通知する。 実際に対応するときの考慮事項を踏まえて整理した結果、レビューフローの全体像は以下のようになりました。 ※あくまでイメージです。実際に構築したリソースの処理の流れとは一部異なる部分があります。 破線の矢印:PowerAutomateで自動的に処理される内容 実線の矢印:ユーザーによる操作等を表す内容 構築したリソース 整理したレビューフローを実現するために以下のステップに分けてリソースを構築しました。 詳細については次回以降にご紹介します。 1.Microsoft Formsでレビュー依頼フォームに回答する。 投稿者がレビューを依頼するための申し込みフォームを構築しました。 詳細は 第2回 で紹介します。 2.Microsoft Listsで進捗管理リストに登録する。 レビューの進捗を管理するために以下のようなMicrosoft Listsを構築しました。 Microsoft Listsの詳細は 第2回 で紹介します。 また、Microsoft Formsの回答送信を検知してMicrosoft Listsに自動登録するためのPower Automateのクラウドフローを構築しました。 Microsoft Formsの回答内容をMicrosoft Listsに自動登録するPower Automateの詳細は第3回で紹介します。 3.レビュアーのアサインを依頼する。 新規のレビュー依頼がきたときには運営の担当者にレビュアーをアサインするように依頼するためのPower Automateのクラウドフローを構築しました。 こちらの詳細は第4回で紹介します。 4.レビュー対応をする。 レビュアーとして設定された担当者宛にレビュー依頼をあげて応答内容を処理するためのPower Automateのクラウドフローを構築しました。 このフローは修正された記事に対する再レビュー依頼をあげる際にも呼び出されます。 こちらの詳細は第5回で紹介します。 5.必要に応じて修正依頼を出す。 レビューの結果、投稿者に修正を依頼するためのPower Automateのクラウドフローを構築しました。 こちらの詳細は第6回で紹介します。 6.記事公開について投稿者に通知する。 レビューが完了し、記事が公開されたことを投稿者に通知するためのPower Automateのクラウドフローを構築しました。 こちらの詳細は第6回で紹介します。 まとめ 今回は本ブログ開設にむけて構築した投稿記事レビューのワークフローとリソースの概要をご紹介しました。 次回以降で各リソースの詳細をご紹介していきます。 執筆者 服部 真智(NTT西日本 ビジネス営業本部所属) 普段はAWS案件の提案、設計、構築等の支援を行っています。 自業務の効率化のためにPython,Power Automate,生成AI等を使って日々試行錯誤しています。 2025 Japan AWS Top Engineers (Services) 商標 Microsoft (Microsoft Entra 、 Microsoft Teams 、 Power Automate 、 Microsoft Lists 、 Microsoft Forms)及び関連する名称並びにそれぞれのロゴは、米国 Microsoft Corporation の米国およびその他の国における商標または登録商標です。
はじめに NTTスマートコネクトの山下です。昨今、生成AIを活用したソフトウェア開発が注目されています。特にコーディングにおいて日夜さまざまなコーディング支援ツールが登場し、その利用法が模索されています。本記事では生成AIを用いたAIコーディングの概要からコーディングのスタイルについて紹介いたします。 ※この記事は2025年8月現在の情報に基づきます 対象読者 本記事で想定する対象読者は以下の通りです。 生成AIを用いたソフトウェア開発に興味がある人 AIコーディングツールの導入を検討している人 AIコーディングを学ぼうとしている人 背景 2022年末のChatGPT登場以降、生成AIを活用したコーディング支援ツールが発展し、ソフトウェア開発に大きな影響をもたらしています。しかし、これらのツールを効果的に活用するためには、AIコーディングに合わせたやり方を身につける必要があります。筆者自身、2024年12月からCursor、2025年6月からClaude Codeを利用しAIコーディングには特有の進め方があることを実感しました。本記事では、その経験から得られた知見を共有し、AIコーディングツールをより効果的に活用するためのアプローチを紹介します。 AIコーディングとは 従来、ソフトウェア開発のコーディングは人が行っていました。要件定義、設計を経てプログラミング言語とエディタと呼ばれるツールを用いてシステムの挙動となるロジックを記述します。またコーディングも負荷を軽減するために、静的解析や補完によって入力を支援するツールが用いられてきましたが、あくまで人が記述することを前提とされています。 ChatGPT登場以降、急速にAIにコーディングさせようとする試みが発展しています。 最初は生成AIをプロンプトを送り、応答結果のソースコードを用いる方法が試されます。 しかし、プロンプトだけでは得られる情報が限られるため、外部の情報にアクセスする技術(RAG)やツール呼び出し(Function calling)などのプロンプト以外から情報を得る技術が注目され、これらの技術はコーディングの場に限らず用いられるようになりました。 またコーディングでは要件や設計などの情報からタスクを計画し、実行する能力が必要となります。タスクの計画と実行をAIが代行する、AIエージェントという仕組みが導入され始めました。このAIエージェントの技術によってコーディング内容を事細かに指示することなく自律的なコーディングが可能となりました。本記事のAIコーディングはAIエージェントを用いたコーディングを前提とします。 AIコーディングは一般的に生成AIと連携してコーディングするツールを利用します。 ここでAIコーディングツールの一例としてCline、Cursor、Claude Codeという3種類のツールを紹介します。 ClineはVisual Studio Codeの拡張機能として動作するオープンソースのコーディングエージェントです。 複数のAIプロバイダー(Claude、OpenAI、Gemini等)に対応しています。AIエージェントとして後述のツールよりも先行してリリースされています。またClineからRoo Codeなど派生ツールが誕生しています。 CursorはAnysphere社が提供するVisual Studio CodeをベースとしたGUIコードエディターです。当初はAIエージェントの機能はなく、入力指示を送りAIで修正する形態でしたが2024年11月にAgentモードがリリースされました。そして2025年8月にCLI版のCursor CLIがリリースされました。 Claude CodeはAnthropic社が提供するCLIで動作するエージェント型コーディングツールとして2025年5月にリリースされました。Anthropic社はClaudeという生成AIを開発しており、1日あたり5時間以内であれば制限なくClaude CodeからClaudeを利用できます。(2025年8月28日から週単位に制限が追加予定) ツール名 特徴 開発元 主な提供形態 Cline Visual Studio Codeの拡張機能として動作するオープンソースのコーディングエージェント(Roo Code等の派生含む) コミュニティ オープンソース Cursor Visual Studio CodeをベースとしたGUIコードエディター Anysphere社 無料 / 有料 Claude Code CLIで動作するエージェント型コーディングツール Anthropic社 有料(定額 / 従量) 上記以外にもAIコーディングのツールは多数提供されており、日々これらのツールが登場しアップデートされています。開発者体験やシステム連携などを考慮して選定する必要があります。 AIコーディングではこれらのツールを利用して生成AIに対して情報を提供し指示することでコーディングを進めていきます。 AIコーディングのスタイルについて 筆者は2024年12月からCursor、2025年6月からClaude Codeを主に利用しています。 初めてAIコーディングをした際は曖昧な指示でコーディングが進むことに感動しました。 しかし早々に、思ったようにコーディングが進まない状態になりました。 AIコーディングにはAIコーディングのアプローチの方法(スタイル)があり、そのスタイルについて知る必要があったのです。 AIコーディングのスタイルとして2つの概念を紹介したいと思います。それは、 「バイブコーディング(Vibe Coding)」と「エージェンティックコーディング(Agentic Coding)」です。 バイブコーディングはOpenAIの共同設立者でもあるアンドレイ・カーパシー氏によって提唱された用語で生成AIと対話をしながら創発的なコーディングを行います。エージェンティックコーディングは高レベルの目標からタスク計画、実行、検証、修正までをエージェントが自律的に行います。 AIエージェントを用いた場合、バイブコーディングでは抽象的な指示に対してもAIエージェントが解釈しコーディングを進めます。一方でエージェンティックコーディングでは、目標設定以降は人を介さずAIエージェントの機能をフル活用するやり方です。 筆者は、はじめてAIコーディングを始めた際にバイブコーディングによって曖昧な指示でさえも動くアプリケーションが生成されることに感動しました。手作業では何時間もかかるであろう実装がAIコーディングによってものの数分で出来上がるのです。 しかし、バイブコーディングを続けているとある問題が発生します。システムの規模がある程度を超えると、コーディングの精度が低下するように感じられます。具体的には、リクエストした機能が実装されない。指摘した修正がいつまでも直らないといったことが起こりました。1、2時間で8割できたものの、残り2割が半日たっても出来上がらないのです。 その原因は何でしょうか?それは、生成AIは一度に無限の情報を扱えるわけではなく、限られた量の情報しか扱えないことにあります。コーディングを進めるなかで扱う情報量が増えていくことで意図した修正が行われないことになります。AIコーディングツールは情報の圧縮や要約する技術を用いて、処理を継続しようとしますが、大きなシステムをすべて探索して的確に修正していくことは困難になります。 そこでエージェンティックコーディングのように戦略的に計画的にタスク設計し、情報を整理しながらコーディングを遂行する考え方を取り入れる必要があります。 バイブコーディング一辺倒ではなく、バイブコーディングやエージェンティックコーディングを適材適所で使い分ける必要があります。例えば、小規模なプロトタイピングではバイブコーディングで行い、システムの要件が明確になったら、エージェンティックコーディングで開発を進める、というように状況によってこれらを組み合わせることも考えられます。 AIコーディングの登場によってエンジニアのコーディング量は減少する可能性が高い一方、これらのスタイルを戦略的に使い分け、開発の見通しを立てることがより重要な仕事になります。 今後もAIコーディングをとりまく状況は間違いなく変化していきますが、AIに ”丸投げ” するのではなく、AIと協調し、ともに成長していく姿勢こそが、結果として良いプロダクトを生み出す近道になるのかもしれません。 まとめ AIコーディングの概要とAIコーディングツールの紹介を行いました。またAIコーディングのスタイルとしてバイブコーディングとエージェンティックコーディングについて説明しました。AIコーディングを進めるにあたって、状況に合わせたコーディングのスタイルを取り入れ、見通しを立てることがより重要になると筆者は考えます。 執筆者 山下 義陽(NTTスマートコネクト株式会社 ビジネスイノベーション部) NTTスマートコネクトの新規事業開発に従事し、医療機関向けのサービスや動画配信・ライブコマースの立ち上げや生成AIサービスの開発に携わっています。 参考資料・出典 本記事を執筆するにあたり、以下のサイトを参考にしました。 【論文】Vibe Coding vs. Agentic Coding: Fundamentals and Practical Implications of Agentic AI 【書籍】現場で活用するためのAIエージェント実践入門 【ポッドキャスト】fukabori.fm 131. AIコーディングの現在地 w/ twada 【ブログ】https://zenn.dev/mizchi/articles/all-in-on-cline 商標 「OpenAI」は、OpenAI, Inc.の商標もしくは登録商標です。 「ChatGPT」は、OpenAI OpCo, LLC の商標もしくは登録商標です。 「Claude」は、Anthropic PBC の商標もしくは登録商標です。 「Cursor」は、Anysphere, Inc. の商標もしくは登録商標です。 「Gemini」は、Google LLC の商標もしくは登録商標です。
はじめに NTTビジネスソリューションズの鶴田です。 最近話題の生成AIツール”Microsoft 365 Copilot”はとても便利ですが、何も考えずに導入してしまうと、機密情報の漏洩など、思いがけないセキュリティ事故につながってしまうリスクがあります。 本記事では、無防備にMicrosoft 365 Copilotを導入してしまうと、セキュリティリスクが増す理由と対処方法を解説させていただきます。 対象読者 本記事が想定する対象読者は以下の通りです。 Microsoft 365 Copilot におけるセキュリティ対策に興味がある方 Microsoft 365 Copilot の導入を検討されている方 Microsoft 365 Copilot を利用されている方 "AI × セキュリティ"全般に興味がある方 Microsoft 365 Copilot とは Teamsなどの Microsoft 365 アプリに組み込まれたAI機能のことです。 プロンプト(自然言語)で Microsoft 365 内のデータを操作(グループチャットの要約 等)することができます。 引用元: Microsoft Teams のチャットとチャネルで Copilot を使用する Microsoft 365 Copilot と Microsoft 365 データの関係 Microsoft 365 Copilot におけるセキュリティを考える上で、 最初に押さえておくべきポイントは、Microsoft 365 Copilot と Microsoft 365 データの関係 についてです。 Microsoft 365 Copilotは、Microsoft 365 内のいかなるデータにもアクセスできるのでしょうか?? 答えは、 "いいえ" です。 大原則として、Microsoft 365 Copilotは、その Microsoft 365 Copilot を操作しているユーザが保持する ”Microsoft 365 データへのアクセス権”に基づいて動作 します。 たとえば、以下のプロンプト①は、ユーザAは自分自身の Exchange Online のメールデータにはアクセス可能なので機能する可能性があります。しかしながら、プロンプト②は、ユーザAはユーザBのExchange Online のメールデータにはアクセスできないので機能しません。 〇:プロンプト① ユーザA「昨日自分が受信したメールで未返信のものを教えて」 ×:プロンプト② ユーザA「ユーザB個人が受信したメールで重要そうなもの教えて」 Microsoft 365 Copilot におけるセキュリティリスクと対処方法 では、次に Microsoft 365 Copilot の利用において、どのようなセキュリティリスクがあるのか見ていきます たとえば、以下のようなシナリオが考えられます。 一般社員であるユーザAは、本来「経営に関わる重要な情報」へアクセスできません。しかし、ユーザAに対し、ファイルへの過剰なアクセス権が付与されている場合、Microsoft 365 Copilot は、「経営に関わる重要な情報」を回答してしまう可能性があります。 アクセス権のかけ方(フォルダ単位のアクセス制御) シンプルな対処方法は、フォルダ単位でアクセス制御をしておくことです。以下のようなフォルダ構成にしておき、ユーザAに経営フォルダにアクセス権を付与しなければ、ユーザAによる「経営に関わる重要な情報を教えて」というプロンプトは機能しなくなります。 ただ、この対処方法には落とし穴があります。たとえば、経営フォルダにアクセス可能な経営幹部が間違って(またはソーシャルエンジニアリングなどの意図的な攻撃により)、ファイル①を、一般社員フォルダにコピーしてしまうリスクがあります。 一般社員であるユーザAは、一般社員フォルダへはアクセス可能ですので、「経営に関わる重要な情報を教えて」というプロンプトは機能する可能性が出てきます。 アクセス権のかけ方(秘密度ラベルによるアクセス制御) フォルダ単位のアクセス制御でも、セキュリティリスクは残存してしまうため、秘密度ラベルによるアクセス制御がおすすめ です。 秘密度ラベルは、Microsoft Purviewの機能の一つです。 秘密度ラベル自体にユーザへのアクセス権限を設定した上で、ファイルに紐づけて利用します。 秘密度ラベルが紐づけられたファイルは、仮にコピーされても秘密度ラベルも一緒にコピーされるため、ファイルへの適切なアクセス権が維持される仕組みになっており、よりセキュア です。 ただし、秘密度ラベルによるアクセス制御も完璧なセキュリティを担保するものではありません。 たとえば、ファイルに紐づけられている秘密度ラベルを別の秘密度ラベル(アクセス制限が緩いもの)に付け替えられてしまう可能性もあります。そのため、多層防御の考えに則り、フォルダ単位のアクセス制御と秘密度ラベルによるアクセス制御を併用するのが望ましいでしょう。 その他のセキュリティ対策 ここまでは、データへのアクセス権の観点でのセキュリティリスクを紹介しました。 他にも様々な観点でのセキュリティリスクを考慮する必要がありますので、いくつか紹介させていただきます。 コミュニケーションコンプライアンス Microsoft 365 Copilot の不適切または危険なプロンプトを検出できる機能です。 こちらは、元々 Microsoft 365 Copilot に特化した機能ではなく、Teamsなどでの人同士のコミュニケーションに不適切な内容(ハラスメント等)が含まれていた場合に検出できる機能でしたが、検出対象が Microsoft 365 Copilot へのプロンプトにも拡張されました。 AI用 DSPM – アクティビティエクスプローラ 組織内で利用されている Microsoft 365 Copilot に投入されたプロンプトを、管理者は確認することが可能です。Microsoft 365 Copilot の利用において何か問題が発生した場合に、監査用途でも利用できます。 Microsoft 365 Copilot の利用者の皆様は、管理者にはプロンプトを見られている可能性があるので、不用意な使い方はしないように注意していただければと思います。 DLP 重要なデータの組織外流出を防止するための機能です。現時点では、Microsoft 365 Copilotとは直接関連がないですが、将来的に、Microsoft 365 Copilot の機能が拡充され、自然言語でメール送信などが実現できてしまうような時代になると、DLP観点も意識しておく必要があります。 まとめ 従来のソフトウェアはコードで記載された通りにしか動かなかったため、ある意味、セキュリティ対策もしやすかったです。しかしながら、AIは人間の想定を超える動きをすることがあるため、AIの利用に際しては、今まで以上にセキュリティを考慮する必要があります。 最近では、AIエージェントを人間と同じようにIDで管理していく潮流もあります。AIの進化は本当に日新月歩で、セキュリティも並走していく必要があります。本ブログではAI時代に役立つセキュリティ情報を発信していきたいと思います。 執筆者 鶴田光彬 クラウドとセキュリティと犬が好き。Microsoft MVP for Security、Microsoft Top Partner Engineer、CISSP、TOEIC L/R 920、IPA システムアーキテクト etc 商標 「Microsoft 365 Copilot」「Microsoft 365」「Microsoft Teams」「Microsoft Exchange Online」「Microsoft Purview」「Microsoft SharePoint」「Microsoft OneDrive」は、米国Microsoft Corporationの米国およびその他の国における登録商標または商標です。
1. はじめに NTT西日本の相浦です。 NTT西日本公式の技術ブログが始まりました。記念すべき第一回ということで、最近の私の「やってみた」を共有したいと思います。 最近よく耳にする AIエージェント 。でも、「結局どういう場面で役立つの?」と思う方も多いのではないでしょうか。 本記事では、自治体業務の一つである粗大ごみ収集申込の受付を例にして、 対話型で申込受付をしてくれるAIエージェント のサンプルを作ってみたのでご紹介します。 作ってみて気づいた工夫ポイントや「ここは意外と難しい」というところも交えつつ、「自分の業務に当てはめられるかも」と思っていただける内容を目指します。 1. はじめに 2. 対象読者 3. 背景 4. 「粗大ごみ収集の申込受付エージェント」を設計する 申込受付では何をする必要があるのか? 設計のポイント どこまでLLMに任せるか 5. 実装 プログラムの流れ LLMへの指示 6. デモ デモまとめ 7. オープンソースモデルでの追加実験 meta/llama-3-1-8b-instruct google/gemma-3-12b-it RedHatAI/gemma-3-27b-it-quantized.w8a8 結果と課題 8. まとめ 実業務を想定してエージェントを設計したら動作した 「なんでもLLM」にしない設計が肝心 最後に 執筆者 商標 2. 対象読者 本記事が想定する対象読者は以下の通りです。 AIエージェントに興味があり、具体的な実装事例を知りたい方 「自分の業務もAIエージェント化できるのでは?」と感じてみたい方 3. 背景 AIエージェントとは何か 「AIエージェント」という言葉を耳にする機会が増えました。簡単に言えば、 LLM(大規模言語モデル)がツールを選び、状況に応じて自律的に動く仕組み のことです。 LangChainの創設者 Harrison Chase氏 は次のように説明しています。 AIエージェントとは、LLMがアプリケーションの制御方法を決定するシステムのこと。重要なのは「どの程度エージェンティックか」という観点でとらえること。(参考: LangChain Blog ) つまり「LLMが会話を進めながら、必要に応じてツールを呼ぶ」仕組みだとイメージしていただければ十分です。 例えばLangChain公式サンプルには、ユーザが「天気は?」と聞くとLLMが「天気APIを呼ぶ」と判断して答えるチャットボットがあります。(参考: LangChain Agents Tutorial ) 今回の題材 こうしたデモは面白いですが、「実際の業務でどう役立つのか?」はまだ見えにくいです。そこで、今回は自治体業務の一つ、 粗大ごみ収集の申込受付 を題材に、対話で必要情報を集めて予約まで進めるエージェントを試作しています。 4. 「粗大ごみ収集の申込受付エージェント」を設計する 今回の題材は、自治体業務の一つである 粗大ごみ収集の申込受付 です。エージェント化するにあたり、必要な要素を整理しました。 申込受付では何をする必要があるのか? 粗大ごみ収集の申込受付では、単に「予約を受け付ける」だけではなく、いくつかの確認ややり取りが必要になります。具体的には次のような内容です。 申込者情報の確認 :氏名・住所・電話番号といった、誰が申し込んでいるのかを特定する情報を集める。 収集希望内容の確認 :どの品目を、何個、いつ、どこで回収してほしいのかを聴き取る。 FAQ対応 :「この品目は回収できる?」「年末年始は対応している?」など、利用者からの質問に答える。 料金見積 :品目と数量に基づいて料金を計算し、利用者に提示する。 つまり、 必要な情報を漏れなく収集し、寄り道的な質問にも答えながら、最終的に予約を確定する ことが申込受付の役割です。 設計のポイント AIエージェントとは「LLMが会話を進めながら、必要に応じてツールを呼ぶ」ものだとすると、LLMに与える役割、呼ぶことのできるツール群は何か、を考える必要があります。 LLMに与える役割 エージェントの目的は、申込に必要な情報を揃えること。そのため、LLMには 不足情報を把握 し、 次に聞く質問を考える 役割を与えます。 ツール群 LLMに使ってほしい機能を関数として与えます。今回は resolve_date (日付正規化)、 check_collectible (収集可能日か判定)、 estimate_fee (料金見積)、 rag_search (FAQ対応)、 reserve (予約確定)を与えます。 どこまでLLMに任せるか AIエージェントでは、LLMが様々な判断を行うことになります。一方、LLMの判断が必ずしも設計者の意図通りになることを保証することはできません。例えば、「申込者には必要なすべての情報を入力してほしい」と考えていても、LLMは「これだけの情報があれば十分だろう」と勝手に判断することもあります。 そのため今回の実装では、 LLM: 柔軟な誘導(質問生成、ツール選択) プログラム: 受付確定や必須情報の充足判定 という役割分担にしました。すべてLLMに任せることもできますが、 LLM+ルールのハイブリッド型 にすることで「自然な会話」と「確実性」を両立します。 なお、プログラムが必須情報の充足判定を行うには、 いまどの情報まで収集したかという情報を構造化して保持する 仕組み必要です。そのため、Pydanticモデル GarbageRequest を用意し、プログラムが扱いやすいJSON形式で情報を管理します。 5. 実装 実装のポイントです。詳細コードは GitHub に掲載するので、ここでは処理の流れとLLMに与えた指示を紹介します。 プログラムの流れ LLMへの指示 LLMには2つの役割を与えます。 不足情報を把握 収集すべき情報は申込情報スキーマ GarbageRequest の中で、氏名・住所・電話番号...と指定されています。LLMにはユーザの発話からこれらの情報を抽出する役割を与えます。 # 会話から申込情報を抽出するためのプロンプト # システムプロンプト あなたは自治体窓口のAIです。ユーザ発話から粗大ごみ申込情報を抽出し、 必ず JSON のみで出力します。説明文やコードブロックは禁止。 {GarbageRequestで指定されたフォーマット} 不明は null のままでよい。電話は数字のみ。time_slot は『午前/午後』。 相対日付は日本時間の本日 {本日の日付をプログラムで取得して埋め込む} 基準で YYYY-MM-DD に正規化する。 # ユーザプロンプト {ユーザの発話を入れる} 次に聞く質問を考える LLMにはもう一つ、次に聞く質問を作る役割も与えます。出力には必ず、 現在のステータス: [ASK](不足情報を聞く) / [REVIEW](申込内容をまとめて確認) / [ANSWER](FAQへの回答) 次に聞く質問 現在までに収集した申込情報一覧(JSON形式) を含めるように指示します。こうすることで、後でLLMの出力を使ってプログラムに判断を仰ぐことができます。 # 次に聞く質問を作るためのプロンプト # システムプロンプト あなたは自治体の粗大ごみ申込アシスタントです。目的は申込に必要な情報を揃えること。 【対話方針】 - ユーザが『可否の質問(例:◯/◯は回収できますか?)』をした場合は、まず可能な範囲で **即答** する。 ・日曜/1月1日/12月31日などの一律NGは、住所が未取得でも『不可』と即答してよい。 ・それ以外は、住所と希望日が揃ったら `check_collectible` で判定する。住所が無い場合は、可否に必要な **最小限の質問(住所)** のみを先に聞く。 - 情報に不足があれば、優先度に従い“1項目だけ”丁寧に質問する。ただし、状況に応じて順番を入れ替えてもよい。(優先度: name > address > phone > item_description > quantity > preferred_date > time_slot > pickup_location)。 - ユーザが相対/曖昧な日付(例:来週水曜、明後日 等)を述べたときは resolve_date で YYYY-MM-DD に正規化し、 そのターンは必ず [ASK] で『この日付(YYYY-MM-DD)でよろしいですか?』と確認してから次へ進む。 - preferred_date と address が揃ったら check_collectible を使う。NGなら代替案を簡潔に提案して [ASK]。 - item_description と quantity が揃ったら estimate_fee で概算料金を出し、[REVIEW] に金額を含める。 - 制度/ルール等のFAQは rag_search を使って短く回答し、その後は不足収集に戻る(通常は[ASK])。 【出力形式(厳守)】 1) 先頭行に [ASK] / [REVIEW] / [ANSWER] のいずれか 2) ユーザに見せる本文(丁寧・簡潔) 3) request の最新状態を JSON で同梱: [REQUEST_JSON] {これまでに収集した申込情報一覧} [/REQUEST_JSON] 【利用可能ツール】{ツール一覧とそれぞれの使い方} 【状況コンテキスト】{直近の会話模様} 【これまでのツール実行ログ】{agent_scratchpad} # ユーザプロンプト {ユーザの入力} 6. デモ ここでは、実際にエージェントを動かし、次のようなシナリオで想定通りの挙動になるかを確認します。 ①曖昧な日付の正規化 :「来週の水曜日に、ソファを一脚回収に来てもらえますか?」という依頼に対し、エージェントが具体的な日付を返し、確認を促すか。 ②不足情報の収集 :エージェントが順に質問を行い、申込に必要な情報の収集が進むか。 ③予約確認と確定 :申込に必要な情報が集まった時、エージェントがユーザに対して確認を促すか。ユーザの確認がOKだった場合に受付を完了するか。 ④寄り道質問 :ユーザが途中で「年末年始は回収可能か?」「料金はいくらになるか?」と質問したとき、適切なツールを使って質問に回答できるか。 では、実際のエージェントの動作をシナリオに沿って追ってみます。左側のパネルには常に現在の申込情報が表示され、進行状況が一目でわかります。 ⓪初期画面 新規スレッド作成直後は空欄。ここからユーザの入力に応じて値が埋まっていきます。 ①曖昧な日付の正規化 「来週の水曜日に、ソファを一脚回収に来てもらえますか?」と依頼すると、 item_description: ソファ , quantity: 1 が抽出され、日付も resolve_date で 2025-09-03 に変換されます。 曖昧な日付を正規化し、確認の質問を返す。 ②不足情報の収集 不足情報は優先度順に一つずつ質問され、回答が左側のパネルに反映されます。 氏名→住所→電話番号...と順番に埋めていく。 ③予約確認と確定 全項目が揃うと[REVIEW]タグで申込内容をまとめ、ユーザが了承すれば reserve が実行されます。 最終確認後に予約番号と回収日を提示。 ④寄り道質問 「年末年始は回収できる?」「料金は?」といった質問にも即応可能です。 check_collectible や estimate_fee を呼び出し、回答後は不足情報収集に戻ります。 デモまとめ 初期入力から曖昧日付の正規化までを自動で処理 不足情報は一問一答で収集 すべて揃えば最終確認の後、予約を確定 FAQ的な寄り道質問にも対応 自然な会話の流れで申し込み完了まで進めること を確認できました。 7. オープンソースモデルでの追加実験 GPT-4oで一通り動作を確認したので、「オープンソースモデルでも再現できるか?」を試しました。対象は以下の3モデルです。 Bedrock (AWS) meta/llama-3-1-8b-instruct 独自デプロイ (EC2 - Lambda - API Gateway経由の利用) google/gemma-3-12b-it RedHatAI/gemma-3-27b-it-quantized.w8a8 プロンプトとツール設計は共通とし、 LLM呼び出し部分と出力JSON制約のみ差し替え ています。 前章のシナリオ(①曖昧な日付の正規化、②不足情報の収集、③予約確認と確定、④寄り道質問)をもとに検証しましたが、結果としてGPT-4oのように最後まで通せたモデルはなく、いずれも途中で課題が明らかになりました。 meta/llama-3-1-8b-instruct ①曖昧な日付の正規化 「来週の水曜日に、ソファを一脚回収に来てもらえますか?」と依頼すると、入力文をそのままオウム返ししてきます。LLMがプロンプトの指示を正しく理解せず、また resolve_date ツールも使っていないようです。 依頼文をそのまま返すのみ。 AWS公式 には「tool use対応」とありますが、 reddit では「ツール呼び出しが不安定」との報告があり、安定性に課題があると確認できました。 冒頭でつまづいたので、ここで中断です。 google/gemma-3-12b-it ①曖昧な日付の正規化 「来週の水曜日に、ソファを一脚回収に来てもらえますか?」の依頼に対し、適切にツールを使い、具体的な日付で確認を促します。 ②不足情報の収集 その後も順に質問を行い、情報収集を行っています。 ただし「電電太郎」という名前は「デンデンタロウ」と読むつもりで入力しましたが、「デントウ太郎」と解釈されたみたいです。カタカナでの入力促すなどの工夫が必要です。 会話を続けます。一度は名前の訂正を試みますが、左側パネルは修正されません。 その後、電話番号を入力した後から挙動が怪しくなります。一度確認したはずの回収日を、再確認されます。さらに「はい、あっています。」と答えても、同じ質問を繰り返すようになりました。左側パネルの preferred_date には日付が入っているため、プログラムは確認済と認識していますが、LLMは未確認と誤認しています。ここでシナリオは中断となります。 なお別の会話では、名前の訂正をきっかけに申込情報全体をリセットする事象も見られました。リセットに留まらず、申込内容を「ソファ」から「テレビ」に書き換えるなど、情報を改ざんしています。今回の実験から、 情報保持の安定性に弱点 があることがわかりました。 RedHatAI/gemma-3-27b-it-quantized.w8a8 ①曖昧な日付の正規化 「来週の水曜日に、ソファを一脚回収に来てもらえますか?」の依頼に対し、適切にツールを使い、具体的な日付で確認を促します。ご丁寧にツールを使うことを宣言しています。 ②不足情報の収集 続いて名前を入力しますが、何度入力しても同じ質問を繰り返されます。「電電太郎」を名前と認識していないようです。これ以上進まないので中断します。 今度は違う名前でシナリオを試します。「山田太郎」は名前と認識するようです。その後も不足情報の収集が続きます。 ③予約確認と確定 予約確認で問題が起きます。まず回収場所の確認をされますが、「マンションのごみ捨て場に置きます」という入力は無視されます。諦めて「はい」と答えると、申込内容の再確認をせずに受付を完了してしまいました。 結果と課題 追加実験を通じ、 モデル毎の得手不得手 がわかります。 GPT-4o: 幅広く安定 llama-3-1-8b: ツール呼び出し不安定 gemma-3-12b: 情報保持不安定 gemma-3-27b: 日本語固有名詞に弱い、指示をスキップすることがある 特にgemma系列は「固有名詞処理の弱さ」が共通の課題でした。 クラウドモデルは安定している一方、コスト・セキュリティの制約があります。そのためにオープンソースモデルを使いたいというニーズを聞くことが多いです。 ただし、今回の実験ではオープンソースモデルをそのまま適用するのは難しく、 モデルをタスクごとに使い分ける設計 や LoRA/DPOなどの調整 など、追加の調整が必要になることがわかりました。 8. まとめ 実業務を想定してエージェントを設計したら動作した 粗大ごみ収集の申込という具体タスクを想定し、受付に必要な情報収集→曖昧情報の補正→ツール連携→最終確認の一連の流れをエージェントとして実装しました。寄り道質問(料金・収集可否)や日付正規化など、実際に想定される状況にも対応できています。 「なんでもLLM」にしない設計が肝心 LLMは会話の誘導や判断に強い一方、確実性が求められる箇所はプログラムでガードし、ルール化できる処理はツール(関数)化して呼び分けるのが安全です。今回も、情報の充足判定や予約の意思決定はコード側で判断しており、LLMの柔軟さ x 決定性の担保を両立しています。 最後に 今回はLangChainベースで単一エージェントを構成しましたが、最近は「こんな小難しいプログラムを書かなくても」エージェントを作れるようになってきています。例えば、ローコード基盤Difyがニュースで取り上げられることが増えています。これを使えばほとんどコードを書かずにエージェントを構築できます。 エージェントを使うのも作るのも、どんどん身近になってきています 。 ただし、エージェントは「魔法」ではありません。 要件定義と設計の積み重ね があってこそ、現場で役立つ実用品として作ることができます。皆さんも、まずは身近な業務から、「ここはエージェント化できるかも」と考える一歩を踏み出してみてはいかがでしょうか? 執筆者 相浦 大司(NTT西日本 技術革新部) AI技術の社内相談役として、プロトタイプ開発や業務適用の検討に従事。 JDLA Deep Learning for ENGINEER(2024#1)取得。 商標 AWS, Amazon Bedrock, Amazon EC2, AWS Lambda, Amazon API Gatewayは、Amazon Web Services, Inc. またはその関連会社の商標または登録商標です。 GPT-4oは、OpenAI, Inc.の商標または登録商標です。 Llamaは、Meta Platforms, Inc.の商標または登録商標です。 Gemmaは、Google LLCの商標または登録商標です。 LangChainは、LangChain, Inc.の商標または登録商標です。 Difyは、LangGenius, Inc.の商標または登録商標です。
ごあいさつ  皆様はじめまして、NTT西日本グループのエンジニアによる公式技術者ブログ「NTT WEST Engineers' Blog」をご訪問いただきありがとうございます!運営の平田です。  NTT西日本グループ各社には、クラウド、AI、セキュリティ、データサイエンス、ネットワーク、サーバ、アプリケーション、電気通信、無線など、幅広い分野のエンジニアが多数在籍しており、日々の業務や自己研鑽を通じて多くの知見が蓄積されています。これまで、そうした知見を社外に発信する機会は限られていましたが、「社外へアウトプットしたい!」という多くのエンジニアの声を受け、技術者ブログを開設する運びとなりました。  本技術者ブログでは、お客さま対応やサービス開発・運用の現場で得られた実践的な知見、課題解決の手段・工夫、Tipsなど、エンジニアならではの視点で情報を発信していきます。「こんなことやってるんだ」「それ、うちでも使えそう!」と思ってもらえるような、役立つ&ニッチな技術ネタをお届けしていきます。気軽に読んでいただけると幸いです。  エンジニアの皆様にとって有益な情報源となるよう努めてまいります。NTT WEST Engineers' Blogの今後にぜひご期待ください! 謝辞  本ブログ開設にあたり、 NTTドコモビジネス(旧NTTコミュニケーションズ)エンジニアブログ 運営の方々に、多くのアドバイスをいただきました。この場を借りて御礼申し上げます。 執筆者 平田賀一(NTTビジネスソリューションズ(株) バリューデザイン部 システム開発部門) PaaS/SaaSの開発・運用、社内案件のコンサル、エンジニア育成、NTT WEST Engineers' Blog運営などに携わっています。 技術士(情報工学部門)/2025 Japan All AWS Certifications Engineers