NTT西日本のブログ - TECH PLAY

TECH PLAY

NTT西日本

NTT西日本 の技術ブログ

全88件

はじめに  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