TECH PLAY

SCSKクラウドソリューション

SCSKクラウドソリューション の技術ブログ

1268

こんにちは。SCSKのふくちーぬです。私はコンテナを扱う際に、Dockerインストール済みのCloud9を頻繁に使っていました。 今回は、EC2(Windowsサーバ)にWSL+Dockerをインストールする方法をご紹介します。 EC2(Windowsサーバ)でDockerを利用するためには WindowsサーバでDockerを利用するためには、Docker Engineに加えてWSL2のインストールが必要になっています。WSLは、Windows上でLinuxを動作させる仮想化技術です。 しかし、 通常のEC2インスタンス では仮想化技術(ハイパーバイザー)を使用してAWSの物理ハードウェア上にVM(仮想マシン)を作成します。この仮想化環境では、VM(仮想マシン)自体に直接のハードウェアアクセスや仮想化の制御を加えることができません。そのためWSLのような仮想化必要とするソフトウェアの実行が制限されます。 一方、 ベアメタルインスタンスでは 、仮想化を使用せずに物理サーバー上で直接実行されます。これにより、ホストOSの仮想化機能に直接アクセスできるため、WSLが必要とする仮想化機能を利用できます。   つまりWindowsサーバでDockerを利用するためには、ベアメタルインスタンスを選定する必要があります。 WSL には、WSL 1 と WSL 2 の 2 つのバージョンがあります。 ・.metal EC2 インスタンスの場合は、WSL 1 または WSL 2 のいずれかをインストールできます。 EC2 Windows インスタンスに Windows Subsystem for Linux をインストールする - Amazon Elastic Compute Cloud Windows インスタンスに Windows Subsystem for Linux (WSL) をインストールする docs.aws.amazon.com   また料金は高額ですが、AWSではベアメタルインスタンスが提供されています。 インスタンス名 オンデマンドの時間単価 vCPU メモリ ストレージ ネットワークパフォーマンス c5n.large USD 0.108 2 5.25 GiB EBS のみ 最大 25 ギガビット c5n.xlarge USD 0.216 4 10.5 GiB EBS のみ 最大 25 ギガビット c5n.2xlarge USD 0.432 8 21 GiB EBS のみ 最大 25 ギガビット c5n.4xlarge USD 0.864 16 42 GiB EBS のみ 最大 25 ギガビット c5n.9xlarge USD 1.944 36 96 GiB EBS のみ 50 ギガビット c5n.18xlarge USD 3.888 72 192 GiB EBS のみ 100 ギガビット c5n.metal USD 3.888 72 192 GiB EBS のみ 100 ギガビット オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS オンデマンドインスタンスについては、お客様が使用された EC2 インスタンスの料金のみのお支払いとなります。オンデマンドインスタンスを使用することにより、ハードウェアのプランニング、購入、維持に伴うコストや手間が省け、高額な固定費となりがち... aws.amazon.com アーキテクチャー Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはWindows Server 2022を利用します。 運用者は、フリートマネージャーを利用してEC2に接続します。 EC2にDockerをインストールし、DockerHubからイメージを取得できるようにします。 完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Internet Gateway # ------------------------------------------------------------# InternetGateway: Type: AWS::EC2::InternetGateway AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway # ------------------------------------------------------------# # Public Subnet # ------------------------------------------------------------# PublicSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-1a # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PublicRouteTable PublicRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1a RouteTableId: !Ref PublicRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Key Pair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: !Sub ${ResourceName}-key # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: c5n.metal ImageId: !Ref AMIId SubnetId: !Ref PublicSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup KeyName: !Ref KeyPair Tags: - Key: Name Value: !Sub ${ResourceName}-ec2  WSLのインストール キーペアの値を確認し、EC2に接続 下記記事を参考に、同様の手順でEC2にフリートマネージャー経由で接続します。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 WSL2のインストール PowerShellを開き、コピー&ペーストを使って下記コマンドを実行します。 wsl --install インストールが完了したら、インスタンスを再起動します。 その後EC2に再接続し、Ubuntuがインストールされていることを確認します。 ベアメタルインスタンスのため接続までに30分ほど時間がかかるのでお待ちください。   自動的にWSLが立ち上がり、Ubuntuのインストールが始まります。 ユーザー名を入力します。その後、パスワードを入力します。 再度パスワードを入力します。 インストールが完了しました。 Dockerのインストール Ubuntuを開き、Dockerのリポジトリをセットアップするために以下のコマンドを実行します。 sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch= $( dpkg --print-architecture ) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $( . /etc/os-release && echo " $VERSION_CODENAME " ) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update   続けて、Docker Engineをインストールします。 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin   sudo権限なしにdockerコマンドを実行できるように、ユーザーに対して権限付与します。 sudo groupadd docker sudo usermod -aG docker <ユーザー名> su - <ユーザー名>   Dockerサービスを起動させておきます。 sudo service docker start   以下のコマンドを実行しDockerのバージョンとコンテナが稼働することを確認します。 docker -v docker run hello-world Ubuntu Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multip... docs.docker.com 最後に いかがだったでしょうか。 ベアメタルインスタンスを選定することで、Dockerを導入してコンテナを利用できるようになります。お値段は高いですが、Docker実行環境の一つの候補として検討いただければと思います。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
こんにちは。SCSKのふくちーぬです。 前回、フリートマネージャー経由でのWindowsサーバ接続時にPowerShellのキーボード入力機能を動作させるための方法をご紹介しました。こちらの記事を読んでいない方は、是非ご一読ください。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 今回は、閉域網環境内で実現させるための方法をご紹介します。 アーキテクチャー インターネットゲートウェイ、NATゲートウェイが存在しない閉域網ネットワーク(プライベート環境)とする。 Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはWindows Server 2022を利用します。 運用者は、フリートマネージャーを利用してEC2に接続します。 運用者は、マネジメントコンソールやAPIを利用してS3にアクセスしファイルのやり取りをします。 プライベートサブネット内のEC2は、VPCエンドポイント経由でS3にアクセスしファイルのやり取りをします。 完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketFor: Type: AWS::S3::Bucket DeletionPolicy: Delete Properties: BucketName: !Sub ${ResourceName}-s3-bucket AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Private Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1a PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.11.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1c # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PrivateRouteTable PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # VPC Endpoint # ------------------------------------------------------------# ssmEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssm SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ec2messagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ec2messages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssmmessages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true S3VpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .s3 VpcId: !Ref VPC VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC VPCeSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: For VPCEndpoint SecurityGroupIngress: - SourceSecurityGroupId: !Ref SecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/AmazonS3FullAccess InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Key Pair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: !Sub ${ResourceName}-key # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: !Ref AMIId SubnetId: !Ref PrivateSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup KeyName: !Ref KeyPair Tags: - Key: Name Value: !Sub ${ResourceName}-ec2  解決策 PSReadlineモジュールをローカルでインストールします。その後サーバに移送し、モジュールを読み込ませることで対応できます。 PSReadlineの手動インストール 下記サイトにて、PowerShellモジュールをインストールすることができます。今回は、最新バージョンの2.3.5を選定しました。 PSReadLine 2.3.5 Great command line editing in the PowerShell console host powershellgallery.com “Manual Download”を押下します。 “Download the raw nupkg file”を押下して、バイナリファイルをダウンロードします。 ファイルの拡張子をzipに変更します。 S3へのアップロード S3に”psreadline.2.3.5.zip”ファイルをアップロードします。 キーペアの値を確認し、EC2に接続 下記記事を参考に、同様の手順でEC2にフリートマネージャー経由で接続します。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 Read-S3Objectコマンドの実行 下記記事を参考に、同様の手順でPowerShellで下記コマンドをコピー&ペーストで実行します。 閉域網環境のEC2(Windows)においてファイル共有する方法 AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。今回は閉域網環境において、ローカル-サーバ間においてファイル共有するためにAWS Tools for Windows PowerShellを用いる方法をご紹介します。 blog.usize-tech.com 2024.09.09   Read -S3Object -BucketName <Bucket Name> - Key <Object Key > - File <Local File Path > 例として、以下のコマンドになります。 Read-S3Object -BucketName fukuchi-s3-bucket -Key psreadline.2.3.5.zip -File C:\Users\Administrator\Downloads\psreadline.2.3.5.zip   サーバ上にダウンロードできれば下記画面が表示されます。 モジュールの入れ替え ダウンロードしたzipファイルを解凍しておきます。   以下のディレクトリ配下の”PSReadline”フォルダを削除します。 └C:\Program Files\WindowsPowerShell\Modules その後、”psreadline.2.3.5″フォルダをコピーします。 再度PowerShellを起動し、キーボードから任意の文字を入力してみます。 無事にキーボード入力が機能しましたね。   最後に いかがだったでしょうか。 フリートマネージャー経由で閉域網のWindowsサーバに接続する必要がある場合でも、モジュールを持ち込むことでPowerShellを正常に機能させることができます。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
本記事は、 ~Catoクラウド運用にあたって知っておくべきIT用語まとめ~ 【セキュリティ編】 – TechHarmony (usize-tech.com) の続編になります。 これまでCatoクラウドを運用するにあたって必要なIT用語として、『ネットワーク編』、『セキュリティ編』と題して解説してきました。 本記事は応用編と題して、これまで解説した用語よりも耳なじみのない用語を取り上げて解説したいと思います。 Catoクラウドとは何か、が知りたい方は以下の記事をご覧いただければと思います。 ・ 世界初のSASEプラットフォーム Catoクラウドとは? – TechHarmony (usize-tech.com) それでは早速、用語解説していきます。 SASEと関連する混同されやすい用語 応用編なのに、SASE?と思われた方も多いかもしれません。 なぜここで取り上げたかというと、後述するSASEと関連する英語の略語との違いがわかりづらく、ご質問いただくことが多いため、あえて応用編でご紹介させていただきます。 Cato社によれば、SASEとは「Secure Access Service Edge」の略称であり、「ネットワークとセキュリティの機能をクラウドベースの単一ソリューションに統合したもの」と説明されています。 その機能はというと、主に以下のことを指します。 ネットワーク機能:SD-WAN セキュリティ機能:ゼロトラストネットワークアクセス(ZTNA)、次世代ファイアウォール(NGFW)、セキュアWebゲートウェイ(SWG)など では、このSASEと混同されやすい用語を以下で詳しく解説していきます。 SD-WAN SD-WANとは、「Software-Defined Wide Area Network」の略称で、Cato社によれば「ブロードバンド、MPLS、5G/LTEなど複数の異なるメディアにおいて、最適なトラフィックルーティングを提供する仮想WANアーキテクチャ」と説明されています。 ネットワークをソフトウェアで制御するSDN(Software Defined Networking)を、ユーザーとアプリケーションを安全かつ効率的に接続するために拠点間接続のWANに適用した仮想的なWANのことです。 上述の通り、SD-WANは、SASEのネットワークの最適化機能の一部とご理解いただければと思います。 ZTNA ZTNAは、「Zero-Trust Network Access」の略称です。ゼロトラストの言葉からも分かる通り、明示的に許可されていない限りは、アプリケーションなどリソースへのアクセスをすべて拒否する、セキュアなアクセスを実現するソリューションのことを言います。 従来のVPNは、社内ユーザを信頼し、信頼できないユーザーは社外にいるとして想定されたネットワーク構成でした。 ですが、リモートワークという新しい働き方が波及した昨今では、この境界線はなくなりつつあります。 また、ユーザーの場所の変化だけではなく、アプリケーションやデータベースの所在もまたオンプレミスからクラウドへの移行が進んでいます。このような変化に対応するためのソリューションの一つとして、ZTNAの普及が進んでいます。 上述の通り、ZTNAも同じくSASEのセキュリティ機能のごく一部です。 SSE SSEは、SASEが登場した2019年の2年後 2021年に登場した用語で、「Security Service Edge」の略称です。 SSEは、SASEからネットワーク機能を除き、セキュリティ機能のみにフォーカスしたものです。 つまり、SSEもまたSASEの一部であり、一般的には、SWG、ZTNA/SDP、CASB/DLP機能のみを指すことが多いです。 このSSEとSASEの違いについては、以下の記事で詳しく解説されています。ご興味ある方はぜひご覧いただければと思います。 ・ SSEとSASEどちらを選べばよいのか? – TechHarmony (usize-tech.com) セキュリティ関連用語 ここからは、セキュリティ分野として証明書に関する理解しづらい仕組み「 証明書のピンニング 」と、 昨今話題に上がる違いがわかりづらいセキュリティ分野の英語の略語「 EPP・EDR・XDR・MDR 」を取り上げてご説明します。 証明書のピンニング ここで言う証明書は、 セキュリティ編 でご紹介したデジタル証明書を指します。 忘れてしまったという方は、リンクから一度振り返ってみていただければと思います。 証明書のピンニング(ピン留め)とは、Webサイトやソフトウェアの中で利用できる証明書が埋め込まれている状態のことを言います。 “埋め込まれている”とは、利用可能な証明書が “制限されている” 状態であり、ほかの証明書を利用しようとすると通信が拒否されます。 これは主にソフトウェア提供者が、偽造された証明書による中間者攻撃のリスクを減少させるために導入する、セキュリティ強化の仕組みです。 なぜこの証明書のピンニングをご紹介したかというと、CatoのTLS Inspectionという機能を利用する際に、証明書のピンニングが理由で通信できない事象が発生することが多くあるからです。 TLS Inspectionはセキュリティ強化のために多くのお客様で利用されている機能の一つで、事前にこの問題を知っておいていただければと思います。 TLS Inspectionの機能詳細や、どうして問題が発生するのか詳しく知りたい方は、 こちらのブログ をご参照いただければと思います。 EPPとEDR EPPとは、「Endpoint Protection Platform」の略称です。PCなどのエンドポイントデバイスを、サイバー脅威から保護するセキュリティ製品のことを言います。 一方で、EDRとは「Endpoint Detection and Response」の略称です。エンドポイント上の不審なふるまいやネットワーク上の異常を分析し、その対処までを行うソリューションのことを一般に指します。 EPPはエンドポイントに対する 攻撃を予防 することに重点を置き、EDRは 侵入後の対処 に焦点を当てているところに違いがあります。 2024年9月現在 Catoでは、EPPをWindowsデバイスに対して提供しています。そしてEDRとして、デバイスから取得した情報をもとに、潜在的な脅威の深刻度や影響度についての分析結果を提供しています。 XDR XDRは、「Extended Detection and Response」の略称です。 エンドポイントや、ネットワーク、セキュリティ、クラウドといった各種のログを収集・分析し、攻撃を可視化し、インシデント管理を一元化できるセキュリティソリューションのことです。 EDRが エンドポイントのログ から分析するのに対し、XDRは、 エンドポイントのほか、ネットワーク・セキュリティ製品のログからも分析し、かつインシデント管理が一元化 できることがポイントです。 CatoにもXDR機能が備わっています。CatoのXDRは、世界初のSASEベースのXDRソリューションで、Catoクラウドで検知したイベントをもとに分析した結果がCatoの管理コンソール上で確認可能です。また、その分析結果をもとに、Cato管理コンソール上でスムーズに必要な対処まで行うことができます。 CatoのEPPとXDRの詳細について、ご説明しているブログがございます。ぜひ合わせてご参照いただければと思います。 ・ CatoクラウドのEPPとXDRについて – TechHarmony (usize-tech.com) MDR MDRとは、「Managed Detection and Response」の略称です。 上記のEPP等のセキュリティ製品から検知したインシデント等の対応を行う マネージドサービス のことです。 CatoにもMDRが用意されています。 AIを活用し、Cato社の専門のセキュリティチームと連携し、脅威の調査と検証、お客様への通知などを行うサービスとなっています。 最後に 3編を通して、Catoクラウドを運用するにあたって必要なIT用語 をご紹介させていただきました。いかがでしたでしょうか。 正確にきちんと理解できていた用語もあれば、あやふやに理解していた用語もあったのではないでしょうか。 当社は豊富な運用実績がございますので、何かCatoクラウドの導入や運用にあたって、不明なことがありましたら、お気軽にお問い合わせいただければと思います。
こんにちは、広野です。 本記事はシリーズもので、以下の記事の続編です。 Amazon Bedrock RAG 環境用 AWS CloudFormation テンプレート series 1 VPC 編 Agents for Amazon Bedrock を使用した最小構成の RAG 環境を構築する AWS CloudFormation テンプレートを紹介します。3部構成になっており、本記事は1つ目、VPC 編です。 blog.usize-tech.com 2024.08.01 Amazon Bedrock RAG 環境用 AWS CloudFormation テンプレート series 2 Aurora 編 Agents for Amazon Bedrock を使用した最小構成の RAG 環境を構築する AWS CloudFormation テンプレートを紹介します。3部構成になっており、本記事は2つ目、Aurora Serverless 編です。 blog.usize-tech.com 2024.08.20 以前、以下の記事で Amazon Bedrock や Agents for Amazon Bedrock を使用した最小構成 RAG 環境構築を紹介しておりました。当時はAmazon Bedrock 関連のリソースを一部 AWS CloudFormation ではデプロイできなかったのですが、今はサポートされたためにできるようになりました。 React アプリに Agents for Amazon Bedrock への問い合わせ画面を組み込む [RAG・レスポンスストリーミング対応] Agents for Amazon Bedrock を使用して簡単な RAG をつくってみましたので、問い合わせ画面コードの一部を紹介します。 blog.usize-tech.com 2024.02.15 当時の構成を現在は変更しており、Knowledge Base に使用するデータベースを Amazon OpenSearch Serverless から Aurora Serverless v2 Postgresql に変更したり、モデルを Claude 3.5 Sonnet に変更したりしています。 本シリーズ記事では、環境構築用の AWS CloudFormation のサンプルテンプレートを 3 記事に分けて紹介します。説明を分割するため、テンプレートを3つに分けていますのでご了承ください。 3回目は Amazon Bedrock 編です。 本記事で取り扱う構成 RAG 環境全体の構成 以下のアーキテクチャで RAG アプリケーションを構築しています。このうち、赤枠の部分が本シリーズ記事で取り扱う箇所です。すみません、当初 Amazon SQS まで含んでおりましたが、コード量が多くなってしまうため今回から割愛いたしました。 series 3 Bedrock 編では、series 2 で構築した Amazon Aurora Serverless v2 Postgresql を Agents for Amazon Bedrock に Knowledge Base として登録し、RAG を使用しない問い合わせ (一般検索) 用の AWS Lambda 関数、および Agents for Amazon Bedrock に問い合わせるための AWS Lambda 関数 URL をデプロイします。 Agents for Amazon Bedrock の構成 Agents for Amazon Bedrock は、ユーザーからの問い合わせの内容から、裏にあるどのナレッジから回答を得るべきか仕分けの判断をしてくれます。ただし、判断基準となる情報は提供してあげないといけないので、それを自然言語で設定します。 「SCSK」に関する問い合わせであった場合は、Knowledge Base を確認するようにします。(RAG 検索ルート) それ以外の問い合わせであれば、AWS Lambda 関数を呼び出します。この関数は Amazon Bedrock Claude モデルに問い合わせます。(一般検索ルート) アプリから Agents for Amazon Bedrock に問い合わせるためには、それ用の AWS Lambda 関数が必要です。ただし関数だけでは API から問い合わせを受け付けられないので、Lambda 関数 URL で公開しています。代わりに API Gateway でもかまいませんが、ストリームレスポンスに対応していなかったため Node.js の関数 URL にしました。 AWS Lambda 関数 URL には、CORS 設定のためドメイン情報を設定しています。ドメイン名などの情報は、AWS CloudFormation テンプレートのパラメータとして入力するようにしています。 AWS Lambda 関数 URL の認証については本記事では割愛します。以下の参考記事をご覧ください。 やってみたら面倒くさい、React アプリからの Amazon Cognito 認証付き AWS Lambda 関数 URL 呼出 Amazon Cognito 認証を施した React アプリから、認証済みユーザのみ AWS Lambda 関数を呼び出せるようにする React コードを紹介します。 blog.usize-tech.com 2024.01.15 AWS CloudFormation テンプレート 図に掲載している赤字部分を今回のテンプレートで作成しています。一部、前回のテンプレートで作成したスタックからの情報をインポートしている箇所があります。 使用する Amazon Bedrock (一般検索用) のリージョンや Anthropic Claude モデルのバージョンは簡単に変更可能にするため、パラメータ化しています。技術の進歩が著しいので。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates an Agent for Amazon Bedrock, a Bedrock Knowledge base, and a Lambda function URL. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SubName: Type: String Description: System sub name of sample. (e.g. test) Default: test MaxLength: 10 MinLength: 1 DomainName: Type: String Description: Domain name for URL. Default: scskexample.com MaxLength: 40 MinLength: 5 AllowedPattern: "[^\\s@]+\\.[^\\s@]+" SubDomainName: Type: String Description: Sub domain name for URL. (e.g. xxx of xxx.scskexample.com) Default: xxx MaxLength: 20 MinLength: 1 BedrockAgentAliasName: Type: String Description: The Alias name of Agents for Amazon Bedrock. Default: Default MaxLength: 20 MinLength: 1 BedrockRegion: Type: String Description: The region name you use for Amazon Bedrock Claude 3 model. (e.g. ap-northeast-1) Default: ap-northeast-1 MaxLength: 50 MinLength: 1 ClaudeModelId: Type: String Description: The Claude 3 model ID. (e.g. anthropic.claude-3-5-sonnet-20240620-v1:0) Default: anthropic.claude-3-5-sonnet-20240620-v1:0 MaxLength: 100 MinLength: 1 Resources: # ------------------------------------------------------------# # Bedrock Knowledge Base # ------------------------------------------------------------# BedrockKnowledgeBase: Type: AWS::Bedrock::KnowledgeBase Properties: Name: !Sub sample-${SubName}-kb Description: !Sub RAG Knowledge Base for sample-${SubName} KnowledgeBaseConfiguration: Type: VECTOR VectorKnowledgeBaseConfiguration: EmbeddingModelArn: !Sub arn:aws:bedrock:${AWS::Region}::foundation-model/amazon.titan-embed-text-v1 RoleArn: Fn::ImportValue: !Sub sample-${SubName}-IAMRoleBedrockKbArn StorageConfiguration: Type: RDS RdsConfiguration: CredentialsSecretArn: Fn::ImportValue: !Sub sample-${SubName}-SecretAurora DatabaseName: bedrockragkb FieldMapping: MetadataField: metadata PrimaryKeyField: id TextField: chunks VectorField: embedding ResourceArn: Fn::ImportValue: !Sub sample-${SubName}-AuroraDBClusterArn TableName: bedrock_integration.bedrock_kb Tags: Cost: !Sub sample-${SubName} BedrockKnowledgeBaseDataSource: Type: AWS::Bedrock::DataSource Properties: Name: !Sub sample-${SubName}-kb-datasource Description: !Sub RAG Knowledge Base Data Source for sample-${SubName} KnowledgeBaseId: !Ref BedrockKnowledgeBase DataDeletionPolicy: RETAIN DataSourceConfiguration: Type: S3 S3Configuration: BucketArn: Fn::ImportValue: !Sub sample-${SubName}-S3BucketKbDatasourceArn # ------------------------------------------------------------# # Agents for Amazon Bedrock # ------------------------------------------------------------# BedrockAgent: Type: AWS::Bedrock::Agent Properties: AgentName: !Sub sample-${SubName} Description : !Sub The agent for sample-${SubName} to assign the appropriate knowledge base or action group. AgentResourceRoleArn: !GetAtt BedrockAgentRole.Arn FoundationModel: "anthropic.claude-v2:1" Instruction: | あなたは優秀なAIアシスタントです。ユーザーの指示には日本語で回答してください。SCSKに関する情報が必要な場合はナレッジベースから情報を取得してください。それ以外の問い合わせには、Action Group に設定している Claude foundation model を使用して回答してください。 KnowledgeBases: - KnowledgeBaseId: !Ref BedrockKnowledgeBase KnowledgeBaseState: ENABLED Description: Knowledge Base for the information related to SCSK ActionGroups: - ActionGroupName: UserInputAction ActionGroupState: ENABLED ParentActionGroupSignature: AMAZON.UserInput - ActionGroupName: LambdaBedrockAgentAgClaude ActionGroupState: ENABLED ActionGroupExecutor: Lambda: !GetAtt LambdaBedrockAgentAgClaude.Arn FunctionSchema: Functions: - Name: LambdaBedrockAgentAgClaude Description: "Lambda Function to invoke Bedrock Claude foundation model triggered from Bedrock Agent" Parameters: url: Description: "Invoke the Claude foundation model to answer for a general query except for the related to SCSK." Required: false Type: string Tags: Cost: !Sub sample-${SubName} DependsOn: - LambdaBedrockAgentAgClaude - BedrockAgentRole BedrockAgentAlias: Type: AWS::Bedrock::AgentAlias Properties: AgentAliasName: !Ref BedrockAgentAliasName AgentId: !Ref BedrockAgent Description: Default alias 2024-07-13 1 Tags: Cost: !Sub sample-${SubName} DependsOn: - BedrockAgent # ------------------------------------------------------------# # Bedrock Agent Role (IAM) # ------------------------------------------------------------# BedrockAgentRole: Type: AWS::IAM::Role Properties: RoleName: !Sub AmazonBedrockExecutionRoleForAgents_sample-${SubName} AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: "sts:AssumeRole" Principal: Service: bedrock.amazonaws.com Condition: StringEquals: "aws:SourceAccount": !Sub ${AWS::AccountId} ArnLike: "aws:SourceArn": !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:agent/*" Policies: - PolicyName: !Sub AmazonBedrockExecutionPolicyForAgents_sample-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeModel" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude*" - Effect: Allow Action: - "bedrock:Retrieve" - "bedrock:RetrieveAndGenerate" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:knowledge-base/${BedrockKnowledgeBase}" DependsOn: - BedrockKnowledgeBase # ------------------------------------------------------------# # Lambda Execution Role (IAM) # ------------------------------------------------------------# LambdaBedrockInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub sample-LambdaBedrockInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Bedrock. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub sample-LambdaBedrockInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeModel" - "bedrock:InvokeModelWithResponseStream" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude*" LambdaBedrockAgentInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub sample-LambdaBedrockAgentInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Bedrock Agent. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub sample-LambdaBedrockAgentInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeAgent" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:agent-alias/${BedrockAgent}/*" DependsOn: - BedrockAgent LambdaBedrockAgentAgClaudeInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub sample-LambdaBedrockAgentAgClaudeInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Bedrock Claude FM. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub sample-LambdaBedrockAgentAgClaudeInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "bedrock:InvokeModel" - "bedrock:InvokeModelWithResponseStream" Resource: - !Sub "arn:aws:bedrock:${AWS::Region}::foundation-model/anthropic.claude*" # ------------------------------------------------------------# # Lambda # ------------------------------------------------------------# LambdaBedrock: Type: AWS::Lambda::Function Properties: FunctionName: !Sub sample-Bedrock-${SubName} Description: !Sub Lambda Function to invoke Bedrock for sample-${SubName} Architectures: - x86_64 Runtime: nodejs20.x Timeout: 180 MemorySize: 128 Role: !GetAtt LambdaBedrockInvocationRole.Arn Handler: index.handler Tags: - Key: Cost Value: !Sub sample-${SubName} Code: ZipFile: !Sub | const { BedrockRuntimeClient, InvokeModelWithResponseStreamCommand } = require("@aws-sdk/client-bedrock-runtime"); const bedrock = new BedrockRuntimeClient({region: "${BedrockRegion}"}); exports.handler = awslambda.streamifyResponse(async (event, responseStream, _context) => { try { const args = JSON.parse(event.body); if (args.prompt == '') { responseStream.write("No prompt provided."); responseStream.end(); } const body = { "max_tokens": 3000, "temperature": 0.5, "top_k": 250, "top_p": 1, "anthropic_version": "bedrock-2023-05-31", "system": "質問文に対して適切な回答をしてください。", "messages": [ { "role": "user", "content": [ { "type": "text", "text": args.prompt } ] } ] }; const input = { modelId: '${ClaudeModelId}', accept: 'application/json', contentType: 'application/json', body: JSON.stringify(body) }; const command = new InvokeModelWithResponseStreamCommand(input); const apiResponse = await bedrock.send(command); let completeMessage = ""; for await (const item of apiResponse.body) { const chunk = JSON.parse(new TextDecoder().decode(item.chunk.bytes)); const chunk_type = chunk.type; if (chunk_type === "content_block_delta") { const text = chunk.delta.text; completeMessage = completeMessage + text; responseStream.write(text); } } responseStream.end(); } catch (error) { console.error(error); responseStream.write('error'); responseStream.end(); } }); DependsOn: - LambdaBedrockInvocationRole LambdaUrlBedrock: Type: AWS::Lambda::Url Properties: AuthType: AWS_IAM Cors: AllowCredentials: false AllowHeaders: - "*" AllowMethods: - POST AllowOrigins: - !Sub https://${SubDomainName}.${DomainName} ExposeHeaders: - "*" MaxAge: 0 InvokeMode: RESPONSE_STREAM TargetFunctionArn: !GetAtt LambdaBedrock.Arn DependsOn: - LambdaBedrock LambdaBedrockAgent: Type: AWS::Lambda::Function Properties: FunctionName: !Sub sample-BedrockAgent-${SubName} Description: !Sub Lambda Function to invoke Bedrock Agent for sample-${SubName} Architectures: - x86_64 Runtime: nodejs20.x Timeout: 600 MemorySize: 128 Role: !GetAtt LambdaBedrockAgentInvocationRole.Arn Handler: index.handler Tags: - Key: Cost Value: !Sub sample-${SubName} Code: ZipFile: !Sub | const { BedrockAgentRuntimeClient, InvokeAgentCommand } = require("@aws-sdk/client-bedrock-agent-runtime"); const bedrockagent = new BedrockAgentRuntimeClient({region: "${AWS::Region}"}); exports.handler = awslambda.streamifyResponse(async (event, responseStream, _context) => { try { // Query Bedrock Agent const args = JSON.parse(event.body); if (args.prompt == '') { responseStream.write("No prompt provided."); responseStream.end(); } const agentInput = { "agentId": "${BedrockAgent}", "agentAliasId": "${BedrockAgentAlias.AgentAliasId}", "sessionId": args.jobid, "enableTrace": false, "endSession": false, "inputText": args.prompt, "sessionState": { "promptSessionAttributes": { "serviceid": args.serviceid, "user": args.username, "datetime": args.datetime } } }; const command = new InvokeAgentCommand(agentInput); const res = await bedrockagent.send(command); const actualStream = res.completion.options.messageStream; const chunks = []; for await (const value of actualStream) { const jsonString = new TextDecoder().decode(value.body); const base64encoded = JSON.parse(jsonString).bytes; const decodedString = Buffer.from(base64encoded,'base64').toString(); try { chunks.push(decodedString); responseStream.write(decodedString); } catch (error) { console.error(error); responseStream.write(null); responseStream.end(); } } responseStream.end(); } catch (error) { console.error(error); responseStream.write('error'); responseStream.end(); } }); DependsOn: - LambdaBedrockAgentInvocationRole - BedrockAgentAlias LambdaUrlBedrockAgent: Type: AWS::Lambda::Url Properties: AuthType: AWS_IAM Cors: AllowCredentials: false AllowHeaders: - "*" AllowMethods: - POST AllowOrigins: - !Sub https://${SubDomainName}.${DomainName} ExposeHeaders: - "*" MaxAge: 0 InvokeMode: RESPONSE_STREAM TargetFunctionArn: !GetAtt LambdaBedrockAgent.Arn DependsOn: - LambdaBedrockAgent LambdaBedrockAgentAgClaude: Type: AWS::Lambda::Function Properties: FunctionName: !Sub sample-BedrockAgentAgClaude-${SubName} Description: !Sub Lambda Function to invoke Bedrock Claude model triggered from Bedrock Agent action group for sample-${SubName} Architectures: - x86_64 Runtime: python3.12 Timeout: 300 MemorySize: 128 Role: !GetAtt LambdaBedrockAgentAgClaudeInvocationRole.Arn Handler: index.lambda_handler Tags: - Key: Cost Value: !Sub sample-${SubName} Code: ZipFile: !Sub | import boto3 import json bedrock = boto3.client('bedrock-runtime', region_name='${BedrockRegion}') def lambda_handler(event, context): print(event) # Invoke Bedrock body = { "max_tokens": 3000, "temperature": 0.5, "top_k": 250, "top_p": 1, "anthropic_version": "bedrock-2023-05-31", "system": "質問文に対して適切な回答をしてください。", "messages": [ { "role": "user", "content": [ { "type": "text", "text": event['inputText'] } ] } ] } res = bedrock.invoke_model( body=json.dumps(body), contentType='application/json', accept='application/json', modelId='${ClaudeModelId}' ) resbody = json.loads(res['body'].read())['content'][0].get('text', '適切な回答が見つかりませんでした。') return { "messageVersion": "1.0", "response": { "actionGroup": event["actionGroup"], "function": event["function"], "functionResponse": { "responseBody": { "TEXT": { "body": resbody } } } }, "sessionAttributes": event["sessionAttributes"], "promptSessionAttributes": event["promptSessionAttributes"] } DependsOn: - LambdaBedrockAgentAgClaudeInvocationRole LambdaBedrockAgentAgClaudePermission: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt LambdaBedrockAgentAgClaude.Arn Action: lambda:InvokeFunction Principal: bedrock.amazonaws.com SourceAccount: !Sub ${AWS::AccountId} SourceArn: !Sub "arn:aws:bedrock:${AWS::Region}:${AWS::AccountId}:agent/${BedrockAgent}" DependsOn: - BedrockAgent # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # Lambda LambdaBedrockArn: Value: !GetAtt LambdaBedrock.Arn Export: Name: !Sub sample-${SubName}-LambdaBedrockArn LambdaBedrockUrl: Value: !GetAtt LambdaUrlBedrock.FunctionUrl Export: Name: !Sub sample-${SubName}-LambdaBedrockUrl LambdaBedrockAgentArn: Value: !GetAtt LambdaBedrockAgent.Arn Export: Name: !Sub sample-${SubName}-LambdaBedrockAgentArn LambdaBedrockAgentUrl: Value: !GetAtt LambdaUrlBedrockAgent.FunctionUrl Export: Name: !Sub sample-${SubName}-LambdaBedrockAgentUrl Agents for Amazon Bedrock 変更時の作業 上述の AWS CloudFormation テンプレートを流しただけで一旦 Agents for Amazon Bedrock の一連の構成が出来上がりますが、何か構成を変更したときには、バージョン管理の機能があるためにエイリアスの情報も更新しておく必要があります。以下の Description の部分を、何か記述ルールを決めて同時に変えていきましょう。 BedrockAgentAlias: Type: AWS::Bedrock::AgentAlias Properties: AgentAliasName: !Ref BedrockAgentAliasName AgentId: !Ref BedrockAgent Description: Default alias 2024-07-13 1 本記事の範囲はこれで終了です。 まとめ いかがでしたでしょうか? あまり説明はなく AWS CloudFormation テンプレートを読んで下さい的な内容になっていますが、そもそもテンプレート化したい人でないとこの記事は読まないと思いますので、ある程度読める方がいらっしゃっているのかな、と思います。その他、AWS Lambda 関数のつくりもなにげに参考になるかと思っております。 本記事が皆様のお役に立てれば幸いです。
こんにちは。SCSKの江木です。 皆さん、チャットボットの質に満足していますか? 従来のルールベースのチャットボットでは、複雑な質問に対応できず、チャットボット利用者の要望を叶えることが難しかったかもしれません。 今回は複雑な質問に対応できるような、より自然で人間らしい会話を実現するため、Dialogflow CXと生成AIを連携する方法を紹介します。 Dialogflow CXとは Dialogflow CXとは、自然言語による対話をシステムに組み込む際に使えるプラットフォームです。高度なチャットボットや音声アシスタントを構築するためのツールであり、複雑な会話の流れや多様なユーザーの質問に柔軟に対応できることが特徴です。 Dialogflow CXの基本については以下のブログにまとめているので、ご参照ください。 Dialogflow CXの基本を整理してみました 今回は、Dialogflowの基礎知識を改めて整理して紹介していきます。この基礎知識があれば、Dialogflow CXでAgentを構築できるようになるので、最後までご覧ください。 blog.usize-tech.com 2024.09.09 Dialogflow CXで生成AIを使う方法 Dialogflow CXで生成AIを使う方法を4つ紹介します。 Generatorを使う Dialogflow CXの中にGeneratorという機能があります。Generatorは要約、パラメータ抽出、データ変換などのタスクで使われることが多いです。 今回は漢字をひらがなに変換する機能をGeneratorで実装したので、実装したAgentを紹介します。 上図は実装したAgentで、Generatorsページにて、ひらがな変換を実装しています。Generatorsページの設定は以下の通りです。 ひらがなにしたい漢字をSession Parameterで受け取るようにしています。 続いて、Generatorの設定を見ていきます。 GeneratorはSession Parameterを受け取る必要があるので、「$page.param.status = “FINAL”」ルートにて設定します。設定は以下の通りです。 Generatorからの変換結果を$request.generative.answerで受け取り、Agent saysでAgentが変換結果を発話するように設定しています。 また、Generatorの細かい設定は以下の通りです。 使用したいモデルを選択することもできますし、プロンプトを自由に書き換えることも可能です。 それでは実装したAgentの動作を確認してみます。 無事、漢字をひらがなに変換することが確認できました。 Webhookを使用する 続いて、Webhookを使って、APIを叩くことで生成AIを利用する方法を2つ紹介します。 ※本節ではフローの全体像、Webhookのソースコードおよび実装結果を紹介します。Webhookの実装については以下のブログで紹介しているので、実装の詳細を知りたい方はご覧ください。 Dialoglflow CXのWebhookを使ってTranslation APIを叩いてみた Dialogflow CXで構築しているチャットボットに翻訳機能を追加するために、WebhookでTranslation APIを叩く方法を紹介します。 blog.usize-tech.com 2024.02.26 WebhookでGemini APIを使用する WebhookでGemini APIを叩く方法を、実装したAgentをもとに紹介します。実装したAgentのフローは以下の通りです。 GeminiページにてGeminiへの質問のパラメータ「$session.params.question」を取得し、APIを叩きます。 WebhookのPythonソースコードは以下の通りです。 ※requirement.txtにモジュールをインポートし忘れないように注意してください。 import functions_framework import requests import vertexai from vertexai.generative_models import GenerationConfig, GenerativeModel, Part def interview(project_id: str,location: str,model: str,text: str) -> str:   # Initialize Vertex AI     vertexai.init(project=project_id, location=location)   # Load the model     model = GenerativeModel(model_name=model)   # Generation Config   config = GenerationConfig(       max_output_tokens=2048, temperature=0.4, top_p=1, top_k=32     )   # Generate text   response = model.generate_content(       text, generation_config=config     )     return response.text @functions_framework.http def webhook(request):   response = request.get_json()   text = response["sessionInfo"]["parameters"]["question"]   tag = response["fulfillmentInfo"]["tag"]   model = "gemini-1.5-flash"   output_text = interview("プロジェクト名","リージョン",model,text)   response["fulfillmentResponse"] = {           "messages": [               {                   "text": {                       "text": [                           output_text                       ],                       "allowPlaybackInterruption": False                   }               }           ]       }     return response webhookをAgentに設定し、テストした結果は以下の通りです。         Geminiが質問に回答してくれました!! WebhookでAgent Builder Searchを使用する WebhookでAgent Builder Search APIをたたく方法を実装したAgentをもとに紹介します。実装したAgentのフローは以下の通りです。 Gemini APIを叩くときと同様に、searchページにて質問のパラメータ「$session.params.question」を取得し、APIを叩きます。 Webhookを紹介する前に、Agent Builder Searchのアプリを作成します。 以下のドキュメントにしたがって、アプリとデータストアを作成します。(説明が長くなるので、詳細は割愛します。) 今回は transformerの論文(pdf) をデータソースとして使用しました。 Get started with generic search  |  Vertex AI Agent Builder  |  Google Cloud Create a search app for a website, structured data, and unstructured data, then preview the results. cloud.google.com Agent Builder Searchの準備ができたので、Webhookのソースコードを紹介します。Pythonソースコードは以下の通りです。 ※requirement.txtにモジュールをインポートし忘れないように注意してください。 import functions_framework import vertexai from google.cloud import discoveryengine from vertexai.preview.generative_models import GenerativeModel, ChatSession from typing import List from google.cloud import storage from google.oauth2 import service_account import json import requests #Search用のparametersを定義 project_id = "プロジェクト名" location = "global" search_engine_id = "データストアのID" #configIDはAgent Builderのコンソール→アプリ→統合で確認することができます。 serving_config_id = "configID" location_v = "ロケーション" model_name = "gemini-pro" vertexai.init(project=project_id, location=location_v) model = GenerativeModel(model_name) chat = model.start_chat() def extract_path_from_link(link: str):     return "/".join(link[5:].split("/")[1:]) def search(   project_id: str,   location: str,   search_engine_id: str,   serving_config_id: str,   search_query: str     ) -> List[discoveryengine.SearchResponse.SearchResult]:     client = discoveryengine.SearchServiceClient()   serving_config = client.serving_config_path(       project=project_id,       location=location,       data_store=search_engine_id,       serving_config=serving_config_id,     )   request = discoveryengine.SearchRequest(       serving_config=serving_config,       query=search_query,       page_size=2,       content_search_spec=discoveryengine.SearchRequest.ContentSearchSpec(           extractive_content_spec=discoveryengine.SearchRequest.ContentSearchSpec.ExtractiveContentSpec(               max_extractive_segment_count=1,               max_extractive_answer_count=1,           ),           snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(               return_snippet=True,           ),           summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(               summary_result_count=5,               include_citations=True,           ),       ),     )     response = client.search(request)   search_result = {}   search_result = {       "answer": response.summary.summary_text,       "retrieved_texts": [           {               "document_path": extract_path_from_link(result.document.derived_struct_data["link"]),               "link": result.document.derived_struct_data["link"],               "snippets": result.document.derived_struct_data["snippets"][0]["snippet"],               "text": result.document.derived_struct_data["extractive_segments"][0]["content"],           }           for result in response.results       ],     }   search_result_text = search_result["answer"]     return search_result_text @functions_framework.http def search_document(request):   response = request.get_json()   sentence = response["sessionInfo"]["parameters"]["question"]     tag = response["fulfillmentInfo"]["tag"]     output_text= search(project_id, location, search_engine_id, serving_config_id, sentence)   response["fulfillmentResponse"] = {           "messages": [               {                   "text": {                       "text": [                           output_text                       ],                       "allowPlaybackInterruption": False                   }               }           ]         }     return response 上記のWebhookでは検索結果の要約のみをAgentに返すように設定しています。 WebhookをAgentに設定し、テストした結果は以下の通りです。 論文の内容であるAttentionについてしっかり回答してくれました!! Agent Builder Conversationを使用する 最後にAgent Builder Conversationを使用する方法を紹介します。 本サービスですが、2024年9月現在日本語版がプレビューであることに注意してください。 さて、Agent Builder Conversationにアクセスするわけですが、もちろんAgent Builderのコンソールからアクセスできます。しかし、今回はDialogflow CXのコンソールからアクセスする方法を紹介します。 まず、Dialogflow CXのコンソールにアクセスし、言語はja、ロケーションはglobalでAgentを作成します。作成したら、Start Pageの詳細を見ます。 [Add State handler]→[Data Stores]にチェック→[Apply]を押下します。 Data Storesの[+]を押下したのち、画面右の[Create Vertex AI Search and Conversation App]を押下します。 Agent Builderのコンソールが立ち上がるので、エージェントの構成を設定します。設定が終わったら[続行]を押下します。 データストアにインポートするデータを選択します。Agent Builder Searchの手法と同様に transformerの論文(pdf) をデータソースとしてインポートします。設定が終わったら[続行]を押下します。 データストアの設定を行い、[作成]を押下します。 作成したデータストアを選択し、[作成]を押下します。 作成が完了したら、画面左にある[プレビュー]を押下します。 Dialogflow CXのコンソールが立ち上がるので、Agent Builderのコンソールを開いたときと同様に[Add State handler]から以下のデータストア設定画面を開きます。Unstructured documentsから作成したデータストアを選択し、[Save]を押下します。 これで準備は完了です。Agentをテストしてみると、以下の結果となりました。 文章は短いですが、Attentionについて答えてくれました!! おわりに 今回はDialogflow CXで生成AIを使う方法をまとめてみました。 Dialogflow CXで生成AIを使う方法が多いと感じたのではないでしょうか? 2度目になりますが、2024年9月現在、Agent Builder Conversationは日本語がpreviewなので注意してください。 本記事が皆様のお役にたてば幸いです。 最後まで読んでいただきありがとうございました。
こんにちは、広野です。 AWS Cloud9 と AWS CodeCommit が新規 AWS アカウントで利用不可、という方針が AWS から打ち出されました。今後の代替ソリューションは色々なパターンがありますので調査もままならない、なかなか決めきれない状況の方が多いのではないかと想像します。 とは言え開発を進めなければならない状況はあり、私も取り急ぎタイトルに書いた対応を暫定的に実施しましたので、一度整理して残しておこうと思います。 置かれていた状況 以下のように、新規作成したアカウント A で AWS を活用してアプリ開発をしたかったが、AWS Cloud9 が利用不可になっていた、という状況です。AWS CodeCommit は利用可能でした。 実施したこと 既存のアカウント B では AWS Cloud9 が利用できたので、取り急ぎそちらを使うことにしました。 作業手順 1. アカウント A で AWS CodeCommit リポジトリを作成する これについては、AWS ドキュメント通りです。 Create an AWS CodeCommit repository - AWS CodeCommit Describes how to use the AWS Management Console or the AWS CLI to create a CodeCommit repository. docs.aws.amazon.com 2. アカウント A で AWS CodeCommit リポジトリにアカウント B からのアクセスを許可する こちらも AWS ドキュメント通りです。 Cross-account repository access: Actions for the administrator in AccountA - AWS CodeCommit To allow users or groups in AccountB to access a repository in AccountA, an AccountA administrator must: docs.aws.amazon.com アカウント A にアカウント B からのアクセスを許可する IAM ロールを作成します。コンソールで作成するのが面倒だったので、以下の AWS CloudFormation テンプレートでも作成できます。この IAM ロールの ARN をアカウント B に提供します。AWS CloudFormation テンプレートを使用した場合、対象の AWS CodeCommit リポジトリ名とアクセスを許可する AWS アカウント ID (ここではアカウント B の) をパラメータとして入力します。結果として、出力タブに IAM ロールの ARN が表示されます。 AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates an IAM Role to allow the cross account access to the CodeCommit. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. (e.g. dev) Default: dev MaxLength: 10 MinLength: 1 CodeCommitRepositoryName: Type: String Description: The target CodeCommit repository name. Default: MySharedDemoRepo MaxLength: 50 MinLength: 1 TargetAwsAccountId: Type: String Description: The target AWS account ID. Default: 999999999999 MaxLength: 12 MinLength: 12 Resources: # ------------------------------------------------------------# # CodeCommit Access Role (IAM) # ------------------------------------------------------------# CodeCommitAccessRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${SystemName}-${SubName}-CodeCommitAccessRole Description: This role allows the target AWS account to access the CodeCommit repository. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: !Ref TargetAwsAccountId Action: - sts:AssumeRole Path: / Policies: - PolicyName: !Sub ${SystemName}-${SubName}-CodeCommitAccessPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "codecommit:BatchGet*" - "codecommit:Create*" - "codecommit:DeleteBranch" - "codecommit:Get*" - "codecommit:List*" - "codecommit:Describe*" - "codecommit:Put*" - "codecommit:Post*" - "codecommit:Merge*" - "codecommit:Test*" - "codecommit:Update*" - "codecommit:GitPull" - "codecommit:GitPush" Resource: - !Sub "arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${CodeCommitRepositoryName}" - Effect: Allow Action: "codecommit:ListRepositories" Resource: "*" # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: # IAM CodeCommitAccessRoleArn: Value: !GetAtt CodeCommitAccessRole.Arn 3. アカウント B で AWS Cloud9 用カスタム IAM ロールを作成する こちらも AWS ドキュメント通りです。 Cross-account repository access: Actions for the administrator in AccountB - AWS CodeCommit To allow users or groups in AccountB to access a repository in AccountA, the AccountB administrator must create a group ... docs.aws.amazon.com 2. で作成したアカウント A の IAM ロール ARN が必要になります。それを使用して、AWS Cloud9 に関連付けるカスタム IAM ロールをアカウント B で作成します。この IAM ロール名をこの後の手順で使用します。以下の AWS CloudFormation テンプレートを使用した場合、IAM ロール名はパラメータに入力した文字列を使用して SystemName-SubName-Cloud9CodeCommitRole という名前で出来上がります。 AWSTemplateFormatVersion: "2010-09-09" Description: The CloudFormation template that creates an EC2 instantance profile and an IAM role to allow Cloud9 instances to access the CodeCommit repository across the account. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SystemName: Type: String Description: System name. (e.g. example) Default: example MaxLength: 10 MinLength: 1 SubName: Type: String Description: System sub name. (e.g. dev) Default: dev MaxLength: 10 MinLength: 1 TargetAccountIamRole: Type: String Description: The IAM role ARN provided from the target AWS account. Default: arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxxxxxxxxx MaxLength: 100 MinLength: 1 Resources: # ------------------------------------------------------------# # EC2 Role / Instance Profile (IAM) # ------------------------------------------------------------# Ec2Role: Type: AWS::IAM::Role Properties: RoleName: !Sub ${SystemName}-${SubName}-Cloud9CodeCommitRole Description: This role allows Cloud9 instances to access the target CodeCommit repository across the account. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSCloud9SSMInstanceProfile Policies: - PolicyName: !Sub ${SystemName}-${SubName}-Cloud9CodeCommitPolicy PolicyDocument: Version: "2012-10-17" Statement: - Action: - "sts:AssumeRole" Resource: !Ref TargetAccountIamRole Effect: Allow - PolicyName: !Sub ${SystemName}-${SubName}-Cloud9QDeveloperPolicy PolicyDocument: Version: "2012-10-17" Statement: - Action: - "codewhisperer:GenerateRecommendations" Resource: "*" Effect: Allow Ec2InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Ref Ec2Role Path: / Roles: - !Ref Ec2Role DependsOn: - Ec2Role このテンプレートには、おまけで Amazon Q Developer からのコード提案を受けられる権限も付けています。 Using CodeWhisperer with AWS Cloud9 - CodeWhisperer For CodeWhisperer to provide recommendations in AWS Cloud9 console, you must enable the correct IAM permissions for eith... docs.aws.amazon.com 4. アカウント B で AWS Cloud9 環境を作成する こちらも AWS ドキュメント通りです。 Step 1: Create an environment - AWS Cloud9 Learn how to create an environment docs.aws.amazon.com VPC とサブネットは、お使いの環境を適切に選択してください。ネットワーク設定で AWS Cloud9 環境へのアクセス方法を選択しますが、SSM を選択してください。その方が推奨ですし、上記で紹介したカスタム IAM ロールは SSM でアクセスする前提で作成しています。 5. アカウント B で AWS Cloud9 をセットアップする ここからは、いくつかのマニュアル手順を実施します。公式手順としては以下が参考になるのですが、若干カスタムしたものを後述しますのでご注意ください。 Cross-account repository access: Actions for the repository user in AccountB - AWS CodeCommit To access the repository in AccountA, users in the AccountB group must configure their local computers for repository ac... docs.aws.amazon.com AWS Cloud9 環境は Amazon EC2 インスタンスとして起動します。インスタンスに自動的に関連付けられている IAM ロールを 3. で作成したカスタム IAM ロールに変更します。 Cloud9 環境の画面から EC2 インスタンスの管理 を押し、EC2 インスタンス情報の画面に移ります。 IAM ロールを、3. で作成した IAM ロールに変更します。一度デフォルトの IAM ロールをデタッチしてからアタッチしないとエラーになることがあります。 AWS Cloud9 環境を起動します。画面左上の Cloud9 アイコンから Preference メニューを選択します。AWS Settings から Credentials メニューに進み、AWS managed temporary credentials の設定を OFF (赤) にします。 ターミナルから、Cloud9 環境内にコンフィグファイルを作成します。 ディレクトリを ~/.aws に移動し、config という名前のファイルを作成します。 cd ~/.aws vi config config ファイルの中身は以下のように記述します。 profile の CrossAccountCodeCommit の部分は任意の名前で良いですが、6. で登場するコマンドと合わせる必要があります。 role_arn は 2. で作成したアカウント A 側の IAM ロールの ARN です。 region も指定します。 [profile CrossAccountCodeCommit] role_arn = arn:aws:iam::xxxxxxxxxxxx:role/xxx-xxx-CodeCommitAccessRole credential_source = Ec2InstanceMetadata region = ap-northeast-1 以上で AWS Cloud9 環境のセットアップは完了です。 6. アカウント B の AWS Cloud9 からアカウント A の AWS CodeCommit に接続する environment ディレクトリに戻り、AWS Cloud9 のターミナルで git の初期設定をします。これは通常の git コマンドです。 git config --global user.name "名前" git config --global user.email メールアドレス この後 git clone をしますが、同一アカウントの AWS Code Commit に接続するときとコマンドが異なります。 先ほど作成した config ファイルに記入した内容に合わせます。@マーク以下は AWS CodeCommit のリポジトリ名を記入します。 git clone codecommit::ap-northeast-1://CrossAccountCodeCommit@CodeCommitのリポジトリ名 ここまで完了すれば、以降は通常の git コマンドを使用します。git add, git commit, git push, git pull など。 まとめ いかがでしたでしょうか。 AWS Cloud9 が新規アカウントで利用不可となったので今後長きに亘り重宝される情報ではないですが、一時的には役立つと思います。 Cloud9 って、AWS 上でアプリを公開していて、AWS CodeCommit を使用し、かつクラウド上に開発環境を置きたい人にとっては本当に便利だったんですけどね。今後の利用不可が残念でならないです。 本記事が皆様のお役に立てれば幸いです。
SCSKの江浜です。(初投稿です!) Oracle CloudWorld 2024 が 現地時間9月9日(火)から12日(木) の4日間にわたりラスベガスにて開催されております。 本記事では4日間に及ぶOracle CloudWorld 2024 現地からの情報をお届けします。 はじめに、、、「Oracle Database@AWS」が発表されました! Oracle社とAWS社が2024年9月9日(米国時間)「 Oracle Database@AWS 」を発表しました! AWS社のデータセンターを利用してOracle社が「Oracle Exadata Database Service」や「Oracle Autonomous Database」を提供する形になります。 今回私が参加している「Oracle CloudWorld 2024」でも2024年9月10日(米国時間)、Oracle社会長兼CTOであるLarry Ellison氏によるKeynoteで改めて紹介があったので後述します。 Oracle and Amazon Web Services Announce Strategic Partnership Customers can now access Oracle Autonomous Database and Oracle Exadata Database Service in AWS, simplifying the migratio... www.oracle.com   9/9(月) 受付・パートナーサミットへの参加 会場はアメリカ、ラスベガスの「The VenetIan Resort Las Vegas」です。 (行ったのは朝ですが夜はこんな感じです。)     初日は受付のために会場へ行ってきました。 会場の外は日中の気温が38度ほどですが日本と違って湿度が低く、数値ほどの暑さは感じません。 (ただとても乾燥しておりリップは必須でした。。。あと目薬。。。) ホテル併設のカジノを抜けて会場に入ると中は空調が効いており、快適でした。(部屋によってはむしろちょっと肌寒かったりしました) 会場入口はこんな感じです。初日は受付とパートナー向けのサミットに参加してきました。 会場に向かう様子   9/10(火) Keynote  概要 9/10(火)よりセッションが本格的に始まりました!人も多くなり盛り上がっています! 今日はその中で2つ参加レポート書きます! 【Keynote】Customers Winning with the Cloud and AI Oracle社CEOのSafra Catz 氏によるクラウドとAIで大きな課題をどのように解決しているかの紹介でした。 各業界のパートナーをゲストとして呼び、対話形式で紹介するような内容でした。 登壇するSafra Catz 氏 個人的にはCIAのCIOであるLa’Naia Jones氏との対話、特にセキュリティの話が印象的でした。 サイバーセキュリティのここ10年の変化に対して、迅速な意思決定をすることやベストでより安全な決定が必要であること、翻訳や要約に関しては生成系AIを取り入れていくことについて話されていました。 【Keynote】Oracle Vision and Strategy Oracle社の会長兼CTOであるLarry Ellison氏がOracleの差別化されたAIイノベーションについて語りました。 登壇する Larry Ellison氏 登壇すると会場では大きな歓声が上がりました! 内容は大きく2点についてでした。 マルチクラウド時代について AIを活用したセキュリティについて   マルチクラウド時代について 2024年6月にAWS社ののCEOに就任したMatt Garman氏がゲストで登場しました。 対談の内容はやはり先日9日に発表のあったAWS社との戦略的パートナーシップについての内容が多かったです。 多くの顧客がAWSを利用していることや、Oracle データベースを AWS に接続する際の課題(レイテンシ等)についても触れ、改めてOracle のサービスと AWS の統合、パフォーマンスの向上について強調していました。 AIを活用したセキュリティについて 大きく4つのセキュリティに分けて話がありました。 ①データセキュリティ ②アプリケーションセキュリティ ③ユーザID ④ネットワークセキュリティ 自律型のセキュリティ運用や、ネットワークセキュリティの 複雑化問題に対して ネットワークコンフィギュレーションとネットワークセキュリティを分離することが重要と強調されていたことが、個人的に印象に残りました。 ちなみにネットワークコンフィギュレーションとネットワークセキュリティの分離に関して、 本日話されたZRP(OCI Zero Trust Packet Routing)のプレスリリースでてました! オラクル、ネットワーク・セキュリティとネットワーク・アーキテクチャを分離してクラウド・セキュリティ体制を強化 OCI Zero Trust Packet Routing、ネットワーク構成とネットワーク・セキュリティを切り離し、人的ミスに起因するデータ漏洩を防止 www.oracle.com   最後に 今日書ききれなかったセッションの内容も含めて、「Oracle CloudWorld 2024 参加レポート②」を頑張って書こうと思います!
こんにちは。SCSKの島村です。 Vertex AI(Gemini API)にて利用できる『関数呼び出し機能(Function Calling API )』についてご存知でしょうか?? 関数呼び出しを利用することで、LLMから 関連性の高いコンテキストに沿った回答 を提供することが可能となります。 本記事では、 『 Function Calling API 』について色々と調査し、実際に触ってみましたので、その魅力について少しだけご紹介させていただければと思います。 Function Calling APIとは?? 『Function Calling』とは、  LLMが質問の内容や文脈から必要な関数(外部の関数やAPI)を判断し呼び出すことで、回答の幅をさらに広げる機能 です。 従来のLLMは、与えられたプロンプトに対して、既に学習しているデータに基づき回答を生成することが主な役割でした。 しかし、Function Callingによって、LLMは単なるテキスト生成にとどまらず、以下のようなことができるようになります。 外部データの取得: 天気予報、株価、ニュース記事など、リアルタイムの情報を取得 計算: 複雑な計算やデータの分析を実行 外部サービスとの連携: 翻訳サービス、画像生成サービスなど、様々な外部サービスと連携してより高度なタスクを実行 Fanction Calling(関数呼び出し)を使用することで、生成 AI モデルに提供するための情報を外部もから取得可能となります。 Function Call(関数呼び出し)とモデル返答までのフロー:Google Cloudドキュメントより 詳細については、以下、Google Cloud公式ドキュメントからご確認ください。 関数呼び出し  |  Vertex AI の生成 AI  |  Google Cloud 利用ステップ Verte AI Geminiにて『Fanction Calling』を利用する手順は以下となります。 モデルを初期化する 。 ユーザー プロンプトを定義する 。 関数宣言を使用して、 使用可能な一連の関数を定義、記述する 。 ユーザーのプロンプトと関数宣言をモデルに送信する 。 モデルから出力された構造化データを使用して、 関数を呼び出す 。 関数の出力をモデルに提供する 。   Function Callingを実際に試してみた。 今回は「Function Calling API」を利用して、あらかじめ用意した簡単な関数を呼び出すことを試してみます。 実際の出力結果の一部を先にお見せします。 簡単な算数の問題をLLMに解かせてみました。 外部の関数を参考にして、LLMは回答を生成していることが分かります。 今回は簡単な算数の問題を例に試してみましたが、LLMに複雑な計算を実行してもらう場合、ハルシネーションの抑制にもつながる機能だと感じました。 Fanction Callingを実装してみる(コード例) 今回はコードについても少しだけ解説してみます。 1. 必要なモジュールのインポート import requests from vertexai.generative_models import (   Content,   FunctionDeclaration,   GenerationConfig,   GenerativeModel,   Part,   Tool, ) 2. プロジェクトの設定と言語モデル(Vertex AI)を使うための準備 import vertexai PROJECT_ID = ! gcloud config get-value project PROJECT_ID = PROJECT_ID[0] LOCATION = "us-central1" # @param {type:"string"} vertexai.init(project=PROJECT_ID, location=LOCATION) 3. LLMから呼び出す関数を定義(今回は簡単に「加算」「乗算」を実施する関数を作成します。) def add_fun(x,y):   print("---加算関数を呼び出しました.---")   return int(x)+int(y)  def multiply_func(x,y):   print("---乗算関数を呼び出しました.---")   return int(x)*int(y) 4. LLMから呼び出すための関数宣言 ・入力から判断するための「説明」と「取得する変数」を定義します。 詳細はリンクをご確認ください。: 関数宣言の例 add_function = FunctionDeclaration(   name="add",   description="質問から計算方法を判別し、加算を算出します。",   parameters={       "type": "object",       "properties": {           "x": {"type": "string", "description": "x."},           "y": {"type": "string", "description": "y."},       },   }, ) multiply_function = FunctionDeclaration(   name="multiply",   description="質問から計算方法を判別し、乗算を算出します。",   parameters={       "type": "object",       "properties": {           "x": {"type": "string", "description": "x."},           "y": {"type": "string", "description": "y."},       },   }, ) 5. Geminiモデル側の設定 tool = Tool(   function_declarations=[       add_function,       multiply_function,   ], ) model = GenerativeModel(   model_name="gemini-1.5-pro-001",   generation_config=GenerationConfig(temperature=0),   system_instruction=[       """       計算に関する質問の場合、自分で計算を行わないでください。       その他の質問の場合、ユーザーの質問に正しく答えてください。       """,   ],   tools=[tool], ) 6. おまけ)定義した2つの関数を直列に利用したい場合を想定して、レスポンスを再帰的に呼び出すための設定 def handle_response(response):   if response.candidates[0].function_calls:       function_call = response.candidates[0].function_calls[0]   else:       print(response.text)       return   if function_call.name == "add":       x_args = function_call.args.get('x')       y_args = function_call.args.get('y')       z_add = add_fun(x_args,y_args)  # Assuming a single string argument       response = chat.send_message(           Part.from_function_response(               name=function_call.name,               response={                   "content": z_add,               },           ),       )       return handle_response(response)   elif function_call.name == "multiply":       x_args = function_call.args.get('x')       y_args = function_call.args.get('y')       # Call your function       z_add = multiply_func(x_args,y_args)       response = chat.send_message(           Part.from_function_response(               name=function_call.name,               response={                   "content": z_add,               },           ),       )       return handle_response(response)   else:         print(function_call) 7. チャットモデルの開始 chat = model.start_chat() 以上で作成は完了です。 作成したモデルを利用して、実際にいくつか試してみます。↓↓↓ 質問の内容を理解し、計算(「乗算」「加算」)が必要な場合には適切に外部関数を呼び出していることが確認できます。 また、Fanction Callされた際のレスポンスを覗いてみると、、、、 利用した関数名( function_call { name: “multiply” } ・・・)が記載されていることが分かります。   最後に 今回は『 Function Calling API 』について実際のデモともにご紹介させていただきました。 簡単な計算問題を外部関数として定義し、LLMから呼び出して回答を補足する。  そんなデモを実感頂けたと思います。 外部データに対してAPIを経由してアクセスすることもでき、LLMの回答も大きく広がるそんな機能ではないでしょうか。 色んな関数を定義し、LLMのからの回答の幅を広げていくことができる『 Function Calling API 』のご紹介でした。 今後とも、AIMLに関する情報やGoogle CloudのAIMLサービスのアップデート情報を掲載していきたいと思います。 最後まで読んでいただき、ありがとうございました!!!
こんにちは。SCSKの吉田です。 今回は、ServiceNowⓇのNow Assist in Virtual Agentに関する記事となります。  生成AIが搭載されたチャットボット機能を活用して、どのように身の回りの業務を効率化できるか検証してみました。 本記事は執筆時点(2024年9月)の情報です。最新の情報は製品ドキュメントを参考にしてください。   Now Assist in Virtual Agentとは Now Assist in Virtual Agentは、ServiceNowのVirtual Agent(チャットボット)に生成AI機能が追加されたものになります。 これにより、ユーザーは会話形式でのVirtual Agent利用が可能となり、ナレッジの検索やサービスカタログのリクエストなどをより簡単に行えるようになりました。 時間を問わず利用可能なセルフサービスを提供することで、ユーザーの自己解決率を向上し、ヘルプデスクへの問い合わせ削減が期待できます。 ちなみに、ユーザーが自己解決し、チケットの作成を回避できた割合を「deflection rate」と呼び、Virtual Agentの導入効果を測定する上で重要な指標となります。 deflection rateの測定方法についても、勉強した内容を別記事でアウトプット予定です。 また、開発者目線でもメリットがあり、これまではVirtual Agentが返答する内容を事前に定義する必要がありましたが、生成AIが回答を生成してくれるので、構築に要する時間も短縮できそうです。 Now Assist in Virtual Agentを使ってみる まずは、前回の記事で作成したユーザーのアカウント登録申請をVirtual Agentから実施してみます。 ServiceNowⓇのNow Assistを活用してカタログアイテム(申請フォーム)とフローを効率的に作成する ServiceNowのNow Assistの機能を活用して、申請書とフローを作成してみました。非常に効率的に作成することができたので、そのプロセスをご紹介します。 blog.usize-tech.com 2024.08.27 Virtual Agentに「ユーザーアカウントを登録したい」とチャットすると、インスタンス内の存在するサービスカタログやナレッジを検索して、いくつかの候補を提示してくれます。 前回作成した「User Registration Request」がヒットしました。 申請を開始すると、「User Registration Request」フォーム内の各質問項目をVirtual Agentが会話形式で質問してくるので、チャット上で回答していきます。 入力内容を間違えた場合も、どの項目を修正したいか伝えることで、Virtual Agentが変更を反映してくれます。 最後に申請予定の内容を表示してくれるので、中身に問題なければSubmitして申請は完了です。 Virtual Agentと会話した通りに申請が作成されたことが確認できました。   身の回りの困り事をVirtuakl Agentで解決してみる シナリオ 【イベント】 新しい社員が自部署に配属される 【困りごと】 PCの調達など色々と準備が必用なのは認識しているけど、 何をすればよいか分からない、何処から申請すればよいか分からない。。 → Virtual Agentに必要なタスクを教えてもらおう、ついでに申請もまとめてVirtual Agentにやってもらおう 実践 今回「User Onboarding」という会話のフローを簡易的に作成してみました。 「User Onboarding」と入力すると、Virtual Agentが社員配属時に必要な申請の要否を順番に質問してくれるので、回答していきます。 回答した内容が一覧で表示されます。 今回はPC、業務携帯電話、名刺、個人ロッカーを用意したいと回答しました。 続いて、前の会話で必用と回答したものに対し、具体的な要望を質問されるので回答していきます。 (例)PCを調達するためにOS、CPU、ストレージを聞かれています。 (例)業務用携帯電話を調達するために、OS、ストレージ、本体のカラーを聞かれています。 申請毎に内容のサマリが表示されるので、問題なければSubmitを選択すれば申請が完了します。 その後、名刺、個人ロッカーについても同様に質問されるので、回答していけば申請は全て完了です。 結果を確認してみると、新しく部署に配属される社員向けに4つの申請をまとめて行うことができました。   開発内容 前セクションのVirtual Agentの会話内容のほとんどは生成AIによって生成されたものであり、非常に簡単に実装できました。 例えば前半でユーザーに対して各種申請の要否を確認している部分は、以下画像のDetailed descriptionにユーザーへ質問したいことを簡単に記載しているのみとなります。 記載した説明をもとに生成AIが会話文を考えてくれました。(もちろん、自分自身で会話文を事前に定義することも可能です)   後半の申請を行う部分に関しては、標準機能の「Request catalog item(LLM)」というトピックブロックと事前に作成したカタログアイテムを紐づけるのみとなります。 ユーザーへ質問したり、最終的に申請をあげる部分は開発不要になります。   まとめ Now Assist in Virtual Agentを触ってみて「何をすればよいのか分からない」という人に対して非常に便利なサービスを提供できると感じました。 今回の記事のように、業務上発生する様々なイベント(海外出張、育児休暇など)ごとに、Virtual Agentの会話フローを作成すれば、従業員体験の向上、ヘルプデスクへの問い合わせ削減など様々な良い効果がありそうです。 さらに生成AIの導入により、自然言語で検索をかけることも可能なので、実施したいことが不明瞭な人でも目的のナレッジやカタログアイテムにたどり着きやすくなったのではないかと思います。 ServiceNow ServiceNowは、企業の生産性向上や業務プロセス改善を支えるサービスマネジメントクラウドソリューションです。従業員満足度・顧客満足度の向上、業務効率化を強力に支援します。 www.scsk.jp
こんにちは。SCSKの江木です。 これまでDialogflow CXでAgentを構築していて、困ったことが多々ありました。 今回はこれまでの経験をもとに、スムーズな開発と高品質なチャットボットを実現するためのTipsをいくつかまとめました。 本記事がAgentを作成するためのヒントになれば幸いです。 Dialogflow CXとは Dialogflow CXとは、自然言語による対話をシステムに組み込む際に使えるプラットフォームです。高度なチャットボットや音声アシスタントを構築するためのツールであり、複雑な会話の流れや多様なユーザーの質問に柔軟に対応できることが特徴です。 Dialogflow CXの基本については以下のブログにまとめているので、ご参照ください。 Dialogflow CXの基本を整理してみました 今回は、Dialogflowの基礎知識を改めて整理して紹介していきます。この基礎知識があれば、Dialogflow CXでAgentを構築できるようになるので、最後までご覧ください。 blog.usize-tech.com 2024.09.09 Agentを作成するときのTips Route Groupを使いこなせ! Route Groupは、Routeを使いまわしたいときに使います。同じintentで遷移先が同じRouteが異なるPageで存在したとき、それぞれのページでRouteを作るよりも、Route Groupを使うことで開発を時間短縮することができます!! Route Groupは以下の手順で新たに作成することができます。設定の仕方はRouteと同様にintentとTransitionを設定すると、動作します。 Pageの詳細 [Add state handler]をクリック [Route groups]にチェックして、[Apply]をクリック [Route groups]右の[+]をクリック [Route group]の[Create new route group]を選択 Parameterを使いこなせ! Parameterを使うことで、Agentの実装の幅が大きく広がります。本節ではParameterについて説明した後、実装例について紹介していきます。 Parameterについて Dialogflow CXにおけるParameterは、セッション中にエンドユーザーが入力した値を取得または参照するときに使用します。Parameterには以下の3種類が存在します。 Intent parameter Form parameter Session parameter それぞれのParameterについて説明します。 Intent parameter Intentが一致した時にエンドユーザーが入力した値を抽出し、Intent parameterに設定されます。 以下のFlowを使用して、Intent parameterの取得方法を紹介します。 Page1の設定は以下の通りです。 curryというRouteに、curryというintentを設定しています。 以下のように、curryというintentにTraining phraseを入力し、curryという名前のIntent parameterを設定します。 続いて、Page2のFulfilmentにて、Intent parameterを取得します。   テストしてみると、以下のようにIntent parameterを取得できていることがわかります。 Form parameter Form parameterは 参照で使用されず 、パラメータの入力ステータスの確認で使われます。つまり、「$page.params.パラメータ名」といった記述はできません。 「$page.params.status = “FINAL”」のように現在のページですべてのパラメータが入力されているのか確認するために使用します。 以下のように、Conditionで設定することが多いです。 Session parameter 実行時に任意のパラメータが設定されると、Session parameterに設定されます。 Session parameterはPageのParameterで設定することが多いですが、Route、eventhandler、PageのFulfillmentのParameter presetsでも設定することができます。 以下のFlowを用いて、Session parameterの取得方法を紹介します。 Page1の設定は以下の通りです。 Parameterにdrinkというパラメータが設定されています。このパラメータに値が入ったときにSession parameterに値が入ります。 続いて、Page2のFulfilmentにて、Session parameterを取得します。 テストしてみると、以下のようにSession parameterを取得できていることがわかります。 Parameterを使った実装例 以下のフローチャートのようなコンサートのチケット申し込みを行うチャットボットを作る例を考えます。 また、以下の2つの機能が含まれるようにチャットボットを作成します。 チケットの確認を行う際に、申し込むチケットによってチャットボットの応答が変わる チケット申し込みと確認におけるループの上限回数が3回である 以降、上から機能1、機能2と記載します。 このフローチャートに従って作成したFlowは以下の通りになります。 このFlowにおけるPageの役割は以下の通りです。 Select Ticket 申し込むチケットをユーザーに選択させる 「男性アイドルグループMと女性アイドルグループWのどちらのチケットが欲しいですか?「M」か「W」で教えてください。」とユーザーに質問する Ticket Confirm 申し込むチケットの確認を行う 作成したFlowとPageについての説明が終了したところで、次は機能1と機能2をどのように実装したのかを説明します。 機能1 Intent parameterを使って、実装していきます。 以下のようにIntentを設定します。 「M」、「W」と入力されたときにきちんとIntent parameterに値が入るように設定しました。 先ほど設定したIntentであるticket.mとticket.wをSelect TicketページのRouteであるticket.mとticket.wに設定します。 次にこのIntent parameterを参照します。Ticket ConfirmページのパラメータであるresponseのAgent responsesという項目で下記のようにIntent parameterによって、チャットボットの返答が変わるように設定します。 ※パラメータであるresponseはエンドユーザーの返答である「はい」か「いいえ」を格納するために設定しています。「はい」ならばEnd Sessionページへ、「いいえ」ならSelect Ticketページに遷移するように設定しています。 機能1の実装は以上になります。 機能2 Session parameterを使って、実装していきます。 ループカウントするためのパラメータを用意するため、Start PageのルートであるtrueのParameter presetsにordercountというSession parameterを定義します。 ※trueは必ず遷移するルートで、遷移先はSelect Ticketに設定しています。 続いて、チケットの確認を行うたびにordercountがインクリメントされるように設定します。Select TicketページのFulfillmentのParameter presetsで以下のように設定します。 また、Select Ticketページのルートに、ordercountが4になったとき(つまり、3回申し込み確認を終えたとき)にEnd Sessionに遷移するようなルートを設定します。 ※ここでAgent responsesで「男性アイドルグループMと女性アイドルグループWのどちらのチケットが欲しいですか?「M」か「W」で教えてください。」と返答する条件として「ordercount < 3」と設定しているのは4回質問しないようにするためです。 機能2の実装は以上になります。 他の細かい設定は説明がかなり長くなってしまうので、今回は割愛させていただきます。 Start Pageのintentに注意しろ! Start Pageに設定したRouteのIntentはすべてのPageに伝播されます。 ある特定のPageからの遷移を設定したいときは、Start PageにIntentを設定しないように気を付けてください。 冒頭で紹介したブログにて作成した、以下のAgentで実際に挙動を確かめてみます。 AgentのPageに設定した項目の一部を以下に示します。 Page Fulfillment Route intent Training phrase Transition Start Page – store.location store.location 任意のお店の場所を聞く フレーズ Store Location store.hour store.hour 任意の営業時間を聞く フレーズ Store Hours Store Location Agent says: 東京都************です。その他ご用件はございますでしょうか。 Route Group: Closing – – – Store Hours Agent says: 月曜日から土曜日まで9:00 -19:00 で営業しています。日曜祝日は定休日です。その他ご用件はございますでしょうか。 Route Group: Closing – –   次にRoute Groupの設定を示します。 Route Group intent Training phrase Transition Closing closing いいえ、ありません等の否定のフレーズ End Session   それではAgentに会話してみます。お店の場所を聞いた後に、試しに営業時間を時間を尋ねたところ、以下のようにAgentが返答を返してきました。 Store LocationからStore Hoursへ遷移するようなRouteを設定していないのに、遷移してしまいました。Start Pageに設定したintentが効いているのが確認できますね!! おわりに いかがだったでしょうか。 今回はDialogflow CXでAgentを作成するときのTipsを紹介しました。 私が開発していて躓いたポイントを盛り込んでいるので、参考にしていただければと思います。 本記事が皆様のお役にたてば幸いです。 最後まで読んでいただきありがとうございました。
こんにちは。SCSKのふくちーぬです。 AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。今回は閉域網環境において、ローカル-サーバ間においてファイル共有するためにAWS Tools for Windows PowerShellを用いる方法をご紹介します。 AWS Tools for Windows PowerShellとは AWS Tools for Windows PowerShellは、PowerShell向けのサービスです。PowerShellからAWSサービスを利用するためのコマンドツール群です。 AWS Tools for PowerShellとは何ですか? - AWS Tools for PowerShell AWS Tools for PowerShell は、 によって公開される機能に基づいて構築された PowerShell モジュールのセットです AWS SDK for .NET。 AWS Tools for PowerShell を使用す... docs.aws.amazon.com Winsows Server 2022においては、”4.1.628″のバージョンがインストール済みとなります。 AWS Windows AMI version history - AWS Windows AMIs Find historical details about AWS Windows AMI version releases. docs.aws.amazon.com   アーキテクチャー Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはWindows Server 2022を利用します。 運用者は、フリートマネージャーを利用してEC2に接続します。 運用者は、マネジメントコンソールやAPIを利用してS3にアクセスしファイルのやり取りをします。 プライベートサブネット内のEC2は、VPCエンドポイント経由でS3にアクセスしファイルのやり取りをします。   完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketFor: Type: AWS::S3::Bucket DeletionPolicy: Delete Properties: BucketName: !Sub ${ResourceName}-s3-bucket AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Private Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1a PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.11.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1c # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PrivateRouteTable PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # VPC Endpoint # ------------------------------------------------------------# ssmEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssm SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ec2messagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ec2messages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssmmessages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true S3VpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .s3 VpcId: !Ref VPC VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC VPCeSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: For VPCEndpoint SecurityGroupIngress: - SourceSecurityGroupId: !Ref SecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/AmazonS3FullAccess InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Key Pair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: !Sub ${ResourceName}-key # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: !Ref AMIId SubnetId: !Ref PrivateSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup KeyName: !Ref KeyPair Tags: - Key: Name Value: !Sub ${ResourceName}-ec2    AWS Tools for Windows PowerShellを利用したローカル⇒サーバへのファイル共有 まず、ローカルからサーバ(EC2)へのファイル転送手順です。 S3へのアップロード まずはローカルのファイルをS3にアップロードします。 今回は、AWS-CLIの導入を対象とします。 AWS CLIの最新バージョンのインストールまたは更新 - AWS Command Line Interface AWS CLI をシステムにインストールまたは更新する手順。 docs.aws.amazon.com ローカルPC上でWindows (64 ビット) 用のインストーラをダウンロードします。 対象ファイルをS3に格納しておきます。 キーペアの値を確認し、EC2に接続 下記記事を参考に、同様の手順でEC2にフリートマネージャー経由で接続します。 フリートマネージャー経由でのWindowsサーバ接続時に、PowerShellのキーボード入力機能を動作させるためには AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 blog.usize-tech.com 2024.09.09 Read-S3Objectコマンドの実行 PowerShellを開き、コピー&ペーストを使って下記コマンドを実行します。 Read-S3Object -BucketName <Bucket Name> -Key <Object Key> -File <Local File Path> 今回の場合は、以下のようなコマンドとなります。 Read-S3Object -BucketName fukuchi-s3-bucket -Key AWSCLIV2.msi -File C:\Users\Administrator\Downloads\AWSCLIV2.msi  Read-S3Object -BucketName <String> -Key <String> -File <String> -Version <String> -ModifiedSinceDate <DateTime> -UnmodifiedSinceDate <DateTime> -UtcModifiedSinceDate <DateTime> -UtcUnmodifiedSinceDate <DateTime> -ServerSideEncryptionCustomerMethod <ServerSideEncryptionCustomerMethod> -ServerSideEncryptionCustomerProvidedKey <String> -ServerSideEncryptionCustomerProvidedKeyMD5 <String> -ChecksumMode <ChecksumMode> -ClientConfig <AmazonS3Config> -UseAccelerateEndpoint <SwitchParameter> -UseDualstackEndpoint <SwitchParameter> -ForcePathStyleAddressing <Boolean> サーバ上にダウンロードできれば下記画面が表示されます。 AWS-CLIの導入 インストーラーをダブルクリックし、画面の指示に従って進めます。 “Next”を押下します。 チェックボックスにチェックを付与して、”Next”を押下します。 “Next”を押下します。 “Install”を押下します。 無事にインストールが完了しました。”Finish”を押下すると、画面が閉じます。 コマンドプロンプトを開き、下記のコマンドを実行します。 aws --version AWS-CLIをインストールすることができました。   AWS Tools for Windows PowerShellを利用したサーバ⇒ローカルへのファイル共有 今度は、サーバ(EC2)からローカルへのファイル転送手順です。 ファイルの作成 サーバ上の任意の場所でファイルを作成してください。 今回は、notepadを利用して”test.txt”ファイルを作成しておきました。 Write-S3Objectコマンドの実行 PowerShellを開き、コピー&ペーストを使って下記コマンドを実行します。 Write-S3Object -BucketName <Bucket Name> -Key <Object Key> -File <Local File Path> 今回の場合は、以下のようなコマンドとなります。 Write-S3Object -BucketName fukuchi-s3-bucket -Key "test.txt" -File "C:\Users\Administrator\Documents\test.txt" Write-S3Object -BucketName <String> -Key <String> -File <String> -CannedACLName <S3CannedACL> -PublicReadOnly <SwitchParameter> -PublicReadWrite <SwitchParameter> -ContentType <String> -StorageClass <S3StorageClass> -StandardStorage <SwitchParameter> -ReducedRedundancyStorage <SwitchParameter> -ServerSideEncryption <ServerSideEncryptionMethod> -ServerSideEncryptionKeyManagementServiceKeyId <String> -ServerSideEncryptionCustomerMethod <ServerSideEncryptionCustomerMethod> -ServerSideEncryptionCustomerProvidedKey <String> -ServerSideEncryptionCustomerProvidedKeyMD5 <String> -Metadata <Hashtable> -HeaderCollection <Hashtable> -TagSet <Tag[]> -ChecksumAlgorithm <ChecksumAlgorithm> -ConcurrentServiceRequest <Int32> -CalculateContentMD5Header <Boolean> -PartSize <FileSize> -IfNoneMatch <String> -Force <SwitchParameter> -ClientConfig <AmazonS3Config> -UseAccelerateEndpoint <SwitchParameter> -UseDualstackEndpoint <SwitchParameter> -ForcePathStyleAddressing <Boolean> S3上にアップロードできれば下記画面が表示されます。 S3コンソールを確認し、該当のファイルが格納されていますね。その後は、マネジメントコンソール等を利用してS3内のファイルをローカルにダウンロードすればOKです。   まとめ 閉域網環境のEC2(Windows)でも、AWS Tools for Windows PowerShellがインストール済みのため、各種AWSのAPIを利用することができます。 AWS Tools for PowerShell Reference docs.aws.amazon.com   最後に いかがだったでしょうか。 AWS Tools for Windows PowerShellを利用すれば、閉域網環境でも容易にファイル共有ができました。普段はAWS-CLIを使う機会が多いですが、これを機に積極的に利用してみようと思います。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
こんにちは。SCSKの磯野です。 Dataplexにはデータリネージ機能があります。BigQueryでどのように加工したときがリネージ対象なのか、調べてみました。 データリネージとは? データリネージ とは、データがいつ、どこで、どのように取得され、今の状態にあるのかを追跡し、データの流れを可視化する機能です。データリネージは、DataPlex の機能名ではありますが、Google Cloud に限らず一般的に使われる用語です。   BigQueryでどのように加工したときにリネージされる? 公式ドキュメント には、以下の記載があります。 BigQuery プロジェクトでデータリネージを有効にすると、Dataplex によって次のリネージ情報が自動的に記録されます。 次の BigQuery ジョブの結果として新しいテーブルが作成されます。 コピージョブ Cloud Storage URI を使用して Cloud Storage から許可された形式でデータを読み込む 読み込みジョブ * Google 標準 SQL で次のデータ定義言語(DDL)を使用する クエリジョブ CREATE TABLE CREATE TABLE AS SELECT CREATE TABLE COPY CREATE TABLE CLONE CREATE TABLE FUNCTION CREATE TABLE LIKE CREATE VIEW CREATE MATERIALIZED VIEW Google 標準 SQL で次のデータ操作言語(DML)ステートメントを使用した結果としての既存のテーブル 次にリストされたテーブルタイプのいずれかに関連付けられた  SELECT 。 BigQuery ビュー BigQuery マテリアライズド ビュー BigQuery 外部テーブル INSERT SELECT MERGE 更新 削除 検証対象 実際にどのように加工するとリネージされるのか、以下の4パターンを調べてみました。 Python(BigQuery API、pandas) ※実行基盤はCloudRunまたはVertex AI Workbench Python( BigQuery DataFrame ) ※実行基盤はCloudRunまたはVertex AI Workbench magicコマンド ※実行基盤はVertex AI Workbench Dataform Python(BigQuery API、pandas) CloudRun・Vertex AI Workbenchの両方で試しましたが、リネージされませんでした。 from google.cloud import bigquery import pandas as pd import google.cloud.logging log_client = google.cloud.logging.Client() log_client.setup_logging() client = bigquery.Client() def main(): query = """ SELECT PassengerId, Survived, Name FROM xxx_dataset.transfer_titanic """ df = client.query(query).to_dataframe() client.load_table_from_dataframe(df,"xxx_dataset.dataplex_test_table_by_vertexai_pandas") if __name__ == '__main__': main() Python(BigQuery DataFrame) CloudRun・Vertex AI Workbench、どちらの環境でもリネージされました。 ※BigQuery DataFrameは2024年9月時点でプレビュー版であるため注意 import bigframes.pandas as bpd import google.cloud.logging log_client = google.cloud.logging.Client() log_client.setup_logging() def main(): query = """ SELECT PassengerId, Survived, Name FROM xxx_dataset.transfer_titanic_test_copy2 """ df = bpd.read_gbq(query) df.to_gbq("xxx_dataset.dataplex_test_table_by_vertexai_bpd", if_exists='replace') if __name__ == '__main__': main() magicコマンド Vertex AI Workbenchで実行したところ、リネージされました。 %%bigquery CREATE TABLE `dxr-poc.xxx_dataset.dataplex_test_magic` CLONE `dxr-poc.xxx_dataset.transfer_titanic_test_copy3`; Dataform 下記に従って検証したところ、リネージされました。 SQL ワークフローを作成して実行する  |  Dataform  |  Google Cloud   さまざまなユースケース スクレイピング等でGCP環境外のデータをBigQueryに格納する場合 リネージ対象はGCP環境内のみ。一度GCSを経由すれば、GCSーBigQuery間のみリネージされます。 プロジェクトをまたぐ場合 両方のプロジェクトにて以下のAPIが有効にされていればリネージ可能です。 Google Cloud Data Catalog API Data Lineage API   結論 GCP外のデータをリネージすることはできないものの、データ取得時に一度GCSへ格納しつつ、BigQuery DataFrameを使うことでデータリネージが可能でした。 pandas APIはリネージの対象外でした。 BigQuery DataFrameを使うことでリネージは可能ですが、実行基盤を特定することはできませんでした。また、実行の度にリネージが作成されるため、視認性は低いです。 Dataformやmagicコマンドはリネージの対象でした。 すべてのリネージ情報は  30 日間のみ システムに保持されます。 →定期実行しているものであれば問題ないですが、スポット実行のテーブルのリネージは消えてしまうため注意が必要です。 補足 カスタムリネージ について Dataplexがメタデータの自動収集の対象外としている処理については、リネージも自動作成できませんが、カスタムリネージを作成することで、表示することは可能です。 データリネージについて  |  Data Catalog のドキュメント  |  Google Cloud リネージが作成されるまで、少しタイムラグがあります。今回の検証では、ジョブが終わってから約10分ほどで生成されました。 ※公式ドキュメントには下記の記載があります。 BigQuery リネージは、BigQuery ジョブが完了してから 24 時間以内に表示されます。 リネージ情報は、関連するデータソースを削除した後も保持されます。つまり、BigQuery テーブルとその Data Catalog エントリを削除しても、API を使用して最大  30 日間 は、そのテーブルのリネージを読み取ることができます。
こんにちは。SCSKの江木です。 以前、以下の記事を執筆しましたが、Dialogflow CX自体が初めてでわかりくいという方もいらっしゃったかもしれません。 Dialoglflow CXのWebhookを使ってTranslation APIを叩いてみた Dialogflow CXで構築しているチャットボットに翻訳機能を追加するために、WebhookでTranslation APIを叩く方法を紹介します。 blog.usize-tech.com 2024.02.26 そこで今回は、Dialogflowの基礎知識を改めて整理して紹介していきます。 この基礎知識があれば、Dialogflow CXでAgentを構築できるようになるので、最後までご覧ください。 Dialogflowとは? CCAIサービスの1つで、仮想エージェントを備えた、自然な会話を実現するAIです。一言でいうと、チャットボット兼ボイスボット(以下、チャットボットと省略して記載します。)を作ることができるサービスです。DialogflowにはCXとESの2種類が存在します。 Dialogflow CX 大規模なエージェントや非常に複雑なエージェントに適した高度なエージェントタイプを提供 Dialogflow ES 小規模エージェントとシンプルなエージェントに適した標準エージェントタイプを提供 Dialogflow CXについて GUI Dialogflow CXのGUIは以下のようになっております。 右側の[Build]タブ、[Manage]タブからAgentの設定をすることができます。また、左側の[Test Agent]でテストを行うこともできます。 用語 続いて、Dialogflow CXを触るうえで理解する必要がある用語解説していきます。 Agents Dialogflow CXで作成する チャットボット のことです。Dialogflow CXでは様々なロケーションにエージェントを作ることができます。また、1つのプロジェクトで複数のエージェントを作成することもできます。 Flows 複雑な会話に関して、複数のトピックを取り扱うための仕組みです。 会話の流れや分岐 を視覚化したもので、Page同士のつながりを見ることができます。開始時にはDefault Start FlowというFlowが存在します。以下の図全体がFlowです。 Pages 会話の各ステップを表したものです。PageにはEntry fulfillmentやRoutes(後述します)を設定します。以下の赤枠で囲った部分がPageです。 Entry fulfillment そのPageに遷移したときにAgentが発言するメッセージです。下図の例ですと、Start PageからStore Hoursに遷移したとき、Entry fulfillmentに設定されている「月曜日から土曜日まで9:00-19:00mで営業していま…」をAgentが発言します。 Routes 会話のFlowを制御するためのもので、PageからPage(またはFlow)への遷移を決定します。Routeにはintentsを設定します。このRouteで以下の図の矢印がRouteです。 Intents エンドユーザー(チャットボットを利用する人)の 意図(言葉) を分類します。以下の図のように「Training phrases」という項目でエンドユーザーが発言する言葉を学習させます。 Agentの作り方 Agentの作り方の基本を紹介していきます。 まず、Dialogflow CXのコンソールにアクセスし、[Create Agent]を押下します。 自由にカスタマイズしたいので、[Build your own]を選択します。 Agentの設定を行います。言語はjaにしてください。設定が完了したら、[Create]を押下してください。 Agent作成画面が立ち上がりました。 FlowやPageを作りたい場合は、[Build]タブから、IntentやEntity、外部との連携をしたい場合は[Manage]タブからAgentの機能を開発していきます。 実際に作成したAgentをもとに、会話の流れをつかんでみる 今回はDialogflow CXのハンズオンをもとにAgentを作成しました。ハンズオンの詳細が知りたい方は以下のサイトをご参照ください 【Dialogflow cx】はじめてみよう google cloud dialogflow cx 編 【Dialogflow cx】はじめてみよう google cloud dialogflow cx 編 - Download as a PDF or view online for free www.slideshare.net 作成したAgentは以下の通りです。ここでは下図のStart PageからStore Hoursへ遷移するときの発言の流れを例に説明します。 Start PageにはStore Hoursに遷移するためにstore.hoursという名前のRouteを設定しています。また、store.hoursにはstore.hoursという名前のintentを設定しています。設定は以下の通りです。 Start Pageからの遷移先であるStore HoursのEntry fulfilmentには以下の通りの設定をしています。 以上の設定を踏まえると、Agentとの会話の流れは以下の通りです。 Start Pageからスタート エンドユーザが営業時間を聞くようなフレーズを入力 intentであるstore.hoursのTraining phrasesに登録されたフレーズに類似したフレーズがエンドユーザーから入力されたため、store.hoursというRouteが選択される Routeであるstore.hoursの遷移先はStore Hoursであるため、Start PageからStore Hoursへ遷移 Store HoursのEntry fulfillmentに登録した、「月曜日から土曜日まで9:00 -19:00 で営業しています。日曜祝日は定休日です。その他ご用件はございますでしょうか。」というフレーズをAgentが発言 一般化してみる Agentとの会話の流れを一般化してまとめてみます。 上のようなフローがあるとき、Agentとの会話の流れは以下の通りとなっています。 Page Aからスタート。Page AのFufillmentのAgent saysで設定された「こんにちは」というフレーズをAgentが発言。 エンドユーザがフレーズを入力 Page AのRoute1に設定されたIntentのTraining phrasesに登録されたフレーズに類似したフレーズがエンドユーザーから入力されるとRoute1が選択される Route1のTransition(遷移先)はPage Bであるため、Page AからPage Bへ遷移 Page AのEntry fulfillmentのAgent saysに設定した、「遷移したよ」というフレーズをAgentが発言 FufillmentやRoute以外にもPageには様々な設定項目があり、Agentに柔軟な発言をさせることができますが、遷移の基礎は上記の通りになります。 おわりに 今回はDialogflow CXの基本を整理してみました。 今回紹介した内容でも十分Agentを作ることができますが、自由度は低いです。 今後の記事では、紹介していない機能や生成AIの機能、Dialogflow CXでAgentを作成するときのTipsについて紹介できたらと思います。 最後まで読んでいただきありがとうございました。
こんにちは。SCSKのふくちーぬです。 AWS Systems Managerのフリートマネージャーを利用して、Windowsサーバにブラウザベースでのリモート接続している方多いかと思います。その際に、PowerShellでキーボード入力が機能しなかった事象が発生しましたので対処策をお話します。 アーキテクチャー Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはWindows Server 2022を利用します。 運用者は、フリートマネージャーを利用してEC2に接続します。 完成したCloudFormationテンプレート 以下のテンプレートをデプロイしてください。 AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Internet Gateway # ------------------------------------------------------------# InternetGateway: Type: AWS::EC2::InternetGateway AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway # ------------------------------------------------------------# # Public Subnet # ------------------------------------------------------------# PublicSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-1a # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PublicRouteTable PublicRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1a RouteTableId: !Ref PublicRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Key Pair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: !Sub ${ResourceName}-key # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: !Ref AMIId SubnetId: !Ref PublicSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup KeyName: !Ref KeyPair Tags: - Key: Name Value: !Sub ${ResourceName}-ec2   本事象の確認 キーペアの値を確認し、EC2に接続 Systems Manager パラメータストアにアクセスし、キーペアの値をメモしておく。 上記の値を利用して管理者パスワードを復号します。 フリートマネージャーを利用し管理者パスワードを入力し、EC2に接続します。 PowerShellでキーボード入力が機能しないことを確認 PowerShellを開き、キーボードで文字の入力を試みますが動作しません。 ※メモ帳内の文字をコピー&ペーストで、PowerShellに貼り付けることはできます。   解決策 PowerShellにて、PSReadlineモジュールをインストールすることで解決できます。 モジュールのインストール PSReadLineモジュールは、コマンド ラインを編集させるためのモジュールとなります。このモジュールのおかげで、コマンド履歴を追ったりすることができます。 PSReadLineのバージョン2.2.2以上をインストールします。 キーボード入力機能は利用できないため、コピー&ペーストを使って下記コマンドを実行します。 Install-Module -Name PSReadLine -Repository PSGallery -MinimumVersion 2.2.2 -Force  Yes/Noの確認プロンプトが表示されたら、”Y”を入力します。この際も、コピー&ペーストを使って入力することに注意してください。 PowerShellでキーボード入力が機能することを確認 再度、PowerShellを開きます。キーボードから任意の文字を入力してみます。 無事にキーボード入力が機能しましたね。   まとめ Windows Server 2022では、PowerShell でキーボードが正常に機能するためにはPSReadLine のバージョン 2.2.2 以上が必要です。 本制約は、フリートマネージャー利用時特有のものとなります。 キーボード機能用 PSReadLine モジュールバージョン PowerShell でキーボードが正しく機能することを確認するには、Windows Server 2022 を実行しているノードに PSReadLine モジュールバージョン 2.2.2 以降がインストールされていることを確認してください。古いバージョンを使用している場合は、以下のコマンドを使用して、必要なバージョンをインストールできます。 Remote Desktop を使用して Windows Server マネージドインスタンスに接続する - AWS Systems Manager Fleet Manager を使用して RDP 経由で Windows Server マネージド EC2 インスタンスに接続します。 docs.aws.amazon.com Install-Module -Name PSReadLine -Repository PSGallery -MinimumVersion 2.2.2 -Force  代替策として、以下の方法もございますので併せてご検討いただければと思います。 プライベートなRDP接続 EC2 Instance Connect Endpoint経由でのRDP接続   最後に いかがだったでしょうか。 フリートマネージャー利用時には、WindowsサーバのモジュールをアップデートすることでPowerShellを正常に機能させることができます。 本記事が皆様のお役にたてば幸いです。 ではサウナラ~🔥
こんにちは。SCSKの山口です。 本ブログでは、前回のブログで作成したBigQuery MLの線形回帰モデルの性能を評価してみたいと思います。 [前回ブログ]モデル作成・予測結果 【GCP】BigQuery MLを触りたいときに読むブログ 今回はBigQuery MLを使って機械学習モデルの作成、テストをやってみます。 AI/MLの知識はあまりないがとにかくBigQuery MLを触ってみたい方、BigQuery MLでモデルを作成して推論してみたい方にぜひ読んでいただきたいブログです。 blog.usize-tech.com 2024.09.06 前回のブログで線形回帰モデルの作成・予測をした結果、下記の出力を得ました。 従業員数 モデル予測結果(原材料費) 正解値(原材料費) 476 1344.5283231034557 1564 この結果は果たしてどうなのでしょうか、、?モデルの予測精度はどうなのでしょうか、、? これを今回は計測したいと思います。   モデル評価 BigQuery ML モデルの評価の概要  |  Google Cloud cloud.google.com 作成したモデルの評価は、 「ML.EVALUATE関数」 を用いることで可能です。 選択したモデルタイプによって、他の評価関数を使用することで様々な評価指標を得ることができます。詳細は 公式ドキュメント をご覧ください。 今回はモデルタイプとして線形回帰を選択したので、ML.EVALUATE関数で評価してみます。 下記SQLを実行します。 SELECT * FROM ML.EVALUATE(MODEL `yamaguchi_test_bqml.test_model_liner_reg`,   (   SELECT     IFNULL(cost_manufacturing, 0) AS cost_mf,     IFNULL(cost_material, 0) AS label,     IFNULL(cost_employees, 0) AS cost_emp,     IFNULL(manufacturing_line, 0) AS manu_line,     IFNULL(manufacturing_efficiency, 0) AS manu_eff,     IFNULL(employees, 0) AS emp   FROM     `scsksdv-dev-dais.yamaguchi_test_bqml.test` )); 実行結果 公式ドキュメントを見ると、線形回帰のモデルでは、ML.EVALUATE関数を実行することで下記の指標が得られます。 mean_absolute_error:平均絶対誤差 mean_squared_error:平均二乗誤差 mean_squared_log_error:平均二乗対数誤差 median_absolute_error:絶対誤差の中央値 r2_score:R2スコア explained_variance:説明分散   回帰モデルの評価指標 平均絶対誤差:MAE SCSK AI AutoML 「誰でも」「簡単に」AIを利用できるようにするために、SCSKでは、H2O Driverless AIやLearning Center Forecastなど、データサイエンティストによる機械学習モデル作成を自動化・高速化するソリューションを... www.scsk.jp 平均絶対誤差(MAE)は、各行で[予測値 – 正解値]の絶対値(=絶対誤差)を取り、その平均を出したものです。 以下の式で表されます。 MAEの代表的な特性は下記のとおりです。 0以上の値 小さいほど良い結果となる 外れ値に対して脆弱 今回の結果で言うと、MAE=190くらいなので、 「予測値と正解値が平均して190くらい離れている」 ということになります。 評価で使用したtestテーブルに外れ値を加えてMAEの値を見てみましょう。 21行目に原材料費が外れ値となるようなデータを追加しました。 この状態で再度モデルを評価してみると、 MAEの値がかなり大きくなりました。 このようにたった一つでも 外れ値のデータが入ってしまうと値が大きくなってしまう のがMAEの弱点です。 平均二乗誤差:MSE SCSK AI AutoML 「誰でも」「簡単に」AIを利用できるようにするために、SCSKでは、H2O Driverless AIやLearning Center Forecastなど、データサイエンティストによる機械学習モデル作成を自動化・高速化するソリューションを... www.scsk.jp 平均二乗誤差(MSE)は下記の式で表されます。 先ほどのMAEとかなり似た式ですが、予測値と正解値の差を二乗している点が違いです。 誤差を二乗しているため、より大きな誤差が発生していると値が大きくなります。すなわち、 間違いをより重要視した指標 ということになります。 この指標も 値が小さいほど良い結果 となります。 お気づきの方も多いかもしれないですが、MSEは MAEよりも外れ値に対して脆弱 です。 誤差を二乗しているため、その分外れ値に対しても弱くなってしまうわけですね。 平均二乗対数誤差:MSLE [損失関数/評価関数]平均二乗対数誤差(MSLE:Mean Squared Logarithmic Error)/RMSLE(MSLEの平方根)とは? 用語「平均二乗対数誤差」について説明。損失関数/評価関数の一つで、各データに対して「予測値の対数と正解値の対数との差(=対数誤差)」の二乗値を計算し、その総和をデータ数で割った値(=平均値)を表す。 atmarkit.itmedia.co.jp 平均二乗対数誤差(MSLE)は、各行で 予測値の対数と正解値の対数の差(=対数誤差)の二乗 を計算し、その平均を出したものです。 0に近いほど良い結果 となります。 下記の式で表されます。 数学では、底が同じ対数の引き算は割り算に変換することができます。これに着目すると、上記の式は 「予測値/正解値」 の形に変換することができます。 すなわちMSLEは、 予測値/正解値の比率に着目した指標 であるということが言えます。 比率に着目することで、 誤差が大きくなっても過大に評価しないこと が可能です。 そのため、MAE,MSEの弱点であった、 外れ値への脆弱性をある程度克服した指標 と言えます。 絶対誤差中央値:MedAE [評価関数]中央絶対誤差(MedAE:Median Absolute Error)とは? 用語「中央絶対誤差」について説明。評価関数の一つで、各データに対して「予測値と正解値の差(=誤差)」の絶対値を計算していき、それら全ての計算結果における中央値を表す。 atmarkit.itmedia.co.jp そのまま略すと「MAE」となり平均絶対誤差と混同してしまうので「MedAE」と略すのが一般的のようです。 MedAEは、各行で[予測値 – 正解値]の絶対値(=絶対誤差)を計算し、 小さい順に並べた際の中央値 を出したものです。 下記の式で表されます。 この値も、 0に近いほど良い結果 となります。 決定計数:R2スコア SCSK AI AutoML 「誰でも」「簡単に」AIを利用できるようにするために、SCSKでは、H2O Driverless AIやLearning Center Forecastなど、データサイエンティストによる機械学習モデル作成を自動化・高速化するソリューションを... www.scsk.jp R2スコアは、回帰モデルを評価する際に 「最も直感的な基準」 だと言われています・ これまで説明した指標はすべて誤差を見るものでしたが、ここでやっと モデルの性能(良し悪し) を測ることのできる指標が登場します。 複数のモデルの性能を比較する際にもよく使われる指標で、 モデルがどれだけデータをうまく説明できているか を表現してくれる値です。 テストの点数に置き換えると理解しやすいです。 数学のテストの点数が高い:数学についてよく理解できており、説明できる。 英語のテストの点数が悪い:英語についてよく英買いできておらず、説明できない。 下記の式で表されます。 SSEとSSTについてみていきます。 残差平方和:SSE 各行に対して、 観測値(正解値)と予測値の差 を二乗した値を総和したもの MSE の平均を求めないバージョン 正解値と予測値がどれくらい離れているかを示す 二乗平均:SST 各行に対して、 観測値(正解値)と全観測値の平均との差 を二乗した値を総和したもの 分散 の平均を求めないバージョン 正解データ自体の平均からのばらつき具合を示す これを抑えたうえでr2スコアの公式をもう一度見ると、 予測値に正解データの平均値を用いた ” 単純なモデル ” と ” 作成したモデル ” を比較(前者で後者を割る)する という作りになっていることがわかります。このことから、 r2スコアは非常に単純なモデルと比較した際のパフォーマンスを示している と言えいます。 R2スコアは、 1に近づくほど良い結果 となります。 説明分散:EV [評価関数]分散説明率(Explained variance score)とは? 用語「分散説明率」について説明。線形回帰モデルなどの評価関数の一つで、回帰式のモデルが「観測データの分散」のうちどれくらいの割合を説明するかを表す。決定係数R2の代わりに用いられることがある。 atmarkit.itmedia.co.jp 説明分散(ここではEVと略します。)は、R2スコアと同様にモデルの性能を測ることができる指標です。 正解データの散らばり(分散)のうち、モデルがどのくらいの割合を説明できるか を表現する指標です。 下記の式で表されます。 式のつくりを見ていきますが、視覚的に把握するために図式化します。 オレンジ色:モデル予測できた割合 紺色:モデル予測できなかった(誤差)割合 です。 EV値では上図のオレンジ色の部分を以下の流れで表現します。 EV値は、 1に近づくほど良い結果 となります。   作成したモデルの性能はどうなの? 必要な知識が揃ったところで、今回作成した線形回帰モデルの性能を見てみたいと思います。 R2スコアとEV値を見てみると、 R2スコア:0.568692977058064 EV値:0.58093681298823574 という結果でした。だいたい60点くらいの性能のモデルですね。   まとめ 今回は線形回帰モデルを評価してみました。 複数の指標を組み合わせて評価することが非常に重要だと感じました。 ほとんど指標の説明に費やしてしまいましたが、今後はモデルの性能を向上させるための方法を調べてみたいなと思っています。
こんにちは。SCSKの山口です。 今回はBigQuery MLを使って機械学習モデルの作成、テストをやってみます。 こんな方にオススメの記事です。 ・とにかくBigQuery MLを触ってみたい ・BigQuery MLでモデルを作成してみたい ・BigQuery MLでモデルを使って推論してみたい 筆者はこんな人です。 ・Google Cloud歴:約2年 ・BigQueryのコンソール操作には慣れている ・ SQLが少し書ける ・AI/MLの知識はあまりない 今回のブログでは、BigQuey MLを試すために最低限必要な事項にフォーカスして書きます。 より詳細な概念、知識に関しては後続のブログをお待ちください。 BigQuery ML BigQuery ML とは  |  Google Cloud cloud.google.com まずはBigQuery MLについて紹介します。 BigQuey MLでは、 GoogleSQLクエリ を使用して、 MLモデルの作成と実行 を行うことができます。 BigQuey MLを使用する最大のメリットは、 AI/MLのプログラミング経験が少ないデータアナリストでも、SQLの知識とツールでモデルの構築・評価ができる点 にあるといえます。 大規模なデータセットでAI/MLタスクを実行するには、各フレームワークに対する高度なプログラミング技術と知識が必要になります。 そのため データをよく理解しているアナリスト が、プログラミング経験が少ないばかりにソリューション開発から除外されてきましたが、BigQuey MLはそれを解決してくれます。 BigQuey MLは、下記の方法で使用できます。 Google Cloudコンソール bqコマンドラインツール BigQuery REST API BigQueryに統合されたColab Enterpriseノートブック Jupyter ノートブックやビジネス インテリジェンス プラットフォームなどの外部ツール 今回は、Google Cloudコンソール(BigQuery画面)でBigQuey MLを触ってみます。 また、BigQuery MLでは 下記のモデル が内部でトレーニング済みで、BigQuery MLに組み込まれています。 線形回帰 ロジスティック回帰 K平均法クラスタリング 行列分解 主成分分析(PCA) 時系列 上記以外にも様々なモデルが使用可能です。詳細は こちら の公式ドキュメントをご参照ください。 今回は、 線形回帰 のモデルを使用して予測を行います。   BigQuey ML使ってみた では、さっそく触ってみます。 事前準備 今回は、モデルのトレーニング用とテスト用で二つのテーブルを用意しました。(※同一データは含んでいない) スキーマ情報(2テーブル共通) training:80行 test:20行 モデルを作成し推論するにあたって、下記を決めておきます。 目的変数:予測したいデータ 説明変数:予測するために使用するデータ 今回は 目的変数を「cost_material:原材料費」 とし、 説明変数をその他のカラム とします。 モデル作成・トレーニング 下記SQLを実行して、モデルを作成します。 CREATE OR REPLACE MODEL `yamaguchi_test_bqml.test_model_liner_reg` OPTIONS(model_type='linear_reg') AS SELECT IFNULL(cost_manufacturing, 0) AS cost_mf, IFNULL(cost_material, 0) AS label, --目的変数 IFNULL(cost_employees, 0) AS cost_emp, IFNULL(manufacturing_line, 0) AS manu_line, IFNULL(manufacturing_efficiency, 0) AS manu_eff, IFNULL(employees, 0) AS emp FROM   `yamaguchi_test_bqml.training` ; CREATE MODEL文で簡単にモデルを作成することが可能です。OPTIONS句内で今回使用する線形回帰(linear_reg)を指定しています。 その後のSELECT文によって指定されたデータを使用してモデルをtrainingします。 また、 「cost_material」 に対して、 「label」 というエイリアスを作成することで、 cost_materialが目的変数であること を示しています。CREATE句でinput_label_cols=オプションを使用して目的変数を設定することも可能です。 最後のFROM句でトレーニング用のテーブル「training」を指定しています。 モデル作成が完了すると、エクスプローラ画面の「モデル」配下に作成したモデルが表示されます。 以上でモデルの作成・トレーニングは完了です。 モデルテスト 作成したモデルを使って予測をしてみます。 下記SQLを実行します。 SELECT predicted_label AS predicted_costs FROM ML.PREDICT(MODEL `yamaguchi_test_bqml.test_model_liner_reg`,   (   SELECT     IFNULL(cost_manufacturing, 0) AS cost_mf,     IFNULL(cost_employees, 0) AS cost_emp,     IFNULL(manufacturing_line, 0) AS manu_line,     IFNULL(manufacturing_efficiency, 0) AS manu_eff,     IFNULL(employees, 0) AS emp   FROM     `yamaguchi_test_bqml.test`   WHERE     employees=476 )) ML.PREDICT関数 を使って予測を行います。モデルの出力列名は predicted_<label_column_name> としています。 SELECT句で指定しているpredicted_labelは labelの推定値 になります。 ネストされたSELECT句は、モデル作成のCREATE MODEL句と同じにしていますが、FROM句にはtestテーブルを指定しています。 trainingのデータでモデルを学習させ、testのデータを使って予測の挙動を見る。といった狙いです。今回は、 「従業員数が476人の場合の原材料費」 を予測しています。 予測結果を見てみましょう。 1344.5283 …という予測が得られました。testテーブルの実際のデータを比較してみると、 、、、、何とも言えない結果ですね。。 とはいえ、そこまでかけ離れている数値ではないです。 予測の精度が良くない原因として、そもそも学習に使用するデータ量が少ない点がまず考えられます。 それ以外にもモデルを学習させる際に、CREATE句のOPTION内で様々な設定をし、予測精度を上げることも可能です。ここについては後続のブログで書きたいと思います。   まとめ 今回は、BigQuery MLを使ってモデルを作成し、実際に予測をしてみました。 今回は 公式ドキュメント に沿って実践を進めたのですが、「モデルの評価」については本ブログでは触れませんでした。(長くなりそうだったので。) 今回作成したモデルの評価結果を先出しておきます。 こんな感じです。初めて見る評価指標がズラリと並んでいたので、この辺りは別のブログで深堀していきます。
こんにちは。SCSK 中山です。 少し前に発表のあったDevice Postureのアップデートでプロファイルでレジストリキーの値や稼働しているプロセスを条件として設定できるようになりました。 弊社アカウントにもアップデートが適用されましたので、今回は設定・動作検証をしてみたいと思います。 と、その前に、、 Device Postureという機能を軽く説明しておきます。 Device Postureとは Device Postureとは、端末の状態をチェックし属性を付与する機能です。付与した属性に対してポリシーを設定することで、要件を満たさない端末をネットワークへ接続させないといったコントロールが可能になります。 詳細については、別途記事を書いておりますので、こちらをご覧ください。 CatoクラウドでDevice Postureを利用したい Device Postureの簡単な設定例と動作検証結果をご紹介します。 blog.usize-tech.com 2024.05.17 Device Postureは設定できる条件がいくつかあり、よく使われるところだとクライアントのセキュリティソフトのインストール有無、セキュリティソフトのバージョンのチェックがありますが、今回のアップデートでは条件として端末のレジストリキーの値や指定したプロセスが稼働しているかが指定できるようになったという感じです。 合わせてこの記事では触れてませんが、MacOS向けに「Property List」での指定も追加されております。 詳しくはCatoのナレッジをご確認ください。対応OS/Cato Clientのバージョンも記載されております。 Creating Device Posture Profiles and Device Checks   それでは早速設定・検証をしていきたいと思います。 実施手順 レジストリキーの設定 ① CMAから、「Access」 >「 Device Posture」>「Device Checks」の「New」から新規のポリシーを作成します。 ②「General」>「Device Test Type」で「Registry Key」を選択します。 ③ 「Criteria」にポリシーの内容を記載します。 OS:Windows Registry Key Path:<設定したいレジストリーのパス> Key Value Name:<設定したいレジストリキーの名前> Key Value Data:<設定したいレジストリキーの値> イメージとしては、「Registry Key Path」と「Key Value Name」でレジストリキーのフルパスを作る感じです。 例えば、以下画像のレジストリキー(HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU\NoAutoUpdate)の値で条件を作成したい場合、CMA側の設定はこんな感じになります。 ◆レジストリエディターの画面 ◆CMAの設定画面 レジストリキーに何かしら値が入っていたら、、、という条件の場合は「Key Value Data」で「Any Value」を選択してください。   ④ ポリシーを作成できたら、「Device Posture Profiles」より、新規でプロファイルを作成し、③で作成したポリシーを紐づけます。   プロセスの設定 ① レジストリキーの設定と同様に新規ポリシーを作成します。 ②「General」>「Device Test Type」で「Running Process」を選択します。   ③「Criteria」にポリシーの内容を記載します。(以下設定はWindowsの場合) OS:Windows Process Name or path:<設定したいプロセスのフルパス or プロセス名> Signer Certificate Thumbprint:<証明書の拇印> 以下は検証の際にAWSのssm-agentで設定した際のCMAの画面です。 プロセス名、拇印の確認方法 ・ プロセス名 「タスクマネージャー」よりプロセスの「プロパティ」を開くことで確認できます。 フルパスで指定したい場合には、同じようにプロパティ画面から確認できます。 CMAには 場所+プロセス名+ファイルの種類で記載すれば設定できます。 上記の場合、「C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe」と指定する感じです。 サービスとして稼働している場合には、各サービスのプロパティ画面から直接フルパスを確認できます。   ・ 証明書の拇印の確認方法 ① プロセス名の確認手順と同様にタスクマネージャからプロセスのプロパティを開きます。 ② 「デジタル署名」タブを開き、署名を選択し、詳細を開きます。 ③「証明書の表示」し、証明書の「詳細タブ」を開きます。 詳細の中に「拇印」という項目があるので、その値をCMAの「Signer Certificate Thumbprint」に記載します。 Device Postureの設定自体はこれで完了です。 「Client Connectivity Policy」や「 Internet Firewall」、「WAN Firewall」で 作成したプロファイルを指定することで、対象のデバイスをコントロールすることができます。   実際にやってみた レジストリキーを指定する場合、プロセスを指定する場合、どちらも検証してみました。 レジストリキーはWindows Updateを無効化しているデバイスをCatoに接続できなくするような設定で検証してみました。 CMAの各設定はこんな感じです。 ◆ Device Checks 「Default」はレジストリエディター上で(規定)となっている箇所の時に使用します。 ◆ Device Posture Profile ◆ Client Connectivity Policy 今回設定しているレジストリキーはWindows Updateの自動更新を有効にする場合は「0」、自動更新を無効にする場合は「1」を設定するような項目になっていて、このポリシーでは自動更新が有効の場合、ポリシー1が適用されCatoに接続できますが、自動更新が無効の場合はポリシー2が適用され、接続できなくするような設定になってます。 クライアント側のレジストリキーはこんな感じで設定しました。 値を1にして自動更新を無効にしてます。 これでいざCato Clientの接続を試みると、、 エラーが出て接続できませんでした。 こんな感じでWindows Updateを無効化している端末をCatoに接続できないようにできました。 次にプロセスを指定する場合を検証しました。 操作ログ取得系のアプリがバックグラウンドで動いているイメージで、そのアプリを停止させるとCatoに接続できなくするような想定で検証しようと思いましたが、操作ログ取得系のアプリが検証環境になかったので、適当にバックグラウンドで動いているアプリを指定して検証しました。 CMAの各設定はこんな感じです。 ◆ Device Checks ◆ Client Connectivity Policy ◆ Client Connectivity Policy 基本的にはレジストリと同様でプロセスが稼働中はポリシー1が適用され、プロセスが停止中の場合はポリシー2が適用され接続できないような設定になってます。   クライアント側のプロセス稼働状況はこんな感じです。 設定した「amazon-ssm-agent」が稼働しております。 この状態で接続をすると、、 プロセス稼働中はもちろん接続はできます。   Catoに接続した状態のまま、「amazon-ssm-agent」のプロセスを停止して放置します。 ~5分後~ 接続が切れてしまい、再接続もできなくなりました。 本環境では、Device Postureのチェック間隔を5分にしていたため、検証では再チェックのタイミングで接続が切れました。 このように定期的にチェックが入るため、接続時のみプロセス稼働させておき、接続後にプロセスを落とすということはできないようになってます。 また、上記含めて「Client Connectivity Policy」でCatoに接続させるか否かを制御しておりますが、 Internet Firewall、WAN Firewallで もDevice Postureの設定を使った制御も可能です。 一応こんな感じです。 ◆ インターネットFW 「Action」部分を載せてませんが、「BLOCK」に設定していて、「Device Posture Profiles」の条件に該当する通信は全拒否するようにしてます。Profileは先程のプロセスで検証したものと同様。 ◆Cato Client 「Client Connectivity Policy」で制御していないので、Cato自体への接続はできてます。 Catoに接続 かつ 「amazon-ssm-agent」のプロセスが稼働している状態でインターネットにアクセスしようとすると、、 今回は条件該当する場合に通信をBLOCKするので、アクセスができないようになってます。   もちろんプロセスを止めると、条件に当てはまらないので、通常通りインターネットにアクセスすることができました。   余談ですが、ふと思いつきで複数ユーザでログインした状態でプロセスの判定を検証したところ、片方のユーザがプロセス起動している状態であれば、もう一方のユーザはプロセスを立ち上げてなくても、Catoに繋げてしまったので、”Device Posture”というだけあって、Catoに接続しようとしているユーザのプロセスだけではなく、端末全体のプロセスを見ているっぽいです。 誰かしらプロセスを立ち上げていればすり抜けられちゃうみたいなので、ユーザ単位で起動しているプロセスを条件に指定する場合には、注意が必要そうです。   ユースケースを考えてみた レジストリ/プロセスを指定して制御するユースケースを考えてみたいと思います。   まず、レジストリから。 レジストリは設定できる内容が多いため、できることはたくさんあると思います。 私が知っているレジストリの知識の範囲で例を挙げてみたいと思います。 まずは検証のようにWindows Updateを無効にしている端末の接続を不可にする場合ですかね。 パッチ管理ソフトでの制御をしている場合は不要かと思いますが、パッチ管理ソフトを導入していない場合、ルールは決めていてもなかなか強制はできず、セキュリティ基準を満たしていないPCが接続してしまう可能性があります。このような端末をレジストリで条件指定することによって、社内NWに接続できないようにできるのかなと思います。 パッチ回りだと適用されているセキュリティパッチを指すレジストリキーがありそうなので、そのキーを条件指定することで、セキュリティパッチを適用していないをCatoに接続させないということができそうかなと思ったのですが、毎回KB○○に新規で作成されるみたいで、毎月条件を変更するといった運用が必要そうなので、やろうと思えばできそうですが、運用を踏まえると現実的ではなさそうです。 他だと会社から支給されたPCに何かしらのフラグが設定されていたりしたら、会社PC or 個人PCとで識別できますかね。Cato Clientは正規のユーザであればログインできてしまうので、個人のPCにClientを入れてCatoから社内NWに接続できてしまいます。これに対し、フラグにあたるレジストリキーを条件にすることで、会社PCのみCatoに接続でき、個人PCは接続させないとかができそうです。   次にプロセス。 こちらも検証でやろうとしていた管理系のアプリ/プロセスを条件にして操作ログの取得できない端末は社内NWに接続させないとかは結構有用な気がします。 あとは、アンチウイルスソフトのプロセスを指定するとかもありな気がします。従来の設定でもアンチウイルスソフトを設定する方法がありましたが、あくまでインストールされているか、バージョンはポリシーを満たしているかをチェックしているだけで、実際に起動しているかを条件にしているものではないです。なので、社内ルールに則りインストールはしていても、実際にはアプリを止めているとかもできてしますので、プロセスの方で条件するのも良いかもです。 ただ、プロセス全般に言えることかもですが、バージョンアップ等でプロセス名が変わってしまうと設定変更が必要なので、注意が必要かもです。アップデートごとに検証をするという運用もセットかもですね。   まとめ 今回はアップデートで追加されたDevice Postureのレジストリキー/プロセスの指定での制御を検証してみました。 レジストリキー/プロセスを条件を指定できることになり、設定にあたりOSの知識も必要になってきましたが、今までの条件より比較的柔軟にデバイス制御ができるようになったかと思います。これまでにデバイス制御を断念したことがある方も今回のアップデートを機に再検討してみては如何でしょうか。  
本記事は 夏休みクラウド自由研究 8/31付の記事です 。 こんにちは、SCSK木澤です。 8/1から始まった夏休みクラウド自由研究も今回で最終回となりました。 今回の企画は幅広いクラウドやソリューションを担当する31名の執筆者にご協力いただき、無事完走することが出来ました。 TechHarmonyは 今春に500記事を超え 、その後も順調に記事数を増やしています。 今後も色々な企画を考えていきたいと思いますので、どうぞ引き続きご愛顧の程よろしくお願いします。 さて今回は自由研究らしく、普段とは違う話題としてAWS Lambdaのファイルシステムについて調査してみました。 きっかけ 私が本件に興味を持ったのは、5年前に携わった案件に遡ります。 管理しているEC2インスタンスに配布する設定ファイル一式についてユーザー毎/インスタンス毎にカスタマイズする必要があり、調査の上、 Lambdaのファイルシステム上で処理してS3に出力することが適切 と判断して実装しました。 S3バケットからzipファイルをダウンロードしてzip解凍 設定ファイルを書き換え 再度zip圧縮して、S3バケットに書き込み サーバレスコンピューティングとはいえ、実態としてはサーバーがあるんだなと興味深く当時は思った次第です。 そのあたりをもう少し詳細にお話していきます。   動作仕様 Lambdaの動作原理 理解を深めるためにも、Lambdaの動作原理についてから触れたいと思います。 とはいえJAWS DAYS 2022でのAWS(当時)の亀田さんの講演がとても解りやすく私の印象に強く残っているので、こちらから紹介します。 AWS Lambdaは2014年のre:Inventで発表されたものとなりますが、当時はユーザー毎に内部にEC2インスタンスを持つ構成でした。 その後Lambdaの実行に特化した構成としてNitroシステムとFirecrackerが導入され、より強固なアイソレーション(環境分離)と高速・多数の起動環境を実現しています。 実は私はAWSを担当する前に自社クラウドに携わっていたため強く思うのですが、AWS Lambdaのリリース当初はEC2ベース+コンテナの技術レベルであったにも関わらず、お客様(ディベロッパー)にとってあるべき姿を定義し、あるべき価格で(赤字でも?)提供する、そしてその後改善・解決していくという姿はThink BigでありCustomer Obesessionでもあるので感銘を受けたのを覚えています。 話が長くなったので戻しますが、現在AWS LambdaはNitroシステム+Firecrackerで提供されています。 つまり Lambdaも小さい仮想サーバー(microVM) という訳です。 よって、当然ながらファイルシステムもあります。 クオータ(制限)についてはこちらをご覧下さい。 Lambda クォータ - AWS Lambda Lambda 関数および API リクエストに関する最大サイズ、制限、およびクォータです。 docs.aws.amazon.com ユーザーがLambdaにアタッチできるローカルファイルシステムは、 /tmp にマウントされ512MB~10240MBの間で設定可能 です。 ウォームスタートとコールドスタート Lambdaのローカルファイルシステムについて触れる際に、この話は避けて通れません。 Lambdaを起動した際にmicroVMを作成される訳ですが、どうしてもこの 初期化作業には一定の時間が掛かります(コールドスタート) 。そのため、 もし再利用できるmicroVMがあれば再利用 してスピードアップするよう動作します (ウォームスタート) 参考:AWS Blackbelt AWS Lambda(p60あたりから) https://pages.awscloud.com/rs/112-TZM-766/images/20190402_AWSBlackbelt_AWSLambda%20Part1&2.pdf この 再利用(ウォームスタート)が発生した際は、前の実行時のファイルがユーザーファイルシステムに残ったまま になっています。 ファイル処理を行った際にファイル重複でエラーになる可能性があるのでご注意ください。 実行開始時に一旦すべて削除するか、例外処理を入れる必要があるでしょう。   調査 さて、ファイルシステムの詳細を調べてみたいと思います。 容量・パーミッションの確認 デフォルトの設定でLambdaを作成し、以下のコードで実行してみます。 PythonのOSライブラリでOSコマンドを実行しています。 import json import os def lambda_handler(event, context): # 実行ユーザーを確認 print("--user") print(os.system("whoami")) # ディスク容量を確認 print("--disk capacity") print(os.system("df -h")) # マウント状態を確認 print("--mount") print(os.system("cat /etc/fstab")) # パーミッションの確認 print("--permisson /") print(os.system("ls -al /")) print("--permisson /tmp") print(os.system("ls -al /tmp")) # 書き込み print("--write /") print(os.system("touch /test1.txt")) print(os.system("ls -al /")) print("--write /tmp") print(os.system("touch /tmp/test2.txt")) print(os.system("ls -al /tmp")) return { 'statusCode': 200, 'body': '' } 実行結果を確認します 実行ユーザー --user sbx_user1051 当然ながら一般ユーザー権限でユーザープロセスは実行されています ディスク容量、マウント状態 --disk capacity Filesystem Size Used Avail Use% Mounted on /dev/vde 144G 143G 0 100% / /dev/vdb 1.5G 18M 1.4G 2% /etc/hosts tmpfs 64M 0 64M 0% /dev /dev/vdd 525M 8.0K 514M 1% /tmp /dev/root 9.7G 386M 9.3G 4% /etc/passwd /dev/vdc 128K 128K 0 100% /var/task --mount # LABEL=/ / auto defaults,noatime 1 1 /tmpはユーザー設定により容量が変わるので、別ディスクとしてマウントされています 。 ルートディスクはリードオンリーではないですが、書き込み不可となっています。 パーミッション --permisson / total 116 drwxr-xr-x 18 root root 4096 Jul 31 08:47 . drwxr-xr-x 18 root root 4096 Jul 31 08:47 .. -rw-r--r-- 1 root root 48222 Jul 31 22:38 THIRD-PARTY-LICENSES.txt lrwxrwxrwx 1 root root 7 Jan 30 2023 bin -> usr/bin dr-xr-xr-x 2 root root 4096 Jan 30 2023 boot drwxr-xr-x 2 root root 200 Aug 30 00:50 dev drwxr-xr-x 34 root root 4096 May 10 11:16 etc drwxr-xr-x 2 root root 4096 Jan 30 2023 home -rwxr-xr-x 1 root root 397 Jul 31 15:59 lambda-entrypoint.sh lrwxrwxrwx 1 root root 7 Jan 30 2023 lib -> usr/lib lrwxrwxrwx 1 root root 9 Jan 30 2023 lib64 -> usr/lib64 drwxr-xr-x 2 root root 4096 Apr 25 19:25 local drwxr-xr-x 2 root root 4096 Jan 30 2023 media drwxr-xr-x 2 root root 4096 Jan 30 2023 mnt drwxr-xr-x 2 root root 4096 Jan 30 2023 opt dr-xr-xr-x 123 root root 0 Aug 30 01:40 proc dr-xr-x--- 2 root root 4096 Jan 30 2023 root drwxr-xr-x 5 root root 4096 Apr 25 19:25 run lrwxrwxrwx 1 root root 8 Jan 30 2023 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Jan 30 2023 srv drwxr-xr-x 2 root root 4096 Apr 25 19:25 sys drwxrwxrwx 2 root root 4096 Aug 5 15:36 tmp drwxr-xr-x 12 root root 4096 Jul 31 08:47 usr drwxr-xr-x 24 root root 4096 May 9 21:46 var /tmpは権限777のため、一般ユーザーでも書き込み可能です。 ファイル書き込みの確認 --write / touch: cannot touch '/test1.txt': Read-only file system 当然ながらルートディスクは書き込み不可です。 --write /tmp total 8 drwxrwxrwx 2 root root 4096 Aug 30 01:40 . drwxr-xr-x 18 root root 4096 Jul 31 08:47 .. -rw-r--r-- 1 sbx_user1051 990 0 Aug 30 01:40 test2.txt /tmpには書き込み可能です。 ファイル入出力速度の調査 さて、ローカルファイルシステム(/tmp)には何も保存されていない訳ですし、データは永続化できません。 よって、 S3バケットなどからダウンロードしてきてから処理を行う必要があります 。 ファイルの入出力時間が気になるので、確認してみます。 S3バケットを作成して、CloudShellから1GBのファイルを作成して保存します。 $ dd if=/dev/zero of=1gb.dat bs=1024k count=1024 $ aws s3 cp 1gb.dat s3://S3バケット名/ 以下のようなコードでLambda関数を作成します。 import json import boto3 import os bucketname = "S3バケット名" def lambda_handler(event, context): s3r = boto3.resource('s3') # /tmp削除 print("--delete") print(os.system("rm -rf /tmp/*")) # コピー data_bucket = s3r.Bucket(bucketname) print("--copy from S3 Bucket Start") data_bucket.download_file('1gb.dat','/tmp/1gb.dat') print("--copy from S3 Bucket End") return { 'statusCode': 200, 'body': '' } S3にアクセスできるLambda用IAMロールを作成し、本関数に適用します。 ディスク容量は増やしておきます。 EC2インスタンスと同様、Lambdaにおいてもメモリ容量とCPUスペックは比例するように設計されています。 そこで、メモリ容量≒CPU割り当てとS3からの読み取り速度を調べたところ、以下の通りになりました。(3回平均、CloudWatch Logsに出力されたログのタイムスタンプから算定) Lambdaメモリ割当量 ダウンロード時間 速度 128MB 74.2秒 110Mbps 256MB 40.4秒 203Mbps 512MB 19.4秒 422Mbps 1024MB 10.7秒 768Mbps 2048MB 10.4秒 785Mbps メモリ割り当てに比例してネットワークI/O帯域も拡張されること、但し(S3バケットからのダウンロードにおいては)800Mbps弱で頭打ちになる ことを確認しました。 つまり、/tmpの最大容量10GBのダウンロードもしくはアップロードを行うには、最低100秒程度の時間が掛かることになります。 この辺りがローカルディスクを用いた処理の限界であるであろうことが解りました。 要件満たさない場合はEFS利用 10GBを超える 大容量ファイルを扱いたい場合、あるいは永続ファイルをマウントしたい場合はAmazon EFSの利用が可能 です。 なお、Amazon EFSはVPC上のサービスですので、LambdaもVPCアタッチが必要となります。   まとめ 実に地味な内容でしたが、Lambdaのファイルシステムについて解説・確認しました。 ネットワーク帯域にも変動があることなど、新たな発見があり楽しかったですね。 Lambdaのローカルファイルシステム(/tmp)は非永続ということもあり、ディスク容量は課金には影響しません。 色々使いこなすと楽しいので、皆様もご活用下さい!
本記事は 夏休みクラウド自由研究 8/30付の記事です 。 こんにちは、SCSKの松岡です。 今回は、Snowflakeをこれから利用する方向けに、環境構築で最低限抑えておきたいポイントをぎゅっと絞ってご紹介します。Snowflakeのアカウントは作ったけど何から始めよう…とお悩みの方はぜひご参考ください! Snowflakeとは Snowflake (Snowflake Cloud Data Platform)は、Snowflake社が提供するSaaS型のクラウドデータプラットフォームです。 データ管理、セキュリティ、ガバナンス、可用性、データレジリエンスをサポートしたフルマネージド型のサービスであり、ウェアハウスのスケーリング/ポリシー制御/データ共有の柔軟性などから、デジタルデータの一元管理に優れたプラットフォームとして注目を集めています。 プラットフォームの概要 Snowflakeのクラウドデータプラットフォームが世界的に、あらゆる規模、あらゆる業界において、をほぼ無制限の同時実行ワークロードで強化した方法をご紹介します。 www.snowflake.com   利用する前に…… エディション Snowflakeでは、4つのエディションが用意されており、利用するアカウントがどのエディションかによって、一部できることが異なります。 (例)Time Travelによるデータの保管期間の90日延長はEnterprise以上のエディションのみ (例)PrivateLinkを使用したプライベート接続のサポートはBusiness Critical以上のエディションのみ Snowflakeは従量課金制ですが、上位のエディションほど利用あたりの単価が高い点にも注意が必要です。 Snowflake Edition | Snowflake Documentation docs.snowflake.com 言語設定 Snowsight(Snowflakeを操作するウェブ画面)のデフォルト表示は英語ですが、アイコンから「My profile」を選択し、Languageで「日本語」を選択することで日本語表示に切り替わります。 システムロール Snowflakeでは、「ロール」と呼ばれる単位でアクセス制御や権限管理を行います。 ユーザーには複数のロールを割り当てることができ、操作を行う際は、その操作ごとにロールを切り替えて(適切なアクティブロールを選択して)から実行を行います。 あらかじめ定義されたロールとして、以下のようなシステムロールが存在しています。 ACCOUNTADMIN アカウント内で最上位のロール。 アカウント管理者に限定して付与し、アカウント全体に関わる設定等をする際に使用します。 SECURITYADMIN セキュリティ管理用のロール。 ユーザーとロールの作成や、ロールの割り当て等が可能です。 USERADMIN ユーザーとロールの管理専用のロール。 SECURITYADMINと同じくユーザーとロールの作成が可能ですが、限定的です。 SYSADMIN ウェアハウスやデータベース、スキーマのようなオブジェクトを作成する権限を持つロール。 PUBLIC アカウント内のすべてのユーザー、ロールにデフォルトで付与されるロール セキュリティや誤操作防止の観点から、付与するロール、指定するロールはなるべく最小権限のものが望ましいです。 最初の時点では、アカウント全体の設定はACCOUNTADMIN、ユーザーの作成はUSERADMIN、ロールの作成・割り当てはUSERADMINかSECURITYADMIN、オブジェクト(データベース・スキーマ・ウェアハウス)の作成はSYSADMINと覚えておくと良いでしょう。 アクセス制御の概要 | Snowflake Documentation docs.snowflake.com Snowsightでは、以下の箇所でロールの切替を行えます。 (GUIで操作する場合) アイコンから「ロールを切り替え」を選択 (クエリを実行する場合) ワークシートの画面右上からロールを選択 Snowsightでは[プロジェクト]>[ワークシート]からワークシートを開くことで、ブラウザ上でSQLクエリの実行が可能です。   環境構築最初にやること集 最低限のパラメータ設定で作成する手順を紹介します。 ユーザー作成 利用者ごとにユーザーを作成しましょう。 GUIで作成 [管理者]>[ユーザーとロール]>[ユーザー]画面から、[+ ユーザー]を選択し、必要情報を入力して作成します。 クエリで作成 (サンプル) --user_001という名前でユーザー作成 CREATE USER user_001   PASSWORD = '[パスワード]'    EMAIL = "[メールアドレス]"    MUST_CHANGE_PASSWORD = TRUE    DISPLAY_NAME = "[表示名]" ; [MUST_CHANGE_PASSWORD]をTRUEにすることで、初回ログイン時にパスワード変更を強制させることができます。 CREATE USER | Snowflake Documentation docs.snowflake.com ユーザーを作成したら、アイコンの[自分のプロファイル]から多要素認証(MFA)を登録してもらいましょう。 特に管理者(ACCOUNTADMIN)ロールを持つユーザーについては設定が強く推奨されています。 多要素認証(MFA) | Snowflake Documentation docs.snowflake.com ウェアハウス作成 ウェアハウスは、クエリの処理時に使用されるコンピューティングリソースです。 データベース・スキーマのようなストレージ領域がコンピューティングリソースと分離しているのがSnowflakeの大きな特徴の一つです。 仮想ウェアハウス | Snowflake Documentation docs.snowflake.com GUIで作成 [管理者]>[ウェアハウス] 画面から、[+ ウェアハウス]を選択し、ウェアハウス名を入力して作成します。 Snowflakeではウェアハウスの稼働時間が長いほど多くの費用が発生するので、ウェアハウスの自動一時停止を有効にしておくことでコスト削減につながります。 クエリで作成 (サンプル) --wh_001という名前でウェアハウス作成 CREATE WAREHOUSE wh_001 WAREHOUSE_SIZE = XSMALL AUTO_SUSPEND = 60 ; 作成時に[WAREHOUSE_SIZE]でウェアハウスのサイズを指定します。お試し用途であれば、一番小さいXSMALLサイズで問題ないでしょう。 [AUTO_SUSPEND]の値が自動一時停止されるまでの秒数を表しますが、デフォルトの600より短い60に変更することで、利用していない場合はより素早く一時停止されます。(※60未満の値は非推奨) CREATE WAREHOUSE | Snowflake Documentation docs.snowflake.com   データベース・スキーマ作成 Snowflakeでは、データを格納するためにテーブルが必要ですが、そのテーブルの格納先としてデータベース、スキーマが必要です。 GUIで作成 [データ]>[データベース] 画面から、[+ データベース]を選択し、データベース名を入力して作成します。 スキーマは作成したデータベースの画面から、[+ スキーマ]を選択して作成します。 クエリで作成 (サンプル) --db_001という名前でデータベース作成 CREATE DATABASE db_001; --schema_001という名前で、db_001にスキーマ作成 CREATE SCHEMA db_001.schema_001; データベース、スキーマともに、通常利用であれば特別なパラメータの指定は必要なく簡単に作成ができます。 CREATE DATABASE | Snowflake Documentation docs.snowflake.com CREATE SCHEMA | Snowflake Documentation docs.snowflake.com   ロール作成・付与 序盤にシステムロールを紹介しましたが、独自のロールを作成してユーザーに権限付与することも可能です。 例として、特定のDB、特定のウェアハウスのみに対して一般的な操作限定で行えるロールを作成してみます。 クエリで作成 (サンプル) --sample_role_001という名前でロールの作成 CREATE ROLE sample_role_001; --sample_role_001ロールにUSAGE権限付与 GRANT USAGE ON DATABASE db_001 TO ROLE sample_role_001; GRANT USAGE ON SCHEMA db_001.schema_001 TO ROLE sample_role_001; GRANT USAGE ON WAREHOUSE wh_001 TO ROLE sample_role_001; --sample_role_001ロールにテーブル、ビューのCREATE権限付与 GRANT CREATE TABLE, CREATE VIEW ON SCHEMA db_001.schema_001 TO ROLE sample_role_001; --sample_role_001ロールにテーブル、ビューの操作権限付与 GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON ALL TABLES IN SCHEMA db_001.schema_001 TO ROLE sample_role_001; GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON FUTURE TABLES IN SCHEMA db_001.schema_001 TO ROLE sample_role_001; GRANT SELECT ON ALL VIEWS IN SCHEMA db_001.schema_001 TO ROLE sample_role_001; GRANT SELECT ON FUTURE VIEWS IN SCHEMA db_001.schema_001 TO ROLE sample_role_001; --user_001ユーザーにample_role_001ロールを付与 GRANT ROLE sample_role_001 TO USER user_001; sample_role_001という名前のロールを作成し、ロールに対して権限を付与し、そのロールを特定のユーザーuser_001に付与してみました。 ロールに付与している権限の中で、「USAGE」は使用権になります。使用できるようにしたいデータベース、スキーマ、ウェアハウスに対して、このUSAGE権限をそれぞれ付与する必要があります。 続けて、ロールに対し、スキーマschema_001に限定してテーブル・ビューのcreate権限や操作権限を付与しています。 テーブルやビューを指定する際に、「ALL TABLES」や「ALL VIEWS」のような指定は、既存のテーブルやビューすべてを対象に権限を付与することを意味します。一方で「FUTURE TABLES」や「FUTURE VIEWS」のような指定は、これから作成されるテーブルやビューに対して権限を付与することを意味します。 「ALL TABLES」で指定しただけでは、新規で作成したテーブルに対して権限が付与されないことに注意が必要です。 最後に、GRANT ROLE でユーザーに対して作成したロールを付与することで、付与した特定のユーザーに対してカスタマイズした権限のみを付与することが可能です。 GRANT <権限> | Snowflake Documentation docs.snowflake.com   ネットワークポリシー設定 Snowflakeでは、ネットワークポリシーを設定し、Snowflakeに接続できるIPアドレスを制限することが推奨されています。例として、IPアドレス範囲を指定して、許可したIPアドレスのみ接続できるようにする設定を示します。 クエリで設定 (サンプル) USE ROLE SYSADMIN; --Network Rules設定用のデータベース・スキーマを作成 CREATE DATABASE securitydb; CREATE SCHEMA securitydb.networkrules; USE ROLE ACCOUNTADMIN; --network_rule_sampleという名前でネットワークルールを作成 CREATE NETWORK RULE network_rule_sample MODE = INGRESS TYPE = IPV4 VALUE_LIST = ('47.88.25.32/27') ; --network_policy_sampleという名前でネットワークポリシーを作成し、network_rule_sampleを許可 CREATE NETWORK POLICY network_policy_sample ALLOWED_NETWORK_RULE_LIST = ('network_rule_sample') ; --作成したネットワークポリシーをアカウント全体に適用 ALTER ACCOUNT SET NETWORK_POLICY = network_policy_sample; ネットワークルールはスキーマオブジェクトなので、作成時にデータベース、スキーマを指定する必要があります。 上記を実行することにより、Snowflakeアカウント全体が、 47.88.25.32/27 のIPアドレス範囲からの接続しか許可されなくなります。 ネットワークルールを複数作成することで、許可する条件をOR条件で複数設定することや、ネットワークポリシーをアカウント全体でなくユーザーごとに別々に適用することも可能です。 アカウント全体に適用する際は、設定誤りに注意しましょう。 適用後、サインアウトする前に別ブラウザを立ち上げる等して接続できるかどうかの動作を確認しておくと安心です。設定誤りがある場合は、  ALTER ACCOUNT UNSET NETWORK_POLICY; を実行することでネットワークポリシーを無効化できます。   ネットワークポリシーを使用したネットワークトラフィックの制御 | Snowflake Documentation docs.snowflake.com   タイムゾーンの変更 Snowflakeでは、デフォルトのタイムゾーンがAmerica/Los_Angelesに設定されています。 アカウント全体でデフォルトのタイムゾーンを日本標準時に変更する場合は、以下のようにアカウントパラメータの値を変更します。 --タイムゾーンを日本標準時に変更 ALTER ACCOUNT SET TIMEZONE = 'Asia/Tokyo';   パラメーター管理 | Snowflake Documentation docs.snowflake.com   リソースモニター リソースモニターを利用することで、Snowflakeアカウント内でのクレジット(リソース使用量)の状況を監視することができます。 リソースモニターによる設定は、新規の場合は[管理者]>[コスト管理]>リソースモニター 画面から、[+ リソースモニター]を選択します。 リソースモニターによる監視は、[モニタータイプ]から、アカウント全体の監視か、ウェアハウス個別の監視かを指定できます。 [クレジットクォータ]で、指定した期間で許可するクレジットの上限を設定します。そして、指定したクレジットクォータに対して実際の使用が何%に達したかに応じて、[アクション]で、通知や即時一時停止といった内容を設定することが可能です。 作成したリソースモニターの通知を受け取りたい場合は、ACCOUNTADMIN権限を持つユーザーのアイコンの[自分のプロファイル]を選択し、「リソースモニターからのメール通知」にチェックが入っていることを確認しましょう。 リソースモニターの操作 | Snowflake Documentation docs.snowflake.com   最後に Snowflakeでは公式のガイドやブログ記事が充実しており、構築に関するヒントやベストプラクティスの記載をたくさん見つけられるので要チェックです。 環境が用意できたら、どんどんデータを投入して活用してみましょう! ガイド - Snowflakeドキュメント docs.snowflake.com Inside the AI Data Cloud From technical articles about AI and application strategies to real-world success stories, the Snowflake Blog explores w... www.snowflake.com
Prisma Cloudにおけるアラートとは、Prisma Cloudがクラウド環境内で検知したセキュリティリスクや脆弱性等を通知するための機能です。アラートが発生した後、適切な対応を取りシステムのセキュリティを維持することが重要です。 Prisma Cloudで検知されたアラートに対して取ることができるアクションにはアラートの解除や一時停止等があります。アラートに対して取ることができる主なアクションについて解説していきたいと思います。 アラートの解決 クラウド側で設定を修正した場合やアラートが発生した対象のリソースが削除された場合等、これらの変更がなされると該当のアラートは自動的に「resolved」(解決済)というステータスに更新されます。   アラートの一時停止 アラートの一時停止は、アラート対応を一時的に保留したい場合や特定の期間中にアラートを無視したい場合等に使用します。この機能により、特定の時間枠内でのアラート通知を抑制することが可能です。 ユースケース メンテナンス期間中: メンテナンス作業中に一時的に発生するアラートを抑制したい場合 テスト中: テスト中に特定のアラートを抑制したい場合 等 設定方法 1.PrismaCloudコンソールにログインします。 2.「アラート」セクションに移動し、対象のアラートを選択します。   3.「一時停止」をクリック → 一時停止の期間や理由を入力し、「Snooze」をクリックします。今回は「まで」を選択し「2024年7月25日木曜日 18:10」までアラートを一時停止することにします。 アラートの最低一時停止時間は1時間です。1時間より短い時間を指定することはできません。 ↓   4.画面右上に「アラートは正常にスヌーズされました。」ポップアップが表示され、対象のアラートは表示されなくなりました。   5.フィルタの「アラートステータス」で「スヌーズ中」を選択してみると対象アラートの「アラートステータス」がsnoozedになっていることが確認できました。   6.「2024年7月25日木曜日 18:10」以降に確認すると、対象アラートの「アラートステータス」がopenに戻っていることを確認できました。(ちなみに、同日18:12時点ではまだ「アラートステータス」がsnoozedでしたが、18:30頃には「アラートステータス」がopenに戻っていました。)   アラートの解除 アラートの解除は、アラートの原因となった設定は意図した設定であり問題なしと判断した場合等に行います。この操作によりアラートは消え、再び同じインシデントが発生しない限り表示されなくなります。 ユースケース テスト環境のアラート解除: テスト環境で発生したアラートであるため解除したい場合 等 設定方法 1.Prisma Cloud コンソールにログインします。 2.「アラート」セクションに移動し、対象のアラートを選択します。   3.「解除」をクリック → 理由を記載して「Dismiss」をクリックします。 ↓     4.画面右上に「アラートは正常に解除されました。」ポップアップが表示され、対象のアラートは表示されなくなりました。   5.フィルタの「アラートステータス」で「解除済」を選択してみると対象アラートの「アラートステータス」がdismissedになっていることが確認できました。   アラートの再オープン アラートの再オープンは、一度解決されたアラートが再び問題となる場合や新たな関連リスクが確認された場合等に使用します。この機能は、アラートのライフサイクルを追跡しやすくし、継続的なセキュリティ監視を可能にします。 ユースケース 問題が再発した場合: 過去に解決したセキュリティ問題が再び発生した場合 等 設定方法 1.Prisma Cloud コンソールにログインします。 2.「アラート」セクションに移動し、再オープンしたいアラートを選択します。   3.「再オープン」をクリックし、「確認する」をクリックします。 ↓   4.画面右上に「アラートは正常に再オープンされました。」ポップアップが表示され、対象のアラートは表示されなくなりました。   5.フィルタの「アラートステータス」で「未解決」を選択してみると対象アラートの「アラートステータス」がopenになっていることが確認できました。   まとめ Prisma Cloudで検知されたアラートに対する対応には、アラートの解除、一時停止等多くの選択肢があります。ユースケースに合わせて活用することで、安全で効率的なクラウド環境を維持することができます。クラウドのセキュリティ管理には迅速かつ正確な対応が求められるため、Prisma Cloudのアラート機能をしっかりと活用することが重要です。このブログが、Prisma Cloudのアラート管理についての理解を深める一助となれば幸いです。 また、当社では、複数クラウド環境の設定状況を自動でチェックし、設定ミスやコンプライアンス違反、異常行動などのリスクを診断するCSPMソリューションを販売しております。   ■マルチクラウド設定診断サービス with CSPM マルチクラウド設定診断サービス with CSPM| SCSK株式会社 ■Smart One Cloud Security CSPM | Smart One Cloud Security® Powered by Prisma Cloud from Palo Alto Networks | SCSK株式会社 ご興味のある方はお気軽にお問い合わせください。